Subversion Repositories HelenOS

Rev

Rev 1787 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2005 Ondrej Palkovsky
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29.  /** @addtogroup mips32
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <arch/drivers/arc.h>
  36. #include <arch/mm/page.h>
  37. #include <print.h>
  38. #include <arch.h>
  39. #include <arch/byteorder.h>
  40. #include <arch/mm/frame.h>
  41. #include <mm/frame.h>
  42. #include <interrupt.h>
  43. #include <align.h>
  44. #include <console/console.h>
  45. #include <console/kconsole.h>
  46. #include <console/cmd.h>
  47. #include <mm/slab.h>
  48.  
  49. /* This is a good joke, SGI HAS different types than NT bioses... */
  50. /* Here is the SGI type */
  51. static char *basetypes[] = {
  52.     "ExceptionBlock",
  53.     "SystemParameterBlock",
  54.     "FreeContiguous",
  55.     "FreeMemory",
  56.     "BadMemory",
  57.     "LoadedProgram",
  58.     "FirmwareTemporary",
  59.     "FirmwarePermanent"
  60. };
  61.  
  62. static char *ctypes[] = {
  63.     "ARC_type",
  64.     "CPU_type",
  65.     "FPU_type",
  66.     "PrimaryICache",
  67.     "PrimaryDCache",
  68.     "SecondaryICache",
  69.     "SecondaryDCache",
  70.     "SecondaryCache",
  71.     "Memory",
  72.     "EISAAdapter",
  73.     "TCAdapter",
  74.     "SCSIAdapter",
  75.     "DTIAdapter",
  76.     "MultiFunctionAdapter",
  77.     "DiskController",
  78.     "TapeController",
  79.     "CDROMController",
  80.     "WORMController",
  81.     "SerialController",
  82.     "NetworkController",
  83.     "DisplayController",
  84.     "ParallelController",
  85.     "PointerController",
  86.     "KeyboardController",
  87.     "AudioController",
  88.     "OtherController",
  89.     "DiskPeripheral",
  90.     "FloppyDiskPeripheral",
  91.     "TapePeripheral",
  92.     "ModemPeripheral",
  93.     "MonitorPeripheral",
  94.     "PrinterPeripheral",
  95.     "PointerPeripheral",
  96.     "KeyboardPeripheral",
  97.     "TerminalPeripheral",
  98.     "OtherPeripheral",
  99.     "LinePeripheral",
  100.     "NetworkPeripheral"
  101.     "OtherPeripheral",
  102.     "XTalkAdapter",
  103.     "PCIAdapter",
  104.     "GIOAdapter",
  105.     "TPUAdapter",
  106.     "Anonymous"
  107. };
  108.  
  109. static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
  110. static arc_func_vector_t *arc_entry;
  111.  
  112.  
  113. static void arc_putchar(char ch);
  114.  
  115. /** Return true if ARC is available */
  116. int arc_enabled(void)
  117. {
  118.     return sbp != NULL;
  119. }
  120.  
  121.  
  122. /** Print configuration data that ARC reports about component */
  123. static void arc_print_confdata(arc_component *c)
  124. {
  125.     cm_resource_list *configdata;
  126.     int i;
  127.  
  128.     if (!c->configdatasize)
  129.         return; /* No configuration data */
  130.  
  131.     configdata = malloc(c->configdatasize, 0);
  132.  
  133.     if (arc_entry->getconfigurationdata(configdata, c)) {
  134.         free(configdata);
  135.         return;
  136.     }
  137.     /* Does not seem to return meaningful data, don't use now */
  138.     free(configdata);
  139.     return;
  140.    
  141.     for (i=0; i < configdata->count; i++) {
  142.         switch (configdata->descr[i].type) {
  143.         case CmResourceTypePort:
  144.             printf("Port: %p-size:%d ",
  145.                    (uintptr_t)configdata->descr[i].u.port.start,
  146.                    configdata->descr[i].u.port.length);
  147.             break;
  148.         case CmResourceTypeInterrupt:
  149.             printf("Irq: level(%d) vector(%d) ",
  150.                    configdata->descr[i].u.interrupt.level,
  151.                    configdata->descr[i].u.interrupt.vector);
  152.             break;
  153.         case CmResourceTypeMemory:
  154.             printf("Memory: %p-size:%d ",
  155.                    (uintptr_t)configdata->descr[i].u.port.start,
  156.                    configdata->descr[i].u.port.length);
  157.             break;
  158.         default:
  159.             break;
  160.         }
  161.     }
  162.  
  163.     free(configdata);
  164. }
  165.  
  166. /** Print information about component */
  167. static void arc_print_component(arc_component *c)
  168. {
  169.     int i;
  170.  
  171.     printf("%s: ",ctypes[c->type]);
  172.     for (i=0;i < c->identifier_len;i++)
  173.         printf("%c",c->identifier[i]);
  174.  
  175.     printf(" ");
  176.     arc_print_confdata(c);
  177.     printf("\n");
  178. }
  179.  
  180. /**
  181.  * Read from ARC bios configuration data and print it
  182.  */
  183. static int cmd_arc_print_devices(cmd_arg_t *argv)
  184. {
  185.     arc_component *c,*next;
  186.  
  187.     c = arc_entry->getchild(NULL);
  188.     while (c) {
  189.         arc_print_component(c);
  190.         next = arc_entry->getchild(c);
  191.         while (!next) {
  192.             next = arc_entry->getpeer(c);
  193.             if (!next)
  194.                 c = arc_entry->getparent(c);
  195.             if (!c)
  196.                 return 0;
  197.         }
  198.         c = next;
  199.     }
  200.     return 1;
  201. }
  202. static cmd_info_t devlist_info = {
  203.     .name = "arcdevlist",
  204.     .description = "Print arc device list",
  205.     .func = cmd_arc_print_devices,
  206.     .argc = 0
  207. };
  208.  
  209.  
  210. /** Read from arc bios memory map and print it
  211.  *
  212.  */
  213. static int cmd_arc_print_memmap(cmd_arg_t *argv)
  214. {
  215.     arc_memdescriptor_t *desc;
  216.  
  217.     printf("Memory map:\n");
  218.  
  219.     desc = arc_entry->getmemorydescriptor(NULL);
  220.     while (desc) {
  221.         printf("%s: %d(%p) (size: %dKB)\n",basetypes[desc->type],
  222.                desc->basepage * ARC_FRAME,
  223.                desc->basepage * ARC_FRAME,
  224.                desc->basecount*ARC_FRAME/1024);
  225.         desc = arc_entry->getmemorydescriptor(desc);
  226.     }
  227.     return 1;
  228. }
  229. static cmd_info_t memmap_info = {
  230.     .name = "arcmemmap",
  231.     .description = "Print arc memory map",
  232.     .func = cmd_arc_print_memmap,
  233.     .argc = 0
  234. };
  235.  
  236. /** Print charactor to console */
  237. static void arc_putchar(char ch)
  238. {
  239.     uint32_t cnt;
  240.     ipl_t ipl;
  241.  
  242.     /* TODO: Should be spinlock? */
  243.     ipl = interrupts_disable();
  244.     arc_entry->write(1, &ch, 1, &cnt);
  245.     interrupts_restore(ipl);
  246.    
  247. }
  248.  
  249. static int cmd_reboot(cmd_arg_t *argv)
  250. {
  251.     arc_entry->reboot();
  252.     return 0;
  253. }
  254. static cmd_info_t reboot_info = {
  255.     .name = "reboot",
  256.     .description = "Reboot computer",
  257.     .func = cmd_reboot,
  258.     .argc = 0
  259. };
  260.  
  261. /** Initialize ARC structure
  262.  *
  263.  * @return 0 - ARC OK, -1 - ARC does not exist
  264.  */
  265. int arc_init(void)
  266. {
  267.     if (sbp->signature != ARC_MAGIC) {
  268.         sbp = NULL;
  269.         return -1;
  270.     }
  271.     arc_entry = sbp->firmwarevector;
  272.  
  273.     arc_putchar('A');
  274.     arc_putchar('R');
  275.     arc_putchar('C');
  276.     arc_putchar('\n');
  277.  
  278.     /* Add command for resetting the computer */
  279.     cmd_initialize(&reboot_info);
  280.     cmd_register(&reboot_info);
  281.     cmd_initialize(&memmap_info);
  282.     cmd_register(&memmap_info);
  283.     cmd_initialize(&devlist_info);
  284.     cmd_register(&devlist_info);
  285.  
  286.     return 0;
  287. }
  288.  
  289. static bool kbd_polling_enabled;
  290. static chardev_t console;
  291.  
  292. /** Try to get character, return character or -1 if not available */
  293. static void arc_keyboard_poll(void)
  294. {
  295.     char ch;
  296.     uint32_t count;
  297.     long result;
  298.    
  299.     if (! kbd_polling_enabled)
  300.         return;
  301.  
  302.     if (arc_entry->getreadstatus(0))
  303.         return;
  304.     result = arc_entry->read(0, &ch, 1, &count);
  305.     if (result || count!=1) {
  306.         return;
  307.     }
  308.     if (ch == '\r')
  309.         ch = '\n';
  310.     if (ch == 0x7f)
  311.         ch = '\b';
  312.    
  313.     chardev_push_character(&console, ch);
  314. }
  315.  
  316. static char arc_read(chardev_t *dev)
  317. {
  318.     char ch;
  319.     uint32_t count;
  320.     long result;
  321.  
  322.     result = arc_entry->read(0, &ch, 1, &count);
  323.     if (result || count!=1) {
  324.         printf("Error reading from ARC keyboard.\n");
  325.         cpu_halt();
  326.     }
  327.     if (ch == '\r')
  328.         return '\n';
  329.     if (ch == 0x7f)
  330.         return '\b';
  331.     return ch;
  332. }
  333.  
  334. static void arc_write(chardev_t *dev, const char ch)
  335. {
  336.     arc_putchar(ch);
  337. }
  338.  
  339. static void arc_enable(chardev_t *dev)
  340. {
  341.     kbd_polling_enabled = true;
  342. }
  343.  
  344. static void arc_disable(chardev_t *dev)
  345. {
  346.     kbd_polling_enabled = false;
  347. }
  348.  
  349. static chardev_operations_t arc_ops = {
  350.     .resume = arc_enable,
  351.     .suspend = arc_disable,
  352.     .write = arc_write,
  353.     .read = arc_read
  354. };
  355.  
  356. iroutine old_timer;
  357. /** Do polling on timer interrupt */
  358. static void timer_replace(int n, istate_t *istate)
  359. {
  360.     arc_keyboard_poll();
  361.     old_timer(n, istate);
  362.     arc_keyboard_poll();
  363. }
  364.  
  365. void arc_console(void)
  366. {
  367.     kbd_polling_enabled = true;
  368.    
  369.     chardev_initialize("arc_console", &console, &arc_ops);
  370.     old_timer = int_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
  371.     stdin = &console;
  372.     stdout = &console;
  373. }
  374.  
  375. /* Initialize frame zones from ARC firmware.
  376.  * In the future we may use even the FirmwareTemporary regions,
  377.  * currently we use the FreeMemory (what about the LoadedProgram?)
  378.  */
  379. void arc_frame_init(void)
  380. {
  381.     arc_memdescriptor_t *desc;
  382.     int total = 0;
  383.     uintptr_t base;
  384.     size_t basesize;
  385.  
  386.     desc = arc_entry->getmemorydescriptor(NULL);
  387.     while (desc) {
  388.         if (desc->type == FreeMemory ||
  389.             desc->type == FreeContiguous) {
  390.             base = desc->basepage*ARC_FRAME;
  391.             basesize = desc->basecount*ARC_FRAME;
  392.  
  393.             if (base % FRAME_SIZE ) {
  394.                 basesize -= FRAME_SIZE - (base % FRAME_SIZE);
  395.                 base = ALIGN_UP(base, FRAME_SIZE);
  396.             }
  397.             basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
  398.  
  399.             total += basesize;
  400.            
  401.             zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
  402.                     ADDR2PFN(base), 0);
  403.         }
  404.         desc = arc_entry->getmemorydescriptor(desc);
  405.     }
  406.  
  407.     config.memory_size = total;
  408. }
  409.  
  410.  
  411.  /** @}
  412.  */
  413.  
  414.