Subversion Repositories HelenOS

Rev

Rev 2725 | Go to most recent revision | Blame | 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. /** Return true if ARC is available */
  114. #define arc_enabled() (sbp != NULL)
  115.  
  116.  
  117. /** Print configuration data that ARC reports about component */
  118. static void arc_print_confdata(arc_component *c)
  119. {
  120.     cm_resource_list *configdata;
  121.     unsigned int i;
  122.  
  123.     if (!c->configdatasize)
  124.         return; /* No configuration data */
  125.  
  126.     configdata = malloc(c->configdatasize, 0);
  127.  
  128.     if (arc_entry->getconfigurationdata(configdata, c)) {
  129.         free(configdata);
  130.         return;
  131.     }
  132.     /* Does not seem to return meaningful data, don't use now */
  133.     free(configdata);
  134.     return;
  135.    
  136.     for (i = 0; i < configdata->count; i++) {
  137.         switch (configdata->descr[i].type) {
  138.         case CmResourceTypePort:
  139.             printf("Port: %p-size:%d ",
  140.                    (uintptr_t) configdata->descr[i].u.port.start,
  141.                    configdata->descr[i].u.port.length);
  142.             break;
  143.         case CmResourceTypeInterrupt:
  144.             printf("Irq: level(%d) vector(%d) ",
  145.                    configdata->descr[i].u.interrupt.level,
  146.                    configdata->descr[i].u.interrupt.vector);
  147.             break;
  148.         case CmResourceTypeMemory:
  149.             printf("Memory: %p-size:%d ",
  150.                    (uintptr_t)configdata->descr[i].u.port.start,
  151.                    configdata->descr[i].u.port.length);
  152.             break;
  153.         default:
  154.             break;
  155.         }
  156.     }
  157.  
  158.     free(configdata);
  159. }
  160.  
  161. /** Print information about component */
  162. static void arc_print_component(arc_component *c)
  163. {
  164.     unsigned int i;
  165.  
  166.     printf("%s: ",ctypes[c->type]);
  167.     for (i = 0; i < c->identifier_len; i++)
  168.         printf("%c", c->identifier[i]);
  169.  
  170.     printf(" ");
  171.     arc_print_confdata(c);
  172.     printf("\n");
  173. }
  174.  
  175. /**
  176.  * Read from ARC bios configuration data and print it
  177.  */
  178. static int cmd_arc_print_devices(cmd_arg_t *argv)
  179. {
  180.     arc_component *c, *next;
  181.  
  182.     c = arc_entry->getchild(NULL);
  183.     while (c) {
  184.         arc_print_component(c);
  185.         next = arc_entry->getchild(c);
  186.         while (!next) {
  187.             next = arc_entry->getpeer(c);
  188.             if (!next)
  189.                 c = arc_entry->getparent(c);
  190.             if (!c)
  191.                 return 0;
  192.         }
  193.         c = next;
  194.     }
  195.     return 1;
  196. }
  197. static cmd_info_t devlist_info = {
  198.     .name = "arcdevlist",
  199.     .description = "Print arc device list",
  200.     .func = cmd_arc_print_devices,
  201.     .argc = 0
  202. };
  203.  
  204.  
  205. /** Read from arc bios memory map and print it
  206.  *
  207.  */
  208. void physmem_print(void)
  209. {
  210.     printf("Base       Size       Type\n");
  211.     printf("---------- ---------- ---------\n");
  212.    
  213.     if (arc_enabled()) {
  214.         arc_memdescriptor_t *desc = arc_entry->getmemorydescriptor(NULL);
  215.        
  216.         while (desc) {
  217.             printf("%#10x %#10x %s\n",
  218.                 desc->basepage * ARC_FRAME, desc->basecount * ARC_FRAME,
  219.                 basetypes[desc->type]);
  220.             desc = arc_entry->getmemorydescriptor(desc);
  221.         }  
  222.     } else
  223.         printf("%#10x %#10x free\n", 0, CONFIG_MEMORY_SIZE);
  224. }
  225.  
  226. /** Print charactor to console */
  227. static void arc_putchar(char ch)
  228. {
  229.     uint32_t cnt;
  230.     ipl_t ipl;
  231.  
  232.     /* TODO: Should be spinlock? */
  233.     ipl = interrupts_disable();
  234.     arc_entry->write(1, &ch, 1, &cnt);
  235.     interrupts_restore(ipl);
  236. }
  237.  
  238.  
  239. /** Initialize ARC structure
  240.  *
  241.  * @return 0 - ARC OK, -1 - ARC does not exist
  242.  */
  243. int arc_init(void)
  244. {
  245.     if (sbp->signature != ARC_MAGIC) {
  246.         sbp = NULL;
  247.         return -1;
  248.     }
  249.     arc_entry = sbp->firmwarevector;
  250.  
  251.     arc_putchar('A');
  252.     arc_putchar('R');
  253.     arc_putchar('C');
  254.     arc_putchar('\n');
  255.  
  256.     /* Add command for resetting the computer */
  257.     cmd_initialize(&devlist_info);
  258.     cmd_register(&devlist_info);
  259.  
  260.     return 0;
  261. }
  262.  
  263. int arc_reboot(void)
  264. {
  265.     if (arc_enabled()) {
  266.         arc_entry->reboot();
  267.         return true;
  268.     }
  269.    
  270.     return false;
  271. }
  272.  
  273.  
  274. static bool kbd_polling_enabled;
  275. static chardev_t console;
  276.  
  277. /** Try to get character, return character or -1 if not available */
  278. static void arc_keyboard_poll(void)
  279. {
  280.     char ch;
  281.     uint32_t count;
  282.     long result;
  283.    
  284.     if (!kbd_polling_enabled)
  285.         return;
  286.  
  287.     if (arc_entry->getreadstatus(0))
  288.         return;
  289.     result = arc_entry->read(0, &ch, 1, &count);
  290.     if ((result) || (count != 1)) {
  291.         return;
  292.     }
  293.     if (ch == '\r')
  294.         ch = '\n';
  295.     if (ch == 0x7f)
  296.         ch = '\b';
  297.    
  298.     chardev_push_character(&console, ch);
  299. }
  300.  
  301. static char arc_read(chardev_t *dev)
  302. {
  303.     char ch;
  304.     uint32_t count;
  305.     long result;
  306.  
  307.     result = arc_entry->read(0, &ch, 1, &count);
  308.     if ((result) || (count != 1)) {
  309.         printf("Error reading from ARC keyboard.\n");
  310.         cpu_halt();
  311.     }
  312.     if (ch == '\r')
  313.         return '\n';
  314.     if (ch == 0x7f)
  315.         return '\b';
  316.     return ch;
  317. }
  318.  
  319. static void arc_write(chardev_t *dev, const char ch)
  320. {
  321.     arc_putchar(ch);
  322. }
  323.  
  324. static void arc_enable(chardev_t *dev)
  325. {
  326.     kbd_polling_enabled = true;
  327. }
  328.  
  329. static void arc_disable(chardev_t *dev)
  330. {
  331.     kbd_polling_enabled = false;
  332. }
  333.  
  334. static chardev_operations_t arc_ops = {
  335.     .resume = arc_enable,
  336.     .suspend = arc_disable,
  337.     .write = arc_write,
  338.     .read = arc_read
  339. };
  340.  
  341. int arc_console(void)
  342. {
  343.     if (arc_enabled()) {
  344.         kbd_polling_enabled = true;
  345.        
  346.         chardev_initialize("arc_console", &console, &arc_ops);
  347.         virtual_timer_fnc = &arc_keyboard_poll;
  348.         stdin = &console;
  349.         stdout = &console;
  350.        
  351.         return true;
  352.     }
  353.    
  354.     return false;
  355. }
  356.  
  357. /* Initialize frame zones from ARC firmware.
  358.  * In the future we may use even the FirmwareTemporary regions,
  359.  * currently we use the FreeMemory (what about the LoadedProgram?)
  360.  */
  361. int arc_frame_init(void)
  362. {
  363.     if (arc_enabled()) {
  364.         arc_memdescriptor_t *desc;
  365.         uintptr_t base;
  366.         size_t basesize;
  367.    
  368.         desc = arc_entry->getmemorydescriptor(NULL);
  369.         while (desc) {
  370.             if ((desc->type == FreeMemory) ||
  371.                 (desc->type == FreeContiguous)) {
  372.                 base = desc->basepage*ARC_FRAME;
  373.                 basesize = desc->basecount*ARC_FRAME;
  374.    
  375.                 if (base % FRAME_SIZE ) {
  376.                     basesize -= FRAME_SIZE - (base % FRAME_SIZE);
  377.                     base = ALIGN_UP(base, FRAME_SIZE);
  378.                 }
  379.                 basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
  380.    
  381.                 zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
  382.                         ADDR2PFN(base), 0);
  383.             }
  384.             desc = arc_entry->getmemorydescriptor(desc);
  385.         }
  386.    
  387.         return true;
  388.     }
  389.    
  390.     return false;
  391. }
  392.  
  393. /** @}
  394.  */
  395.