Changes in boot/genarch/ofw.c [e0565005:fd375a8d] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • boot/genarch/ofw.c

    re0565005 rfd375a8d  
    3232#include <asm.h>
    3333#include <types.h>
    34 #include <string.h>
    35 
    36 #define RED(i)    (((i) >> 5) & ((1 << 3) - 1))
    37 #define GREEN(i)  (((i) >> 3) & ((1 << 2) - 1))
    38 #define BLUE(i)   ((i) & ((1 << 3) - 1))
    39 #define CLIP(i)   ((i) <= 255 ? (i) : 255)
    4034
    4135uintptr_t ofw_cif;
     
    4741ihandle ofw_memory_prop;
    4842phandle ofw_memory;
     43phandle ofw_aliases;
    4944
    5045void ofw_init(void)
     
    7469                halt();
    7570        }
    76        
     71
    7772        ofw_memory = ofw_find_device("/memory");
    7873        if (ofw_memory == -1) {
     
    8075                halt();
    8176        }
     77       
     78        ofw_aliases = ofw_find_device("/aliases");
     79        if (ofw_aliases == -1) {
     80                puts("\r\nError: Unable to find /aliases device, halted.\r\n");
     81                halt();
     82        }
    8283}
    8384
    8485/** Perform a call to OpenFirmware client interface.
    8586 *
    86  * @param service String identifying the service requested.
    87  * @param nargs   Number of input arguments.
    88  * @param nret    Number of output arguments. This includes the return
    89  *                value.
    90  * @param rets    Buffer for output arguments or NULL. The buffer must
    91  *                accommodate nret - 1 items.
    92  *
    93  * @return Return value returned by the client interface.
    94  *
     87 * @param service       String identifying the service requested.
     88 * @param nargs         Number of input arguments.
     89 * @param nret          Number of output arguments. This includes the return
     90 *                      value.
     91 * @param rets          Buffer for output arguments or NULL. The buffer must
     92 *                      accommodate nret - 1 items.
     93 *
     94 * @return              Return value returned by the client interface.
    9595 */
    9696unsigned long
     
    127127}
    128128
    129 int ofw_get_property(const phandle device, const char *name, void *buf,
     129int
     130ofw_get_property(const phandle device, const char *name, void *buf,
    130131    const int buflen)
    131132{
     
    160161}
    161162
     163
    162164unsigned int ofw_get_size_cells(const phandle device)
    163165{
     
    219221}
    220222
    221 void *ofw_claim_virt(const void *virt, const unsigned int len)
     223void *ofw_claim_virt(const void *virt, const int len)
    222224{
    223225        ofw_arg_t retaddr;
     
    232234}
    233235
    234 static void *ofw_claim_phys_internal(const void *phys, const unsigned int len, const unsigned int alignment)
    235 {
    236         /*
    237          * Note that the return value check will help
    238          * us to discover conflicts between OpenFirmware
    239          * allocations and our use of physical memory.
    240          * It is better to detect collisions here
    241          * than to cope with weird errors later.
    242          *
    243          * So this is really not to make the loader
    244          * more generic; it is here for debugging
    245          * purposes.
    246          */
    247        
     236void *ofw_claim_phys(const void *phys, const int len)
     237{
     238        ofw_arg_t retaddr[2];
     239        int shift;
     240
    248241        if (sizeof(unative_t) == 8) {
    249                 ofw_arg_t retaddr[2];
    250                 int shift = 32;
    251                
     242                shift = 32;
    252243                if (ofw_call("call-method", 6, 3, retaddr, "claim",
    253                     ofw_memory_prop, alignment, len, ((uintptr_t) phys) >> shift,
     244                    ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift,
    254245                    ((uintptr_t) phys) & ((uint32_t) -1)) != 0) {
     246                        /*
     247                         * Note that this will help us to discover
     248                         * conflicts between OpenFirmware allocations
     249                         * and our use of physical memory.
     250                         * It is better to detect collisions here
     251                         * than to cope with weird errors later.
     252                         *
     253                         * So this is really not to make the loader
     254                         * more generic; it is here for debugging
     255                         * purposes.
     256                         */
    255257                        puts("Error: memory method claim() failed, halting.\n");
    256258                        halt();
    257259                }
    258                
    259                 return (void *) ((retaddr[0] << shift) | retaddr[1]);
    260260        } else {
    261                 ofw_arg_t retaddr[1];
    262                
    263                 if (ofw_call("call-method", 5, 2, retaddr, "claim",
    264                     ofw_memory_prop, alignment, len, (uintptr_t) phys) != 0) {
    265                         puts("Error: memory method claim() failed, halting.\n");
    266                         halt();
    267                 }
    268                
    269                 return (void *) retaddr[0];
    270         }
    271 }
    272 
    273 void *ofw_claim_phys(const void *phys, const unsigned int len)
    274 {
    275         return ofw_claim_phys_internal(phys, len, 0);
    276 }
    277 
    278 void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment)
    279 {
    280         return ofw_claim_phys_internal(NULL, len, alignment);
    281 }
    282 
    283 int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode)
     261                shift = 0;
     262                /*
     263                 * FIXME: the number of arguments is probably different...
     264                 */
     265                puts("Error: 32-bit ofw_claim_phys not implemented.\n");
     266                halt();
     267        }
     268
     269        return (void *) ((retaddr[0] << shift) | retaddr[1]);
     270}
     271
     272int ofw_map(const void *phys, const void *virt, const int size, const int mode)
    284273{
    285274        uintptr_t phys_hi, phys_lo;
     
    325314
    326315                /*
    327                  * This is a hot fix of the issue which occurs on machines
    328                  * where there are holes in the physical memory (such as
    329                  * SunBlade 1500). Should we detect a hole in the physical
    330                  * memory, we will ignore any memory detected behind
    331                  * the hole and pretend the hole does not exist.
     316                 * This is a hot fix of the issue which occurs on machines
     317                 * where there are holes in the physical memory (such as
     318                 * SunBlade 1500). Should we detect a hole in the physical
     319                 * memory, we will ignore any memory detected behind
     320                 * the hole and pretend the hole does not exist.
    332321                 */
    333322                if ((map->count > 0) && (map->zones[map->count - 1].start +
     
    346335}
    347336
    348 static void ofw_setup_screen(phandle handle)
    349 {
    350         /* Check for device type */
    351         char device_type[OFW_TREE_PROPERTY_MAX_VALUELEN];
    352         if (ofw_get_property(handle, "device_type", device_type, OFW_TREE_PROPERTY_MAX_VALUELEN) <= 0)
    353                 return;
    354        
    355         device_type[OFW_TREE_PROPERTY_MAX_VALUELEN - 1] = '\0';
    356         if (strcmp(device_type, "display") != 0)
    357                 return;
    358        
    359         /* Check for 8 bit depth */
     337int ofw_screen(screen_t *screen)
     338{
     339        char device_name[BUF_SIZE];
     340        uint32_t virtaddr;
     341       
     342        if (ofw_get_property(ofw_aliases, "screen", device_name,
     343            sizeof(device_name)) <= 0)
     344                return false;
     345       
     346        phandle device = ofw_find_device(device_name);
     347        if (device == -1)
     348                return false;
     349       
     350        if (ofw_get_property(device, "address", &virtaddr,
     351            sizeof(virtaddr)) <= 0)
     352                return false;
     353
     354        screen->addr = (void *) ((uintptr_t) virtaddr);
     355
     356        if (ofw_get_property(device, "width", &screen->width,
     357            sizeof(screen->width)) <= 0)
     358                return false;
     359       
     360        if (ofw_get_property(device, "height", &screen->height,
     361            sizeof(screen->height)) <= 0)
     362                return false;
     363       
     364        if (ofw_get_property(device, "depth", &screen->bpp,
     365            sizeof(screen->bpp)) <= 0)
     366                return false;
     367       
     368        if (ofw_get_property(device, "linebytes", &screen->scanline,
     369            sizeof(screen->scanline)) <= 0)
     370                return false;
     371       
     372        return true;
     373}
     374
     375#define RED(i)    (((i) >> 5) & ((1 << 3) - 1))
     376#define GREEN(i)  (((i) >> 3) & ((1 << 2) - 1))
     377#define BLUE(i)   ((i) & ((1 << 3) - 1))
     378#define CLIP(i)   ((i) <= 255 ? (i) : 255)
     379
     380
     381/**
     382 * Sets up the palette for the 8-bit color depth configuration so that the
     383 * 3:2:3 color scheme can be used. Checks that setting the palette makes sense
     384 * (appropriate nodes exist in the OBP tree and the color depth is not greater
     385 * than 8).
     386 *
     387 * @return true if the palette has been set, false otherwise
     388 *
     389 */
     390int ofw_setup_palette(void)
     391{
     392        char device_name[BUF_SIZE];
     393       
     394        /* resolve alias */
     395        if (ofw_get_property(ofw_aliases, "screen", device_name,
     396            sizeof(device_name)) <= 0)
     397                return false;
     398       
     399        /* for depth greater than 8 it makes no sense to set up the palette */
    360400        uint32_t depth;
    361         if (ofw_get_property(handle, "depth", &depth, sizeof(uint32_t)) <= 0)
    362                 depth = 0;
    363        
    364         /* Get device path */
    365         static char path[OFW_TREE_PATH_MAX_LEN + 1];
    366         size_t len = ofw_package_to_path(handle, path, OFW_TREE_PATH_MAX_LEN);
    367         if (len == -1)
    368                 return;
    369        
    370         path[len] = '\0';
    371        
    372         /* Open the display to initialize it */
    373         ihandle screen = ofw_open(path);
     401        phandle device = ofw_find_device(device_name);
     402        if (device == -1)
     403                return false;
     404        if (ofw_get_property(device, "depth", &depth, sizeof(uint32_t)) <= 0)
     405                return false;
     406        if (depth != 8)
     407                return false;
     408       
     409        /* required in order to be able to make a method call */
     410        ihandle screen = ofw_open(device_name);
    374411        if (screen == -1)
    375                 return;
    376        
    377         if (depth == 8) {
    378                 /* Setup the palette so that the (inverted) 3:2:3 scheme is usable */
    379                 unsigned int i;
    380                 for (i = 0; i < 256; i++) {
    381                         ofw_call("call-method", 6, 1, NULL, "color!", screen,
    382                             255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37));
    383                 }
    384         }
    385 }
    386 
    387 static void ofw_setup_screens_internal(phandle current)
    388 {
    389         while ((current != 0) && (current != -1)) {
    390                 ofw_setup_screen(current);
    391                
    392                 /*
    393                  * Recursively process the potential child node.
    394                  */
    395                 phandle child = ofw_get_child_node(current);
    396                 if ((child != 0) && (child != -1))
    397                         ofw_setup_screens_internal(child);
    398                
    399                 /*
    400                  * Iteratively process the next peer node.
    401                  * Note that recursion is a bad idea here.
    402                  * Due to the topology of the OpenFirmware device tree,
    403                  * the nesting of peer nodes could be to wide and the
    404                  * risk of overflowing the stack is too real.
    405                  */
    406                 phandle peer = ofw_get_peer_node(current);
    407                 if ((peer != 0) && (peer != -1)) {
    408                         current = peer;
    409                         /*
    410                          * Process the peer in next iteration.
    411                          */
    412                         continue;
    413                 }
    414                
    415                 /*
    416                  * No more peers on this level.
    417                  */
    418                 break;
    419         }
    420 }
    421 
    422 /** Setup all screens which can be detected.
    423  *
    424  * Open all screens which can be detected and set up the palette for the 8-bit
    425  * color depth configuration so that the 3:2:3 color scheme can be used.
    426  * Check that setting the palette makes sense (the color depth is not greater
    427  * than 8).
    428  *
    429  */
    430 void ofw_setup_screens(void)
    431 {
    432         ofw_setup_screens_internal(ofw_root);
     412                return false;
     413       
     414        /* setup the palette so that the (inverted) 3:2:3 scheme is usable */
     415        unsigned int i;
     416        for (i = 0; i < 256; i++)
     417                ofw_call("call-method", 6, 1, NULL, "color!", screen,
     418                    255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37));
     419        return true;
    433420}
    434421
Note: See TracChangeset for help on using the changeset viewer.