source: rtems/c/src/lib/libbsp/powerpc/shared/console/polled_io.c @ 0b8a6d7

Last change on this file since 0b8a6d7 was 0b8a6d7, checked in by Joel Sherrill <joel@…>, on Mar 28, 2018 at 4:17:45 PM

Eliminate PowerPC libcpu/page.h

Started to eliminate warnings and then realized that only one one-line
macro in the file was used by a few files. The rest of the file was
was not needed. Eliminate the file.

Closes #3354.

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