00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <arch/drivers/arc.h>
00036 #include <arch/mm/page.h>
00037 #include <print.h>
00038 #include <arch.h>
00039 #include <arch/byteorder.h>
00040 #include <arch/mm/frame.h>
00041 #include <mm/frame.h>
00042 #include <interrupt.h>
00043 #include <align.h>
00044 #include <console/console.h>
00045 #include <console/kconsole.h>
00046 #include <console/cmd.h>
00047 #include <mm/slab.h>
00048
00049
00050
00051 static char *basetypes[] = {
00052 "ExceptionBlock",
00053 "SystemParameterBlock",
00054 "FreeContiguous",
00055 "FreeMemory",
00056 "BadMemory",
00057 "LoadedProgram",
00058 "FirmwareTemporary",
00059 "FirmwarePermanent"
00060 };
00061
00062 static char *ctypes[] = {
00063 "ARC_type",
00064 "CPU_type",
00065 "FPU_type",
00066 "PrimaryICache",
00067 "PrimaryDCache",
00068 "SecondaryICache",
00069 "SecondaryDCache",
00070 "SecondaryCache",
00071 "Memory",
00072 "EISAAdapter",
00073 "TCAdapter",
00074 "SCSIAdapter",
00075 "DTIAdapter",
00076 "MultiFunctionAdapter",
00077 "DiskController",
00078 "TapeController",
00079 "CDROMController",
00080 "WORMController",
00081 "SerialController",
00082 "NetworkController",
00083 "DisplayController",
00084 "ParallelController",
00085 "PointerController",
00086 "KeyboardController",
00087 "AudioController",
00088 "OtherController",
00089 "DiskPeripheral",
00090 "FloppyDiskPeripheral",
00091 "TapePeripheral",
00092 "ModemPeripheral",
00093 "MonitorPeripheral",
00094 "PrinterPeripheral",
00095 "PointerPeripheral",
00096 "KeyboardPeripheral",
00097 "TerminalPeripheral",
00098 "OtherPeripheral",
00099 "LinePeripheral",
00100 "NetworkPeripheral"
00101 "OtherPeripheral",
00102 "XTalkAdapter",
00103 "PCIAdapter",
00104 "GIOAdapter",
00105 "TPUAdapter",
00106 "Anonymous"
00107 };
00108
00109 static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
00110 static arc_func_vector_t *arc_entry;
00111
00112
00113 static void arc_putchar(char ch);
00114
00116 int arc_enabled(void)
00117 {
00118 return sbp != NULL;
00119 }
00120
00121
00123 static void arc_print_confdata(arc_component *c)
00124 {
00125 cm_resource_list *configdata;
00126 int i;
00127
00128 if (!c->configdatasize)
00129 return;
00130
00131 configdata = malloc(c->configdatasize, 0);
00132
00133 if (arc_entry->getconfigurationdata(configdata, c)) {
00134 free(configdata);
00135 return;
00136 }
00137
00138 free(configdata);
00139 return;
00140
00141 for (i=0; i < configdata->count; i++) {
00142 switch (configdata->descr[i].type) {
00143 case CmResourceTypePort:
00144 printf("Port: %p-size:%d ",
00145 (__address)configdata->descr[i].u.port.start,
00146 configdata->descr[i].u.port.length);
00147 break;
00148 case CmResourceTypeInterrupt:
00149 printf("Irq: level(%d) vector(%d) ",
00150 configdata->descr[i].u.interrupt.level,
00151 configdata->descr[i].u.interrupt.vector);
00152 break;
00153 case CmResourceTypeMemory:
00154 printf("Memory: %p-size:%d ",
00155 (__address)configdata->descr[i].u.port.start,
00156 configdata->descr[i].u.port.length);
00157 break;
00158 default:
00159 break;
00160 }
00161 }
00162
00163 free(configdata);
00164 }
00165
00167 static void arc_print_component(arc_component *c)
00168 {
00169 int i;
00170
00171 printf("%s: ",ctypes[c->type]);
00172 for (i=0;i < c->identifier_len;i++)
00173 printf("%c",c->identifier[i]);
00174
00175 printf(" ");
00176 arc_print_confdata(c);
00177 printf("\n");
00178 }
00179
00183 static int cmd_arc_print_devices(cmd_arg_t *argv)
00184 {
00185 arc_component *c,*next;
00186
00187 c = arc_entry->getchild(NULL);
00188 while (c) {
00189 arc_print_component(c);
00190 next = arc_entry->getchild(c);
00191 while (!next) {
00192 next = arc_entry->getpeer(c);
00193 if (!next)
00194 c = arc_entry->getparent(c);
00195 if (!c)
00196 return 0;
00197 }
00198 c = next;
00199 }
00200 return 1;
00201 }
00202 static cmd_info_t devlist_info = {
00203 .name = "arcdevlist",
00204 .description = "Print arc device list",
00205 .func = cmd_arc_print_devices,
00206 .argc = 0
00207 };
00208
00209
00213 static int cmd_arc_print_memmap(cmd_arg_t *argv)
00214 {
00215 arc_memdescriptor_t *desc;
00216
00217 printf("Memory map:\n");
00218
00219 desc = arc_entry->getmemorydescriptor(NULL);
00220 while (desc) {
00221 printf("%s: %d(%p) (size: %dKB)\n",basetypes[desc->type],
00222 desc->basepage * ARC_FRAME,
00223 desc->basepage * ARC_FRAME,
00224 desc->basecount*ARC_FRAME/1024);
00225 desc = arc_entry->getmemorydescriptor(desc);
00226 }
00227 return 1;
00228 }
00229 static cmd_info_t memmap_info = {
00230 .name = "arcmemmap",
00231 .description = "Print arc memory map",
00232 .func = cmd_arc_print_memmap,
00233 .argc = 0
00234 };
00235
00237 static void arc_putchar(char ch)
00238 {
00239 __u32 cnt;
00240 ipl_t ipl;
00241
00242
00243 ipl = interrupts_disable();
00244 arc_entry->write(1, &ch, 1, &cnt);
00245 interrupts_restore(ipl);
00246
00247 }
00248
00249 static int cmd_reboot(cmd_arg_t *argv)
00250 {
00251 arc_entry->reboot();
00252 return 0;
00253 }
00254 static cmd_info_t reboot_info = {
00255 .name = "reboot",
00256 .description = "Reboot computer",
00257 .func = cmd_reboot,
00258 .argc = 0
00259 };
00260
00265 int arc_init(void)
00266 {
00267 if (sbp->signature != ARC_MAGIC) {
00268 sbp = NULL;
00269 return -1;
00270 }
00271 arc_entry = sbp->firmwarevector;
00272
00273 arc_putchar('A');
00274 arc_putchar('R');
00275 arc_putchar('C');
00276 arc_putchar('\n');
00277
00278
00279 cmd_initialize(&reboot_info);
00280 cmd_register(&reboot_info);
00281 cmd_initialize(&memmap_info);
00282 cmd_register(&memmap_info);
00283 cmd_initialize(&devlist_info);
00284 cmd_register(&devlist_info);
00285
00286 return 0;
00287 }
00288
00289 static bool kbd_polling_enabled;
00290 static chardev_t console;
00291
00293 static void arc_keyboard_poll(void)
00294 {
00295 char ch;
00296 __u32 count;
00297 long result;
00298
00299 if (! kbd_polling_enabled)
00300 return;
00301
00302 if (arc_entry->getreadstatus(0))
00303 return;
00304 result = arc_entry->read(0, &ch, 1, &count);
00305 if (result || count!=1) {
00306 return;
00307 }
00308 if (ch == '\r')
00309 ch = '\n';
00310 if (ch == 0x7f)
00311 ch = '\b';
00312
00313 chardev_push_character(&console, ch);
00314 }
00315
00316 static char arc_read(chardev_t *dev)
00317 {
00318 char ch;
00319 __u32 count;
00320 long result;
00321
00322 result = arc_entry->read(0, &ch, 1, &count);
00323 if (result || count!=1) {
00324 printf("Error reading from ARC keyboard.\n");
00325 cpu_halt();
00326 }
00327 if (ch == '\r')
00328 return '\n';
00329 if (ch == 0x7f)
00330 return '\b';
00331 return ch;
00332 }
00333
00334 static void arc_write(chardev_t *dev, const char ch)
00335 {
00336 arc_putchar(ch);
00337 }
00338
00339 static void arc_enable(chardev_t *dev)
00340 {
00341 kbd_polling_enabled = true;
00342 }
00343
00344 static void arc_disable(chardev_t *dev)
00345 {
00346 kbd_polling_enabled = false;
00347 }
00348
00349 static chardev_operations_t arc_ops = {
00350 .resume = arc_enable,
00351 .suspend = arc_disable,
00352 .write = arc_write,
00353 .read = arc_read
00354 };
00355
00356 iroutine old_timer;
00358 static void timer_replace(int n, istate_t *istate)
00359 {
00360 arc_keyboard_poll();
00361 old_timer(n, istate);
00362 arc_keyboard_poll();
00363 }
00364
00365 void arc_console(void)
00366 {
00367 kbd_polling_enabled = true;
00368
00369 chardev_initialize("arc_console", &console, &arc_ops);
00370 old_timer = int_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
00371 stdin = &console;
00372 stdout = &console;
00373 }
00374
00375
00376
00377
00378
00379 void arc_frame_init(void)
00380 {
00381 arc_memdescriptor_t *desc;
00382 int total = 0;
00383 __address base;
00384 size_t basesize;
00385
00386 desc = arc_entry->getmemorydescriptor(NULL);
00387 while (desc) {
00388 if (desc->type == FreeMemory ||
00389 desc->type == FreeContiguous) {
00390 base = desc->basepage*ARC_FRAME;
00391 basesize = desc->basecount*ARC_FRAME;
00392
00393 if (base % FRAME_SIZE ) {
00394 basesize -= FRAME_SIZE - (base % FRAME_SIZE);
00395 base = ALIGN_UP(base, FRAME_SIZE);
00396 }
00397 basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
00398
00399 total += basesize;
00400
00401 zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
00402 ADDR2PFN(base), 0);
00403 }
00404 desc = arc_entry->getmemorydescriptor(desc);
00405 }
00406
00407 config.memory_size = total;
00408 }
00409
00410