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

4.115
Last change on this file since c972c36 was c972c36, checked in by Sebastian Huber <sebastian.huber@…>, on 08/24/11 at 09:51:30

2011-08-24 Sebastian Huber <sebastian.huber@…>

  • console/polled_io.c: Update due to API changes.
  • 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.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
384#endif /* USE_KBD_SUPPORT */
385
386
387/* Early messages after mm init but before console init are kept in log
388 * buffers.
389 */
390#define PAGE_LOG_CHARS (PAGE_SIZE-sizeof(int)-sizeof(u_long)-1)
391
392typedef struct _console_log {
393        struct _console_log *next;
394        int offset;
395        u_char data[PAGE_LOG_CHARS];
396} console_log;
397
398#ifdef STATIC_LOG_ALLOC
399
400#define STATIC_LOG_DATA_PAGE_NB 3
401
402static  u_char  log_page_pool   [STATIC_LOG_DATA_PAGE_NB * PAGE_SIZE];
403
404#endif
405#endif
406
407static board_memory_map mem_map = {
408  (__io_ptr) _IO_BASE,          /* from libcpu/io.h */
409  (__io_ptr) _ISA_MEM_BASE,
410};
411
412board_memory_map *ptr_mem_map = &mem_map;
413
414#if 0
415struct _console_global_data {
416        console_log *log;
417        int vacuum_sent;
418        int lines;
419        int cols;
420        int orig_x;
421        int orig_y;
422        u_char shfts, ctls, alts, caps;
423} console_global_data = {NULL, 0, 25, 80, 0, 24, 0, 0, 0, 0};
424
425typedef struct console_io {
426        void    (*putc) (const u_char);
427        int     (*getc) (void);
428        int     (*tstc) (void);
429}console_io;
430
431extern console_io* curIo;
432
433void debug_putc(const u_char c)
434{
435  curIo->putc(c);
436}
437
438/* const char arg to be compatible with BSP_output_char decl. */
439void
440debug_putc_onlcr(const char c)
441{
442        if ('\n'==c)
443                debug_putc('\r');
444        debug_putc(c);
445}
446
447int debug_getc(void)
448{
449  return curIo->getc();
450}
451
452int debug_tstc(void)
453{
454  return curIo->tstc();
455}
456
457#define vidmem ((__io_ptr)(ptr_mem_map->isa_mem_base+0xb8000))
458
459void vacuum_putc(u_char c) {
460        console_global_data.vacuum_sent++;
461}
462
463int vacuum_getc(void) {
464        return -1;
465}
466
467int vacuum_tstc(void) {
468        return 0;
469}
470
471/*
472 * COM1 NS16550 support
473 */
474
475#define rbr 0
476#define ier 1
477#define fcr 2
478#define lcr 3
479#define mcr 4
480#define lsr 5
481#define msr 6
482#define scr 7
483#define thr rbr
484#define iir fcr
485#define dll rbr
486#define dlm ier
487
488#define LSR_DR   0x01  /* Data ready */
489#define LSR_OE   0x02  /* Overrun */
490#define LSR_PE   0x04  /* Parity error */
491#define LSR_FE   0x08  /* Framing error */
492#define LSR_BI   0x10  /* Break */
493#define LSR_THRE 0x20  /* Xmit holding register empty */
494#define LSR_TEMT 0x40  /* Xmitter empty */
495#define LSR_ERR  0x80  /* Error */
496
497
498#ifdef STATIC_LOG_ALLOC
499static int global_index = 0;
500
501static void *__palloc(int s)
502{
503  if (global_index ==( STATIC_LOG_DATA_PAGE_NB - 1) ) return (void*) 0;
504  return  (void*) &(log_page_pool [PAGE_SIZE * global_index++]);
505}
506
507static void pfree(void* p)
508{
509  --global_index;
510}
511#endif
512
513
514void log_putc(const u_char c) {
515        console_log *l;
516        for(l=console_global_data.log; l; l=l->next) {
517                if (l->offset<PAGE_LOG_CHARS) break;
518        }
519        if (!l) {
520                l=__palloc(sizeof(console_log));
521                memset(l, 0, sizeof(console_log));
522                if (!console_global_data.log)
523                        console_global_data.log = l;
524                else {
525                        console_log *p;
526                        for (p=console_global_data.log;
527                             p->next; p=p->next);
528                        p->next = l;
529                }
530        }
531        l->data[l->offset++] = c;
532}
533
534/* This puts is non standard since it does not automatically add a newline
535 * at the end. So it is made private to avoid confusion in other files.
536 */
537static
538void puts(const u_char *s)
539{
540        char c;
541
542        while ( ( c = *s++ ) != '\0' ) {
543                                debug_putc_onlcr((const char)c);
544        }
545}
546
547
548static
549void flush_log(void) {
550        console_log *p, *next;
551        if (console_global_data.vacuum_sent) {
552#ifdef TRACE_FLUSH_LOG
553                printk("%d characters sent into oblivion before MM init!\n",
554                       console_global_data.vacuum_sent);
555#endif
556        }
557        for(p=console_global_data.log; p; p=next) {
558                puts(p->data);
559                next = p->next;
560                pfree(p);
561        }
562}
563
564#ifndef INL_CONSOLE_INB
565#error "BSP probably didn't define a console port"
566#endif
567
568void serial_putc(const u_char c)
569{
570        while ((INL_CONSOLE_INB(lsr) & LSR_THRE) == 0) ;
571        INL_CONSOLE_OUTB(thr, c);
572}
573
574int serial_getc(void)
575{
576        while ((INL_CONSOLE_INB(lsr) & LSR_DR) == 0) ;
577        return (INL_CONSOLE_INB(rbr));
578}
579
580int serial_tstc(void)
581{
582        return ((INL_CONSOLE_INB(lsr) & LSR_DR) != 0);
583}
584
585#ifdef USE_VGA_SUPPORT
586static void scroll(void)
587{
588        int i;
589
590        memcpy ( (u_char *)vidmem, (u_char *)vidmem + console_global_data.cols * 2,
591                 ( console_global_data.lines - 1 ) * console_global_data.cols * 2 );
592        for ( i = ( console_global_data.lines - 1 ) * console_global_data.cols * 2;
593              i < console_global_data.lines * console_global_data.cols * 2;
594              i += 2 )
595                vidmem[i] = ' ';
596}
597
598/*
599 * cursor() sets an offset (0-1999) into the 80x25 text area
600 */
601static void
602cursor(int x, int y)
603{
604        int pos = console_global_data.cols*y + x;
605        vga_outb(14, 0x14);
606        vga_outb(0x15, pos>>8);
607        vga_outb(0x14, 15);
608        vga_outb(0x15, pos);
609}
610
611void
612vga_putc(const u_char c)
613{
614        int x,y;
615
616        x = console_global_data.orig_x;
617        y = console_global_data.orig_y;
618
619        if ( c == '\n' ) {
620                if ( ++y >= console_global_data.lines ) {
621                        scroll();
622                        y--;
623                }
624        } else if (c == '\b') {
625                if (x > 0) {
626                        x--;
627                }
628        } else if (c == '\r') {
629                x = 0;
630        } else {
631                vidmem [ ( x + console_global_data.cols * y ) * 2 ] = c;
632                if ( ++x >= console_global_data.cols ) {
633                        x = 0;
634                        if ( ++y >= console_global_data.lines ) {
635                                scroll();
636                                y--;
637                        }
638                }
639        }
640
641        cursor(x, y);
642
643        console_global_data.orig_x = x;
644        console_global_data.orig_y = y;
645}
646#endif /* USE_VGA_SUPPORT */
647
648#ifdef USE_KBD_SUPPORT
649/* Keyboard support */
650static int kbd_getc(void)
651{
652        unsigned char dt, brk, val;
653        unsigned code;
654loop:
655        while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
656
657        dt = kbd_inb(KBD_DATA_REG);
658
659        brk = dt & 0x80;        /* brk == 1 on key release */
660        dt = dt & 0x7f;         /* keycode */
661
662        if (console_global_data.shfts)
663            code = shift_map[dt];
664        else if (console_global_data.ctls)
665            code = ctrl_map[dt];
666        else
667            code = plain_map[dt];
668
669        val = KVAL(code);
670        switch (KTYP(code) & 0x0f) {
671            case KT_LATIN:
672                if (brk)
673                    break;
674                if (console_global_data.alts)
675                    val |= 0x80;
676                if (val == 0x7f)        /* map delete to backspace */
677                    val = '\b';
678                return val;
679
680            case KT_LETTER:
681                if (brk)
682                    break;
683                if (console_global_data.caps)
684                    val -= 'a'-'A';
685                return val;
686
687            case KT_SPEC:
688                if (brk)
689                    break;
690                if (val == KVAL(K_CAPS))
691                    console_global_data.caps = !console_global_data.caps;
692                else if (val == KVAL(K_ENTER)) {
693enter:              /* Wait for key up */
694                    while (1) {
695                        while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
696                        dt = kbd_inb(KBD_DATA_REG);
697                        if (dt & 0x80) /* key up */ break;
698                    }
699                    return 10;
700                }
701                break;
702
703            case KT_PAD:
704                if (brk)
705                    break;
706                if (val < 10)
707                    return val;
708                if (val == KVAL(K_PENTER))
709                    goto enter;
710                break;
711
712            case KT_SHIFT:
713                switch (val) {
714                    case KG_SHIFT:
715                    case KG_SHIFTL:
716                    case KG_SHIFTR:
717                        console_global_data.shfts = brk ? 0 : 1;
718                        break;
719                    case KG_ALT:
720                    case KG_ALTGR:
721                        console_global_data.alts = brk ? 0 : 1;
722                        break;
723                    case KG_CTRL:
724                    case KG_CTRLL:
725                    case KG_CTRLR:
726                        console_global_data.ctls = brk ? 0 : 1;
727                        break;
728                }
729                break;
730
731            case KT_LOCK:
732                switch (val) {
733                    case KG_SHIFT:
734                    case KG_SHIFTL:
735                    case KG_SHIFTR:
736                        if (brk)
737                            console_global_data.shfts = !console_global_data.shfts;
738                        break;
739                    case KG_ALT:
740                    case KG_ALTGR:
741                        if (brk)
742                            console_global_data.alts = !console_global_data.alts;
743                        break;
744                    case KG_CTRL:
745                    case KG_CTRLL:
746                    case KG_CTRLR:
747                        if (brk)
748                            console_global_data.ctls = !console_global_data.ctls;
749                        break;
750                }
751                break;
752        }
753        /* if (brk) return (0); */  /* Ignore initial 'key up' codes */
754        goto loop;
755}
756
757static int kbd_get(int ms) {
758        int status, data;
759        while(1) {
760                status = kbd_inb(KBD_STATUS_REG);
761                if (status & KBD_STAT_OBF) {
762                        data = kbd_inb(KBD_DATA_REG);
763                        if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
764                                return -1;
765                        else
766                                return data;
767                }
768                if (--ms < 0) return -1;
769#ifdef __BOOT__
770                boot_udelay(1000);
771#else
772                rtems_bsp_delay(1000);
773#endif
774        }
775}
776
777static void kbd_put(u_char c, int ms, int port) {
778        while (kbd_inb(KBD_STATUS_REG) & KBD_STAT_IBF) {
779                if (--ms < 0) return;
780#ifdef __BOOT__
781                boot_udelay(1000);
782#else
783                rtems_bsp_delay(1000);
784#endif
785        }
786        kbd_outb(port, c);
787}
788
789int kbdreset(void)
790{
791        int c;
792
793        /* Flush all pending data */
794        while(kbd_get(10) != -1);
795
796        /* Send self-test */
797        kbd_put(KBD_CCMD_SELF_TEST, 10, KBD_CNTL_REG);
798        c = kbd_get(1000);
799        if (c != 0x55) return 1;
800
801        /* Enable then reset the KB */
802        kbd_put(KBD_CCMD_KBD_ENABLE, 10, KBD_CNTL_REG);
803
804        while (1) {
805                kbd_put(KBD_CMD_RESET, 10, KBD_DATA_REG);
806                c = kbd_get(1000);
807                if (c == KBD_REPLY_ACK) break;
808                if (c != KBD_REPLY_RESEND) return 2;
809        }
810
811        if (kbd_get(1000) != KBD_REPLY_POR) return 3;
812
813        /* Disable the keyboard while setting up the controller */
814        kbd_put(KBD_CMD_DISABLE, 10, KBD_DATA_REG);
815        if (kbd_get(10)!=KBD_REPLY_ACK) return 4;
816
817        /* Enable interrupts and keyboard controller */
818        kbd_put(KBD_CCMD_WRITE_MODE, 10, KBD_CNTL_REG);
819        kbd_put(KBD_MODE_KBD_INT | KBD_MODE_SYS |
820                KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC,
821                10, KBD_DATA_REG);
822
823        /* Reenable the keyboard */
824        kbd_put(KBD_CMD_ENABLE, 10, KBD_DATA_REG);
825        if (kbd_get(10)!=KBD_REPLY_ACK) return 5;
826
827        return 0;
828}
829
830int kbd_tstc(void)
831{
832        return ((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0);
833}
834#endif /* USE_KBD_SUPPORT */
835
836const struct console_io
837vacuum_console_functions = {
838        vacuum_putc,
839        vacuum_getc,
840        vacuum_tstc
841};
842
843static const struct console_io
844log_console_functions = {
845        log_putc,
846        vacuum_getc,
847        vacuum_tstc
848}
849,
850serial_console_functions = {
851        serial_putc,
852        serial_getc,
853        serial_tstc
854}
855#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
856,
857vga_console_functions = {
858        vga_putc,
859        kbd_getc,
860        kbd_tstc
861}
862#endif
863;
864
865console_io* curIo = (console_io*) &vacuum_console_functions;
866
867int select_console(ioType t) {
868  static ioType curType = CONSOLE_VACUUM;
869
870  switch (t) {
871  case CONSOLE_VACUUM   : curIo = (console_io*)&vacuum_console_functions; break;
872  case CONSOLE_LOG      : curIo = (console_io*)&log_console_functions; break;
873  case CONSOLE_SERIAL   : curIo = (console_io*)&serial_console_functions; break;
874#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
875  case CONSOLE_VGA      : curIo = (console_io*)&vga_console_functions; break;
876#endif
877  default               : curIo = (console_io*)&vacuum_console_functions;break;
878  }
879  if (curType == CONSOLE_LOG) flush_log();
880  curType = t;
881  return 0;
882}
883
884/* we use this so that we can do without the ctype library */
885#define is_digit(c)     ((c) >= '0' && (c) <= '9')
886
887
888/* provide this for the bootloader only; otherwise
889 * use libcpu implementation
890 */
891#if defined(__BOOT__)
892static int skip_atoi(const char **s)
893{
894        int i=0;
895
896        while (is_digit(**s))
897                i = i*10 + *((*s)++) - '0';
898        return i;
899}
900
901/* Based on linux/lib/vsprintf.c and modified to suit our needs,
902 * bloat has been limited since we basically only need %u, %x, %s and %c.
903 * But we need 64 bit values !
904 */
905int k_vsprintf(char *buf, const char *fmt, va_list args);
906
907int printk(const char *fmt, ...) {
908        va_list args;
909        int i;
910        /* Should not be a problem with 8kB of stack */
911        char buf[1024];
912
913        va_start(args, fmt);
914        i = k_vsprintf(buf, fmt, args);
915        va_end(args);
916        puts(buf);
917        return  i;
918}
919
920#endif
921
922/* Necessary to avoid including a library, and GCC won't do this inline. */
923#define div10(num, rmd)                                                  \
924do {    u32 t1, t2, t3;                                                  \
925        __asm__ ("lis %4,0xcccd; "                                               \
926            "addi %4,%4,0xffffcccd; "   /* Build 0xcccccccd */           \
927            "mulhwu %3,%0+1,%4; "       /* (num.l*cst.l).h  */           \
928            "mullw %2,%0,%4; "          /* (num.h*cst.l).l  */           \
929            "addc %3,%3,%2; "                                            \
930            "mulhwu %2,%0,%4; "         /* (num.h*cst.l).h  */           \
931            "addi %4,%4,-1; "           /* Build 0xcccccccc */           \
932            "mullw %1,%0,%4; "          /* (num.h*cst.h).l  */           \
933            "adde %2,%2,%1; "                                            \
934            "mulhwu %1,%0,%4; "         /* (num.h*cst.h).h  */           \
935            "addze %1,%1; "                                              \
936            "mullw %0,%0+1,%4; "        /* (num.l*cst.h).l  */           \
937            "addc %3,%3,%0; "                                            \
938            "mulhwu %0,%0+1,%4; "       /* (num.l*cst.h).h  */           \
939            "adde %2,%2,%0; "                                            \
940            "addze %1,%1; "                                              \
941            "srwi %2,%2,3; "                                             \
942            "srwi %0,%1,3; "                                             \
943            "rlwimi %2,%1,29,0,2; "                                      \
944            "mulli %4,%2,10; "                                           \
945            "sub %4,%0+1,%4; "                                           \
946            "mr %0+1,%2; " :                                             \
947            "=r" (num), "=&r" (t1), "=&r" (t2), "=&r"(t3), "=&b" (rmd) : \
948            "0" (num));                                                  \
949                                                                         \
950} while(0);
951
952#define SIGN    1               /* unsigned/signed long */
953#define LARGE   2               /* use 'ABCDEF' instead of 'abcdef' */
954#define HEX     4               /* hexadecimal instead of decimal */
955#define ADDR    8               /* Value is an addres (p) */
956#define ZEROPAD 16              /* pad with zero */
957#define HALF    32
958#define LONG    64              /* long argument */
959#define LLONG   128             /* 64 bit argument */
960
961#if defined(__BOOT__)
962static char * number(char * str, int size, int type, u64 num)
963{
964        char fill,sign,tmp[24];
965        const char *digits="0123456789abcdef";
966        int i;
967
968        if (type & LARGE)
969                digits = "0123456789ABCDEF";
970        fill = (type & ZEROPAD) ? '0' : ' ';
971        sign = 0;
972        if (type & SIGN) {
973                if ((s64)num <0) {
974                        sign = '-';
975                        num = -num;
976                        size--;
977                }
978        }
979
980        i = 0;
981        do {
982                unsigned rem;
983                if (type&HEX) {
984                        rem = num & 0x0f;
985                        num >>=4;
986                } else {
987                        div10(num, rem);
988                }
989                tmp[i++] = digits[rem];
990        } while (num != 0);
991
992        size -= i;
993        if (!(type&(ZEROPAD)))
994                while(size-->0)
995                        *str++ = ' ';
996        if (sign)
997                *str++ = sign;
998
999        while (size-- > 0)
1000                *str++ = fill;
1001        while (i-- > 0)
1002                *str++ = tmp[i];
1003        while (size-- > 0)
1004                *str++ = ' ';
1005        return str;
1006}
1007
1008int k_vsprintf(char *buf, const char *fmt, va_list args)
1009{
1010        int len;
1011        u64 num;
1012        int i;
1013        char * str;
1014        const char *s;
1015
1016        int flags;              /* flags to number() and private */
1017
1018        int field_width;        /* width of output field */
1019
1020        for (str=buf ; *fmt ; ++fmt) {
1021                if (*fmt != '%') {
1022                        *str++ = *fmt;
1023                        continue;
1024                }
1025
1026                /* process flags, only 0 padding needed */
1027                flags = 0;
1028                if (*++fmt == '0' ) {
1029                        flags |= ZEROPAD;
1030                        fmt++;
1031                }
1032
1033                /* get field width */
1034                field_width = -1;
1035                if (is_digit(*fmt))
1036                        field_width = skip_atoi(&fmt);
1037
1038                /* get the conversion qualifier */
1039                if (*fmt == 'h') {
1040                        flags |= HALF;
1041                        fmt++;
1042                } else if (*fmt == 'L') {
1043                        flags |= LLONG;
1044                        fmt++;
1045                } else if (*fmt == 'l') {
1046                        flags |= LONG;
1047                        fmt++;
1048                }
1049
1050                switch (*fmt) {
1051                case 'c':
1052                        *str++ = (unsigned char) va_arg(args, int);
1053                        while (--field_width > 0)
1054                                *str++ = ' ';
1055                        continue;
1056
1057                case 's':
1058                        s = va_arg(args, char *);
1059                        len = strlen(s);
1060
1061                        for (i = 0; i < len; ++i)
1062                                *str++ = *s++;
1063                        while (len < field_width--)
1064                                *str++ = ' ';
1065                        continue;
1066
1067                case 'p':
1068                        if (field_width == -1) {
1069                                field_width = 2*sizeof(void *);
1070                        }
1071                        flags |= ZEROPAD|HEX|ADDR;
1072                        break;
1073
1074                case 'X':
1075                        flags |= LARGE;
1076                case 'x':
1077                        flags |= HEX;
1078                        break;
1079
1080                case 'd':
1081                case 'i':
1082                        flags |= SIGN;
1083                case 'u':
1084                        break;
1085
1086                default:
1087                        if (*fmt != '%')
1088                                *str++ = '%';
1089                        if (*fmt)
1090                                *str++ = *fmt;
1091                        else
1092                                --fmt;
1093                        continue;
1094                }
1095                /* This ugly code tries to minimize the number of va_arg()
1096                 * since they expand to a lot of code on PPC under the SYSV
1097                 * calling conventions (but not with -mcall-aix which has
1098                 * other problems). Arguments have at least the size of a
1099                 * long allocated, and we use this fact to minimize bloat.
1100                 * (and pointers are assimilated to unsigned long too).
1101                 */
1102                if (sizeof(long long) > sizeof(long) && flags & LLONG)
1103                        num = va_arg(args, unsigned long long);
1104                else {
1105                        u_long n = va_arg(args, unsigned long);
1106                        if (flags & HALF) {
1107                                if (flags & SIGN)
1108                                        n = (short) n;
1109                                else
1110                                        n = (unsigned short) n;
1111                        } else if (! flags & LONG) {
1112                                /* Here the compiler correctly removes this
1113                                 * do nothing code on 32 bit PPC.
1114                                 */
1115                                if (flags & SIGN)
1116                                        n = (int) n;
1117                                else
1118                                        n = (unsigned) n;
1119                        }
1120                        if (flags & SIGN)  num = (long) n; else num = n;
1121                }
1122                str = number(str, field_width, flags, num);
1123        }
1124        *str = '\0';
1125        return str-buf;
1126}
1127#endif
1128#endif
Note: See TracBrowser for help on using the repository browser.