1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * XIP fixup macros, only useful in assembly. 4 */ 5 #ifndef _ASM_RISCV_XIP_FIXUP_H 6 #define _ASM_RISCV_XIP_FIXUP_H 7 8 #include <linux/pgtable.h> 9 10 #ifdef CONFIG_XIP_KERNEL 11 .macro XIP_FIXUP_OFFSET reg 12 /* Fix-up address in Flash into address in RAM early during boot before 13 * MMU is up. Because generated code "thinks" data is in Flash, but it 14 * is actually in RAM (actually data is also in Flash, but Flash is 15 * read-only, thus we need to use the data residing in RAM). 16 * 17 * The start of data in Flash is _sdata and the start of data in RAM is 18 * CONFIG_PHYS_RAM_BASE. So this fix-up essentially does this: 19 * reg += CONFIG_PHYS_RAM_BASE - _start 20 */ 21 li t0, CONFIG_PHYS_RAM_BASE 22 add \reg, \reg, t0 23 la t0, _sdata 24 sub \reg, \reg, t0 25 .endm 26 .macro XIP_FIXUP_FLASH_OFFSET reg 27 /* In linker script, at the transition from read-only section to 28 * writable section, the VMA is increased while LMA remains the same. 29 * (See in linker script how _sdata, __data_loc and LOAD_OFFSET is 30 * changed) 31 * 32 * Consequently, early during boot before MMU is up, the generated code 33 * reads the "writable" section at wrong addresses, because VMA is used 34 * by compiler to generate code, but the data is located in Flash using 35 * LMA. 36 */ 37 la t0, _sdata 38 sub \reg, \reg, t0 39 la t0, __data_loc 40 add \reg, \reg, t0 41 .endm 42 #else 43 .macro XIP_FIXUP_OFFSET reg 44 .endm 45 .macro XIP_FIXUP_FLASH_OFFSET reg 46 .endm 47 #endif /* CONFIG_XIP_KERNEL */ 48 49 #endif 50