Subversion Repositories HelenOS

Rev

Rev 1075 | Rev 1146 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2005 Martin Decky
  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 "ofw.h"
  30. #include "asm.h"
  31. #include "printf.h"
  32.  
  33. #define MAX_OFW_ARGS    10
  34. #define STRING_SIZE     1024
  35.  
  36. typedef unsigned int ofw_arg_t;
  37. typedef unsigned int ihandle;
  38. typedef unsigned int phandle;
  39.  
  40. /** OpenFirmware command structure
  41.  *
  42.  */
  43. typedef struct {
  44.     const char *service;          /**< Command name */
  45.     unsigned int nargs;           /**< Number of in arguments */
  46.     unsigned int nret;            /**< Number of out arguments */
  47.     ofw_arg_t args[MAX_OFW_ARGS]; /**< List of arguments */
  48. } ofw_args_t;
  49.  
  50. typedef void (*ofw_entry)(ofw_args_t *);
  51.  
  52.  
  53. ofw_entry ofw;
  54.  
  55. phandle ofw_chosen;
  56. phandle ofw_aliases;
  57. ihandle ofw_mmu;
  58. ihandle ofw_stdout;
  59.  
  60.  
  61. static int ofw_call(const char *service, const int nargs, const int nret, ...)
  62. {
  63.     va_list list;
  64.     ofw_args_t args;
  65.     int i;
  66.    
  67.     args.service = service;
  68.     args.nargs = nargs;
  69.     args.nret = nret;
  70.    
  71.     va_start(list, nret);
  72.     for (i = 0; i < nargs; i++)
  73.         args.args[i] = va_arg(list, ofw_arg_t);
  74.     va_end(list);
  75.    
  76.     for (i = 0; i < nret; i++)
  77.         args.args[i + nargs] = 0;
  78.    
  79.     ofw(&args);
  80.    
  81.     return args.args[nargs];
  82. }
  83.  
  84.  
  85. static phandle ofw_find_device(const char *name)
  86. {
  87.     return ofw_call("finddevice", 1, 1, name);
  88. }
  89.  
  90.  
  91. static int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen)
  92. {
  93.     return ofw_call("getprop", 4, 1, device, name, buf, buflen);
  94. }
  95.  
  96. static ihandle ofw_open(const char *name)
  97. {
  98.     return ofw_call("open", 1, 1, name);
  99. }
  100.  
  101.  
  102. void init(void)
  103. {
  104.     ofw_chosen = ofw_find_device("/chosen");
  105.     if (ofw_chosen == -1)
  106.         halt();
  107.    
  108.     if (ofw_get_property(ofw_chosen, "stdout",  &ofw_stdout, sizeof(ofw_stdout)) <= 0) 
  109.         ofw_stdout = 0;
  110.    
  111.     ofw_aliases = ofw_find_device("/aliases");
  112.     if (ofw_aliases == -1) {
  113.         puts("\nUnable to find /aliases device\n");
  114.         halt();
  115.     }
  116.    
  117.     ofw_mmu = ofw_open("/mmu");
  118.     if (ofw_mmu == -1) {
  119.         puts("\nUnable to open /mmu node\n");
  120.         halt();
  121.     }
  122. }
  123.  
  124.  
  125. void ofw_write(const char *str, const int len)
  126. {
  127.     if (ofw_stdout == 0)
  128.         return;
  129.    
  130.     ofw_call("write", 3, 1, ofw_stdout, str, len);
  131. }
  132.  
  133.  
  134. void *ofw_translate(const void *virt)
  135. {
  136.     return (void *) ofw_call("call-method", 7, 1, "translate", ofw_mmu, virt, 0, 0, 0, 0);
  137. }
  138.  
  139.  
  140. int ofw_map(const void *phys, const void *virt, const int size, const int mode)
  141. {
  142.     return ofw_call("call-method", 6, 1, "map", ofw_mmu, mode, size, virt, phys);
  143. }
  144.  
  145.  
  146. int ofw_memmap(memmap_t *map)
  147. {
  148.     int i;
  149.     int ret;
  150.  
  151.     phandle handle = ofw_find_device("/memory");
  152.     if (handle == -1)
  153.         return false;
  154.    
  155.     ret = ofw_get_property(handle, "reg", &map->zones, sizeof(map->zones));
  156.     if (ret == -1)
  157.         return false;
  158.    
  159.     map->total = 0;
  160.     map->count = 0;
  161.     for (i = 0; i < MEMMAP_MAX_RECORDS; i++) {
  162.         if (map->zones[i].size == 0)
  163.             break;
  164.         map->count++;
  165.         map->total += map->zones[i].size;
  166.     }
  167. }
  168.  
  169.  
  170. int ofw_screen(screen_t *screen)
  171. {
  172.     char device_name[STRING_SIZE];
  173.    
  174.     if (ofw_get_property(ofw_aliases, "screen", device_name, STRING_SIZE) <= 0)
  175.         return false;
  176.    
  177.     phandle device = ofw_find_device(device_name);
  178.     if (device == -1)
  179.         return false;
  180.    
  181.     if (ofw_get_property(device, "address", &screen->addr, sizeof(screen->addr)) <= 0)
  182.         return false;
  183.    
  184.     if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0)
  185.         return false;
  186.    
  187.     if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0)
  188.         return false;
  189.    
  190.     if (ofw_get_property(device, "depth", &screen->bpp, sizeof(screen->bpp)) <= 0)
  191.         return false;
  192.    
  193.     if (ofw_get_property(device, "linebytes", &screen->scanline, sizeof(screen->scanline)) <= 0)
  194.         return false;
  195.    
  196.     return true;
  197. }
  198.