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