diff --git a/include/arch/riscv/arch/model/statedata.h b/include/arch/riscv/arch/model/statedata.h index 5559b2763..39652b159 100644 --- a/include/arch/riscv/arch/model/statedata.h +++ b/include/arch/riscv/arch/model/statedata.h @@ -40,10 +40,9 @@ extern asid_pool_t *riscvKSASIDTable[BIT(asidHighBits)]; /* Kernel Page Tables */ extern pte_t kernel_root_pageTable[BIT(PT_INDEX_BITS)] VISIBLE; -/* If our PADDR_LOAD is not 1GiB aligned then we need to introduce a level2 pagetable - * in order to map in our kernel image at KERNEL_BASE */ -#if CONFIG_PT_LEVELS == 3 && !IS_ALIGNED(PADDR_LOAD, RISCV_GET_LVL_PGSIZE_BITS(1)) -#define RISCV_KERNEL_WINDOW_LEVEL2_PT +/* We need to introduce a level2 pagetable in order to map the BBL to a separate + * page entry to avoid PMP exception. */ +#if __riscv_xlen != 32 extern pte_t kernel_image_level2_pt[BIT(PT_INDEX_BITS)]; #endif #endif diff --git a/include/plat/spike/plat/64/plat_mode/machine/hardware.h b/include/plat/spike/plat/64/plat_mode/machine/hardware.h index 5dabfa111..635b9c1bd 100644 --- a/include/plat/spike/plat/64/plat_mode/machine/hardware.h +++ b/include/plat/spike/plat/64/plat_mode/machine/hardware.h @@ -26,7 +26,7 @@ /* This is the base of the kernel window, which is directly mapped to PADDR_BASE */ #define PPTR_BASE 0xFFFFFFC000000000lu /* This is the mapping of the kernel (mapped above the kernel window currently) */ -#define KERNEL_BASE 0xFFFFFFFF80000000lu +#define KERNEL_BASE 0xFFFFFFFF84000000lu #else #error Only PT_LEVELS == 3 is supported #endif diff --git a/include/plat/spike/plat/machine/hardware.h b/include/plat/spike/plat/machine/hardware.h index b7c1930ac..f7ce26537 100644 --- a/include/plat/spike/plat/machine/hardware.h +++ b/include/plat/spike/plat/machine/hardware.h @@ -38,7 +38,7 @@ /* This represents the physical address that the kernel image will be linked to. This needs to * be on a 1gb boundary as we currently require being able to creating a mapping to this address * as the largest frame size */ -#define PADDR_LOAD 0xC0000000lu +#define PADDR_LOAD 0x84000000lu #endif /* The highest valid physical address that can be indexed in the kernel window */ diff --git a/src/arch/riscv/kernel/vspace.c b/src/arch/riscv/kernel/vspace.c index a9c1e2039..53fb99503 100644 --- a/src/arch/riscv/kernel/vspace.c +++ b/src/arch/riscv/kernel/vspace.c @@ -38,6 +38,7 @@ #include #include #include +#include struct resolve_ret { paddr_t frameBase; @@ -107,7 +108,7 @@ BOOT_CODE VISIBLE void map_kernel_window(void) /* first we map in memory from PADDR_BASE */ word_t paddr = PADDR_BASE; - while (pptr < KERNEL_BASE) { + while (pptr < ROUND_DOWN(KERNEL_BASE, RISCV_GET_LVL_PGSIZE_BITS(1))) { assert(IS_ALIGNED(pptr, RISCV_GET_LVL_PGSIZE_BITS(1))); assert(IS_ALIGNED(paddr, RISCV_GET_LVL_PGSIZE_BITS(1))); @@ -116,19 +117,25 @@ BOOT_CODE VISIBLE void map_kernel_window(void) pptr += RISCV_GET_LVL_PGSIZE(1); paddr += RISCV_GET_LVL_PGSIZE(1); } - /* now we should be mapping the 1GiB kernel base, starting again from PADDR_LOAD */ - assert(pptr == KERNEL_BASE); - paddr = PADDR_LOAD; + /* now we should be mapping the 1GiB kernel base */ + assert(pptr == ROUND_DOWN(KERNEL_BASE, RISCV_GET_LVL_PGSIZE_BITS(1))); + paddr = ROUND_DOWN(PADDR_LOAD, RISCV_GET_LVL_PGSIZE_BITS(1)); -#ifndef RISCV_KERNEL_WINDOW_LEVEL2_PT +#if __riscv_xlen == 32 kernel_root_pageTable[RISCV_GET_PT_INDEX(pptr, 1)] = pte_next(paddr, true); pptr += RISCV_GET_LVL_PGSIZE(1); paddr += RISCV_GET_LVL_PGSIZE(1); #else word_t index = 0; + /* The kernel image are mapped twice, locating the two indexes in the + * root page table, pointing them to the same second level page table. + */ + kernel_root_pageTable[RISCV_GET_PT_INDEX(PADDR_LOAD + BASE_OFFSET, 1)] = + pte_next(kpptr_to_paddr(kernel_image_level2_pt), false); kernel_root_pageTable[RISCV_GET_PT_INDEX(pptr, 1)] = pte_next(kpptr_to_paddr(kernel_image_level2_pt), false); - while (pptr < KERNEL_BASE + RISCV_GET_LVL_PGSIZE(1)) { + while (pptr < ROUND_DOWN(KERNEL_BASE, RISCV_GET_LVL_PGSIZE_BITS(1)) + + RISCV_GET_LVL_PGSIZE(1)) { kernel_image_level2_pt[index] = pte_next(paddr, true); index++; pptr += RISCV_GET_LVL_PGSIZE(2); diff --git a/src/arch/riscv/model/statedata.c b/src/arch/riscv/model/statedata.c index c68f44112..e9c6630dc 100644 --- a/src/arch/riscv/model/statedata.c +++ b/src/arch/riscv/model/statedata.c @@ -31,6 +31,7 @@ asid_pool_t *riscvKSASIDTable[BIT(asidHighBits)]; /* Kernel Page Tables */ pte_t kernel_root_pageTable[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTableBits)); -#ifdef RISCV_KERNEL_WINDOW_LEVEL2_PT + +#if __riscv_xlen != 32 pte_t kernel_image_level2_pt[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTableBits)); #endif diff --git a/src/plat/spike/linker.lds b/src/plat/spike/linker.lds index e88c33da6..ea6bc06e3 100644 --- a/src/plat/spike/linker.lds +++ b/src/plat/spike/linker.lds @@ -24,7 +24,7 @@ ENTRY(_start) #if CONFIG_PT_LEVELS == 2 KERNEL_BASE = 0xFF800000; #elif CONFIG_PT_LEVELS == 3 -KERNEL_BASE = 0xFFFFFFFF80000000; +KERNEL_BASE = 0xFFFFFFFF84000000; #elif CONFIG_PT_LEVELS == 4 #error PT_LEVELS == 4 is not supported yet #endif @@ -33,7 +33,7 @@ KERNEL_BASE = 0xFFFFFFFF80000000; #ifdef CONFIG_BUILD_ROCKET_CHIP_ZEDBOARD PADDR_LOAD = 0x0000000088000000; #else -PADDR_LOAD = 0x00000000C0000000; +PADDR_LOAD = 0x0000000084000000; #endif KERNEL_OFFSET = KERNEL_BASE - PADDR_LOAD;