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

4.104.114.84.95
Last change on this file since e79a1947 was f05b2ac, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/21/04 at 16:01:48

Remove duplicate white lines.

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