]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - arch/powerpc/platforms/powermac/bootx_init.c
[POWERPC] Fix BootX booting with an initrd
[linux-2.6.git] / arch / powerpc / platforms / powermac / bootx_init.c
index eacbfd9beabcd8c47f27ee81158f44bbc3519d85..9d73d0234c5d3228cf0bd87a59d91ef83441aaef 100644 (file)
@@ -9,11 +9,10 @@
  *  2 of the License, or (at your option) any later version.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/version.h>
+#include <linux/utsrelease.h>
 #include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/page.h>
@@ -163,6 +162,8 @@ static void __init bootx_add_chosen_props(unsigned long base,
 {
        u32 val;
 
+       bootx_dt_add_prop("linux,bootx", NULL, 0, mem_end);
+
        if (bootx_info->kernelParamsOffset) {
                char *args = (char *)((unsigned long)bootx_info) +
                        bootx_info->kernelParamsOffset;
@@ -180,10 +181,32 @@ static void __init bootx_add_chosen_props(unsigned long base,
 }
 
 static void __init bootx_add_display_props(unsigned long base,
-                                          unsigned long *mem_end)
+                                          unsigned long *mem_end,
+                                          int has_real_node)
 {
-       bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end);
-       bootx_dt_add_prop("linux,opened", NULL, 0, mem_end);
+       boot_infos_t *bi = bootx_info;
+       u32 tmp;
+
+       if (has_real_node) {
+               bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end);
+               bootx_dt_add_prop("linux,opened", NULL, 0, mem_end);
+       } else
+               bootx_dt_add_prop("linux,bootx-noscreen", NULL, 0, mem_end);
+
+       tmp = bi->dispDeviceDepth;
+       bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end);
+       tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0];
+       bootx_dt_add_prop("linux,bootx-width", &tmp, 4, mem_end);
+       tmp = bi->dispDeviceRect[3] - bi->dispDeviceRect[1];
+       bootx_dt_add_prop("linux,bootx-height", &tmp, 4, mem_end);
+       tmp = bi->dispDeviceRowBytes;
+       bootx_dt_add_prop("linux,bootx-linebytes", &tmp, 4, mem_end);
+       tmp = (u32)bi->dispDeviceBase;
+       if (tmp == 0)
+               tmp = (u32)bi->logicalDisplayBase;
+       tmp += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes;
+       tmp += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8);
+       bootx_dt_add_prop("linux,bootx-addr", &tmp, 4, mem_end);
 }
 
 static void __init bootx_dt_add_string(char *s, unsigned long *mem_end)
@@ -212,7 +235,7 @@ static void __init bootx_scan_dt_build_strings(unsigned long base,
 
        if (!strcmp(namep, "/chosen")) {
                DBG(" detected /chosen ! adding properties names !\n");
-               bootx_dt_add_string("linux,platform", mem_end);
+               bootx_dt_add_string("linux,bootx", mem_end);
                bootx_dt_add_string("linux,stdout-path", mem_end);
                bootx_dt_add_string("linux,initrd-start", mem_end);
                bootx_dt_add_string("linux,initrd-end", mem_end);
@@ -306,10 +329,13 @@ static void __init bootx_scan_dt_build_struct(unsigned long base,
                ppp = &pp->next;
        }
 
-       if (node == bootx_node_chosen)
+       if (node == bootx_node_chosen) {
                bootx_add_chosen_props(base, mem_end);
-       if (node == bootx_info->dispDeviceRegEntryOffset)
-               bootx_add_display_props(base, mem_end);
+               if (bootx_info->dispDeviceRegEntryOffset == 0)
+                       bootx_add_display_props(base, mem_end, 0);
+       }
+       else if (node == bootx_info->dispDeviceRegEntryOffset)
+               bootx_add_display_props(base, mem_end, 1);
 
        /* do all our children */
        cpp = &np->child;
@@ -351,6 +377,14 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
        mem_end += 4;
        bootx_dt_strend = mem_end;
        bootx_scan_dt_build_strings(base, 4, &mem_end);
+       /* Add some strings */
+       bootx_dt_add_string("linux,bootx-noscreen", &mem_end);
+       bootx_dt_add_string("linux,bootx-depth", &mem_end);
+       bootx_dt_add_string("linux,bootx-width", &mem_end);
+       bootx_dt_add_string("linux,bootx-height", &mem_end);
+       bootx_dt_add_string("linux,bootx-linebytes", &mem_end);
+       bootx_dt_add_string("linux,bootx-addr", &mem_end);
+       /* Wrap up strings */
        hdr->off_dt_strings = bootx_dt_strbase - mem_start;
        hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase;
 
@@ -377,8 +411,15 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
        DBG("End of boot params: %x\n", mem_end);
        rsvmap[0] = mem_start;
        rsvmap[1] = mem_end;
-       rsvmap[2] = 0;
-       rsvmap[3] = 0;
+       if (bootx_info->ramDisk) {
+               rsvmap[2] = ((unsigned long)bootx_info) + bootx_info->ramDisk;
+               rsvmap[3] = rsvmap[2] + bootx_info->ramDiskSize;
+               rsvmap[4] = 0;
+               rsvmap[5] = 0;
+       } else {
+               rsvmap[2] = 0;
+               rsvmap[3] = 0;
+       }
 
        return (unsigned long)hdr;
 }
@@ -444,7 +485,15 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
        if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
                bi->logicalDisplayBase = bi->dispDeviceBase;
 
+       /* Fixup depth 16 -> 15 as that's what MacOS calls 16bpp */
+       if (bi->dispDeviceDepth == 16)
+               bi->dispDeviceDepth = 15;
+
+
 #ifdef CONFIG_BOOTX_TEXT
+       ptr = (unsigned long)bi->logicalDisplayBase;
+       ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes;
+       ptr += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8);
        btext_setup_display(bi->dispDeviceRect[2] - bi->dispDeviceRect[0],
                            bi->dispDeviceRect[3] - bi->dispDeviceRect[1],
                            bi->dispDeviceDepth, bi->dispDeviceRowBytes,
@@ -478,6 +527,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
 #ifdef CONFIG_BOOTX_TEXT
        btext_welcome(bi);
 #endif
+
        /* New BootX enters kernel with MMU off, i/os are not allowed
         * here. This hack will have been done by the boostrap anyway.
         */
@@ -500,12 +550,12 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
         */
        if (bi->version < 5) {
                space = bi->deviceTreeOffset + bi->deviceTreeSize;
-               if (bi->ramDisk)
+               if (bi->ramDisk >= space)
                        space = bi->ramDisk + bi->ramDiskSize;
        } else
                space = bi->totalParamsSize;
 
-       bootx_printf("Total space used by parameters & ramdisk: %x \n", space);
+       bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space);
 
        /* New BootX will have flushed all TLBs and enters kernel with
         * MMU switched OFF, so this should not be useful anymore.