From: Rusty Russell Clean up initrd handling. 1) Expose initrd_start and initrd_end to prom.c (replacing its local initrd_start and initrd_len). 2) Don't hand mem (aka klimit) through functions which don't need it. 3) Add more debugging under DEBUG_PROM in case we broke anything. --- 25-akpm/arch/ppc64/kernel/chrp_setup.c | 33 ++------ 25-akpm/arch/ppc64/kernel/process.c | 3 25-akpm/arch/ppc64/kernel/prom.c | 135 +++++++++++++++++++++++++++------ 25-akpm/arch/ppc64/kernel/setup.c | 43 ++-------- 25-akpm/arch/ppc64/mm/init.c | 8 - 5 files changed, 133 insertions(+), 89 deletions(-) diff -puN arch/ppc64/kernel/chrp_setup.c~ppc64-initrd-cleanup arch/ppc64/kernel/chrp_setup.c --- 25/arch/ppc64/kernel/chrp_setup.c~ppc64-initrd-cleanup Fri Apr 23 13:30:27 2004 +++ 25-akpm/arch/ppc64/kernel/chrp_setup.c Fri Apr 23 13:30:27 2004 @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -136,15 +135,10 @@ chrp_setup_arch(void) /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; -#ifdef CONFIG_BLK_DEV_INITRD - /* this is fine for chrp */ - initrd_below_start_ok = 1; - - if (initrd_start) - ROOT_DEV = Root_RAM0; - else -#endif - ROOT_DEV = Root_SDA2; + if (ROOT_DEV == 0) { + printk("No ramdisk, default root is /dev/sda2\n"); + ROOT_DEV = Root_SDA2; + } printk("Boot arguments: %s\n", cmd_line); @@ -239,17 +233,6 @@ chrp_init(unsigned long r3, unsigned lon char * hypertas; unsigned int len; -#if 0 /* PPPBBB remove this later... -Peter */ -#ifdef CONFIG_BLK_DEV_INITRD - /* take care of initrd if we have one */ - if ( r6 ) - { - initrd_start = __va(r6); - initrd_end = __va(r6 + r7); - } -#endif /* CONFIG_BLK_DEV_INITRD */ -#endif - ppc_md.setup_arch = chrp_setup_arch; ppc_md.get_cpuinfo = chrp_get_cpuinfo; if (naca->interrupt_controller == IC_OPEN_PIC) { @@ -280,8 +263,13 @@ chrp_init(unsigned long r3, unsigned lon * using contents of device-tree/ibm,hypertas-functions. * Ultimately this functionality may be moved into prom.c prom_init(). */ - dn = of_find_node_by_path("/rtas"); cur_cpu_spec->firmware_features = 0; + dn = of_find_node_by_path("/rtas"); + if (dn == NULL) { + printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n"); + goto no_rtas; + } + hypertas = get_property(dn, "ibm,hypertas-functions", &len); if (hypertas) { while (len > 0){ @@ -303,6 +291,7 @@ chrp_init(unsigned long r3, unsigned lon } of_node_put(dn); + no_rtas: printk(KERN_INFO "firmware_features = 0x%lx\n", cur_cpu_spec->firmware_features); } diff -puN arch/ppc64/kernel/process.c~ppc64-initrd-cleanup arch/ppc64/kernel/process.c --- 25/arch/ppc64/kernel/process.c~ppc64-initrd-cleanup Fri Apr 23 13:30:27 2004 +++ 25-akpm/arch/ppc64/kernel/process.c Fri Apr 23 13:30:27 2004 @@ -65,9 +65,6 @@ struct mm_struct ioremap_mm = { .page_table_lock = SPIN_LOCK_UNLOCKED, }; -char *sysmap = NULL; -unsigned long sysmap_size = 0; - void enable_kernel_fp(void) { #ifdef CONFIG_SMP diff -puN arch/ppc64/kernel/prom.c~ppc64-initrd-cleanup arch/ppc64/kernel/prom.c --- 25/arch/ppc64/kernel/prom.c~ppc64-initrd-cleanup Fri Apr 23 13:30:27 2004 +++ 25-akpm/arch/ppc64/kernel/prom.c Fri Apr 23 13:30:27 2004 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -137,6 +138,9 @@ phandle prom_display_nodes[FB_MAX] __ini unsigned int prom_num_displays = 0; char *of_stdout_device = 0; +static int iommu_force_on; +int ppc64_iommu_off; + extern struct rtas_t rtas; extern unsigned long klimit; extern struct lmb lmb; @@ -162,8 +166,6 @@ extern void enter_prom(struct prom_args extern void copy_and_flush(unsigned long dest, unsigned long src, unsigned long size, unsigned long offset); -static unsigned long __initdata initrd_start /* = 0 */, initrd_len; - unsigned long dev_tree_size; unsigned long _get_PIR(void); @@ -288,8 +290,8 @@ static int __init prom_next_node(phandle } } -static unsigned long -prom_initialize_naca(unsigned long mem) + +static void __init prom_initialize_naca(void) { phandle node; char type[64]; @@ -504,12 +506,8 @@ prom_initialize_naca(unsigned long mem) prom_print(RELOC("prom_initialize_naca: end...\n")); #endif - - return mem; } -static int iommu_force_on; -int ppc64_iommu_off; static void __init early_cmdline_parse(void) { @@ -592,8 +590,7 @@ void prom_dump_lmb(void) } #endif /* DEBUG_PROM */ -static unsigned long __init -prom_initialize_lmb(unsigned long mem) +static void __init prom_initialize_lmb(void) { phandle node; char type[64]; @@ -655,8 +652,6 @@ prom_initialize_lmb(unsigned long mem) #ifdef DEBUG_PROM prom_dump_lmb(); #endif /* DEBUG_PROM */ - - return mem; } static char hypertas_funcs[1024]; @@ -1555,7 +1550,7 @@ static void __init *__make_room(unsigned if (*mem_start + needed > *mem_end) { if (*mem_end != RELOC(initrd_start)) prom_panic(RELOC("No memory for copy_device_tree")); - *mem_start = RELOC(initrd_start) + RELOC(initrd_len); + *mem_start = RELOC(initrd_end); /* We can't pass huge values to OF, so use 1G. */ *mem_end = *mem_start + 1024*1024*1024; } @@ -1714,22 +1709,52 @@ copy_device_tree(unsigned long mem_start static struct bi_record * __init prom_bi_rec_verify(struct bi_record *bi_recs) { struct bi_record *first, *last; +#ifdef DEBUG_PROM + unsigned long offset = reloc_offset(); + + prom_print(RELOC("birec_verify: r6=0x")); + prom_print_hex((unsigned long)bi_recs); + prom_print_nl(); + if (bi_recs != NULL) { + prom_print(RELOC(" tag=0x")); + prom_print_hex(bi_recs->tag); + prom_print_nl(); + } +#endif /* DEBUG_PROM */ if ( bi_recs == NULL || bi_recs->tag != BI_FIRST ) return NULL; last = (struct bi_record *)(long)bi_recs->data[0]; + +#ifdef DEBUG_PROM + prom_print(RELOC(" last=0x")); + prom_print_hex((unsigned long)last); + prom_print_nl(); + if (last != NULL) { + prom_print(RELOC(" last_tag=0x")); + prom_print_hex(last->tag); + prom_print_nl(); + } +#endif /* DEBUG_PROM */ + if ( last == NULL || last->tag != BI_LAST ) return NULL; first = (struct bi_record *)(long)last->data[0]; +#ifdef DEBUG_PROM + prom_print(RELOC(" first=0x")); + prom_print_hex((unsigned long)first); + prom_print_nl(); +#endif /* DEBUG_PROM */ + if ( first == NULL || first != bi_recs ) return NULL; return bi_recs; } -static unsigned long __init prom_bi_rec_reserve(unsigned long mem) +static void __init prom_bi_rec_reserve(void) { unsigned long offset = reloc_offset(); struct prom_t *_prom = PTRRELOC(&prom); @@ -1740,11 +1765,16 @@ static unsigned long __init prom_bi_rec_ for ( rec=_prom->bi_recs; rec->tag != BI_LAST; rec=bi_rec_next(rec) ) { +#ifdef DEBUG_PROM + prom_print(RELOC("bi: 0x")); + prom_print_hex(rec->tag); + prom_print_nl(); +#endif /* DEBUG_PROM */ switch (rec->tag) { #ifdef CONFIG_BLK_DEV_INITRD case BI_INITRD: - RELOC(initrd_start) = rec->data[0]; - RELOC(initrd_len) = rec->data[1]; + RELOC(initrd_start) = (unsigned long)(rec->data[0]); + RELOC(initrd_end) = RELOC(initrd_start) + rec->data[1]; break; #endif /* CONFIG_BLK_DEV_INITRD */ } @@ -1755,8 +1785,6 @@ static unsigned long __init prom_bi_rec_ */ _prom->bi_recs = PTRUNRELOC(_prom->bi_recs); } - - return mem; } /* @@ -1794,11 +1822,43 @@ prom_init(unsigned long r3, unsigned lon /* Init prom stdout device */ prom_init_stdout(); +#ifdef DEBUG_PROM + prom_print(RELOC("klimit=0x")); + prom_print_hex(RELOC(klimit)); + prom_print_nl(); + prom_print(RELOC("offset=0x")); + prom_print_hex(offset); + prom_print_nl(); + prom_print(RELOC("->mem=0x")); + prom_print_hex(RELOC(klimit) - offset); + prom_print_nl(); +#endif /* DEBUG_PROM */ + /* check out if we have bi_recs */ _prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6); - if ( _prom->bi_recs != NULL ) + if ( _prom->bi_recs != NULL ) { RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs + _prom->bi_recs->data[1]); +#ifdef DEBUG_PROM + prom_print(RELOC("bi_recs=0x")); + prom_print_hex((unsigned long)_prom->bi_recs); + prom_print_nl(); + prom_print(RELOC("new mem=0x")); + prom_print_hex(RELOC(klimit) - offset); + prom_print_nl(); +#endif /* DEBUG_PROM */ + } + + /* If we don't have birec's or didn't find them, check for an initrd + * using the "yaboot" way + */ +#ifdef CONFIG_BLK_DEV_INITRD + if ( _prom->bi_recs == NULL && r3 && r4 && r4 != 0xdeadbeef) { + RELOC(initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; + RELOC(initrd_end) = RELOC(initrd_start) + r4; + RELOC(initrd_below_start_ok) = 1; + } +#endif /* CONFIG_BLK_DEV_INITRD */ /* Default machine type. */ _systemcfg->platform = prom_find_machine_type(); @@ -1870,9 +1930,9 @@ prom_init(unsigned long r3, unsigned lon early_cmdline_parse(); - mem = prom_initialize_lmb(mem); + prom_initialize_lmb(); - mem = prom_bi_rec_reserve(mem); + prom_bi_rec_reserve(); mem = check_display(mem); @@ -1880,7 +1940,7 @@ prom_init(unsigned long r3, unsigned lon prom_instantiate_rtas(); /* Initialize some system info into the Naca early... */ - mem = prom_initialize_naca(mem); + prom_initialize_naca(); smt_setup(); @@ -1891,17 +1951,36 @@ prom_init(unsigned long r3, unsigned lon prom_hold_cpus(mem); #ifdef DEBUG_PROM + prom_print(RELOC("after basic inits, mem=0x")); + prom_print_hex(mem); + prom_print_nl(); + prom_print(RELOC("initrd_start=0x")); + prom_print_hex(RELOC(initrd_start)); + prom_print_nl(); + prom_print(RELOC("initrd_end=0x")); + prom_print_hex(RELOC(initrd_end)); + prom_print_nl(); prom_print(RELOC("copying OF device tree...\n")); -#endif +#endif /* DEBUG_PROM */ mem = copy_device_tree(mem); RELOC(klimit) = mem + offset; +#ifdef DEBUG_PROM + prom_print(RELOC("new klimit is\n")); + prom_print(RELOC("klimit=0x")); + prom_print_hex(RELOC(klimit)); + prom_print(RELOC(" ->mem=0x\n")); + prom_print(RELOC("klimit=0x")); + prom_print_hex(mem); + prom_print_nl(); +#endif /* DEBUG_PROM */ + lmb_reserve(0, __pa(RELOC(klimit))); #ifdef CONFIG_BLK_DEV_INITRD /* If this didn't cover the initrd, do so now */ if (mem < RELOC(initrd_start)) - lmb_reserve(RELOC(initrd_start), RELOC(initrd_len)); + lmb_reserve(RELOC(initrd_start), RELOC(initrd_end) - RELOC(initrd_start)); #endif /* CONFIG_BLK_DEV_INITRD */ if (_systemcfg->platform == PLATFORM_PSERIES) @@ -1923,6 +2002,14 @@ prom_init(unsigned long r3, unsigned lon call_prom(RELOC("quiesce"), 0, 0); phys = KERNELBASE - offset; +#ifdef CONFIG_BLK_DEV_INITRD + /* If we had an initrd, we convert its address to virtual */ + if (RELOC(initrd_start)) { + RELOC(initrd_start) = (unsigned long)__va(RELOC(initrd_start)); + RELOC(initrd_end) = (unsigned long)__va(RELOC(initrd_end)); + } +#endif /* CONFIG_BLK_DEV_INITRD */ + prom_print(RELOC("returning from prom_init\n")); return phys; } diff -puN arch/ppc64/kernel/setup.c~ppc64-initrd-cleanup arch/ppc64/kernel/setup.c --- 25/arch/ppc64/kernel/setup.c~ppc64-initrd-cleanup Fri Apr 23 13:30:27 2004 +++ 25-akpm/arch/ppc64/kernel/setup.c Fri Apr 23 13:30:27 2004 @@ -188,30 +188,32 @@ void setup_system(unsigned long r3, unsi #ifdef CONFIG_PPC_PSERIES case PLATFORM_PSERIES: pSeries_init_early(); -#ifdef CONFIG_BLK_DEV_INITRD - initrd_start = initrd_end = 0; -#endif parse_bootinfo(); break; case PLATFORM_PSERIES_LPAR: pSeriesLP_init_early(); -#ifdef CONFIG_BLK_DEV_INITRD - initrd_start = initrd_end = 0; -#endif parse_bootinfo(); break; #endif /* CONFIG_PPC_PSERIES */ #ifdef CONFIG_PPC_PMAC case PLATFORM_POWERMAC: pmac_init_early(); -#ifdef CONFIG_BLK_DEV_INITRD - initrd_start = initrd_end = 0; -#endif parse_bootinfo(); #endif /* CONFIG_PPC_PMAC */ } + /* If we were passed an initrd, set the ROOT_DEV properly if the values + * look sensible. If not, clear initrd reference. + */ +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && + initrd_end > initrd_start) + ROOT_DEV = Root_RAM0; + else + initrd_start = initrd_end = 0; +#endif /* CONFIG_BLK_DEV_INITRD */ + #ifdef CONFIG_BOOTX_TEXT map_boot_text(); if (systemcfg->platform == PLATFORM_POWERMAC) { @@ -425,15 +427,6 @@ struct seq_operations cpuinfo_op = { void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { -#ifdef CONFIG_BLK_DEV_INITRD - if ((initrd_start == 0) && r3 && r4 && r4 != 0xdeadbeef) { - initrd_start = (r3 >= KERNELBASE) ? r3 : (unsigned long)__va(r3); - initrd_end = initrd_start + r4; - ROOT_DEV = Root_RAM0; - initrd_below_start_ok = 1; - } -#endif - cmd_line[0] = 0; #ifdef CONFIG_CMDLINE @@ -533,8 +526,6 @@ console_initcall(set_preferred_console); int parse_bootinfo(void) { struct bi_record *rec; - extern char *sysmap; - extern unsigned long sysmap_size; rec = prom.bi_recs; @@ -546,18 +537,6 @@ int parse_bootinfo(void) case BI_CMD_LINE: strlcpy(cmd_line, (void *)rec->data, sizeof(cmd_line)); break; - case BI_SYSMAP: - sysmap = __va(rec->data[0]); - sysmap_size = rec->data[1]; - break; -#ifdef CONFIG_BLK_DEV_INITRD - case BI_INITRD: - initrd_start = (unsigned long)__va(rec->data[0]); - initrd_end = initrd_start + rec->data[1]; - ROOT_DEV = Root_RAM0; - initrd_below_start_ok = 1; - break; -#endif /* CONFIG_BLK_DEV_INITRD */ } } diff -puN arch/ppc64/mm/init.c~ppc64-initrd-cleanup arch/ppc64/mm/init.c --- 25/arch/ppc64/mm/init.c~ppc64-initrd-cleanup Fri Apr 23 13:30:27 2004 +++ 25-akpm/arch/ppc64/mm/init.c Fri Apr 23 13:30:27 2004 @@ -621,8 +621,6 @@ module_init(setup_kcore); void __init mem_init(void) { #ifndef CONFIG_DISCONTIGMEM - extern char *sysmap; - extern unsigned long sysmap_size; unsigned long addr; #endif int codepages = 0; @@ -656,12 +654,6 @@ void __init mem_init(void) totalram_pages += free_all_bootmem(); - if ( sysmap_size ) - for (addr = (unsigned long)sysmap; - addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ; - addr += PAGE_SIZE) - SetPageReserved(virt_to_page(addr)); - for (addr = KERNELBASE; addr <= (unsigned long)__va(lmb_end_of_DRAM()); addr += PAGE_SIZE) { if (!PageReserved(virt_to_page(addr))) _