1 From 48342ae751c797ac73ac9c894b3f312df18ffd21 Mon Sep 17 00:00:00 2001
2 From: Geert Uytterhoeven <geert+renesas@glider.be>
3 Date: Wed, 15 Sep 2021 13:46:20 +0100
4 Subject: [PATCH] ARM: 9124/1: uncompress: Parse "linux,usable-memory-range" DT
7 Add support for parsing the "linux,usable-memory-range" DT property.
8 This property is used to describe the usable memory reserved for the
9 crash dump kernel, and thus makes the memory reservation explicit.
10 If present, Linux no longer needs to mask the program counter, and rely
11 on the "mem=" kernel parameter to obtain the start and size of usable
14 For backwards compatibility, the traditional method to derive the start
15 of memory is still used if "linux,usable-memory-range" is absent.
17 Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
18 Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
19 Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
21 .../arm/boot/compressed/fdt_check_mem_start.c | 48 ++++++++++++++++---
22 1 file changed, 42 insertions(+), 6 deletions(-)
24 diff --git a/arch/arm/boot/compressed/fdt_check_mem_start.c b/arch/arm/boot/compressed/fdt_check_mem_start.c
25 index 62450d824c3c..9291a2661bdf 100644
26 --- a/arch/arm/boot/compressed/fdt_check_mem_start.c
27 +++ b/arch/arm/boot/compressed/fdt_check_mem_start.c
28 @@ -55,16 +55,17 @@ static uint64_t get_val(const fdt32_t *cells, uint32_t ncells)
29 * DTB, and, if out-of-range, replace it by the real start address.
30 * To preserve backwards compatibility (systems reserving a block of memory
31 * at the start of physical memory, kdump, ...), the traditional method is
32 - * always used if it yields a valid address.
33 + * used if it yields a valid address, unless the "linux,usable-memory-range"
34 + * property is present.
36 * Return value: start address of physical memory to use
38 uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
40 - uint32_t addr_cells, size_cells, base;
41 + uint32_t addr_cells, size_cells, usable_base, base;
42 uint32_t fdt_mem_start = 0xffffffff;
43 - const fdt32_t *reg, *endp;
45 + const fdt32_t *usable, *reg, *endp;
46 + uint64_t size, usable_end, end;
50 @@ -80,6 +81,27 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
51 if (addr_cells > 2 || size_cells > 2)
55 + * Usable memory in case of a crash dump kernel
56 + * This property describes a limitation: memory within this range is
57 + * only valid when also described through another mechanism
59 + usable = get_prop(fdt, "/chosen", "linux,usable-memory-range",
60 + (addr_cells + size_cells) * sizeof(fdt32_t));
62 + size = get_val(usable + addr_cells, size_cells);
66 + if (addr_cells > 1 && fdt32_ld(usable)) {
67 + /* Outside 32-bit address space */
71 + usable_base = fdt32_ld(usable + addr_cells - 1);
72 + usable_end = usable_base + size;
75 /* Walk all memory nodes and regions */
76 for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0;
77 offset = fdt_next_node(fdt, offset, NULL)) {
78 @@ -107,7 +129,20 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
80 base = fdt32_ld(reg + addr_cells - 1);
82 - if (mem_start >= base && mem_start < end) {
85 + * Clip to usable range, which takes precedence
88 + if (base < usable_base)
91 + if (end > usable_end)
96 + } else if (mem_start >= base && mem_start < end) {
97 /* Calculated address is valid, use it */
100 @@ -123,7 +158,8 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
104 - * The calculated address is not usable.
105 + * The calculated address is not usable, or was overridden by the
106 + * "linux,usable-memory-range" property.
107 * Use the lowest usable physical memory address from the DTB instead,
108 * and make sure this is a multiple of 2 MiB for phys/virt patching.