Example #1
0
static void __init process_multiboot_node(const void *fdt, int node,
                                          const char *name,
                                          u32 address_cells, u32 size_cells)
{
    static int kind_guess = 0;
    const struct fdt_property *prop;
    const __be32 *cell;
    bootmodule_kind kind;
    paddr_t start, size;
    const char *cmdline;
    int len;

    if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
         fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
        kind = BOOTMOD_KERNEL;
    else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 ||
              fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 )
        kind = BOOTMOD_RAMDISK;
    else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 )
        kind = BOOTMOD_XSM;
    else
        kind = BOOTMOD_UNKNOWN;

    /* Guess that first two unknown are kernel and ramdisk respectively. */
    if ( kind == BOOTMOD_UNKNOWN )
    {
        switch ( kind_guess++ )
        {
        case 0: kind = BOOTMOD_KERNEL; break;
        case 1: kind = BOOTMOD_RAMDISK; break;
        default: break;
        }
    }

    prop = fdt_get_property(fdt, node, "reg", &len);
    if ( !prop )
        panic("node %s missing `reg' property\n", name);

    if ( len < dt_cells_to_size(address_cells + size_cells) )
        panic("fdt: node `%s': `reg` property length is too short\n",
                    name);

    cell = (const __be32 *)prop->data;
    device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);

    prop = fdt_get_property(fdt, node, "bootargs", &len);
    if ( prop )
    {
        if ( len > BOOTMOD_MAX_CMDLINE )
            panic("module %s command line too long\n", name);
        cmdline = prop->data;
    }
    else
        cmdline = NULL;

    add_boot_module(kind, start, size, cmdline);
}
Example #2
0
static void __init process_memory_node(const void *fdt, int node,
                                       const char *name,
                                       u32 address_cells, u32 size_cells)
{
    const struct fdt_property *prop;
    int i;
    int banks;
    const __be32 *cell;
    paddr_t start, size;
    u32 reg_cells = address_cells + size_cells;

    if ( address_cells < 1 || size_cells < 1 )
    {
        printk("fdt: node `%s': invalid #address-cells or #size-cells",
               name);
        return;
    }

    prop = fdt_get_property(fdt, node, "reg", NULL);
    if ( !prop )
    {
        printk("fdt: node `%s': missing `reg' property\n", name);
        return;
    }

    cell = (const __be32 *)prop->data;
    banks = fdt32_to_cpu(prop->len) / (reg_cells * sizeof (u32));

    for ( i = 0; i < banks && bootinfo.mem.nr_banks < NR_MEM_BANKS; i++ )
    {
        device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
        if ( !size )
            continue;
        bootinfo.mem.bank[bootinfo.mem.nr_banks].start = start;
        bootinfo.mem.bank[bootinfo.mem.nr_banks].size = size;
        bootinfo.mem.nr_banks++;
    }
}
Example #3
0
void __init video_init(void)
{
    int node, depth;
    u32 address_cells, size_cells;
    struct lfb_prop lfbp;
    unsigned char *lfb;
    paddr_t hdlcd_start, hdlcd_size;
    paddr_t framebuffer_start, framebuffer_size;
    const struct fdt_property *prop;
    const u32 *cell;
    const char *mode_string;
    char _mode_string[16];
    int bytes_per_pixel = 4;
    struct color_masks *c = NULL;
    struct modeline *videomode = NULL;
    int i;

    if ( find_compatible_node("arm,hdlcd", &node, &depth,
                &address_cells, &size_cells) <= 0 )
        return;

    prop = fdt_get_property(device_tree_flattened, node, "reg", NULL);
    if ( !prop )
        return;

    cell = (const u32 *)prop->data;
    device_tree_get_reg(&cell, address_cells, size_cells,
            &hdlcd_start, &hdlcd_size);

    prop = fdt_get_property(device_tree_flattened, node, "framebuffer", NULL);
    if ( !prop )
        return;

    cell = (const u32 *)prop->data;
    device_tree_get_reg(&cell, address_cells, size_cells,
            &framebuffer_start, &framebuffer_size);

    if ( !hdlcd_start )
    {
        printk(KERN_ERR "HDLCD address missing from device tree, disabling driver\n");
        return;
    }

    if ( !hdlcd_start || !framebuffer_start )
    {
        printk(KERN_ERR "HDLCD: framebuffer address missing from device tree, disabling driver\n");
        return;
    }

    mode_string = fdt_getprop(device_tree_flattened, node, "mode", NULL);
    if ( !mode_string )
    {
        get_color_masks("32", &c);
        memcpy(_mode_string, "1280x1024@60", strlen("1280x1024@60") + 1);
        bytes_per_pixel = 4;
    }
    else if ( strlen(mode_string) < strlen("800x600@60") ||
            strlen(mode_string) > sizeof(_mode_string) - 1 )
    {
        printk(KERN_ERR "HDLCD: invalid modeline=%s\n", mode_string);
        return;
    } else {
        char *s = strchr(mode_string, '-');
        if ( !s )
        {
            printk(KERN_INFO "HDLCD: bpp not found in modeline %s, assume 32 bpp\n",
                    mode_string);
            get_color_masks("32", &c);
            memcpy(_mode_string, mode_string, strlen(mode_string) + 1);
            bytes_per_pixel = 4;
        } else {
            if ( strlen(s) < 6 )
            {
                printk(KERN_ERR "HDLCD: invalid mode %s\n", mode_string);
                return;
            }
            s++;
            if ( get_color_masks(s, &c) < 0 )
            {
                printk(KERN_WARNING "HDLCD: unsupported bpp %s\n", s);
                return;
            }
            bytes_per_pixel = simple_strtoll(s, NULL, 10) / 8;
        }
        i = s - mode_string - 1;
        memcpy(_mode_string, mode_string, i);
        memcpy(_mode_string + i, mode_string + i + 3, 4);
    }

    for ( i = 0; i < ARRAY_SIZE(videomodes); i++ ) {
        if ( !strcmp(_mode_string, videomodes[i].mode) )
        {
            videomode = &videomodes[i];
            break;
        }
    }
    if ( !videomode )
    {
        printk(KERN_WARNING "HDLCD: unsupported videomode %s\n", _mode_string);
        return;
    }

    if ( framebuffer_size < bytes_per_pixel * videomode->xres * videomode->yres )
    {
        printk(KERN_ERR "HDLCD: the framebuffer is too small, disabling the HDLCD driver\n");
        return;
    }

    printk(KERN_INFO "Initializing HDLCD driver\n");

    lfb = ioremap_wc(framebuffer_start, framebuffer_size);
    if ( !lfb )
    {
        printk(KERN_ERR "Couldn't map the framebuffer\n");
        return;
    }
    memset(lfb, 0x00, bytes_per_pixel * videomode->xres * videomode->yres);

    /* uses FIXMAP_MISC */
    set_pixclock(videomode->pixclock);

    set_fixmap(FIXMAP_MISC, hdlcd_start >> PAGE_SHIFT, DEV_SHARED);
    HDLCD[HDLCD_COMMAND] = 0;

    HDLCD[HDLCD_LINELENGTH] = videomode->xres * bytes_per_pixel;
    HDLCD[HDLCD_LINECOUNT] = videomode->yres - 1;
    HDLCD[HDLCD_LINEPITCH] = videomode->xres * bytes_per_pixel;
    HDLCD[HDLCD_PF] = ((bytes_per_pixel - 1) << 3);
    HDLCD[HDLCD_INTMASK] = 0;
    HDLCD[HDLCD_FBBASE] = framebuffer_start;
    HDLCD[HDLCD_BUS] = 0xf00 | (1 << 4);
    HDLCD[HDLCD_VBACK] = videomode->vback - 1;
    HDLCD[HDLCD_VSYNC] = videomode->vsync - 1;
    HDLCD[HDLCD_VDATA] = videomode->yres - 1;
    HDLCD[HDLCD_VFRONT] = videomode->vfront - 1;
    HDLCD[HDLCD_HBACK] = videomode->hback - 1;
    HDLCD[HDLCD_HSYNC] = videomode->hsync - 1;
    HDLCD[HDLCD_HDATA] = videomode->xres - 1;
    HDLCD[HDLCD_HFRONT] = videomode->hfront - 1;
    HDLCD[HDLCD_POLARITIES] = (1 << 2) | (1 << 3);
    HDLCD[HDLCD_RED] = (c->red_size << 8) | c->red_shift;
    HDLCD[HDLCD_GREEN] = (c->green_size << 8) | c->green_shift;
    HDLCD[HDLCD_BLUE] = (c->blue_size << 8) | c->blue_shift;
    HDLCD[HDLCD_COMMAND] = 1;
    clear_fixmap(FIXMAP_MISC);

    lfbp.pixel_on = (((1 << c->red_size) - 1) << c->red_shift) |
        (((1 << c->green_size) - 1) << c->green_shift) |
        (((1 << c->blue_size) - 1) << c->blue_shift);
    lfbp.lfb = lfb;
    lfbp.font = &font_vga_8x16;
    lfbp.bits_per_pixel = bytes_per_pixel*8;
    lfbp.bytes_per_line = bytes_per_pixel*videomode->xres;
    lfbp.width = videomode->xres;
    lfbp.height = videomode->yres;
    lfbp.flush = hdlcd_flush;
    lfbp.text_columns = videomode->xres / 8;
    lfbp.text_rows = videomode->yres / 16;
    if ( lfb_init(&lfbp) < 0 )
            return;
    video_puts = lfb_scroll_puts;
}