Changeset e0565005 in mainline for boot/genarch/ofw.c


Ignore:
Timestamp:
2009-08-24T14:41:42Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ed5ad30
Parents:
21d8020
Message:

initialize and setup all displays which can be detected in OFW tree (not only stdin)
reduce the number of newlines during boot (speedups especially in simulators)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • boot/genarch/ofw.c

    r21d8020 re0565005  
    3232#include <asm.h>
    3333#include <types.h>
     34#include <string.h>
    3435
    3536#define RED(i)    (((i) >> 5) & ((1 << 3) - 1))
     
    4647ihandle ofw_memory_prop;
    4748phandle ofw_memory;
    48 phandle ofw_aliases;
    4949
    5050void ofw_init(void)
     
    7474                halt();
    7575        }
    76 
     76       
    7777        ofw_memory = ofw_find_device("/memory");
    7878        if (ofw_memory == -1) {
    7979                puts("\r\nError: Unable to find /memory device, halted.\r\n");
    80                 halt();
    81         }
    82        
    83         ofw_aliases = ofw_find_device("/aliases");
    84         if (ofw_aliases == -1) {
    85                 puts("\r\nError: Unable to find /aliases device, halted.\r\n");
    8680                halt();
    8781        }
     
    133127}
    134128
    135 int
    136 ofw_get_property(const phandle device, const char *name, void *buf,
     129int ofw_get_property(const phandle device, const char *name, void *buf,
    137130    const int buflen)
    138131{
     
    166159        return ret;
    167160}
    168 
    169161
    170162unsigned int ofw_get_size_cells(const phandle device)
     
    354346}
    355347
    356 /**
    357  * Sets up the palette for the 8-bit color depth configuration so that the
    358  * 3:2:3 color scheme can be used. Checks that setting the palette makes sense
    359  * (appropriate nodes exist in the OBP tree and the color depth is not greater
     348static 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 */
     360        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);
     374        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
     387static 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
    360427 * than 8).
    361428 *
    362  * @return true if the palette has been set, false otherwise
    363  *
    364429 */
    365 int ofw_setup_palette(void)
    366 {
    367         char device_name[BUF_SIZE];
    368        
    369         /* Resolve alias */
    370         if (ofw_get_property(ofw_aliases, "screen", device_name,
    371             sizeof(device_name)) <= 0)
    372                 return false;
    373        
    374         /* For depth greater than 8 it makes no sense to set up the palette */
    375         uint32_t depth;
    376         phandle device = ofw_find_device(device_name);
    377         if (device == -1)
    378                 return false;
    379         if (ofw_get_property(device, "depth", &depth, sizeof(uint32_t)) <= 0)
    380                 return false;
    381         if (depth != 8)
    382                 return false;
    383        
    384         /* Required in order to be able to make a method call */
    385         ihandle screen = ofw_open(device_name);
    386         if (screen == -1)
    387                 return false;
    388        
    389         /* Setup the palette so that the (inverted) 3:2:3 scheme is usable */
    390         unsigned int i;
    391         for (i = 0; i < 256; i++)
    392                 ofw_call("call-method", 6, 1, NULL, "color!", screen,
    393                     255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37));
    394         return true;
     430void ofw_setup_screens(void)
     431{
     432        ofw_setup_screens_internal(ofw_root);
    395433}
    396434
Note: See TracChangeset for help on using the changeset viewer.