source: rtems/c/src/lib/libbsp/powerpc/shared/console/polled_io.c @ 69ed59f

4.104.114.84.95
Last change on this file since 69ed59f was 69ed59f, checked in by Joel Sherrill <joel.sherrill@…>, on May 14, 2002 at 5:10:17 PM

2001-05-14 Till Straumann <strauman@…>

  • bootloader/misc.c, console/Makefile.am, console/console.c, console/consoleIo.h, console/inch.c, console/polled_io.c, console/uart.c, console/uart.h, include/bsp.h, irq/Makefile.am, irq/irq.c, irq/irq.h, irq/irq_init.c, openpic/openpic.c, openpic/openpic.h, pci/Makefile.am, pci/pci.c, pci/pci.h, residual/Makefile.am, start/start.S, startup/bspstart.c, vectors/vectors.S, vectors/vectors.h, vectors/vectors_init.c: Per PR216, "libbsp/powerpc/shared" BSP has been modified considerably with the goal to make it more flexible and reusable by other BSPs. The main strategies were:
    • eliminate hardcoded base addresses; devices use offsets and a BSP defined base address.
    • separate functionality into different files (e.g. reboot from inch.c to reboot.c) which can be overridden by a 'derived' BSP.
    • separate initialization code into separate files (e.g. PCI bridge detection/initialization was separated from the more generic PCI access routines), also to make it easier for 'derived' BSPs to substitute their own initialization code.

There are also a couple of enhancements and fixes:

  • IRQ handling code now has a hook for attaching a VME bridge.
  • OpenPIC is now explicitely initialized (polarities, senses). Eliminated the implicit assumption on the presence of an ISA PIC.
  • UART and console driver now supports more than 1 port. The current maximum of 2 can easily be extended by enlarging a table (it would even be easier if the ISR API was not broken by design).
  • fixed polled_io.c so it correctly supports console on COM2
  • fixed TLB invalidation code (start.S).
  • exception handler prints a stack backtrace.
  • added BSP_pciFindDevice() to scan the pci bus for a particular vendor/device/instance.
  • Property mode set to 100644
