From 604804efbe3390f1dca1e08a60eec5e4290d6f13 Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Mon, 27 Nov 2023 15:38:49 +0200 Subject: [PATCH] mpfs_opensbi: Re-organize SBI areas so that RW areas follow each other Change the ordering of the SBI areas so that: - The first area is the executable area (.text) - The second area is the heap (RW) - The last area is the scratch registers (RW) This makes it easier to encode PMP areas for OpenSBI. --- arch/risc-v/src/mpfs/mpfs_opensbi.c | 55 ++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/arch/risc-v/src/mpfs/mpfs_opensbi.c b/arch/risc-v/src/mpfs/mpfs_opensbi.c index cb6a66837bbc0..29c4da8bb636a 100644 --- a/arch/risc-v/src/mpfs/mpfs_opensbi.c +++ b/arch/risc-v/src/mpfs/mpfs_opensbi.c @@ -105,6 +105,8 @@ extern const uint8_t __mpfs_nuttx_start[]; extern const uint8_t __mpfs_nuttx_end[]; extern const uint8_t _ssbi_zerodev[]; extern const uint8_t _esbi_zerodev[]; +extern const uint8_t _sbi_heap_start[]; +extern const uint8_t _sbi_heap_size[]; /**************************************************************************** * Private Function Prototypes @@ -470,27 +472,41 @@ static void mpfs_opensbi_scratch_setup(uint32_t hartid) (unsigned long)mpfs_hart_to_scratch; g_scratches[hartid].scratch.platform_addr = (unsigned long)&platform; - /* Our FW area in l2lim section. OpenSBI needs to be aware of it in order - * to protect the area. However, we set the PMP values already and lock - * them so that OpenSBI has no chance override then. + /* Our FW area, heap and the scratch area are in l2lim. + * + * The memory is organized as follows: + * + * ---------------------------------------------------------------------- + * | | | | + * | SBI .text (0000h) | SBI heap (8000h) | SBI scratch (8000h + 4000h) | + * | | | | + * ---------------------------------------------------------------------- + * + * The reason for this organization is that the RX and RW areas can be set + * to the physical memory protection unit (PMP) as two contiguous areas. */ g_scratches[hartid].scratch.fw_start = (unsigned long)_ssbi_zerodev; g_scratches[hartid].scratch.fw_size = (unsigned long)_esbi_zerodev - (unsigned long)_ssbi_zerodev; - g_scratches[hartid].scratch.fw_rw_offset = - (unsigned long)g_scratches[hartid].scratch.fw_size; + /* RW area starts from the heap */ - /* fw_rw_offset needs to be an aligned address */ + g_scratches[hartid].scratch.fw_heap_offset = + (unsigned long)_sbi_heap_start - + (unsigned long)g_scratches[hartid].scratch.fw_start; - g_scratches[hartid].scratch.fw_rw_offset += 1024 * 2; - g_scratches[hartid].scratch.fw_rw_offset &= 0xffffff800; - g_scratches[hartid].scratch.fw_size = - g_scratches[hartid].scratch.fw_rw_offset; + g_scratches[hartid].scratch.fw_heap_size = + (unsigned long)_sbi_heap_size; - g_scratches[hartid].scratch.fw_heap_offset = - (unsigned long)g_scratches[hartid].scratch.fw_size; + g_scratches[hartid].scratch.fw_rw_offset = + g_scratches[hartid].scratch.fw_heap_offset; + + /* Because sbi_heap_init does not work otherwise */ + + g_scratches[hartid].scratch.fw_size = + g_scratches[hartid].scratch.fw_heap_offset + + g_scratches[hartid].scratch.fw_heap_size; /* Heap minimum is 16k. Otherwise sbi_heap.c fails: * hpctrl.hksize = hpctrl.size / HEAP_HOUSEKEEPING_FACTOR; @@ -500,10 +516,17 @@ static void mpfs_opensbi_scratch_setup(uint32_t hartid) * hpctrl.hksize gets to be zero making the OpenSBI crash. */ - g_scratches[hartid].scratch.fw_heap_size = 1024 * 16; - g_scratches[hartid].scratch.fw_size = - g_scratches[hartid].scratch.fw_heap_offset + - g_scratches[hartid].scratch.fw_heap_size; + if (g_scratches[hartid].scratch.fw_heap_size < 0x4000) + { + sbi_panic(__func__); + } + + /* fw_rw_offset needs to be an aligned address */ + + if (g_scratches[hartid].scratch.fw_rw_offset & 0x7FF) + { + sbi_panic(__func__); + } } /****************************************************************************