From 23d1742179170b69e61ac9166248ffd64857e55a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 14 Jul 2008 09:59:21 +0200 Subject: [S390] Move memory detection code to own file. Move memory detection code to own file and also simplify it. Also add an interface which can be called at any time to get the current memory layout. This interface is needed by our kernel internal system dumper. Cc: Peter Oberparleiter Cc: Michael Holzheu Cc: Frank Munzert Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/early.c | 109 +---------------------------------------------- 1 file changed, 1 insertion(+), 108 deletions(-) (limited to 'arch/s390/kernel/early.c') diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index e22473993dc..4c0ec7b46e3 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -192,100 +192,6 @@ static noinline __init void detect_machine_type(void) machine_flags |= MACHINE_FLAG_KVM; } -#ifdef CONFIG_64BIT -static noinline __init int memory_fast_detect(void) -{ - unsigned long val0 = 0; - unsigned long val1 = 0xc; - int ret = -ENOSYS; - - if (ipl_flags & IPL_NSS_VALID) - return -ENOSYS; - - asm volatile( - " diag %1,%2,0x260\n" - "0: lhi %0,0\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (ret), "+d" (val0), "+d" (val1) : : "cc"); - - if (ret || val0 != val1) - return -ENOSYS; - - memory_chunk[0].size = val0 + 1; - return 0; -} -#else -static inline int memory_fast_detect(void) -{ - return -ENOSYS; -} -#endif - -static inline __init unsigned long __tprot(unsigned long addr) -{ - int cc = -1; - - asm volatile( - " tprot 0(%1),0\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "+d" (cc) : "a" (addr) : "cc"); - return (unsigned long)cc; -} - -/* Checking memory in 128KB increments. */ -#define CHUNK_INCR (1UL << 17) -#define ADDR2G (1UL << 31) - -static noinline __init void find_memory_chunks(unsigned long memsize) -{ - unsigned long addr = 0, old_addr = 0; - unsigned long old_cc = CHUNK_READ_WRITE; - unsigned long cc; - int chunk = 0; - - while (chunk < MEMORY_CHUNKS) { - cc = __tprot(addr); - while (cc == old_cc) { - addr += CHUNK_INCR; - if (memsize && addr >= memsize) - break; -#ifndef CONFIG_64BIT - if (addr == ADDR2G) - break; -#endif - cc = __tprot(addr); - } - - if (old_addr != addr && - (old_cc == CHUNK_READ_WRITE || old_cc == CHUNK_READ_ONLY)) { - memory_chunk[chunk].addr = old_addr; - memory_chunk[chunk].size = addr - old_addr; - memory_chunk[chunk].type = old_cc; - chunk++; - } - - old_addr = addr; - old_cc = cc; - -#ifndef CONFIG_64BIT - if (addr == ADDR2G) - break; -#endif - /* - * Finish memory detection at the first hole - * if storage size is unknown. - */ - if (cc == -1UL && !memsize) - break; - if (memsize && addr >= memsize) - break; - } -} - static __init void early_pgm_check_handler(void) { unsigned long addr; @@ -465,8 +371,6 @@ static void __init setup_boot_command_line(void) */ void __init startup_init(void) { - unsigned long long memsize; - ipl_save_parameters(); rescue_initrd(); clear_bss_section(); @@ -486,18 +390,7 @@ void __init startup_init(void) detect_diag44(); detect_machine_facilities(); setup_hpage(); - sclp_read_info_early(); sclp_facilities_detect(); - memsize = sclp_memory_detect(); -#ifndef CONFIG_64BIT - /* - * Can't deal with more than 2G in 31 bit addressing mode, so - * limit the value in order to avoid strange side effects. - */ - if (memsize > ADDR2G) - memsize = ADDR2G; -#endif - if (memory_fast_detect() < 0) - find_memory_chunks((unsigned long) memsize); + detect_memory_layout(memory_chunk); lockdep_on(); } -- cgit v1.2.3