All patches automatically rebased Build system: x86_64 Build-tested: bcm2711/RPi4B, mt7622/RT3200 Run-tested: bcm2711/RPi4B, mt7622/RT3200 Signed-off-by: John Audia <therealgraysky@proton.me>
		
			
				
	
	
		
			108 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 48342ae751c797ac73ac9c894b3f312df18ffd21 Mon Sep 17 00:00:00 2001
 | |
| From: Geert Uytterhoeven <geert+renesas@glider.be>
 | |
| Date: Wed, 15 Sep 2021 13:46:20 +0100
 | |
| Subject: [PATCH] ARM: 9124/1: uncompress: Parse "linux,usable-memory-range" DT
 | |
|  property
 | |
| 
 | |
| Add support for parsing the "linux,usable-memory-range" DT property.
 | |
| This property is used to describe the usable memory reserved for the
 | |
| crash dump kernel, and thus makes the memory reservation explicit.
 | |
| If present, Linux no longer needs to mask the program counter, and rely
 | |
| on the "mem=" kernel parameter to obtain the start and size of usable
 | |
| memory.
 | |
| 
 | |
| For backwards compatibility, the traditional method to derive the start
 | |
| of memory is still used if "linux,usable-memory-range" is absent.
 | |
| 
 | |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
 | |
| Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
 | |
| Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
 | |
| ---
 | |
|  .../arm/boot/compressed/fdt_check_mem_start.c | 48 ++++++++++++++++---
 | |
|  1 file changed, 42 insertions(+), 6 deletions(-)
 | |
| 
 | |
| --- a/arch/arm/boot/compressed/fdt_check_mem_start.c
 | |
| +++ b/arch/arm/boot/compressed/fdt_check_mem_start.c
 | |
| @@ -55,16 +55,17 @@ static uint64_t get_val(const fdt32_t *c
 | |
|   * DTB, and, if out-of-range, replace it by the real start address.
 | |
|   * To preserve backwards compatibility (systems reserving a block of memory
 | |
|   * at the start of physical memory, kdump, ...), the traditional method is
 | |
| - * always used if it yields a valid address.
 | |
| + * used if it yields a valid address, unless the "linux,usable-memory-range"
 | |
| + * property is present.
 | |
|   *
 | |
|   * Return value: start address of physical memory to use
 | |
|   */
 | |
|  uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
 | |
|  {
 | |
| -	uint32_t addr_cells, size_cells, base;
 | |
| +	uint32_t addr_cells, size_cells, usable_base, base;
 | |
|  	uint32_t fdt_mem_start = 0xffffffff;
 | |
| -	const fdt32_t *reg, *endp;
 | |
| -	uint64_t size, end;
 | |
| +	const fdt32_t *usable, *reg, *endp;
 | |
| +	uint64_t size, usable_end, end;
 | |
|  	const char *type;
 | |
|  	int offset, len;
 | |
|  
 | |
| @@ -80,6 +81,27 @@ uint32_t fdt_check_mem_start(uint32_t me
 | |
|  	if (addr_cells > 2 || size_cells > 2)
 | |
|  		return mem_start;
 | |
|  
 | |
| +	/*
 | |
| +	 * Usable memory in case of a crash dump kernel
 | |
| +	 * This property describes a limitation: memory within this range is
 | |
| +	 * only valid when also described through another mechanism
 | |
| +	 */
 | |
| +	usable = get_prop(fdt, "/chosen", "linux,usable-memory-range",
 | |
| +			  (addr_cells + size_cells) * sizeof(fdt32_t));
 | |
| +	if (usable) {
 | |
| +		size = get_val(usable + addr_cells, size_cells);
 | |
| +		if (!size)
 | |
| +			return mem_start;
 | |
| +
 | |
| +		if (addr_cells > 1 && fdt32_ld(usable)) {
 | |
| +			/* Outside 32-bit address space */
 | |
| +			return mem_start;
 | |
| +		}
 | |
| +
 | |
| +		usable_base = fdt32_ld(usable + addr_cells - 1);
 | |
| +		usable_end = usable_base + size;
 | |
| +	}
 | |
| +
 | |
|  	/* Walk all memory nodes and regions */
 | |
|  	for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0;
 | |
|  	     offset = fdt_next_node(fdt, offset, NULL)) {
 | |
| @@ -107,7 +129,20 @@ uint32_t fdt_check_mem_start(uint32_t me
 | |
|  
 | |
|  			base = fdt32_ld(reg + addr_cells - 1);
 | |
|  			end = base + size;
 | |
| -			if (mem_start >= base && mem_start < end) {
 | |
| +			if (usable) {
 | |
| +				/*
 | |
| +				 * Clip to usable range, which takes precedence
 | |
| +				 * over mem_start
 | |
| +				 */
 | |
| +				if (base < usable_base)
 | |
| +					base = usable_base;
 | |
| +
 | |
| +				if (end > usable_end)
 | |
| +					end = usable_end;
 | |
| +
 | |
| +				if (end <= base)
 | |
| +					continue;
 | |
| +			} else if (mem_start >= base && mem_start < end) {
 | |
|  				/* Calculated address is valid, use it */
 | |
|  				return mem_start;
 | |
|  			}
 | |
| @@ -123,7 +158,8 @@ uint32_t fdt_check_mem_start(uint32_t me
 | |
|  	}
 | |
|  
 | |
|  	/*
 | |
| -	 * The calculated address is not usable.
 | |
| +	 * The calculated address is not usable, or was overridden by the
 | |
| +	 * "linux,usable-memory-range" property.
 | |
|  	 * Use the lowest usable physical memory address from the DTB instead,
 | |
|  	 * and make sure this is a multiple of 2 MiB for phys/virt patching.
 | |
|  	 */
 |