source: rtems/c/src/lib/libbsp/powerpc/ep1a/console/polled_io.c @ 76094b5

4.115
Last change on this file since 76094b5 was 76094b5, checked in by Joel Sherrill <joel.sherrill@…>, on 08/15/10 at 23:30:59

2010-08-15 Joel Sherrill <joel.sherrilL@…>

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