Commit 54c832af authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Initrd Cleanup

From: Rusty Russell <rusty@rustcorp.com.au>

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.
parent 79293254
......@@ -31,7 +31,6 @@
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/initrd.h>
#include <linux/ioport.h>
#include <linux/console.h>
#include <linux/pci.h>
......@@ -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 long r4, unsigned long r5,
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 long r4, unsigned long r5,
* 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 long r4, unsigned long r5,
}
of_node_put(dn);
no_rtas:
printk(KERN_INFO "firmware_features = 0x%lx\n",
cur_cpu_spec->firmware_features);
}
......
......@@ -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
......
......@@ -32,6 +32,7 @@
#include <linux/proc_fs.h>
#include <linux/stringify.h>
#include <linux/delay.h>
#include <linux/initrd.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/lmb.h>
......@@ -137,6 +138,9 @@ phandle prom_display_nodes[FB_MAX] __initdata;
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 *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 *nodep)
}
}
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 long *mem_start, unsigned long *mem_end
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_reserve(unsigned long mem)
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_reserve(unsigned long mem)
*/
_prom->bi_recs = PTRUNRELOC(_prom->bi_recs);
}
return mem;
}
/*
......@@ -1794,11 +1822,43 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
/* 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 long r4, unsigned long pp,
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 long r4, unsigned long pp,
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 long r4, unsigned long pp,
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 long r4, unsigned long pp,
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;
}
......
......@@ -188,30 +188,32 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
#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 */
}
}
......
......@@ -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)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment