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

4.115
Last change on this file since e160e41 was e160e41, checked in by Joel Sherrill <joel.sherrill@…>, on 10/09/14 at 20:15:55

powerpc/ep1a: Remove if 0 sections

There may be useful nuggets for debug and alternate configurations
in this code. There may be methods directly called by the application
which are beyond normal APIs. We have no way of knowing this based
on the comments in these files. There were no public prototypes
so the routines and code in question should have be unused private
methods.

These will always be in the source code control system as a deletion.
If some of the code is needed, justify it and provide a patch to restore
it along with a prototype in a public place if needed and a better name.

  • Property mode set to 100644
File size: 27.4 KB
Line 
1/*
2 *  polled_io.c -- Basic input/output for early boot
3 *
4 *  Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
5 *
6 *  Modified to compile in RTEMS development environment
7 *  by Eric Valette
8 *
9 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#include <rtems/system.h>
17#include <sys/types.h>
18#include <libcpu/byteorder.h>
19#include <libcpu/page.h>
20#include <libcpu/mmu.h>
21#include <libcpu/io.h>
22#include <string.h>
23#include <stdarg.h>
24#include <bsp/consoleIo.h>
25#include <bsp.h>
26#include <libcpu/spr.h>
27
28#if 0
29#ifdef BSP_KBD_IOBASE
30#define USE_KBD_SUPPORT
31#endif
32#ifdef BSP_VGA_IOBASE
33#define USE_VGA_SUPPORT
34#endif
35
36#ifdef USE_KBD_SUPPORT
37#include "keyboard.h"
38#endif
39#include "console.inl"
40
41#ifdef __BOOT__
42extern void boot_udelay();
43void * __palloc(u_long);
44void  pfree(void *);
45#else
46#include <rtems/bspIo.h>
47#endif
48
49typedef unsigned long long u64;
50typedef long long s64;
51typedef unsigned int u32;
52
53#ifndef __BOOT__
54BSP_output_char_function_type     BSP_output_char = debug_putc_onlcr;
55BSP_polling_getchar_function_type BSP_poll_char = NULL;
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
320
321
322/* These #defines have been copied from drivers/char/pc_keyb.h, by
323 * Martin Mares (mj@ucw.cz).
324 * converted to offsets by Till Straumann <strauman@slac.stanford.edu>
325 */
326#define KBD_STATUS_REG          0x4     /* Status register (R) */
327#define KBD_CNTL_REG            0x4     /* Controller command register (W) */
328#define KBD_DATA_REG            0x0     /* Keyboard data register (R/W) */
329
330/*
331 *      Keyboard Controller Commands
332 */
333
334#define KBD_CCMD_WRITE_MODE     0x60    /* Write mode bits */
335#define KBD_CCMD_GET_VERSION    0xA1    /* Get controller version */
336#define KBD_CCMD_MOUSE_DISABLE  0xA7    /* Disable mouse interface */
337#define KBD_CCMD_MOUSE_ENABLE   0xA8    /* Enable mouse interface */
338#define KBD_CCMD_TEST_MOUSE     0xA9    /* Mouse interface test */
339#define KBD_CCMD_SELF_TEST      0xAA    /* Controller self test */
340#define KBD_CCMD_KBD_TEST       0xAB    /* Keyboard interface test */
341#define KBD_CCMD_KBD_DISABLE    0xAD    /* Keyboard interface disable */
342#define KBD_CCMD_KBD_ENABLE     0xAE    /* Keyboard interface enable */
343
344/*
345 *      Keyboard Commands
346 */
347
348#define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
349#define KBD_CMD_DISABLE         0xF5    /* Disable scanning */
350#define KBD_CMD_RESET           0xFF    /* Reset */
351
352/*
353 *      Keyboard Replies
354 */
355
356#define KBD_REPLY_POR           0xAA    /* Power on reset */
357#define KBD_REPLY_ACK           0xFA    /* Command ACK */
358#define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
359
360/*
361 *      Status Register Bits
362 */
363
364#define KBD_STAT_OBF            0x01    /* Keyboard output buffer full */
365#define KBD_STAT_IBF            0x02    /* Keyboard input buffer full */
366#define KBD_STAT_UNLOCKED       0x10    /* Zero if keyboard locked */
367#define KBD_STAT_GTO            0x40    /* General receive/xmit timeout */
368#define KBD_STAT_PERR           0x80    /* Parity error */
369
370/*
371 *      Controller Mode Register Bits
372 */
373
374#define KBD_MODE_KBD_INT        0x01    /* Keyboard data generate IRQ1 */
375#define KBD_MODE_SYS            0x04    /* The system flag (?) */
376#define KBD_MODE_NO_KEYLOCK     0x08    /* The keylock doesn't affect the keyboard if set */
377#define KBD_MODE_DISABLE_KBD    0x10    /* Disable keyboard interface */
378#define KBD_MODE_DISABLE_MOUSE  0x20    /* Disable mouse interface */
379#define KBD_MODE_KCC            0x40    /* Scan code conversion to PC format */
380#define KBD_MODE_RFU            0x80
381
382#endif /* USE_KBD_SUPPORT */
383
384
385/* Early messages after mm init but before console init are kept in log
386 * buffers.
387 */
388#define PAGE_LOG_CHARS (PAGE_SIZE-sizeof(int)-sizeof(u_long)-1)
389
390typedef struct _console_log {
391        struct _console_log *next;
392        int offset;
393        u_char data[PAGE_LOG_CHARS];
394} console_log;
395
396#ifdef STATIC_LOG_ALLOC
397
398#define STATIC_LOG_DATA_PAGE_NB 3
399
400static  u_char  log_page_pool   [STATIC_LOG_DATA_PAGE_NB * PAGE_SIZE];
401
402#endif
403#endif
404
405static board_memory_map mem_map = {
406  (__io_ptr) _IO_BASE,          /* from libcpu/io.h */
407  (__io_ptr) _ISA_MEM_BASE,
408};
409
410board_memory_map *ptr_mem_map = &mem_map;
411
412void log_putc(const u_char c) {
413        console_log *l;
414        for(l=console_global_data.log; l; l=l->next) {
415                if (l->offset<PAGE_LOG_CHARS) break;
416        }
417        if (!l) {
418                l=__palloc(sizeof(console_log));
419                memset(l, 0, sizeof(console_log));
420                if (!console_global_data.log)
421                        console_global_data.log = l;
422                else {
423                        console_log *p;
424                        for (p=console_global_data.log;
425                             p->next; p=p->next);
426                        p->next = l;
427                }
428        }
429        l->data[l->offset++] = c;
430}
431
432/* This puts is non standard since it does not automatically add a newline
433 * at the end. So it is made private to avoid confusion in other files.
434 */
435static
436void puts(const u_char *s)
437{
438        char c;
439
440        while ( ( c = *s++ ) != '\0' ) {
441                                debug_putc_onlcr((const char)c);
442        }
443}
444
445
446static
447void flush_log(void) {
448        console_log *p, *next;
449        if (console_global_data.vacuum_sent) {
450#ifdef TRACE_FLUSH_LOG
451                printk("%d characters sent into oblivion before MM init!\n",
452                       console_global_data.vacuum_sent);
453#endif
454        }
455        for(p=console_global_data.log; p; p=next) {
456                puts(p->data);
457                next = p->next;
458                pfree(p);
459        }
460}
461
462#ifndef INL_CONSOLE_INB
463#error "BSP probably didn't define a console port"
464#endif
465
466void serial_putc(const u_char c)
467{
468        while ((INL_CONSOLE_INB(lsr) & LSR_THRE) == 0) ;
469        INL_CONSOLE_OUTB(thr, c);
470}
471
472int serial_getc(void)
473{
474        while ((INL_CONSOLE_INB(lsr) & LSR_DR) == 0) ;
475        return (INL_CONSOLE_INB(rbr));
476}
477
478int serial_tstc(void)
479{
480        return ((INL_CONSOLE_INB(lsr) & LSR_DR) != 0);
481}
482
483#ifdef USE_VGA_SUPPORT
484static void scroll(void)
485{
486        int i;
487
488        memcpy ( (u_char *)vidmem, (u_char *)vidmem + console_global_data.cols * 2,
489                 ( console_global_data.lines - 1 ) * console_global_data.cols * 2 );
490        for ( i = ( console_global_data.lines - 1 ) * console_global_data.cols * 2;
491              i < console_global_data.lines * console_global_data.cols * 2;
492              i += 2 )
493                vidmem[i] = ' ';
494}
495
496/*
497 * cursor() sets an offset (0-1999) into the 80x25 text area
498 */
499static void
500cursor(int x, int y)
501{
502        int pos = console_global_data.cols*y + x;
503        vga_outb(14, 0x14);
504        vga_outb(0x15, pos>>8);
505        vga_outb(0x14, 15);
506        vga_outb(0x15, pos);
507}
508
509void
510vga_putc(const u_char c)
511{
512        int x,y;
513
514        x = console_global_data.orig_x;
515        y = console_global_data.orig_y;
516
517        if ( c == '\n' ) {
518                if ( ++y >= console_global_data.lines ) {
519                        scroll();
520                        y--;
521                }
522        } else if (c == '\b') {
523                if (x > 0) {
524                        x--;
525                }
526        } else if (c == '\r') {
527                x = 0;
528        } else {
529                vidmem [ ( x + console_global_data.cols * y ) * 2 ] = c;
530                if ( ++x >= console_global_data.cols ) {
531                        x = 0;
532                        if ( ++y >= console_global_data.lines ) {
533                                scroll();
534                                y--;
535                        }
536                }
537        }
538
539        cursor(x, y);
540
541        console_global_data.orig_x = x;
542        console_global_data.orig_y = y;
543}
544#endif /* USE_VGA_SUPPORT */
545
546#ifdef USE_KBD_SUPPORT
547/* Keyboard support */
548static int kbd_getc(void)
549{
550        unsigned char dt, brk, val;
551        unsigned code;
552loop:
553        while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
554
555        dt = kbd_inb(KBD_DATA_REG);
556
557        brk = dt & 0x80;        /* brk == 1 on key release */
558        dt = dt & 0x7f;         /* keycode */
559
560        if (console_global_data.shfts)
561            code = shift_map[dt];
562        else if (console_global_data.ctls)
563            code = ctrl_map[dt];
564        else
565            code = plain_map[dt];
566
567        val = KVAL(code);
568        switch (KTYP(code) & 0x0f) {
569            case KT_LATIN:
570                if (brk)
571                    break;
572                if (console_global_data.alts)
573                    val |= 0x80;
574                if (val == 0x7f)        /* map delete to backspace */
575                    val = '\b';
576                return val;
577
578            case KT_LETTER:
579                if (brk)
580                    break;
581                if (console_global_data.caps)
582                    val -= 'a'-'A';
583                return val;
584
585            case KT_SPEC:
586                if (brk)
587                    break;
588                if (val == KVAL(K_CAPS))
589                    console_global_data.caps = !console_global_data.caps;
590                else if (val == KVAL(K_ENTER)) {
591enter:              /* Wait for key up */
592                    while (1) {
593                        while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
594                        dt = kbd_inb(KBD_DATA_REG);
595                        if (dt & 0x80) /* key up */ break;
596                    }
597                    return 10;
598                }
599                break;
600
601            case KT_PAD:
602                if (brk)
603                    break;
604                if (val < 10)
605                    return val;
606                if (val == KVAL(K_PENTER))
607                    goto enter;
608                break;
609
610            case KT_SHIFT:
611                switch (val) {
612                    case KG_SHIFT:
613                    case KG_SHIFTL:
614                    case KG_SHIFTR:
615                        console_global_data.shfts = brk ? 0 : 1;
616                        break;
617                    case KG_ALT:
618                    case KG_ALTGR:
619                        console_global_data.alts = brk ? 0 : 1;
620                        break;
621                    case KG_CTRL:
622                    case KG_CTRLL:
623                    case KG_CTRLR:
624                        console_global_data.ctls = brk ? 0 : 1;
625                        break;
626                }
627                break;
628
629            case KT_LOCK:
630                switch (val) {
631                    case KG_SHIFT:
632                    case KG_SHIFTL:
633                    case KG_SHIFTR:
634                        if (brk)
635                            console_global_data.shfts = !console_global_data.shfts;
636                        break;
637                    case KG_ALT:
638                    case KG_ALTGR:
639                        if (brk)
640                            console_global_data.alts = !console_global_data.alts;
641                        break;
642                    case KG_CTRL:
643                    case KG_CTRLL:
644                    case KG_CTRLR:
645                        if (brk)
646                            console_global_data.ctls = !console_global_data.ctls;
647                        break;
648                }
649                break;
650        }
651        /* if (brk) return (0); */  /* Ignore initial 'key up' codes */
652        goto loop;
653}
654
655static int kbd_get(int ms) {
656        int status, data;
657        while(1) {
658                status = kbd_inb(KBD_STATUS_REG);
659                if (status & KBD_STAT_OBF) {
660                        data = kbd_inb(KBD_DATA_REG);
661                        if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
662                                return -1;
663                        else
664                                return data;
665                }
666                if (--ms < 0) return -1;
667#ifdef __BOOT__
668                boot_udelay(1000);
669#else
670                rtems_bsp_delay(1000);
671#endif
672        }
673}
674
675static void kbd_put(u_char c, int ms, int port) {
676        while (kbd_inb(KBD_STATUS_REG) & KBD_STAT_IBF) {
677                if (--ms < 0) return;
678#ifdef __BOOT__
679                boot_udelay(1000);
680#else
681                rtems_bsp_delay(1000);
682#endif
683        }
684        kbd_outb(port, c);
685}
686
687int kbdreset(void)
688{
689        int c;
690
691        /* Flush all pending data */
692        while(kbd_get(10) != -1);
693
694        /* Send self-test */
695        kbd_put(KBD_CCMD_SELF_TEST, 10, KBD_CNTL_REG);
696        c = kbd_get(1000);
697        if (c != 0x55) return 1;
698
699        /* Enable then reset the KB */
700        kbd_put(KBD_CCMD_KBD_ENABLE, 10, KBD_CNTL_REG);
701
702        while (1) {
703                kbd_put(KBD_CMD_RESET, 10, KBD_DATA_REG);
704                c = kbd_get(1000);
705                if (c == KBD_REPLY_ACK) break;
706                if (c != KBD_REPLY_RESEND) return 2;
707        }
708
709        if (kbd_get(1000) != KBD_REPLY_POR) return 3;
710
711        /* Disable the keyboard while setting up the controller */
712        kbd_put(KBD_CMD_DISABLE, 10, KBD_DATA_REG);
713        if (kbd_get(10)!=KBD_REPLY_ACK) return 4;
714
715        /* Enable interrupts and keyboard controller */
716        kbd_put(KBD_CCMD_WRITE_MODE, 10, KBD_CNTL_REG);
717        kbd_put(KBD_MODE_KBD_INT | KBD_MODE_SYS |
718                KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC,
719                10, KBD_DATA_REG);
720
721        /* Reenable the keyboard */
722        kbd_put(KBD_CMD_ENABLE, 10, KBD_DATA_REG);
723        if (kbd_get(10)!=KBD_REPLY_ACK) return 5;
724
725        return 0;
726}
727
728int kbd_tstc(void)
729{
730        return ((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0);
731}
732#endif /* USE_KBD_SUPPORT */
733
734const struct console_io
735vacuum_console_functions = {
736        vacuum_putc,
737        vacuum_getc,
738        vacuum_tstc
739};
740
741static const struct console_io
742log_console_functions = {
743        log_putc,
744        vacuum_getc,
745        vacuum_tstc
746}
747,
748serial_console_functions = {
749        serial_putc,
750        serial_getc,
751        serial_tstc
752}
753#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
754,
755vga_console_functions = {
756        vga_putc,
757        kbd_getc,
758        kbd_tstc
759}
760#endif
761;
762
763console_io* curIo = (console_io*) &vacuum_console_functions;
764
765int select_console(ioType t) {
766  static ioType curType = CONSOLE_VACUUM;
767
768  switch (t) {
769  case CONSOLE_VACUUM   : curIo = (console_io*)&vacuum_console_functions; break;
770  case CONSOLE_LOG      : curIo = (console_io*)&log_console_functions; break;
771  case CONSOLE_SERIAL   : curIo = (console_io*)&serial_console_functions; break;
772#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
773  case CONSOLE_VGA      : curIo = (console_io*)&vga_console_functions; break;
774#endif
775  default               : curIo = (console_io*)&vacuum_console_functions;break;
776  }
777  if (curType == CONSOLE_LOG) flush_log();
778  curType = t;
779  return 0;
780}
781
782/* we use this so that we can do without the ctype library */
783#define is_digit(c)     ((c) >= '0' && (c) <= '9')
784
785
786/* provide this for the bootloader only; otherwise
787 * use libcpu implementation
788 */
789#if defined(__BOOT__)
790static int skip_atoi(const char **s)
791{
792        int i=0;
793
794        while (is_digit(**s))
795                i = i*10 + *((*s)++) - '0';
796        return i;
797}
798
799/* Based on linux/lib/vsprintf.c and modified to suit our needs,
800 * bloat has been limited since we basically only need %u, %x, %s and %c.
801 * But we need 64 bit values !
802 */
803int k_vsprintf(char *buf, const char *fmt, va_list args);
804
805int printk(const char *fmt, ...) {
806        va_list args;
807        int i;
808        /* Should not be a problem with 8kB of stack */
809        char buf[1024];
810
811        va_start(args, fmt);
812        i = k_vsprintf(buf, fmt, args);
813        va_end(args);
814        puts(buf);
815        return  i;
816}
817
818#endif
819
820/* Necessary to avoid including a library, and GCC won't do this inline. */
821#define div10(num, rmd)                                                  \
822do {    u32 t1, t2, t3;                                                  \
823        __asm__ ("lis %4,0xcccd; "                                               \
824            "addi %4,%4,0xffffcccd; "   /* Build 0xcccccccd */           \
825            "mulhwu %3,%0+1,%4; "       /* (num.l*cst.l).h  */           \
826            "mullw %2,%0,%4; "          /* (num.h*cst.l).l  */           \
827            "addc %3,%3,%2; "                                            \
828            "mulhwu %2,%0,%4; "         /* (num.h*cst.l).h  */           \
829            "addi %4,%4,-1; "           /* Build 0xcccccccc */           \
830            "mullw %1,%0,%4; "          /* (num.h*cst.h).l  */           \
831            "adde %2,%2,%1; "                                            \
832            "mulhwu %1,%0,%4; "         /* (num.h*cst.h).h  */           \
833            "addze %1,%1; "                                              \
834            "mullw %0,%0+1,%4; "        /* (num.l*cst.h).l  */           \
835            "addc %3,%3,%0; "                                            \
836            "mulhwu %0,%0+1,%4; "       /* (num.l*cst.h).h  */           \
837            "adde %2,%2,%0; "                                            \
838            "addze %1,%1; "                                              \
839            "srwi %2,%2,3; "                                             \
840            "srwi %0,%1,3; "                                             \
841            "rlwimi %2,%1,29,0,2; "                                      \
842            "mulli %4,%2,10; "                                           \
843            "sub %4,%0+1,%4; "                                           \
844            "mr %0+1,%2; " :                                             \
845            "=r" (num), "=&r" (t1), "=&r" (t2), "=&r"(t3), "=&b" (rmd) : \
846            "0" (num));                                                  \
847                                                                         \
848} while(0);
849
850#define SIGN    1               /* unsigned/signed long */
851#define LARGE   2               /* use 'ABCDEF' instead of 'abcdef' */
852#define HEX     4               /* hexadecimal instead of decimal */
853#define ADDR    8               /* Value is an addres (p) */
854#define ZEROPAD 16              /* pad with zero */
855#define HALF    32
856#define LONG    64              /* long argument */
857#define LLONG   128             /* 64 bit argument */
858
859#if defined(__BOOT__)
860static char * number(char * str, int size, int type, u64 num)
861{
862        char fill,sign,tmp[24];
863        const char *digits="0123456789abcdef";
864        int i;
865
866        if (type & LARGE)
867                digits = "0123456789ABCDEF";
868        fill = (type & ZEROPAD) ? '0' : ' ';
869        sign = 0;
870        if (type & SIGN) {
871                if ((s64)num <0) {
872                        sign = '-';
873                        num = -num;
874                        size--;
875                }
876        }
877
878        i = 0;
879        do {
880                unsigned rem;
881                if (type&HEX) {
882                        rem = num & 0x0f;
883                        num >>=4;
884                } else {
885                        div10(num, rem);
886                }
887                tmp[i++] = digits[rem];
888        } while (num != 0);
889
890        size -= i;
891        if (!(type&(ZEROPAD)))
892                while(size-->0)
893                        *str++ = ' ';
894        if (sign)
895                *str++ = sign;
896
897        while (size-- > 0)
898                *str++ = fill;
899        while (i-- > 0)
900                *str++ = tmp[i];
901        while (size-- > 0)
902                *str++ = ' ';
903        return str;
904}
905
906int k_vsprintf(char *buf, const char *fmt, va_list args)
907{
908        int len;
909        u64 num;
910        int i;
911        char * str;
912        const char *s;
913
914        int flags;              /* flags to number() and private */
915
916        int field_width;        /* width of output field */
917
918        for (str=buf ; *fmt ; ++fmt) {
919                if (*fmt != '%') {
920                        *str++ = *fmt;
921                        continue;
922                }
923
924                /* process flags, only 0 padding needed */
925                flags = 0;
926                if (*++fmt == '0' ) {
927                        flags |= ZEROPAD;
928                        fmt++;
929                }
930
931                /* get field width */
932                field_width = -1;
933                if (is_digit(*fmt))
934                        field_width = skip_atoi(&fmt);
935
936                /* get the conversion qualifier */
937                if (*fmt == 'h') {
938                        flags |= HALF;
939                        fmt++;
940                } else if (*fmt == 'L') {
941                        flags |= LLONG;
942                        fmt++;
943                } else if (*fmt == 'l') {
944                        flags |= LONG;
945                        fmt++;
946                }
947
948                switch (*fmt) {
949                case 'c':
950                        *str++ = (unsigned char) va_arg(args, int);
951                        while (--field_width > 0)
952                                *str++ = ' ';
953                        continue;
954
955                case 's':
956                        s = va_arg(args, char *);
957                        len = strlen(s);
958
959                        for (i = 0; i < len; ++i)
960                                *str++ = *s++;
961                        while (len < field_width--)
962                                *str++ = ' ';
963                        continue;
964
965                case 'p':
966                        if (field_width == -1) {
967                                field_width = 2*sizeof(void *);
968                        }
969                        flags |= ZEROPAD|HEX|ADDR;
970                        break;
971
972                case 'X':
973                        flags |= LARGE;
974                case 'x':
975                        flags |= HEX;
976                        break;
977
978                case 'd':
979                case 'i':
980                        flags |= SIGN;
981                case 'u':
982                        break;
983
984                default:
985                        if (*fmt != '%')
986                                *str++ = '%';
987                        if (*fmt)
988                                *str++ = *fmt;
989                        else
990                                --fmt;
991                        continue;
992                }
993                /* This ugly code tries to minimize the number of va_arg()
994                 * since they expand to a lot of code on PPC under the SYSV
995                 * calling conventions (but not with -mcall-aix which has
996                 * other problems). Arguments have at least the size of a
997                 * long allocated, and we use this fact to minimize bloat.
998                 * (and pointers are assimilated to unsigned long too).
999                 */
1000                if (sizeof(long long) > sizeof(long) && flags & LLONG)
1001                        num = va_arg(args, unsigned long long);
1002                else {
1003                        u_long n = va_arg(args, unsigned long);
1004                        if (flags & HALF) {
1005                                if (flags & SIGN)
1006                                        n = (short) n;
1007                                else
1008                                        n = (unsigned short) n;
1009                        } else if (! flags & LONG) {
1010                                /* Here the compiler correctly removes this
1011                                 * do nothing code on 32 bit PPC.
1012                                 */
1013                                if (flags & SIGN)
1014                                        n = (int) n;
1015                                else
1016                                        n = (unsigned) n;
1017                        }
1018                        if (flags & SIGN)  num = (long) n; else num = n;
1019                }
1020                str = number(str, field_width, flags, num);
1021        }
1022        *str = '\0';
1023        return str-buf;
1024}
1025#endif
1026#endif
Note: See TracBrowser for help on using the repository browser.