Subversion Repositories HelenOS-historic

Rev

Rev 820 | Rev 853 | Go to most recent revision | 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. #include <arch/drivers/arc.h>
  30. #include <arch/mm/page.h>
  31. #include <print.h>
  32. #include <arch.h>
  33. #include <arch/byteorder.h>
  34. #include <arch/mm/frame.h>
  35. #include <mm/frame.h>
  36. #include <interrupt.h>
  37. #include <align.h>
  38. #include <console/console.h>
  39. #include <console/kconsole.h>
  40. #include <console/cmd.h>
  41.  
  42. /* This is a good joke, SGI HAS different types than NT bioses... */
  43. /* Here is the SGI type */
  44. static char *basetypes[] = {
  45.     "ExceptionBlock",
  46.     "SystemParameterBlock",
  47.     "FreeContiguous",
  48.     "FreeMemory",
  49.     "BadMemory",
  50.     "LoadedProgram",
  51.     "FirmwareTemporary",
  52.     "FirmwarePermanent"
  53. };
  54.  
  55. static char *ctypes[] = {
  56.     "ARC_type",
  57.     "CPU_type",
  58.     "FPU_type",
  59.     "PrimaryICache",
  60.     "PrimaryDCache",
  61.     "SecondaryICache",
  62.     "SecondaryDCache",
  63.     "SecondaryCache",
  64.     "Memory",
  65.     "EISAAdapter",
  66.     "TCAdapter",
  67.     "SCSIAdapter",
  68.     "DTIAdapter",
  69.     "MultiFunctionAdapter",
  70.     "DiskController",
  71.     "TapeController",
  72.     "CDROMController",
  73.     "WORMController",
  74.     "SerialController",
  75.     "NetworkController",
  76.     "DisplayController",
  77.     "ParallelController",
  78.     "PointerController",
  79.     "KeyboardController",
  80.     "AudioController",
  81.     "OtherController",
  82.     "DiskPeripheral",
  83.     "FloppyDiskPeripheral",
  84.     "TapePeripheral",
  85.     "ModemPeripheral",
  86.     "MonitorPeripheral",
  87.     "PrinterPeripheral",
  88.     "PointerPeripheral",
  89.     "KeyboardPeripheral",
  90.     "TerminalPeripheral",
  91.     "OtherPeripheral",
  92.     "LinePeripheral",
  93.     "NetworkPeripheral"
  94.     "OtherPeripheral",
  95.     "XTalkAdapter",
  96.     "PCIAdapter",
  97.     "GIOAdapter",
  98.     "TPUAdapter",
  99.     "Anonymous"
  100. };
  101.  
  102. static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
  103. static arc_func_vector_t *arc_entry;
  104.  
  105.  
  106. static void arc_putchar(char ch);
  107.  
  108. /** Return true if ARC is available */
  109. int arc_enabled(void)
  110. {
  111.     return sbp != NULL;
  112. }
  113.  
  114. static void arc_print_component(arc_component *c)
  115. {
  116.     int i;
  117.  
  118.     printf("%s: ",ctypes[c->type]);
  119.     for (i=0;i < c->identifier_len;i++)
  120.         arc_putchar(c->identifier[i]);
  121.     arc_putchar('\n');
  122. }
  123.  
  124. void arc_print_devices(void)
  125. {
  126.     arc_component *c,*next;
  127.  
  128.     if (!arc_enabled())
  129.         return;
  130.  
  131.     c = arc_entry->getchild(NULL);
  132.     while (c) {
  133.         arc_print_component(c);
  134.         next = arc_entry->getchild(c);
  135.         while (!next) {
  136.             next = arc_entry->getpeer(c);
  137.             if (!next)
  138.                 c = arc_entry->getparent(c);
  139.             if (!c)
  140.                 return;
  141.         }
  142.         c = next;
  143.     }
  144. }
  145.  
  146. void arc_print_memory_map(void)
  147. {
  148.     arc_memdescriptor_t *desc;
  149.  
  150.     if (!arc_enabled())
  151.         return;
  152.  
  153.     printf("Memory map:\n");
  154.  
  155.     desc = arc_entry->getmemorydescriptor(NULL);
  156.     while (desc) {
  157.         printf("%s: %d(%P) (size: %dKB)\n",basetypes[desc->type],
  158.                desc->basepage * ARC_FRAME,
  159.                desc->basepage * ARC_FRAME,
  160.                desc->basecount*ARC_FRAME/1024);
  161.         desc = arc_entry->getmemorydescriptor(desc);
  162.     }
  163. }
  164.  
  165. /** Print charactor to console */
  166. static void arc_putchar(char ch)
  167. {
  168.     __u32 cnt;
  169.     ipl_t ipl;
  170.  
  171.     /* TODO: Should be spinlock? */
  172.     ipl = interrupts_disable();
  173.     arc_entry->write(1, &ch, 1, &cnt);
  174.     interrupts_restore(ipl);
  175.    
  176. }
  177.  
  178. static int cmd_reboot(cmd_arg_t *argv)
  179. {
  180.     arc_entry->reboot();
  181.     return 0;
  182. }
  183. static cmd_info_t reboot_info = {
  184.     .name = "reboot",
  185.     .description = "Reboot computer",
  186.     .func = cmd_reboot,
  187.     .argc = 0
  188. };
  189.  
  190. /** Initialize ARC structure
  191.  *
  192.  * @return 0 - ARC OK, -1 - ARC does not exist
  193.  */
  194. int arc_init(void)
  195. {
  196.     if (sbp->signature != ARC_MAGIC) {
  197.         sbp = NULL;
  198.         return -1;
  199.     }
  200.     arc_entry = sbp->firmwarevector;
  201.  
  202.     arc_putchar('A');
  203.     arc_putchar('R');
  204.     arc_putchar('C');
  205.     arc_putchar('\n');
  206.  
  207.     /* Add command for resetting the computer */
  208.     cmd_initialize(&reboot_info);
  209.     cmd_register(&reboot_info);
  210.  
  211.     return 0;
  212. }
  213.  
  214. static bool kbd_polling_enabled;
  215. static chardev_t console;
  216.  
  217. /** Try to get character, return character or -1 if not available */
  218. static void arc_keyboard_poll(void)
  219. {
  220.     char ch;
  221.     __u32 count;
  222.     long result;
  223.    
  224.     if (! kbd_polling_enabled)
  225.         return;
  226.  
  227.     if (arc_entry->getreadstatus(0))
  228.         return;
  229.     result = arc_entry->read(0, &ch, 1, &count);
  230.     if (result || count!=1) {
  231.         return;
  232.     }
  233.     if (ch == '\r')
  234.         ch = '\n';
  235.     if (ch == 0x7f)
  236.         ch = '\b';
  237.    
  238.     chardev_push_character(&console, ch);
  239. }
  240.  
  241. static char arc_read(chardev_t *dev)
  242. {
  243.     char ch;
  244.     __u32 count;
  245.     long result;
  246.  
  247.     result = arc_entry->read(0, &ch, 1, &count);
  248.     if (result || count!=1) {
  249.         printf("Error reading from ARC keyboard.\n");
  250.         cpu_halt();
  251.     }
  252.     if (ch == '\r')
  253.         return '\n';
  254.     if (ch == 0x7f)
  255.         return '\b';
  256.     return ch;
  257. }
  258.  
  259. static void arc_write(chardev_t *dev, const char ch)
  260. {
  261.     arc_putchar(ch);
  262. }
  263.  
  264. static void arc_enable(chardev_t *dev)
  265. {
  266.     kbd_polling_enabled = true;
  267. }
  268.  
  269. static void arc_disable(chardev_t *dev)
  270. {
  271.     kbd_polling_enabled = false;
  272. }
  273.  
  274. static chardev_operations_t arc_ops = {
  275.     .resume = arc_enable,
  276.     .suspend = arc_disable,
  277.     .write = arc_write,
  278.     .read = arc_read
  279. };
  280.  
  281. iroutine old_timer;
  282. /** Do polling on timer interrupt */
  283. static void timer_replace(int n, void *stack)
  284. {
  285.     arc_keyboard_poll();
  286.     old_timer(n, stack);
  287.     arc_keyboard_poll();
  288. }
  289.  
  290. void arc_console(void)
  291. {
  292.     kbd_polling_enabled = true;
  293.    
  294.     chardev_initialize("arc_console", &console, &arc_ops);
  295.     old_timer = int_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
  296.     stdin = &console;
  297.     stdout = &console;
  298. }
  299.  
  300. /* Initialize frame zones from ARC firmware.
  301.  * In the future we may use even the FirmwareTemporary regions,
  302.  * currently we use the FreeMemory (what about the LoadedProgram?)
  303.  */
  304. void arc_frame_init(void)
  305. {
  306.     arc_memdescriptor_t *desc;
  307.     int total = 0;
  308.     __address base;
  309.     size_t basesize;
  310.  
  311.     desc = arc_entry->getmemorydescriptor(NULL);
  312.     while (desc) {
  313.         if (desc->type == FreeMemory ||
  314.             desc->type == FreeContiguous) {
  315.             base = desc->basepage*ARC_FRAME;
  316.             basesize = desc->basecount*ARC_FRAME;
  317.  
  318.             if (base % FRAME_SIZE ) {
  319.                 basesize -= FRAME_SIZE - (base % FRAME_SIZE);
  320.                 base = ALIGN_UP(base, FRAME_SIZE);
  321.             }
  322.             basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
  323.  
  324.             total += basesize;
  325.            
  326.             zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
  327.                     ADDR2PFN(base), 0);
  328.         }
  329.         desc = arc_entry->getmemorydescriptor(desc);
  330.     }
  331.  
  332.     config.memory_size = total;
  333. }
  334.  
  335.