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

4.104.114.84.95
Last change on this file since e422da8 was e422da8, checked in by Joel Sherrill <joel.sherrill@…>, on 09/07/07 at 16:15:27

2007-09-07 Joel Sherrill <joel.sherrill@…>

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