OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [shared/] [console/] [polled_io.c] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.