Commit | Line | Data |
---|---|---|
23d17421 | 1 | /* |
155af2f9 HJP |
2 | * Copyright IBM Corp. 2008, 2009 |
3 | * | |
4 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | |
23d17421 HC |
5 | */ |
6 | ||
7 | #include <linux/kernel.h> | |
8 | #include <linux/module.h> | |
50be6345 PH |
9 | #include <linux/memblock.h> |
10 | #include <linux/init.h> | |
11 | #include <linux/debugfs.h> | |
12 | #include <linux/seq_file.h> | |
23d17421 HC |
13 | #include <asm/ipl.h> |
14 | #include <asm/sclp.h> | |
15 | #include <asm/setup.h> | |
16 | ||
23d17421 HC |
17 | #define ADDR2G (1ULL << 31) |
18 | ||
50be6345 PH |
19 | #define CHUNK_READ_WRITE 0 |
20 | #define CHUNK_READ_ONLY 1 | |
21 | ||
22 | static inline void memblock_physmem_add(phys_addr_t start, phys_addr_t size) | |
23 | { | |
24 | memblock_add_range(&memblock.memory, start, size, 0, 0); | |
25 | memblock_add_range(&memblock.physmem, start, size, 0, 0); | |
26 | } | |
27 | ||
28 | void __init detect_memory_memblock(void) | |
23d17421 HC |
29 | { |
30 | unsigned long long memsize, rnmax, rzm; | |
50be6345 PH |
31 | unsigned long addr, size; |
32 | int type; | |
23d17421 | 33 | |
37c5f6c8 DH |
34 | rzm = sclp.rzm; |
35 | rnmax = sclp.rnmax; | |
23d17421 HC |
36 | memsize = rzm * rnmax; |
37 | if (!rzm) | |
38 | rzm = 1ULL << 17; | |
50be6345 PH |
39 | max_physmem_end = memsize; |
40 | addr = 0; | |
41 | /* keep memblock lists close to the kernel */ | |
42 | memblock_set_bottom_up(true); | |
23d17421 HC |
43 | do { |
44 | size = 0; | |
45 | type = tprot(addr); | |
46 | do { | |
47 | size += rzm; | |
50be6345 | 48 | if (max_physmem_end && addr + size >= max_physmem_end) |
23d17421 HC |
49 | break; |
50 | } while (type == tprot(addr + size)); | |
51 | if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) { | |
50be6345 PH |
52 | if (max_physmem_end && (addr + size > max_physmem_end)) |
53 | size = max_physmem_end - addr; | |
54 | memblock_physmem_add(addr, size); | |
23d17421 HC |
55 | } |
56 | addr += size; | |
50be6345 PH |
57 | } while (addr < max_physmem_end); |
58 | memblock_set_bottom_up(false); | |
59 | if (!max_physmem_end) | |
60 | max_physmem_end = memblock_end_of_DRAM(); | |
60a0c68d | 61 | } |