File size: 28.7 KB
Line 
1/*
2 *  polled_io.c -- Basic input/output for early boot
3 *
4 *  Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
5 *
6 *  Modified to compile in RTEMS development environment
7 *  by Eric Valette
8 *
9 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
10 *
11 *  The license and distribution terms for this file may be
12 *  found in found in the file LICENSE in this distribution or at
13 *  http://www.OARcorp.com/rtems/license.html.
14 *
15 * $Id$
16 */
17
18#include <rtems/system.h>
19#include <sys/types.h>
20#include <libcpu/byteorder.h>
21#include <libcpu/page.h>
22#include <libcpu/mmu.h>
23#include <libcpu/io.h>
24#include <string.h>
25#include <stdarg.h>
26#include <bsp/consoleIo.h>
27#include <bsp.h>
28#include <libcpu/spr.h>
29
30#ifdef BSP_KBD_IOBASE
31#define USE_KBD_SUPPORT
32#endif
33#ifdef BSP_VGA_IOBASE
34#define USE_VGA_SUPPORT
35#endif
36
37#ifdef USE_KBD_SUPPORT
38#include "keyboard.h"
39#endif
40#include "console.inl"
41
42#ifdef __BOOT__
43extern void boot_udelay();
44#endif
45
46typedef unsigned long long u64;
47typedef long long s64;
48typedef unsigned int u32;
49
50#ifdef USE_KBD_SUPPORT
51unsigned short plain_map[NR_KEYS] = {
52        0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
53        0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
54        0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
55        0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
56        0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
57        0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
58        0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
59        0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
60        0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
61        0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
62        0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
63        0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
64        0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
65        0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
66        0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
67        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
68};
69
70unsigned short shift_map[NR_KEYS] = {
71        0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
72        0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
73        0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
74        0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
75        0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
76        0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
77        0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
78        0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
79        0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
80        0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
81        0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
82        0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
83        0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
84        0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
85        0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
86        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
87};
88
89unsigned short altgr_map[NR_KEYS] = {
90        0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
91        0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
92        0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
93        0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
94        0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
95        0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
96        0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
97        0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
98        0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
99        0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
100        0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
101        0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
102        0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
103        0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
104        0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
105        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
106};
107
108unsigned short ctrl_map[NR_KEYS] = {
109        0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
110        0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
111        0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
112        0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
113        0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
114        0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
115        0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
116        0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
117        0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
118        0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
119        0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
120        0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
121        0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
122        0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
123        0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
124        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
125};
126
127unsigned short shift_ctrl_map[NR_KEYS] = {
128        0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
129        0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
130        0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
131        0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
132        0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
133        0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
134        0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
135        0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
136        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
137        0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
138        0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
139        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
140        0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
141        0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
142        0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
143        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
144};
145
146unsigned short alt_map[NR_KEYS] = {
147        0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
148        0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
149        0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
150        0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
151        0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
152        0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
153        0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
154        0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
155        0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
156        0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
157        0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
158        0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
159        0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
160        0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
161        0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
162        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
163};
164
165unsigned short ctrl_alt_map[NR_KEYS] = {
166        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
167        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
168        0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
169        0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
170        0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
171        0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
172        0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
173        0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
174        0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
175        0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
176        0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
177        0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
178        0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
179        0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
180        0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
181        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
182};
183
184ushort *key_maps[MAX_NR_KEYMAPS] = {
185        plain_map, shift_map, altgr_map, 0,
186        ctrl_map, shift_ctrl_map, 0, 0,
187        alt_map, 0, 0, 0,
188        ctrl_alt_map,   0
189};
190
191unsigned int keymap_count = 7;
192
193/*
194 * Philosophy: most people do not define more strings, but they who do
195 * often want quite a lot of string space. So, we statically allocate
196 * the default and allocate dynamically in chunks of 512 bytes.
197 */
198
199char func_buf[] = {
200        '\033', '[', '[', 'A', 0, 
201        '\033', '[', '[', 'B', 0, 
202        '\033', '[', '[', 'C', 0, 
203        '\033', '[', '[', 'D', 0, 
204        '\033', '[', '[', 'E', 0, 
205        '\033', '[', '1', '7', '~', 0, 
206        '\033', '[', '1', '8', '~', 0, 
207        '\033', '[', '1', '9', '~', 0, 
208        '\033', '[', '2', '0', '~', 0, 
209        '\033', '[', '2', '1', '~', 0, 
210        '\033', '[', '2', '3', '~', 0, 
211        '\033', '[', '2', '4', '~', 0, 
212        '\033', '[', '2', '5', '~', 0, 
213        '\033', '[', '2', '6', '~', 0, 
214        '\033', '[', '2', '8', '~', 0, 
215        '\033', '[', '2', '9', '~', 0, 
216        '\033', '[', '3', '1', '~', 0, 
217        '\033', '[', '3', '2', '~', 0, 
218        '\033', '[', '3', '3', '~', 0, 
219        '\033', '[', '3', '4', '~', 0, 
220        '\033', '[', '1', '~', 0, 
221        '\033', '[', '2', '~', 0, 
222        '\033', '[', '3', '~', 0, 
223        '\033', '[', '4', '~', 0, 
224        '\033', '[', '5', '~', 0, 
225        '\033', '[', '6', '~', 0, 
226        '\033', '[', 'M', 0, 
227        '\033', '[', 'P', 0, 
228};
229
230char *funcbufptr = func_buf;
231int funcbufsize = sizeof(func_buf);
232int funcbufleft = 0;          /* space left */
233
234char *func_table[MAX_NR_FUNC] = {
235        func_buf + 0,
236        func_buf + 5,
237        func_buf + 10,
238        func_buf + 15,
239        func_buf + 20,
240        func_buf + 25,
241        func_buf + 31,
242        func_buf + 37,
243        func_buf + 43,
244        func_buf + 49,
245        func_buf + 55,
246        func_buf + 61,
247        func_buf + 67,
248        func_buf + 73,
249        func_buf + 79,
250        func_buf + 85,
251        func_buf + 91,
252        func_buf + 97,
253        func_buf + 103,
254        func_buf + 109,
255        func_buf + 115,
256        func_buf + 120,
257        func_buf + 125,
258        func_buf + 130,
259        func_buf + 135,
260        func_buf + 140,
261        func_buf + 145,
262        0,
263        0,
264        func_buf + 149,
265        0,
266};
267
268struct kbdiacr {
269        unsigned char diacr, base, result;
270};
271
272struct kbdiacr accent_table[MAX_DIACR] = {
273        {'`', 'A', '\300'},     {'`', 'a', '\340'},
274        {'\'', 'A', '\301'},    {'\'', 'a', '\341'},
275        {'^', 'A', '\302'},     {'^', 'a', '\342'},
276        {'~', 'A', '\303'},     {'~', 'a', '\343'},
277        {'"', 'A', '\304'},     {'"', 'a', '\344'},
278        {'O', 'A', '\305'},     {'o', 'a', '\345'},
279        {'0', 'A', '\305'},     {'0', 'a', '\345'},
280        {'A', 'A', '\305'},     {'a', 'a', '\345'},
281        {'A', 'E', '\306'},     {'a', 'e', '\346'},
282        {',', 'C', '\307'},     {',', 'c', '\347'},
283        {'`', 'E', '\310'},     {'`', 'e', '\350'},
284        {'\'', 'E', '\311'},    {'\'', 'e', '\351'},
285        {'^', 'E', '\312'},     {'^', 'e', '\352'},
286        {'"', 'E', '\313'},     {'"', 'e', '\353'},
287        {'`', 'I', '\314'},     {'`', 'i', '\354'},
288        {'\'', 'I', '\315'},    {'\'', 'i', '\355'},
289        {'^', 'I', '\316'},     {'^', 'i', '\356'},
290        {'"', 'I', '\317'},     {'"', 'i', '\357'},
291        {'-', 'D', '\320'},     {'-', 'd', '\360'},
292        {'~', 'N', '\321'},     {'~', 'n', '\361'},
293        {'`', 'O', '\322'},     {'`', 'o', '\362'},
294        {'\'', 'O', '\323'},    {'\'', 'o', '\363'},
295        {'^', 'O', '\324'},     {'^', 'o', '\364'},
296        {'~', 'O', '\325'},     {'~', 'o', '\365'},
297        {'"', 'O', '\326'},     {'"', 'o', '\366'},
298        {'/', 'O', '\330'},     {'/', 'o', '\370'},
299        {'`', 'U', '\331'},     {'`', 'u', '\371'},
300        {'\'', 'U', '\332'},    {'\'', 'u', '\372'},
301        {'^', 'U', '\333'},     {'^', 'u', '\373'},
302        {'"', 'U', '\334'},     {'"', 'u', '\374'},
303        {'\'', 'Y', '\335'},    {'\'', 'y', '\375'},
304        {'T', 'H', '\336'},     {'t', 'h', '\376'},
305        {'s', 's', '\337'},     {'"', 'y', '\377'},
306        {'s', 'z', '\337'},     {'i', 'j', '\377'},
307};
308
309unsigned int accent_table_size = 68;
310
311
312
313
314/* These #defines have been copied from drivers/char/pc_keyb.h, by
315 * Martin Mares (mj@ucw.cz). 
316 * converted to offsets by Till Straumann <strauman@slac.stanford.edu>
317 */
318#define KBD_STATUS_REG          0x4     /* Status register (R) */
319#define KBD_CNTL_REG            0x4     /* Controller command register (W) */
320#define KBD_DATA_REG            0x0     /* Keyboard data register (R/W) */
321
322/*
323 *      Keyboard Controller Commands
324 */
325
326#define KBD_CCMD_WRITE_MODE     0x60    /* Write mode bits */
327#define KBD_CCMD_GET_VERSION    0xA1    /* Get controller version */
328#define KBD_CCMD_MOUSE_DISABLE  0xA7    /* Disable mouse interface */
329#define KBD_CCMD_MOUSE_ENABLE   0xA8    /* Enable mouse interface */
330#define KBD_CCMD_TEST_MOUSE     0xA9    /* Mouse interface test */
331#define KBD_CCMD_SELF_TEST      0xAA    /* Controller self test */
332#define KBD_CCMD_KBD_TEST       0xAB    /* Keyboard interface test */
333#define KBD_CCMD_KBD_DISABLE    0xAD    /* Keyboard interface disable */
334#define KBD_CCMD_KBD_ENABLE     0xAE    /* Keyboard interface enable */
335
336/*
337 *      Keyboard Commands
338 */
339
340#define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
341#define KBD_CMD_DISABLE         0xF5    /* Disable scanning */
342#define KBD_CMD_RESET           0xFF    /* Reset */
343
344/*
345 *      Keyboard Replies
346 */
347
348#define KBD_REPLY_POR           0xAA    /* Power on reset */
349#define KBD_REPLY_ACK           0xFA    /* Command ACK */
350#define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
351
352/*
353 *      Status Register Bits
354 */
355
356#define KBD_STAT_OBF            0x01    /* Keyboard output buffer full */
357#define KBD_STAT_IBF            0x02    /* Keyboard input buffer full */
358#define KBD_STAT_UNLOCKED       0x10    /* Zero if keyboard locked */
359#define KBD_STAT_GTO            0x40    /* General receive/xmit timeout */
360#define KBD_STAT_PERR           0x80    /* Parity error */
361
362/*
363 *      Controller Mode Register Bits
364 */
365
366#define KBD_MODE_KBD_INT        0x01    /* Keyboard data generate IRQ1 */
367#define KBD_MODE_SYS            0x04    /* The system flag (?) */
368#define KBD_MODE_NO_KEYLOCK     0x08    /* The keylock doesn't affect the keyboard if set */
369#define KBD_MODE_DISABLE_KBD    0x10    /* Disable keyboard interface */
370#define KBD_MODE_DISABLE_MOUSE  0x20    /* Disable mouse interface */
371#define KBD_MODE_KCC            0x40    /* Scan code conversion to PC format */
372#define KBD_MODE_RFU            0x80
373
374SPR_RW(DEC)
375SPR_RO(PVR)
376
377#endif /* USE_KBD_SUPPORT */
378
379
380/* Early messages after mm init but before console init are kept in log
381 * buffers.
382 */
383#define PAGE_LOG_CHARS (PAGE_SIZE-sizeof(int)-sizeof(u_long)-1)
384
385typedef struct _console_log {
386        struct _console_log *next;
387        int offset;
388        u_char data[PAGE_LOG_CHARS];
389} console_log;
390
391#ifdef STATIC_LOG_ALLOC
392
393#define STATIC_LOG_DATA_PAGE_NB 3
394
395static  u_char  log_page_pool   [STATIC_LOG_DATA_PAGE_NB * PAGE_SIZE];
396
397#endif
398
399static board_memory_map mem_map = {
400  (__io_ptr) _IO_BASE,          /* from libcpu/io.h */
401  (__io_ptr) _ISA_MEM_BASE,
402};
403
404board_memory_map *ptr_mem_map = &mem_map;
405
406
407struct _console_global_data {
408        console_log *log;
409        int vacuum_sent;
410        int lines;
411        int cols;
412        int orig_x;
413        int orig_y;
414        u_char shfts, ctls, alts, caps;
415} console_global_data = {NULL, 0, 25, 80, 0, 24, 0, 0, 0, 0};
416
417typedef struct console_io {
418        void    (*putc) (const u_char);
419        int     (*getc) (void);
420        int     (*tstc) (void);
421}console_io;
422
423extern console_io* curIo;
424
425void debug_putc(const u_char c)
426{
427  curIo->putc(c);
428}
429
430int debug_getc(void)
431{
432  return curIo->getc();
433}
434
435int debug_tstc(void)
436{
437  return curIo->tstc();
438}
439
440
441
442#define vidmem ((__io_ptr)(ptr_mem_map->isa_mem_base+0xb8000))
443
444void vacuum_putc(u_char c) {
445        console_global_data.vacuum_sent++;
446}
447
448int vacuum_getc(void) {
449        return -1;
450}
451
452int vacuum_tstc(void) {
453        return 0;
454}
455
456/*
457 * COM1 NS16550 support
458 */
459
460#define rbr 0
461#define ier 1
462#define fcr 2
463#define lcr 3
464#define mcr 4
465#define lsr 5
466#define msr 6
467#define scr 7
468#define thr rbr
469#define iir fcr
470#define dll rbr
471#define dlm ier
472
473#define LSR_DR   0x01  /* Data ready */
474#define LSR_OE   0x02  /* Overrun */
475#define LSR_PE   0x04  /* Parity error */
476#define LSR_FE   0x08  /* Framing error */
477#define LSR_BI   0x10  /* Break */
478#define LSR_THRE 0x20  /* Xmit holding register empty */
479#define LSR_TEMT 0x40  /* Xmitter empty */
480#define LSR_ERR  0x80  /* Error */
481
482
483#ifdef STATIC_LOG_ALLOC
484static int global_index = 0;
485
486static void *__palloc(int s)
487{
488  if (global_index ==( STATIC_LOG_DATA_PAGE_NB - 1) ) return (void*) 0;
489  return  (void*) &(log_page_pool [PAGE_SIZE * global_index++]);
490}
491
492static void pfree(void* p)
493{
494  --global_index;
495}
496#endif
497 
498
499void log_putc(const u_char c) {
500        console_log *l;
501        for(l=console_global_data.log; l; l=l->next) {
502                if (l->offset<PAGE_LOG_CHARS) break;
503        }
504        if (!l) {
505                l=__palloc(sizeof(console_log));
506                memset(l, 0, sizeof(console_log));
507                if (!console_global_data.log) 
508                        console_global_data.log = l;
509                else {
510                        console_log *p;
511                        for (p=console_global_data.log; 
512                             p->next; p=p->next);
513                        p->next = l;
514                }
515        }
516        l->data[l->offset++] = c;
517}
518
519/* This puts is non standard since it does not automatically add a newline
520 * at the end. So it is made private to avoid confusion in other files.
521 */
522static 
523void puts(const u_char *s)
524{
525        char c;
526
527        while ( ( c = *s++ ) != '\0' ) {
528                debug_putc(c);
529                if ( c == '\n' )
530                        debug_putc('\r');
531        }
532}
533
534
535static
536void flush_log(void) {
537        console_log *p, *next;
538        if (console_global_data.vacuum_sent) {
539#ifdef TRACE_FLUSH_LOG   
540                printk("%d characters sent into oblivion before MM init!\n", 
541                       console_global_data.vacuum_sent);
542#endif         
543        }
544        for(p=console_global_data.log; p; p=next) {
545                puts(p->data);
546                next = p->next;
547                pfree(p);
548        }
549}
550
551#ifndef INL_CONSOLE_INB
552#error "BSP probably didn't define a console port"
553#endif
554
555void serial_putc(const u_char c)
556{
557        while ((INL_CONSOLE_INB(lsr) & LSR_THRE) == 0) ;
558        INL_CONSOLE_OUTB(thr, c);
559}
560 
561int serial_getc(void)
562{
563        while ((INL_CONSOLE_INB(lsr) & LSR_DR) == 0) ;
564        return (INL_CONSOLE_INB(rbr));
565}
566
567int serial_tstc(void)
568{
569        return ((INL_CONSOLE_INB(lsr) & LSR_DR) != 0);
570}
571
572#ifdef USE_VGA_SUPPORT
573static void scroll(void)
574{
575        int i;
576
577        memcpy ( (u_char *)vidmem, (u_char *)vidmem + console_global_data.cols * 2, 
578                 ( console_global_data.lines - 1 ) * console_global_data.cols * 2 );
579        for ( i = ( console_global_data.lines - 1 ) * console_global_data.cols * 2; 
580              i < console_global_data.lines * console_global_data.cols * 2; 
581              i += 2 )
582                vidmem[i] = ' ';
583}
584
585/*
586 * cursor() sets an offset (0-1999) into the 80x25 text area   
587 */
588static void
589cursor(int x, int y)
590{
591        int pos = console_global_data.cols*y + x;
592        vga_outb(14, 0x14);
593        vga_outb(0x15, pos>>8);
594        vga_outb(0x14, 15);
595        vga_outb(0x15, pos);
596}
597
598void 
599vga_putc(const u_char c)
600{
601        int x,y;
602
603        x = console_global_data.orig_x;
604        y = console_global_data.orig_y;
605
606        if ( c == '\n' ) {
607                if ( ++y >= console_global_data.lines ) {
608                        scroll();
609                        y--;
610                }
611        } else if (c == '\b') {
612                if (x > 0) {
613                        x--;
614                }
615        } else if (c == '\r') {
616                x = 0;
617        } else {
618                vidmem [ ( x + console_global_data.cols * y ) * 2 ] = c; 
619                if ( ++x >= console_global_data.cols ) {
620                        x = 0;
621                        if ( ++y >= console_global_data.lines ) {
622                                scroll();
623                                y--;
624                        }
625                }
626        }
627
628        cursor(x, y);
629
630        console_global_data.orig_x = x;
631        console_global_data.orig_y = y;
632}
633#endif /* USE_VGA_SUPPORT */
634
635#ifdef USE_KBD_SUPPORT
636/* Keyboard support */
637static int kbd_getc(void)
638{
639        unsigned char dt, brk, val;
640        unsigned code;
641loop:
642        while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
643
644        dt = kbd_inb(KBD_DATA_REG);
645
646        brk = dt & 0x80;        /* brk == 1 on key release */
647        dt = dt & 0x7f;         /* keycode */
648
649        if (console_global_data.shfts)
650            code = shift_map[dt];
651        else if (console_global_data.ctls)
652            code = ctrl_map[dt];
653        else
654            code = plain_map[dt];
655
656        val = KVAL(code);
657        switch (KTYP(code) & 0x0f) {
658            case KT_LATIN:
659                if (brk)
660                    break;
661                if (console_global_data.alts)
662                    val |= 0x80;
663                if (val == 0x7f)        /* map delete to backspace */
664                    val = '\b';
665                return val;
666
667            case KT_LETTER:
668                if (brk)
669                    break;
670                if (console_global_data.caps)
671                    val -= 'a'-'A';
672                return val;
673
674            case KT_SPEC:
675                if (brk)
676                    break;
677                if (val == KVAL(K_CAPS))
678                    console_global_data.caps = !console_global_data.caps;
679                else if (val == KVAL(K_ENTER)) {
680enter:              /* Wait for key up */
681                    while (1) {
682                        while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
683                        dt = kbd_inb(KBD_DATA_REG);
684                        if (dt & 0x80) /* key up */ break;
685                    }
686                    return 10;
687                }
688                break;
689
690            case KT_PAD:
691                if (brk)
692                    break;
693                if (val < 10)
694                    return val;
695                if (val == KVAL(K_PENTER))
696                    goto enter;
697                break;
698
699            case KT_SHIFT:
700                switch (val) {
701                    case KG_SHIFT:
702                    case KG_SHIFTL:
703                    case KG_SHIFTR:
704                        console_global_data.shfts = brk ? 0 : 1;
705                        break;
706                    case KG_ALT:
707                    case KG_ALTGR:
708                        console_global_data.alts = brk ? 0 : 1;
709                        break;
710                    case KG_CTRL:
711                    case KG_CTRLL:
712                    case KG_CTRLR:
713                        console_global_data.ctls = brk ? 0 : 1;
714                        break;
715                }
716                break;
717
718            case KT_LOCK:
719                switch (val) {
720                    case KG_SHIFT:
721                    case KG_SHIFTL:
722                    case KG_SHIFTR:
723                        if (brk)
724                            console_global_data.shfts = !console_global_data.shfts;
725                        break;
726                    case KG_ALT:
727                    case KG_ALTGR:
728                        if (brk)
729                            console_global_data.alts = !console_global_data.alts;
730                        break;
731                    case KG_CTRL:
732                    case KG_CTRLL:
733                    case KG_CTRLR:
734                        if (brk)
735                            console_global_data.ctls = !console_global_data.ctls;
736                        break;
737                }
738                break;
739        }
740        /* if (brk) return (0); */  /* Ignore initial 'key up' codes */
741        goto loop;
742}
743
744static int kbd_get(int ms) {
745        int status, data;
746        while(1) {
747                status = kbd_inb(KBD_STATUS_REG);
748                if (status & KBD_STAT_OBF) {
749                        data = kbd_inb(KBD_DATA_REG);
750                        if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
751                                return -1;
752                        else
753                                return data;
754                }
755                if (--ms < 0) return -1; 
756#ifdef __BOOT__
757                boot_udelay(1000);
758#else
759                rtems_bsp_delay(1000);
760#endif
761        }
762}
763
764static void kbd_put(u_char c, int ms, int port) {
765        while (kbd_inb(KBD_STATUS_REG) & KBD_STAT_IBF) {
766                if (--ms < 0) return; 
767#ifdef __BOOT__
768                boot_udelay(1000);
769#else
770                rtems_bsp_delay(1000);
771#endif
772        }
773        kbd_outb(port, c);
774}
775
776int kbdreset(void)
777{
778        int c;
779
780        /* Flush all pending data */
781        while(kbd_get(10) != -1);
782
783        /* Send self-test */
784        kbd_put(KBD_CCMD_SELF_TEST, 10, KBD_CNTL_REG);
785        c = kbd_get(1000);
786        if (c != 0x55) return 1;
787
788        /* Enable then reset the KB */
789        kbd_put(KBD_CCMD_KBD_ENABLE, 10, KBD_CNTL_REG);
790       
791        while (1) {
792                kbd_put(KBD_CMD_RESET, 10, KBD_DATA_REG);
793                c = kbd_get(1000);
794                if (c == KBD_REPLY_ACK) break;
795                if (c != KBD_REPLY_RESEND) return 2;
796        }
797       
798        if (kbd_get(1000) != KBD_REPLY_POR) return 3;
799
800        /* Disable the keyboard while setting up the controller */
801        kbd_put(KBD_CMD_DISABLE, 10, KBD_DATA_REG);
802        if (kbd_get(10)!=KBD_REPLY_ACK) return 4;
803
804        /* Enable interrupts and keyboard controller */
805        kbd_put(KBD_CCMD_WRITE_MODE, 10, KBD_CNTL_REG);
806        kbd_put(KBD_MODE_KBD_INT | KBD_MODE_SYS | 
807                KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC,
808                10, KBD_DATA_REG);
809
810        /* Reenable the keyboard */
811        kbd_put(KBD_CMD_ENABLE, 10, KBD_DATA_REG);
812        if (kbd_get(10)!=KBD_REPLY_ACK) return 5;
813
814        return 0;
815}
816
817int kbd_tstc(void)
818{
819        return ((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0);
820}
821#endif /* USE_KBD_SUPPORT */
822
823const struct console_io
824vacuum_console_functions = {
825        vacuum_putc, 
826        vacuum_getc, 
827        vacuum_tstc
828};
829
830static const struct console_io
831log_console_functions = {
832        log_putc, 
833        vacuum_getc, 
834        vacuum_tstc
835}
836,
837serial_console_functions = {
838        serial_putc, 
839        serial_getc, 
840        serial_tstc
841}
842#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
843,
844vga_console_functions = {
845        vga_putc, 
846        kbd_getc, 
847        kbd_tstc
848}
849#endif
850;
851
852console_io* curIo = (console_io*) &vacuum_console_functions;
853
854int select_console(ioType t) {
855  static ioType curType = CONSOLE_VACUUM;
856 
857  switch (t) {
858  case CONSOLE_VACUUM   : curIo = (console_io*)&vacuum_console_functions; break;
859  case CONSOLE_LOG      : curIo = (console_io*)&log_console_functions; break;
860  case CONSOLE_SERIAL   : curIo = (console_io*)&serial_console_functions; break;
861#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
862  case CONSOLE_VGA      : curIo = (console_io*)&vga_console_functions; break;
863#endif
864  default               : curIo = (console_io*)&vacuum_console_functions;break;
865  }
866  if (curType == CONSOLE_LOG) flush_log();
867  curType = t;
868  return 0;
869}
870
871/* we use this so that we can do without the ctype library */
872#define is_digit(c)     ((c) >= '0' && (c) <= '9')
873
874
875static int skip_atoi(const char **s)
876{
877        int i=0;
878
879        while (is_digit(**s))
880                i = i*10 + *((*s)++) - '0';
881        return i;
882}
883
884/* Based on linux/lib/vsprintf.c and modified to suit our needs,
885 * bloat has been limited since we basically only need %u, %x, %s and %c.
886 * But we need 64 bit values !
887 */
888int vsprintf(char *buf, const char *fmt, va_list args);
889
890int printk(const char *fmt, ...) {
891        va_list args;
892        int i;
893        /* Should not be a problem with 8kB of stack */
894        char buf[1024];
895       
896        va_start(args, fmt);
897        i = vsprintf(buf, fmt, args);
898        va_end(args);
899        puts(buf);
900        return  i;
901}
902
903/* Necessary to avoid including a library, and GCC won't do this inline. */
904#define div10(num, rmd)                                                  \
905do {    u32 t1, t2, t3;                                                  \
906        asm("lis %4,0xcccd; "                                            \
907            "addi %4,%4,0xffffcccd; "   /* Build 0xcccccccd */           \
908            "mulhwu %3,%0+1,%4; "       /* (num.l*cst.l).h  */           \
909            "mullw %2,%0,%4; "          /* (num.h*cst.l).l  */           \
910            "addc %3,%3,%2; "                                            \
911            "mulhwu %2,%0,%4; "         /* (num.h*cst.l).h  */           \
912            "addi %4,%4,-1; "           /* Build 0xcccccccc */           \
913            "mullw %1,%0,%4; "          /* (num.h*cst.h).l  */           \
914            "adde %2,%2,%1; "                                            \
915            "mulhwu %1,%0,%4; "         /* (num.h*cst.h).h  */           \
916            "addze %1,%1; "                                              \
917            "mullw %0,%0+1,%4; "        /* (num.l*cst.h).l  */           \
918            "addc %3,%3,%0; "                                            \
919            "mulhwu %0,%0+1,%4; "       /* (num.l*cst.h).h  */           \
920            "adde %2,%2,%0; "                                            \
921            "addze %1,%1; "                                              \
922            "srwi %2,%2,3; "                                             \
923            "srwi %0,%1,3; "                                             \
924            "rlwimi %2,%1,29,0,2; "                                      \
925            "mulli %4,%2,10; "                                           \
926            "sub %4,%0+1,%4; "                                           \
927            "mr %0+1,%2; " :                                             \
928            "=r" (num), "=&r" (t1), "=&r" (t2), "=&r"(t3), "=&b" (rmd) : \
929            "0" (num));                                                  \
930                                                                         \
931} while(0);
932
933#define SIGN    1               /* unsigned/signed long */
934#define LARGE   2               /* use 'ABCDEF' instead of 'abcdef' */
935#define HEX     4               /* hexadecimal instead of decimal */
936#define ADDR    8               /* Value is an addres (p) */
937#define ZEROPAD 16              /* pad with zero */
938#define HALF    32
939#define LONG    64              /* long argument */
940#define LLONG   128             /* 64 bit argument */
941
942static char * number(char * str, int size, int type, u64 num)
943{
944        char fill,sign,tmp[24];
945        const char *digits="0123456789abcdef";
946        int i;
947
948        if (type & LARGE)
949                digits = "0123456789ABCDEF";
950        fill = (type & ZEROPAD) ? '0' : ' ';
951        sign = 0;
952        if (type & SIGN) {
953                if ((s64)num <0) {
954                        sign = '-';
955                        num = -num;
956                        size--;
957                } 
958        }
959
960        i = 0;
961        do {
962                unsigned rem;
963                if (type&HEX) {
964                        rem = num & 0x0f;
965                        num >>=4;
966                } else {
967                        div10(num, rem);
968                }
969                tmp[i++] = digits[rem];
970        } while (num != 0);
971               
972        size -= i;
973        if (!(type&(ZEROPAD)))
974                while(size-->0)
975                        *str++ = ' ';
976        if (sign)
977                *str++ = sign;
978
979        while (size-- > 0)
980                *str++ = fill;
981        while (i-- > 0)
982                *str++ = tmp[i];
983        while (size-- > 0)
984                *str++ = ' ';
985        return str;
986}
987
988int vsprintf(char *buf, const char *fmt, va_list args)
989{
990        int len;
991        u64 num;
992        int i;
993        char * str;
994        const char *s;
995
996        int flags;              /* flags to number() and private */
997
998        int field_width;        /* width of output field */
999
1000        for (str=buf ; *fmt ; ++fmt) {
1001                if (*fmt != '%') {
1002                        *str++ = *fmt;
1003                        continue;
1004                }
1005                       
1006                /* process flags, only 0 padding needed */
1007                flags = 0;
1008                if (*++fmt == '0' ) {
1009                        flags |= ZEROPAD;
1010                        fmt++;
1011                }
1012               
1013                /* get field width */
1014                field_width = -1;
1015                if (is_digit(*fmt))
1016                        field_width = skip_atoi(&fmt);
1017
1018                /* get the conversion qualifier */
1019                if (*fmt == 'h') {
1020                        flags |= HALF;
1021                        fmt++;
1022                } else if (*fmt == 'L') {
1023                        flags |= LLONG;
1024                        fmt++;
1025                } else if (*fmt == 'l') {
1026                        flags |= LONG;
1027                        fmt++;
1028                }
1029
1030                switch (*fmt) {
1031                case 'c':
1032                        *str++ = (unsigned char) va_arg(args, int);
1033                        while (--field_width > 0)
1034                                *str++ = ' ';
1035                        continue;
1036
1037                case 's':
1038                        s = va_arg(args, char *);
1039                        len = strlen(s);
1040
1041                        for (i = 0; i < len; ++i)
1042                                *str++ = *s++;
1043                        while (len < field_width--)
1044                                *str++ = ' ';
1045                        continue;
1046
1047                case 'p':
1048                        if (field_width == -1) {
1049                                field_width = 2*sizeof(void *);
1050                        }
1051                        flags |= ZEROPAD|HEX|ADDR;
1052                        break;
1053
1054                case 'X':
1055                        flags |= LARGE;
1056                case 'x':
1057                        flags |= HEX;
1058                        break;
1059
1060                case 'd':
1061                case 'i':
1062                        flags |= SIGN;
1063                case 'u':
1064                        break;
1065
1066                default:
1067                        if (*fmt != '%')
1068                                *str++ = '%';
1069                        if (*fmt)
1070                                *str++ = *fmt;
1071                        else
1072                                --fmt;
1073                        continue;
1074                }
1075                /* This ugly code tries to minimize the number of va_arg()
1076                 * since they expand to a lot of code on PPC under the SYSV
1077                 * calling conventions (but not with -mcall-aix which has
1078                 * other problems). Arguments have at least the size of a
1079                 * long allocated, and we use this fact to minimize bloat.
1080                 * (and pointers are assimilated to unsigned long too).
1081                 */
1082                if (sizeof(long long) > sizeof(long) && flags & LLONG) 
1083                        num = va_arg(args, unsigned long long);
1084                else {
1085                        u_long n = va_arg(args, unsigned long);
1086                        if (flags & HALF) {
1087                                if (flags & SIGN)
1088                                        n = (short) n;
1089                                else
1090                                        n = (unsigned short) n;
1091                        } else if (! flags & LONG) {
1092                                /* Here the compiler correctly removes this
1093                                 * do nothing code on 32 bit PPC.
1094                                 */
1095                                if (flags & SIGN) 
1096                                        n = (int) n;
1097                                else
1098                                        n = (unsigned) n;
1099                        }
1100                        if (flags & SIGN)  num = (long) n; else num = n;
1101                }
1102                str = number(str, field_width, flags, num);
1103        }
1104        *str = '\0';
1105        return str-buf;
1106}
Note: See TracBrowser for help on using the repository browser.