Unverified Commit 658e2c51 authored by Alexandre Ghiti's avatar Alexandre Ghiti Committed by Palmer Dabbelt
Browse files

riscv: Introduce structure that group all variables regarding kernel mapping



We have a lot of variables that are used to hold kernel mapping addresses,
offsets between physical and virtual mappings and some others used for XIP
kernels: they are all defined at different places in mm/init.c, so group
them into a single structure with, for some of them, more explicit and concise
names.

Signed-off-by: default avatarAlexandre Ghiti <alex@ghiti.fr>
Signed-off-by: default avatarPalmer Dabbelt <palmerdabbelt@google.com>
parent 01112e5e
Loading
Loading
Loading
Loading
+30 −24
Original line number Diff line number Diff line
@@ -79,46 +79,52 @@ typedef struct page *pgtable_t;
#endif

#ifdef CONFIG_MMU
extern unsigned long va_pa_offset;
#ifdef CONFIG_64BIT
extern unsigned long va_kernel_pa_offset;
#endif
extern unsigned long va_kernel_xip_pa_offset;
extern unsigned long pfn_base;
extern uintptr_t load_sz;
#define ARCH_PFN_OFFSET		(pfn_base)
#else
#define va_pa_offset		0
#ifdef CONFIG_64BIT
#define va_kernel_pa_offset	0
#endif
#define va_kernel_xip_pa_offset 0
#define ARCH_PFN_OFFSET		(PAGE_OFFSET >> PAGE_SHIFT)
#endif /* CONFIG_MMU */

extern unsigned long kernel_virt_addr;
struct kernel_mapping {
	unsigned long virt_addr;
	uintptr_t phys_addr;
	uintptr_t size;
	/* Offset between linear mapping virtual address and kernel load address */
	unsigned long va_pa_offset;
#ifdef CONFIG_64BIT
	/* Offset between kernel mapping virtual address and kernel load address */
	unsigned long va_kernel_pa_offset;
#endif
	unsigned long va_kernel_xip_pa_offset;
#ifdef CONFIG_XIP_KERNEL
	uintptr_t xiprom;
	uintptr_t xiprom_sz;
#endif
};

extern struct kernel_mapping kernel_map;

#ifdef CONFIG_64BIT
#define is_kernel_mapping(x)	\
	((x) >= kernel_virt_addr && (x) < (kernel_virt_addr + load_sz))
	((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
#define is_linear_mapping(x)	\
	((x) >= PAGE_OFFSET && (x) < kernel_virt_addr)
	((x) >= PAGE_OFFSET && (x) < kernel_map.virt_addr)

#define linear_mapping_pa_to_va(x)	((void *)((unsigned long)(x) + va_pa_offset))
#define linear_mapping_pa_to_va(x)	((void *)((unsigned long)(x) + kernel_map.va_pa_offset))
#define kernel_mapping_pa_to_va(y)	({						\
	unsigned long _y = y;								\
	(_y >= CONFIG_PHYS_RAM_BASE) ?							\
		(void *)((unsigned long)(_y) + va_kernel_pa_offset + XIP_OFFSET) :	\
		(void *)((unsigned long)(_y) + va_kernel_xip_pa_offset);		\
		(void *)((unsigned long)(_y) + kernel_map.va_kernel_pa_offset + XIP_OFFSET) :	\
		(void *)((unsigned long)(_y) + kernel_map.va_kernel_xip_pa_offset);		\
	})
#define __pa_to_va_nodebug(x)		linear_mapping_pa_to_va(x)

#define linear_mapping_va_to_pa(x)	((unsigned long)(x) - va_pa_offset)
#define linear_mapping_va_to_pa(x)	((unsigned long)(x) - kernel_map.va_pa_offset)
#define kernel_mapping_va_to_pa(y) ({						\
	unsigned long _y = y;							\
	(_y < kernel_virt_addr + XIP_OFFSET) ?					\
		((unsigned long)(_y) - va_kernel_xip_pa_offset) :		\
		((unsigned long)(_y) - va_kernel_pa_offset - XIP_OFFSET);	\
	(_y < kernel_map.virt_addr + XIP_OFFSET) ?					\
		((unsigned long)(_y) - kernel_map.va_kernel_xip_pa_offset) :		\
		((unsigned long)(_y) - kernel_map.va_kernel_pa_offset - XIP_OFFSET);	\
	})

#define __va_to_pa_nodebug(x)	({						\
@@ -128,12 +134,12 @@ extern unsigned long kernel_virt_addr;
	})
#else
#define is_kernel_mapping(x)	\
	((x) >= kernel_virt_addr && (x) < (kernel_virt_addr + load_sz))
	((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
#define is_linear_mapping(x)	\
	((x) >= PAGE_OFFSET)

#define __pa_to_va_nodebug(x)  ((void *)((unsigned long) (x) + va_pa_offset))
#define __va_to_pa_nodebug(x)  ((unsigned long)(x) - va_pa_offset)
#define __pa_to_va_nodebug(x)  ((void *)((unsigned long) (x) + kernel_map.va_pa_offset))
#define __va_to_pa_nodebug(x)  ((unsigned long)(x) - kernel_map.va_pa_offset)
#endif /* CONFIG_64BIT */

#ifdef CONFIG_DEBUG_VIRTUAL
+2 −0
Original line number Diff line number Diff line
@@ -311,4 +311,6 @@ void asm_offsets(void)
	 * ensures the alignment is sane.
	 */
	DEFINE(PT_SIZE_ON_STACK, ALIGN(sizeof(struct pt_regs), STACK_ALIGN));

	OFFSET(KERNEL_MAP_VIRT_ADDR, kernel_mapping, virt_addr);
}
+2 −2
Original line number Diff line number Diff line
@@ -81,9 +81,9 @@ pe_head_start:
#ifdef CONFIG_MMU
relocate:
	/* Relocate return address */
	la a1, kernel_virt_addr
	la a1, kernel_map
	XIP_FIXUP_OFFSET a1
	REG_L a1, 0(a1)
	REG_L a1, KERNEL_MAP_VIRT_ADDR(a1)
	la a2, _start
	sub a1, a1, a2
	add ra, ra, a1
+2 −2
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ SYM_CODE_START(riscv_kexec_relocate)
	 * s4: Pointer to the destination address for the relocation
	 * s5: (const) Number of words per page
	 * s6: (const) 1, used for subtraction
	 * s7: (const) va_pa_offset, used when switching MMU off
	 * s7: (const) kernel_map.va_pa_offset, used when switching MMU off
	 * s8: (const) Physical address of the main loop
	 * s9: (debug) indirection page counter
	 * s10: (debug) entry counter
@@ -159,7 +159,7 @@ SYM_CODE_START(riscv_kexec_norelocate)
	 * s0: (const) Phys address to jump to
	 * s1: (const) Phys address of the FDT image
	 * s2: (const) The hartid of the current hart
	 * s3: (const) va_pa_offset, used when switching MMU off
	 * s3: (const) kernel_map.va_pa_offset, used when switching MMU off
	 */
	mv	s0, a1
	mv	s1, a2
+1 −1
Original line number Diff line number Diff line
@@ -188,6 +188,6 @@ machine_kexec(struct kimage *image)
	/* Jump to the relocation code */
	pr_notice("Bye...\n");
	kexec_method(first_ind_entry, jump_addr, fdt_addr,
		     this_hart_id, va_pa_offset);
		     this_hart_id, kernel_map.va_pa_offset);
	unreachable();
}
Loading