Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
23d17421 | 2 | /* |
155af2f9 HJP |
3 | * Copyright IBM Corp. 2008, 2009 |
4 | * | |
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | |
23d17421 HC |
6 | */ |
7 | ||
8 | #include <linux/kernel.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 | ||
50be6345 PH |
17 | #define CHUNK_READ_WRITE 0 |
18 | #define CHUNK_READ_ONLY 1 | |
19 | ||
20 | static inline void memblock_physmem_add(phys_addr_t start, phys_addr_t size) | |
21 | { | |
a2ce2a95 HC |
22 | memblock_dbg("memblock_physmem_add: [%#016llx-%#016llx]\n", |
23 | start, start + size - 1); | |
50be6345 PH |
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 | 29 | { |
423d5b36 | 30 | unsigned long memsize, rnmax, rzm, addr, size; |
50be6345 | 31 | int type; |
23d17421 | 32 | |
37c5f6c8 DH |
33 | rzm = sclp.rzm; |
34 | rnmax = sclp.rnmax; | |
23d17421 HC |
35 | memsize = rzm * rnmax; |
36 | if (!rzm) | |
423d5b36 | 37 | rzm = 1UL << 17; |
50be6345 PH |
38 | max_physmem_end = memsize; |
39 | addr = 0; | |
40 | /* keep memblock lists close to the kernel */ | |
41 | memblock_set_bottom_up(true); | |
23d17421 HC |
42 | do { |
43 | size = 0; | |
00de54c8 HC |
44 | /* assume lowcore is writable */ |
45 | type = addr ? tprot(addr) : CHUNK_READ_WRITE; | |
23d17421 HC |
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(); | |
a2ce2a95 | 61 | memblock_dump_all(); |
60a0c68d | 62 | } |