From 6ac26c8a7eb149dbd669cc6cd9b77ffc9cd0d2fb Mon Sep 17 00:00:00 2001 From: Manish Ahuja Date: Sat, 22 Mar 2008 10:37:08 +1100 Subject: [POWERPC] pseries: phyp dump: Reserve and release memory Initial patch for reserving memory in early boot, and freeing it later. If the previous boot had ended with a crash, the reserved memory would contain a copy of the crashed kernel data. Signed-off-by: Manish Ahuja Signed-off-by: Linas Vepstas Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index ff600ef0b4d6..e6c022ef12ee 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #ifdef DEBUG @@ -1040,6 +1041,51 @@ static void __init early_reserve_mem(void) #endif } +#ifdef CONFIG_PHYP_DUMP +/** + * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory + * + * This routine may reserve memory regions in the kernel only + * if the system is supported and a dump was taken in last + * boot instance or if the hardware is supported and the + * scratch area needs to be setup. In other instances it returns + * without reserving anything. The memory in case of dump being + * active is freed when the dump is collected (by userland tools). + */ +static void __init phyp_dump_reserve_mem(void) +{ + unsigned long base, size; + if (!phyp_dump_info->phyp_dump_configured) { + printk(KERN_ERR "Phyp-dump not supported on this hardware\n"); + return; + } + + if (phyp_dump_info->phyp_dump_is_active) { + /* Reserve *everything* above RMR.Area freed by userland tools*/ + base = PHYP_DUMP_RMR_END; + size = lmb_end_of_DRAM() - base; + + /* XXX crashed_ram_end is wrong, since it may be beyond + * the memory_limit, it will need to be adjusted. */ + lmb_reserve(base, size); + + phyp_dump_info->init_reserve_start = base; + phyp_dump_info->init_reserve_size = size; + } else { + size = phyp_dump_info->cpu_state_size + + phyp_dump_info->hpte_region_size + + PHYP_DUMP_RMR_END; + base = lmb_end_of_DRAM() - size; + lmb_reserve(base, size); + phyp_dump_info->init_reserve_start = base; + phyp_dump_info->init_reserve_size = size; + } +} +#else +static inline void __init phyp_dump_reserve_mem(void) {} +#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */ + + void __init early_init_devtree(void *params) { DBG(" -> early_init_devtree(%p)\n", params); @@ -1052,6 +1098,11 @@ void __init early_init_devtree(void *params) of_scan_flat_dt(early_init_dt_scan_rtas, NULL); #endif +#ifdef CONFIG_PHYP_DUMP + /* scan tree to see if dump occured during last boot */ + of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); +#endif + /* Retrieve various informations from the /chosen node of the * device-tree, including the platform type, initrd location and * size, TCE reserve, and more ... @@ -1072,6 +1123,7 @@ void __init early_init_devtree(void *params) reserve_kdump_trampoline(); reserve_crashkernel(); early_reserve_mem(); + phyp_dump_reserve_mem(); lmb_enforce_memory_limit(memory_limit); lmb_analyze(); -- cgit v1.2.3