File indexing completed on 2025-05-11 08:23:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <sys/param.h>
0017 #include <sys/types.h>
0018 #include <libcpu/byteorder.h>
0019 #include <libcpu/mmu.h>
0020 #include <libcpu/io.h>
0021 #include <string.h>
0022 #include <stdarg.h>
0023 #include <bsp/consoleIo.h>
0024 #include <bsp.h>
0025 #include <libcpu/spr.h>
0026
0027 #ifndef __BOOT__
0028 #define STATIC_LOG_ALLOC
0029 #endif
0030
0031 #ifdef BSP_KBD_IOBASE
0032 #define USE_KBD_SUPPORT
0033 #endif
0034 #ifdef BSP_VGA_IOBASE
0035 #define USE_VGA_SUPPORT
0036 #endif
0037
0038 #ifdef USE_KBD_SUPPORT
0039 #include "keyboard.h"
0040 #endif
0041 #include "console.inl"
0042
0043 #ifdef __BOOT__
0044 extern void boot_udelay(uint32_t _microseconds);
0045 void * __palloc(u_long);
0046 void pfree(void *);
0047 #else
0048 #include <rtems/bspIo.h>
0049 #endif
0050
0051 #ifndef __BOOT__
0052 BSP_output_char_function_type BSP_output_char = debug_putc;
0053 BSP_polling_getchar_function_type BSP_poll_char = NULL;
0054 #endif
0055
0056 #ifdef USE_KBD_SUPPORT
0057 unsigned short plain_map[NR_KEYS] = {
0058 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
0059 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
0060 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0061 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
0062 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
0063 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
0064 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
0065 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0066 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
0067 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0068 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
0069 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0070 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0071 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0072 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0073 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0074 };
0075
0076 unsigned short shift_map[NR_KEYS] = {
0077 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
0078 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
0079 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
0080 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
0081 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
0082 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
0083 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
0084 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
0085 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
0086 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0087 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
0088 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0089 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0090 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
0091 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0092 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0093 };
0094
0095 unsigned short altgr_map[NR_KEYS] = {
0096 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
0097 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
0098 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0099 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
0100 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
0101 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
0102 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0103 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
0104 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
0105 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
0106 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
0107 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0108 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0109 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0110 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0111 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0112 };
0113
0114 unsigned short ctrl_map[NR_KEYS] = {
0115 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
0116 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
0117 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0118 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
0119 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0120 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
0121 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
0122 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0123 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
0124 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0125 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
0126 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0127 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0128 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0129 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0130 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0131 };
0132
0133 unsigned short shift_ctrl_map[NR_KEYS] = {
0134 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
0135 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
0136 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0137 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
0138 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0139 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
0140 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0141 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0142 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
0143 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0144 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
0145 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0146 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0147 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0148 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0149 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0150 };
0151
0152 unsigned short alt_map[NR_KEYS] = {
0153 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
0154 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
0155 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
0156 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
0157 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
0158 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
0159 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
0160 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0161 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
0162 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
0163 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
0164 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0165 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0166 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0167 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0168 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0169 };
0170
0171 unsigned short ctrl_alt_map[NR_KEYS] = {
0172 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0173 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0174 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
0175 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
0176 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
0177 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
0178 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0179 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0180 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
0181 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0182 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
0183 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0184 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0185 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
0186 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0187 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0188 };
0189
0190 ushort *key_maps[MAX_NR_KEYMAPS] = {
0191 plain_map, shift_map, altgr_map, 0,
0192 ctrl_map, shift_ctrl_map, 0, 0,
0193 alt_map, 0, 0, 0,
0194 ctrl_alt_map, 0
0195 };
0196
0197 unsigned int keymap_count = 7;
0198
0199
0200
0201
0202
0203
0204
0205 char func_buf[] = {
0206 '\033', '[', '[', 'A', 0,
0207 '\033', '[', '[', 'B', 0,
0208 '\033', '[', '[', 'C', 0,
0209 '\033', '[', '[', 'D', 0,
0210 '\033', '[', '[', 'E', 0,
0211 '\033', '[', '1', '7', '~', 0,
0212 '\033', '[', '1', '8', '~', 0,
0213 '\033', '[', '1', '9', '~', 0,
0214 '\033', '[', '2', '0', '~', 0,
0215 '\033', '[', '2', '1', '~', 0,
0216 '\033', '[', '2', '3', '~', 0,
0217 '\033', '[', '2', '4', '~', 0,
0218 '\033', '[', '2', '5', '~', 0,
0219 '\033', '[', '2', '6', '~', 0,
0220 '\033', '[', '2', '8', '~', 0,
0221 '\033', '[', '2', '9', '~', 0,
0222 '\033', '[', '3', '1', '~', 0,
0223 '\033', '[', '3', '2', '~', 0,
0224 '\033', '[', '3', '3', '~', 0,
0225 '\033', '[', '3', '4', '~', 0,
0226 '\033', '[', '1', '~', 0,
0227 '\033', '[', '2', '~', 0,
0228 '\033', '[', '3', '~', 0,
0229 '\033', '[', '4', '~', 0,
0230 '\033', '[', '5', '~', 0,
0231 '\033', '[', '6', '~', 0,
0232 '\033', '[', 'M', 0,
0233 '\033', '[', 'P', 0,
0234 };
0235
0236 char *funcbufptr = func_buf;
0237 int funcbufsize = sizeof(func_buf);
0238 int funcbufleft = 0;
0239
0240 char *func_table[MAX_NR_FUNC] = {
0241 func_buf + 0,
0242 func_buf + 5,
0243 func_buf + 10,
0244 func_buf + 15,
0245 func_buf + 20,
0246 func_buf + 25,
0247 func_buf + 31,
0248 func_buf + 37,
0249 func_buf + 43,
0250 func_buf + 49,
0251 func_buf + 55,
0252 func_buf + 61,
0253 func_buf + 67,
0254 func_buf + 73,
0255 func_buf + 79,
0256 func_buf + 85,
0257 func_buf + 91,
0258 func_buf + 97,
0259 func_buf + 103,
0260 func_buf + 109,
0261 func_buf + 115,
0262 func_buf + 120,
0263 func_buf + 125,
0264 func_buf + 130,
0265 func_buf + 135,
0266 func_buf + 140,
0267 func_buf + 145,
0268 0,
0269 0,
0270 func_buf + 149,
0271 0,
0272 };
0273
0274 struct kbdiacr {
0275 unsigned char diacr, base, result;
0276 };
0277
0278 struct kbdiacr accent_table[MAX_DIACR] = {
0279 {'`', 'A', '\300'}, {'`', 'a', '\340'},
0280 {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
0281 {'^', 'A', '\302'}, {'^', 'a', '\342'},
0282 {'~', 'A', '\303'}, {'~', 'a', '\343'},
0283 {'"', 'A', '\304'}, {'"', 'a', '\344'},
0284 {'O', 'A', '\305'}, {'o', 'a', '\345'},
0285 {'0', 'A', '\305'}, {'0', 'a', '\345'},
0286 {'A', 'A', '\305'}, {'a', 'a', '\345'},
0287 {'A', 'E', '\306'}, {'a', 'e', '\346'},
0288 {',', 'C', '\307'}, {',', 'c', '\347'},
0289 {'`', 'E', '\310'}, {'`', 'e', '\350'},
0290 {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
0291 {'^', 'E', '\312'}, {'^', 'e', '\352'},
0292 {'"', 'E', '\313'}, {'"', 'e', '\353'},
0293 {'`', 'I', '\314'}, {'`', 'i', '\354'},
0294 {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
0295 {'^', 'I', '\316'}, {'^', 'i', '\356'},
0296 {'"', 'I', '\317'}, {'"', 'i', '\357'},
0297 {'-', 'D', '\320'}, {'-', 'd', '\360'},
0298 {'~', 'N', '\321'}, {'~', 'n', '\361'},
0299 {'`', 'O', '\322'}, {'`', 'o', '\362'},
0300 {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
0301 {'^', 'O', '\324'}, {'^', 'o', '\364'},
0302 {'~', 'O', '\325'}, {'~', 'o', '\365'},
0303 {'"', 'O', '\326'}, {'"', 'o', '\366'},
0304 {'/', 'O', '\330'}, {'/', 'o', '\370'},
0305 {'`', 'U', '\331'}, {'`', 'u', '\371'},
0306 {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
0307 {'^', 'U', '\333'}, {'^', 'u', '\373'},
0308 {'"', 'U', '\334'}, {'"', 'u', '\374'},
0309 {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
0310 {'T', 'H', '\336'}, {'t', 'h', '\376'},
0311 {'s', 's', '\337'}, {'"', 'y', '\377'},
0312 {'s', 'z', '\337'}, {'i', 'j', '\377'},
0313 };
0314
0315 unsigned int accent_table_size = 68;
0316
0317
0318
0319
0320
0321 #define KBD_STATUS_REG 0x4
0322 #define KBD_CNTL_REG 0x4
0323 #define KBD_DATA_REG 0x0
0324
0325
0326
0327
0328
0329 #define KBD_CCMD_WRITE_MODE 0x60
0330 #define KBD_CCMD_GET_VERSION 0xA1
0331 #define KBD_CCMD_MOUSE_DISABLE 0xA7
0332 #define KBD_CCMD_MOUSE_ENABLE 0xA8
0333 #define KBD_CCMD_TEST_MOUSE 0xA9
0334 #define KBD_CCMD_SELF_TEST 0xAA
0335 #define KBD_CCMD_KBD_TEST 0xAB
0336 #define KBD_CCMD_KBD_DISABLE 0xAD
0337 #define KBD_CCMD_KBD_ENABLE 0xAE
0338
0339
0340
0341
0342
0343 #define KBD_CMD_ENABLE 0xF4
0344 #define KBD_CMD_DISABLE 0xF5
0345 #define KBD_CMD_RESET 0xFF
0346
0347
0348
0349
0350
0351 #define KBD_REPLY_POR 0xAA
0352 #define KBD_REPLY_ACK 0xFA
0353 #define KBD_REPLY_RESEND 0xFE
0354
0355
0356
0357
0358
0359 #define KBD_STAT_OBF 0x01
0360 #define KBD_STAT_IBF 0x02
0361 #define KBD_STAT_UNLOCKED 0x10
0362 #define KBD_STAT_GTO 0x40
0363 #define KBD_STAT_PERR 0x80
0364
0365
0366
0367
0368
0369 #define KBD_MODE_KBD_INT 0x01
0370 #define KBD_MODE_SYS 0x04
0371 #define KBD_MODE_NO_KEYLOCK 0x08
0372 #define KBD_MODE_DISABLE_KBD 0x10
0373 #define KBD_MODE_DISABLE_MOUSE 0x20
0374 #define KBD_MODE_KCC 0x40
0375 #define KBD_MODE_RFU 0x80
0376
0377 #endif
0378
0379
0380
0381
0382 #define PAGE_LOG_CHARS (PAGE_SIZE-sizeof(int)-sizeof(u_long)-1)
0383
0384 typedef struct _console_log {
0385 struct _console_log *next;
0386 int offset;
0387 u_char data[PAGE_LOG_CHARS];
0388 } console_log;
0389
0390 #ifdef STATIC_LOG_ALLOC
0391
0392 #define STATIC_LOG_DATA_PAGE_NB 3
0393
0394 static u_char log_page_pool [STATIC_LOG_DATA_PAGE_NB * PAGE_SIZE];
0395
0396 #endif
0397
0398 static board_memory_map mem_map = {
0399 (__io_ptr) _IO_BASE,
0400 (__io_ptr) _ISA_MEM_BASE,
0401 };
0402
0403 board_memory_map *ptr_mem_map = &mem_map;
0404
0405 struct _console_global_data {
0406 console_log *log;
0407 int vacuum_sent;
0408 int lines;
0409 int cols;
0410 int orig_x;
0411 int orig_y;
0412 u_char shfts, ctls, alts, caps;
0413 } console_global_data = {NULL, 0, 25, 80, 0, 24, 0, 0, 0, 0};
0414
0415 typedef struct console_io {
0416 void (*console_io_putc) (const u_char);
0417 int (*console_io_getc) (void);
0418 int (*console_io_tstc) (void);
0419 }console_io;
0420
0421 extern console_io* curIo;
0422
0423 void debug_putc(const char c)
0424 {
0425 curIo->console_io_putc(c);
0426 }
0427
0428
0429 void
0430 debug_putc_onlcr(const char c)
0431 {
0432 if (c == '\n') {
0433 debug_putc('\r');
0434 }
0435
0436 debug_putc(c);
0437 }
0438
0439 int debug_getc(void)
0440 {
0441 return curIo->console_io_getc();
0442 }
0443
0444 int debug_tstc(void)
0445 {
0446 return curIo->console_io_tstc();
0447 }
0448
0449 #define vidmem ((__io_ptr)(ptr_mem_map->isa_mem_base+0xb8000))
0450
0451 static void vacuum_putc(u_char c) {
0452 console_global_data.vacuum_sent++;
0453 }
0454
0455 static int vacuum_getc(void) {
0456 return -1;
0457 }
0458
0459 static int vacuum_tstc(void) {
0460 return 0;
0461 }
0462
0463
0464
0465
0466
0467 #define rbr 0
0468 #define ier 1
0469 #define fcr 2
0470 #define lcr 3
0471 #define mcr 4
0472 #define lsr 5
0473 #define msr 6
0474 #define scr 7
0475 #define thr rbr
0476 #define iir fcr
0477 #define dll rbr
0478 #define dlm ier
0479
0480 #define LSR_DR 0x01
0481 #define LSR_OE 0x02
0482 #define LSR_PE 0x04
0483 #define LSR_FE 0x08
0484 #define LSR_BI 0x10
0485 #define LSR_THRE 0x20
0486 #define LSR_TEMT 0x40
0487 #define LSR_ERR 0x80
0488
0489 #ifdef STATIC_LOG_ALLOC
0490 static int global_index = 0;
0491
0492 static void *__palloc(int s)
0493 {
0494 if (global_index ==( STATIC_LOG_DATA_PAGE_NB - 1) ) return (void*) 0;
0495 return (void*) &(log_page_pool [PAGE_SIZE * global_index++]);
0496 }
0497
0498 static void pfree(void* p)
0499 {
0500 --global_index;
0501 }
0502 #endif
0503
0504 static void log_putc(const u_char c) {
0505 console_log *l;
0506 for(l=console_global_data.log; l; l=l->next) {
0507 if (l->offset<PAGE_LOG_CHARS) break;
0508 }
0509 if (!l) {
0510 l=__palloc(sizeof(console_log));
0511 memset(l, 0, sizeof(console_log));
0512 if (!console_global_data.log)
0513 console_global_data.log = l;
0514 else {
0515 console_log *p;
0516 for (p=console_global_data.log;
0517 p->next; p=p->next);
0518 p->next = l;
0519 }
0520 }
0521 l->data[l->offset++] = c;
0522 }
0523
0524
0525
0526
0527 static
0528 void my_puts(const u_char *s)
0529 {
0530 char c;
0531
0532 while ( ( c = *s++ ) != '\0' ) {
0533 debug_putc_onlcr(c);
0534 }
0535 }
0536
0537 static
0538 void flush_log(void) {
0539 console_log *p, *next;
0540 if (console_global_data.vacuum_sent) {
0541 #ifdef TRACE_FLUSH_LOG
0542 printk("%d characters sent into oblivion before MM init!\n",
0543 console_global_data.vacuum_sent);
0544 #endif
0545 }
0546 for(p=console_global_data.log; p; p=next) {
0547 my_puts(p->data);
0548 next = p->next;
0549 pfree(p);
0550 }
0551 }
0552
0553 #ifndef INL_CONSOLE_INB
0554 #error "BSP probably didn't define a console port"
0555 #endif
0556
0557 static void serial_putc(const u_char c)
0558 {
0559 while ((INL_CONSOLE_INB(lsr) & LSR_THRE) == 0) ;
0560 INL_CONSOLE_OUTB(thr, c);
0561 }
0562
0563 static int serial_getc(void)
0564 {
0565 while ((INL_CONSOLE_INB(lsr) & LSR_DR) == 0) ;
0566 return (INL_CONSOLE_INB(rbr));
0567 }
0568
0569 static int serial_tstc(void)
0570 {
0571 return ((INL_CONSOLE_INB(lsr) & LSR_DR) != 0);
0572 }
0573
0574 #ifdef USE_VGA_SUPPORT
0575 static void scroll(void)
0576 {
0577 int i;
0578
0579 memcpy ( (u_char *)vidmem, (u_char *)vidmem + console_global_data.cols * 2,
0580 ( console_global_data.lines - 1 ) * console_global_data.cols * 2 );
0581 for ( i = ( console_global_data.lines - 1 ) * console_global_data.cols * 2;
0582 i < console_global_data.lines * console_global_data.cols * 2;
0583 i += 2 )
0584 vidmem[i] = ' ';
0585 }
0586
0587
0588
0589
0590 static void
0591 cursor(int x, int y)
0592 {
0593 int pos = console_global_data.cols*y + x;
0594 vga_outb(14, 0x14);
0595 vga_outb(0x15, pos>>8);
0596 vga_outb(0x14, 15);
0597 vga_outb(0x15, pos);
0598 }
0599
0600 static void
0601 vga_putc(const u_char c)
0602 {
0603 int x,y;
0604
0605 x = console_global_data.orig_x;
0606 y = console_global_data.orig_y;
0607
0608 if ( c == '\n' ) {
0609 if ( ++y >= console_global_data.lines ) {
0610 scroll();
0611 y--;
0612 }
0613 } else if (c == '\b') {
0614 if (x > 0) {
0615 x--;
0616 }
0617 } else if (c == '\r') {
0618 x = 0;
0619 } else {
0620 vidmem [ ( x + console_global_data.cols * y ) * 2 ] = c;
0621 if ( ++x >= console_global_data.cols ) {
0622 x = 0;
0623 if ( ++y >= console_global_data.lines ) {
0624 scroll();
0625 y--;
0626 }
0627 }
0628 }
0629
0630 cursor(x, y);
0631
0632 console_global_data.orig_x = x;
0633 console_global_data.orig_y = y;
0634 }
0635 #endif
0636
0637 #ifdef USE_KBD_SUPPORT
0638
0639 static int kbd_getc(void)
0640 {
0641 unsigned char dt, brk, val;
0642 unsigned code;
0643 loop:
0644 while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
0645
0646 dt = kbd_inb(KBD_DATA_REG);
0647
0648 brk = dt & 0x80;
0649 dt = dt & 0x7f;
0650
0651 if (console_global_data.shfts)
0652 code = shift_map[dt];
0653 else if (console_global_data.ctls)
0654 code = ctrl_map[dt];
0655 else
0656 code = plain_map[dt];
0657
0658 val = KVAL(code);
0659 switch (KTYP(code) & 0x0f) {
0660 case KT_LATIN:
0661 if (brk)
0662 break;
0663 if (console_global_data.alts)
0664 val |= 0x80;
0665 if (val == 0x7f)
0666 val = '\b';
0667 return val;
0668
0669 case KT_LETTER:
0670 if (brk)
0671 break;
0672 if (console_global_data.caps)
0673 val -= 'a'-'A';
0674 return val;
0675
0676 case KT_SPEC:
0677 if (brk)
0678 break;
0679 if (val == KVAL(K_CAPS))
0680 console_global_data.caps = !console_global_data.caps;
0681 else if (val == KVAL(K_ENTER)) {
0682 enter:
0683 while (1) {
0684 while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
0685 dt = kbd_inb(KBD_DATA_REG);
0686 if (dt & 0x80) break;
0687 }
0688 return 10;
0689 }
0690 break;
0691
0692 case KT_PAD:
0693 if (brk)
0694 break;
0695 if (val < 10)
0696 return val;
0697 if (val == KVAL(K_PENTER))
0698 goto enter;
0699 break;
0700
0701 case KT_SHIFT:
0702 switch (val) {
0703 case KG_SHIFT:
0704 case KG_SHIFTL:
0705 case KG_SHIFTR:
0706 console_global_data.shfts = brk ? 0 : 1;
0707 break;
0708 case KG_ALT:
0709 case KG_ALTGR:
0710 console_global_data.alts = brk ? 0 : 1;
0711 break;
0712 case KG_CTRL:
0713 case KG_CTRLL:
0714 case KG_CTRLR:
0715 console_global_data.ctls = brk ? 0 : 1;
0716 break;
0717 }
0718 break;
0719
0720 case KT_LOCK:
0721 switch (val) {
0722 case KG_SHIFT:
0723 case KG_SHIFTL:
0724 case KG_SHIFTR:
0725 if (brk)
0726 console_global_data.shfts = !console_global_data.shfts;
0727 break;
0728 case KG_ALT:
0729 case KG_ALTGR:
0730 if (brk)
0731 console_global_data.alts = !console_global_data.alts;
0732 break;
0733 case KG_CTRL:
0734 case KG_CTRLL:
0735 case KG_CTRLR:
0736 if (brk)
0737 console_global_data.ctls = !console_global_data.ctls;
0738 break;
0739 }
0740 break;
0741 }
0742
0743 goto loop;
0744 }
0745
0746 static int kbd_get(int ms) {
0747 int status, data;
0748 while(1) {
0749 status = kbd_inb(KBD_STATUS_REG);
0750 if (status & KBD_STAT_OBF) {
0751 data = kbd_inb(KBD_DATA_REG);
0752 if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
0753 return -1;
0754 else
0755 return data;
0756 }
0757 if (--ms < 0) return -1;
0758 #ifdef __BOOT__
0759 boot_udelay(1000);
0760 #else
0761 rtems_bsp_delay(1000);
0762 #endif
0763 }
0764 }
0765
0766 static void kbd_put(u_char c, int ms, int port) {
0767 while (kbd_inb(KBD_STATUS_REG) & KBD_STAT_IBF) {
0768 if (--ms < 0) return;
0769 #ifdef __BOOT__
0770 boot_udelay(1000);
0771 #else
0772 rtems_bsp_delay(1000);
0773 #endif
0774 }
0775 kbd_outb(port, c);
0776 }
0777
0778 int kbdreset(void)
0779 {
0780 int c;
0781
0782
0783 while(kbd_get(10) != -1);
0784
0785
0786 kbd_put(KBD_CCMD_SELF_TEST, 10, KBD_CNTL_REG);
0787 c = kbd_get(1000);
0788 if (c != 0x55) return 1;
0789
0790
0791 kbd_put(KBD_CCMD_KBD_ENABLE, 10, KBD_CNTL_REG);
0792
0793 while (1) {
0794 kbd_put(KBD_CMD_RESET, 10, KBD_DATA_REG);
0795 c = kbd_get(1000);
0796 if (c == KBD_REPLY_ACK) break;
0797 if (c != KBD_REPLY_RESEND) return 2;
0798 }
0799
0800 if (kbd_get(1000) != KBD_REPLY_POR) return 3;
0801
0802
0803 kbd_put(KBD_CMD_DISABLE, 10, KBD_DATA_REG);
0804 if (kbd_get(10)!=KBD_REPLY_ACK) return 4;
0805
0806
0807 kbd_put(KBD_CCMD_WRITE_MODE, 10, KBD_CNTL_REG);
0808 kbd_put(KBD_MODE_KBD_INT | KBD_MODE_SYS |
0809 KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC,
0810 10, KBD_DATA_REG);
0811
0812
0813 kbd_put(KBD_CMD_ENABLE, 10, KBD_DATA_REG);
0814 if (kbd_get(10)!=KBD_REPLY_ACK) return 5;
0815
0816 return 0;
0817 }
0818
0819 static int kbd_tstc(void)
0820 {
0821 return ((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0);
0822 }
0823 #endif
0824
0825 const struct console_io
0826 vacuum_console_functions = {
0827 vacuum_putc,
0828 vacuum_getc,
0829 vacuum_tstc
0830 };
0831
0832 static const struct console_io
0833 log_console_functions = {
0834 log_putc,
0835 vacuum_getc,
0836 vacuum_tstc
0837 }
0838 ,
0839 serial_console_functions = {
0840 serial_putc,
0841 serial_getc,
0842 serial_tstc
0843 }
0844 #if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
0845 ,
0846 vga_console_functions = {
0847 vga_putc,
0848 kbd_getc,
0849 kbd_tstc
0850 }
0851 #endif
0852 ;
0853
0854 console_io* curIo = (console_io*) &vacuum_console_functions;
0855
0856 int select_console(ioType t) {
0857 static ioType curType = CONSOLE_VACUUM;
0858
0859 switch (t) {
0860 case CONSOLE_VACUUM : curIo = (console_io*)&vacuum_console_functions; break;
0861 case CONSOLE_LOG : curIo = (console_io*)&log_console_functions; break;
0862 case CONSOLE_SERIAL : curIo = (console_io*)&serial_console_functions; break;
0863 #if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
0864 case CONSOLE_VGA : curIo = (console_io*)&vga_console_functions; break;
0865 #endif
0866 default : curIo = (console_io*)&vacuum_console_functions;break;
0867 }
0868 if (curType == CONSOLE_LOG) flush_log();
0869 curType = t;
0870 return 0;
0871 }
0872
0873
0874 #define is_digit(c) ((c) >= '0' && (c) <= '9')
0875
0876
0877
0878
0879 #if defined(__BOOT__)
0880 static int skip_atoi(const char **s)
0881 {
0882 int i=0;
0883
0884 while (is_digit(**s))
0885 i = i*10 + *((*s)++) - '0';
0886 return i;
0887 }
0888
0889
0890
0891
0892
0893 int k_vsprintf(char *buf, const char *fmt, va_list args);
0894
0895 int printk(const char *fmt, ...) {
0896 va_list args;
0897 int i;
0898
0899 char buf[1024];
0900
0901 va_start(args, fmt);
0902 i = k_vsprintf(buf, fmt, args);
0903 va_end(args);
0904 my_puts((u_char*)buf);
0905 return i;
0906 }
0907
0908 #endif
0909
0910
0911 #define div10(num, rmd) \
0912 do { uint32_t t1, t2, t3; \
0913 __asm__ ("lis %4,0xcccd; " \
0914 "addi %4,%4,0xffffcccd; " \
0915 "mulhwu %3,%0+1,%4; " \
0916 "mullw %2,%0,%4; " \
0917 "addc %3,%3,%2; " \
0918 "mulhwu %2,%0,%4; " \
0919 "addi %4,%4,-1; " \
0920 "mullw %1,%0,%4; " \
0921 "adde %2,%2,%1; " \
0922 "mulhwu %1,%0,%4; " \
0923 "addze %1,%1; " \
0924 "mullw %0,%0+1,%4; " \
0925 "addc %3,%3,%0; " \
0926 "mulhwu %0,%0+1,%4; " \
0927 "adde %2,%2,%0; " \
0928 "addze %1,%1; " \
0929 "srwi %2,%2,3; " \
0930 "srwi %0,%1,3; " \
0931 "rlwimi %2,%1,29,0,2; " \
0932 "mulli %4,%2,10; " \
0933 "sub %4,%0+1,%4; " \
0934 "mr %0+1,%2; " : \
0935 "=r" (num), "=&r" (t1), "=&r" (t2), "=&r"(t3), "=&b" (rmd) : \
0936 "0" (num)); \
0937 \
0938 } while(0);
0939
0940 #define SIGN 1
0941 #define LARGE 2
0942 #define HEX 4
0943 #define ADDR 8
0944 #define ZEROPAD 16
0945 #define HALF 32
0946 #define LONG 64
0947 #define LLONG 128
0948
0949 #if defined(__BOOT__)
0950 static char * number(char * str, int size, int type, uint64_t num)
0951 {
0952 char fill,sign,tmp[24];
0953 const char *digits="0123456789abcdef";
0954 int i;
0955
0956 if (type & LARGE)
0957 digits = "0123456789ABCDEF";
0958 fill = (type & ZEROPAD) ? '0' : ' ';
0959 sign = 0;
0960 if (type & SIGN) {
0961 if ((int64_t)num <0) {
0962 sign = '-';
0963 num = -num;
0964 size--;
0965 }
0966 }
0967
0968 i = 0;
0969 do {
0970 unsigned rem;
0971 if (type&HEX) {
0972 rem = num & 0x0f;
0973 num >>=4;
0974 } else {
0975 div10(num, rem);
0976 }
0977 tmp[i++] = digits[rem];
0978 } while (num != 0);
0979
0980 size -= i;
0981 if (!(type&(ZEROPAD)))
0982 while(size-->0)
0983 *str++ = ' ';
0984 if (sign)
0985 *str++ = sign;
0986
0987 while (size-- > 0)
0988 *str++ = fill;
0989 while (i-- > 0)
0990 *str++ = tmp[i];
0991 while (size-- > 0)
0992 *str++ = ' ';
0993 return str;
0994 }
0995
0996 int k_vsprintf(char *buf, const char *fmt, va_list args)
0997 {
0998 int len;
0999 uint64_t num;
1000 int i;
1001 char * str;
1002 const char *s;
1003
1004 int flags;
1005
1006 int field_width;
1007
1008 for (str=buf ; *fmt ; ++fmt) {
1009 if (*fmt != '%') {
1010 *str++ = *fmt;
1011 continue;
1012 }
1013
1014
1015 flags = 0;
1016 if (*++fmt == '0' ) {
1017 flags |= ZEROPAD;
1018 fmt++;
1019 }
1020
1021
1022 field_width = -1;
1023 if (is_digit(*fmt))
1024 field_width = skip_atoi(&fmt);
1025
1026
1027 if (*fmt == 'h') {
1028 flags |= HALF;
1029 fmt++;
1030 } else if (*fmt == 'L') {
1031 flags |= LLONG;
1032 fmt++;
1033 } else if (*fmt == 'l') {
1034 flags |= LONG;
1035 fmt++;
1036 }
1037
1038 switch (*fmt) {
1039 case 'c':
1040 *str++ = (unsigned char) va_arg(args, int);
1041 while (--field_width > 0)
1042 *str++ = ' ';
1043 continue;
1044
1045 case 's':
1046 s = va_arg(args, char *);
1047 len = strlen(s);
1048
1049 for (i = 0; i < len; ++i)
1050 *str++ = *s++;
1051 while (len < field_width--)
1052 *str++ = ' ';
1053 continue;
1054
1055 case 'p':
1056 if (field_width == -1) {
1057 field_width = 2*sizeof(void *);
1058 }
1059 flags |= ZEROPAD|HEX|ADDR;
1060 break;
1061
1062 case 'X':
1063 flags |= LARGE;
1064 case 'x':
1065 flags |= HEX;
1066 break;
1067
1068 case 'd':
1069 case 'i':
1070 flags |= SIGN;
1071 case 'u':
1072 break;
1073
1074 default:
1075 if (*fmt != '%')
1076 *str++ = '%';
1077 if (*fmt)
1078 *str++ = *fmt;
1079 else
1080 --fmt;
1081 continue;
1082 }
1083
1084
1085
1086
1087
1088
1089
1090 if (sizeof(long long) > sizeof(long) && flags & LLONG)
1091 num = va_arg(args, unsigned long long);
1092 else {
1093 u_long n = va_arg(args, unsigned long);
1094 if (flags & HALF) {
1095 if (flags & SIGN)
1096 n = (short) n;
1097 else
1098 n = (unsigned short) n;
1099 } else if (!(flags & LONG)) {
1100
1101
1102
1103 if (flags & SIGN)
1104 n = (int) n;
1105 else
1106 n = (unsigned) n;
1107 }
1108 if (flags & SIGN) num = (long) n; else num = n;
1109 }
1110 str = number(str, field_width, flags, num);
1111 }
1112 *str = '\0';
1113 return str-buf;
1114 }
1115 #endif