This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 81188d9c942d238129c8f58355259e4767322514 Author: Ville Juven <[email protected]> AuthorDate: Mon Jan 24 10:17:08 2022 +0200 Extend the RISC-V PMP functionality - Add test for mode support, which is architecture dependent - Add tests for address alignment and region size - Add option to query for access rights - The function goes through every PMP entry and tests if an address range from [base, base+size] has been configured for desired access rights. - If several PMP entries match the range and access rights, the information is combined - End result is either no access, a partial match was found, or a full match was found. Details about the partial match are not provided. The intent for testing access rights and not just blindly applying them is a case where they are already set in e.g. a bootloader. In this case, nothing should be done, unless the configuration does not match, in which case the software must not continue further. --- arch/risc-v/Kconfig | 24 ++ arch/risc-v/include/csr.h | 1 + arch/risc-v/src/common/riscv_internal.h | 14 +- arch/risc-v/src/common/riscv_pmp.c | 562 +++++++++++++++++++++++++++++++- arch/risc-v/src/mpfs/Kconfig | 14 + arch/risc-v/src/mpfs/mpfs_userspace.c | 80 +++-- 6 files changed, 666 insertions(+), 29 deletions(-) diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 72bc2b2..4fac78e 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -101,6 +101,7 @@ config ARCH_CHIP_MPFS select ARCH_HAVE_RESET select ARCH_HAVE_SPI_CS_CONTROL select ARCH_HAVE_PWM_MULTICHAN + select PMP_HAS_LIMITED_FEATURES ---help--- MicroChip Polarfire processor (RISC-V 64bit core with GCVX extensions). @@ -188,6 +189,29 @@ config ARCH_MMU_TYPE_SV39 bool default n +# MPU has certain architecture dependent configurations, which are presented +# here. Default is that the full RISC-V PMP specification is supported. + +config PMP_HAS_LIMITED_FEATURES + bool + default n + +config ARCH_MPU_MIN_BLOCK_SIZE + int "Minimum MPU (PMP) block size" + default 4 if !PMP_HAS_LIMITED_FEATURES + +config ARCH_MPU_HAS_TOR + bool "PMP supports TOR" + default y if !PMP_HAS_LIMITED_FEATURES + +config ARCH_MPU_HAS_NO4 + bool "PMP supports NO4" + default y if !PMP_HAS_LIMITED_FEATURES + +config ARCH_MPU_HAS_NAPOT + bool "PMP supports NAPOT" + default y if !PMP_HAS_LIMITED_FEATURES + source "arch/risc-v/src/opensbi/Kconfig" source "arch/risc-v/src/common/Kconfig" diff --git a/arch/risc-v/include/csr.h b/arch/risc-v/include/csr.h index 5d023ed..d1c1c70 100644 --- a/arch/risc-v/include/csr.h +++ b/arch/risc-v/include/csr.h @@ -346,6 +346,7 @@ #define PMPCFG_R (1 << 0) /* readable ? */ #define PMPCFG_W (1 << 1) /* writeable ? */ #define PMPCFG_X (1 << 2) /* excutable ? */ +#define PMPCFG_RWX_MASK (7 << 0) /* access rights mask */ #define PMPCFG_A_OFF (0 << 3) /* null region (disabled) */ #define PMPCFG_A_TOR (1 << 3) /* top of range */ #define PMPCFG_A_NA4 (2 << 3) /* naturally aligned four-byte region */ diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index 87c4158..596dcae 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -91,6 +91,12 @@ # endif #endif +/* Return values from riscv_check_pmp_access */ + +#define PMP_ACCESS_OFF (0) /* Access for area not set */ +#define PMP_ACCESS_DENIED (-1) /* Access set and denied */ +#define PMP_ACCESS_FULL (1) /* Access set and allowed */ + /**************************************************************************** * Public Types ****************************************************************************/ @@ -177,8 +183,12 @@ void riscv_restorefpu(const uintptr_t *regs); /* RISC-V PMP Config ********************************************************/ -void riscv_config_pmp_region(uintptr_t region, uintptr_t attr, - uintptr_t base, uintptr_t size); +int riscv_config_pmp_region(uintptr_t region, uintptr_t attr, + uintptr_t base, uintptr_t size); + +int riscv_check_pmp_access(uintptr_t attr, uintptr_t base, uintptr_t size); +int riscv_configured_pmp_regions(void); +int riscv_next_free_pmp_region(void); /* Power management *********************************************************/ diff --git a/arch/risc-v/src/common/riscv_pmp.c b/arch/risc-v/src/common/riscv_pmp.c index 1fa0daf..b746e7f 100644 --- a/arch/risc-v/src/common/riscv_pmp.c +++ b/arch/risc-v/src/common/riscv_pmp.c @@ -22,6 +22,9 @@ * Included Files ****************************************************************************/ +#include <stdbool.h> + +#include <nuttx/compiler.h> #include <nuttx/config.h> #include <nuttx/arch.h> #include <arch/csr.h> @@ -32,6 +35,18 @@ * Pre-processor Definitions ****************************************************************************/ +/* Minimum supported block size */ + +#if !defined CONFIG_ARCH_MPU_MIN_BLOCK_SIZE +#define MIN_BLOCK_SIZE (__riscv_xlen / 8) +#else +#define MIN_BLOCK_SIZE CONFIG_ARCH_MPU_MIN_BLOCK_SIZE +#endif + +/* Address and block size alignment mask */ + +#define BLOCK_ALIGN_MASK (MIN_BLOCK_SIZE - 1) + #define PMP_CFG_BITS_CNT (8) #define PMP_CFG_FLAG_MASK (0xFF) @@ -44,6 +59,361 @@ reg |= attr << (offset * PMP_CFG_BITS_CNT); \ } while(0); +#define PMP_READ_REGION_FROM_REG(region, reg) \ + ({ \ + uintptr_t tmp = READ_CSR(reg); \ + tmp >>= ((region % PMP_CFG_CNT_IN_REG) * PMP_CFG_BITS_CNT); \ + tmp &= PMP_CFG_FLAG_MASK; \ + tmp; \ + }) + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Helper structure for handling a PMP entry */ + +struct pmp_entry_s +{ + uintptr_t base; /* Base address of region */ + uintptr_t end; /* End address of region */ + uintptr_t size; /* Region size */ + uint8_t mode; /* Address matching mode */ + uint8_t rwx; /* Access rights */ +}; + +typedef struct pmp_entry_s pmp_entry_t; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pmp_check_addrmatch_type + * + * Description: + * Test if an address matching type is supported by the architecture. + * + * Input Parameters: + * type - The type to test. + * + * Returned Value: + * true if it is, false otherwise. + * + ****************************************************************************/ + +static bool pmp_check_addrmatch_type(uintptr_t type) +{ + /* Parameter is potentially unused */ + + UNUSED(type); +#ifdef CONFIG_ARCH_MPU_HAS_TOR + if (type == PMPCFG_A_TOR) + { + return true; + } + +#endif +#ifdef CONFIG_ARCH_MPU_HAS_NO4 + if (type == PMPCFG_A_NA4) + { + return true; + } + +#endif +#ifdef CONFIG_ARCH_MPU_HAS_NAPOT + if (type == PMPCFG_A_NAPOT) + { + return true; + } +#endif + + /* None of the supported types match */ + + return false; +} + +/**************************************************************************** + * Name: pmp_check_region_attrs + * + * Description: + * Test if the base address and size of region meet alignment requirements. + * + * Input Parameters: + * base - The base address of the region. + * size - The memory length of the region. + * + * Returned Value: + * true if it is, false otherwise. + * + ****************************************************************************/ + +static bool pmp_check_region_attrs(uintptr_t base, uintptr_t size) +{ + /* Check that the size is not too small */ + + if (size < MIN_BLOCK_SIZE) + { + return false; + } + + /* Check that the base address is aligned properly */ + + if ((base & BLOCK_ALIGN_MASK) != 0) + { + return false; + } + + /* Check that the size is aligned properly */ + + if ((size & BLOCK_ALIGN_MASK) != 0) + { + return false; + } + + return OK; +} + +/**************************************************************************** + * Name: pmp_read_region_cfg + * + * Description: + * Read PMP configuration for region + * + * Input Parameters: + * region - Region number. + * + * Returned Value: + * Configuration value from pmpcfg+region + * + ****************************************************************************/ + +static uintptr_t pmp_read_region_cfg(uintptr_t region) +{ +# if (__riscv_xlen == 32) + switch (region) + { + case 0 ... 3: + return PMP_READ_REGION_FROM_REG(region, pmpcfg0); + + case 4 ... 7: + return PMP_READ_REGION_FROM_REG(region, pmpcfg1); + + case 8 ... 11: + return PMP_READ_REGION_FROM_REG(region, pmpcfg2); + + case 12 ... 15: + return PMP_READ_REGION_FROM_REG(region, pmpcfg3); + + default: + break; + } +# elif (__riscv_xlen == 64) + switch (region) + { + case 0 ... 7: + return PMP_READ_REGION_FROM_REG(region, pmpcfg0); + + case 8 ... 15: + return PMP_READ_REGION_FROM_REG(region, pmpcfg2); + + default: + break; + } +#endif + + /* Never executed */ + + return 0; +} + +/**************************************************************************** + * Name: pmp_read_addr + * + * Description: + * Read address for region + * + * Input Parameters: + * region - Region number. + * + * Returned Value: + * Address value from pmpcfg+region + * + ****************************************************************************/ + +static uintptr_t pmp_read_addr(uintptr_t region) +{ + switch (region) + { + case 0: + return READ_CSR(pmpaddr0); + + case 1: + return READ_CSR(pmpaddr1); + + case 2: + return READ_CSR(pmpaddr2); + + case 3: + return READ_CSR(pmpaddr3); + + case 4: + return READ_CSR(pmpaddr4); + + case 5: + return READ_CSR(pmpaddr5); + + case 6: + return READ_CSR(pmpaddr6); + + case 7: + return READ_CSR(pmpaddr7); + + case 8: + return READ_CSR(pmpaddr8); + + case 9: + return READ_CSR(pmpaddr9); + + case 10: + return READ_CSR(pmpaddr10); + + case 11: + return READ_CSR(pmpaddr11); + + case 12: + return READ_CSR(pmpaddr12); + + case 13: + return READ_CSR(pmpaddr13); + + case 14: + return READ_CSR(pmpaddr14); + + case 15: + return READ_CSR(pmpaddr15); + + default: + break; + } + + /* Never executed */ + + return 0; +} + +/**************************************************************************** + * Name: pmp_napot_decode + * + * Description: + * Decode base and size from NAPOT value + * + * Input Parameters: + * val - Value to decode. + * base - Base out. + * size - Size out. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pmp_napot_decode(uintptr_t val, uintptr_t * base, + uintptr_t * size) +{ + uint64_t mask = (uint64_t)(-1) >> 1; + uint64_t pot = __riscv_xlen + 2; + + while (mask) + { + if ((val & mask) == mask) + { + break; + } + + pot--; + mask >>= 1; + } + + val &= ~mask; + *base = (val << 2); + *size = (1 << pot); +} + +/**************************************************************************** + * Name: pmp_read + * + * Description: + * Read PMP region into PMP entry + * + * Input Parameters: + * region - Region number. + * entry - Entry out + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void pmp_read(uintptr_t region, pmp_entry_t * entry) +{ + uintptr_t addr = 0; + uintptr_t size = 0; + uintptr_t mode = 0; + uintptr_t rwx = 0; + uintptr_t cfg = 0; + + addr = pmp_read_addr(region); + cfg = pmp_read_region_cfg(region); + mode = cfg & PMPCFG_A_MASK; + rwx = cfg & PMPCFG_RWX_MASK; + + switch (mode) + { + case PMPCFG_A_TOR: + addr <<= 2; + + /* TOR region, must peek into prior region for size */ + + if (region == 0) + { + size = addr; + } + else + { + size = addr - pmp_read_addr(region - 1); + } + + break; + + case PMPCFG_A_NA4: + addr <<= 2; + size = 4; + break; + + case PMPCFG_A_NAPOT: + pmp_napot_decode(addr, &addr, &size); + break; + + default: + break; + } + + entry->base = addr; + entry->end = addr + size; + entry->size = size; + entry->rwx = rwx; + entry->mode = mode; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -63,17 +433,32 @@ * and the size must be power-of-two according to the the PMP spec. * * Returned Value: - * None. + * 0 on succeess; negated error on failure * ****************************************************************************/ -void riscv_config_pmp_region(uintptr_t region, uintptr_t attr, - uintptr_t base, uintptr_t size) +int riscv_config_pmp_region(uintptr_t region, uintptr_t attr, + uintptr_t base, uintptr_t size) { - uintptr_t addr = 0; - uintptr_t cfg = 0; + uintptr_t addr = 0; + uintptr_t cfg = 0; + uintptr_t type = (attr & PMPCFG_A_MASK); + + /* Check that the architecture supports address matching type */ + + if (pmp_check_addrmatch_type(type) == false) + { + return -EINVAL; + } + + /* Check the region attributes */ + + if (pmp_check_region_attrs(base, size)) + { + return -EINVAL; + } - /* TODO: check the base address alignment and size */ + /* Calculate new base address from type */ addr = base >> 2; if (PMPCFG_A_NAPOT == (attr & PMPCFG_A_MASK)) @@ -81,6 +466,8 @@ void riscv_config_pmp_region(uintptr_t region, uintptr_t attr, addr |= (size - 1) >> 3; } + /* Set the address value */ + switch (region) { case 0: @@ -151,6 +538,8 @@ void riscv_config_pmp_region(uintptr_t region, uintptr_t attr, break; } + /* Set the configuration register value */ + # if (__riscv_xlen == 32) switch (region) { @@ -206,4 +595,165 @@ void riscv_config_pmp_region(uintptr_t region, uintptr_t attr, /* fence is needed when page-based virtual memory is implemented */ __asm volatile("sfence.vma x0, x0" : : : "memory"); + + return OK; +} + +/**************************************************************************** + * Name: riscv_check_pmp_access + * + * Description: + * This function will set the specific PMP region with the desired cfg. + * + * Input Parameters: + * attr - The region configurations. + * base - The base address of the region. + * size - The memory length of the region. + * For the NAPOT mode, the base address must aligned to the size boundary, + * and the size must be power-of-two according to the the PMP spec. + * + * Returned Value: + * 0 if access rights are not set at all + * < 0 if access rights are set and match match partially + * > 0 if access rights are set and match fully + * + ****************************************************************************/ + +int riscv_check_pmp_access(uintptr_t attr, uintptr_t base, uintptr_t size) +{ + pmp_entry_t entry; + uintptr_t end; + uintptr_t orgsize; + unsigned int region; + + /* Go through every single configured region and test the attributes */ + + attr = (attr & PMPCFG_RWX_MASK); + end = base + size; + orgsize = size; + + for (region = 0; region < 16 && size > 0; region++) + { + /* Find matching configuration first */ + + pmp_read(region, &entry); + + /* Check if any configuration at all */ + + if (entry.mode == PMPCFG_A_OFF) + { + continue; + } + + /* Does this address range match ? Take partial matches into account. + * + * There are four possibilities: + * 1: Full match; region inside mapped area + * 2: Partial match; mapped area inside region + * 3: Partial match; base inside mapped region, end outside + * 4: Partial match; base outside mapped region, end inside + */ + + if ((base >= entry.base && end <= entry.end) || + (base <= entry.base && end >= entry.end) || + (base >= entry.base && base <= entry.end) || + (end >= entry.base && end <= entry.end)) + { + /* Found a matching splice, check rights */ + + if ((entry.rwx & attr) == attr) + { + /* Found matching region that allows access */ + + size -= min(end, entry.end) - max(base, entry.base); + } + else + { + /* Found matching region that does not allow access */ + + return PMP_ACCESS_DENIED; + } + } + } + + /* Check if nothing configured at all ? */ + + if (size == orgsize) + { + return PMP_ACCESS_OFF; + } + + /* If size is non-positive, the requested range is accessible */ + + if (size <= 0) + { + return PMP_ACCESS_FULL; + } + + /* The requested range is either fully or partially inaccessible */ + + return PMP_ACCESS_DENIED; +} + +/**************************************************************************** + * Name: riscv_configured_pmp_regions + * + * Description: + * Count amount of configured PMP regions, note: is not atomic + * + * Input Parameters: + * + * Returned Value: + * Amount of configured PMP regions + * + ****************************************************************************/ + +int riscv_configured_pmp_regions(void) +{ + pmp_entry_t entry; + unsigned int region; + int ret = 0; + + for (region = 0; region < 16; region++) + { + pmp_read(region, &entry); + + if (entry.mode != PMPCFG_A_OFF) + { + ret++; + } + } + + return ret; +} + +/**************************************************************************** + * Name: riscv_next_free_pmp_region + * + * Description: + * Returns next free PMP region, note: is not atomic + * + * Input Parameters: + * + * Returned Value: + * Next free PMP region, or -1 if none found + * + ****************************************************************************/ + +int riscv_next_free_pmp_region(void) +{ + pmp_entry_t entry; + unsigned int region; + + for (region = 0; region < 16; region++) + { + pmp_read(region, &entry); + + if (entry.mode == PMPCFG_A_OFF) + { + return region; + } + } + + return -1; } diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig index 8074909..3c03635 100755 --- a/arch/risc-v/src/mpfs/Kconfig +++ b/arch/risc-v/src/mpfs/Kconfig @@ -312,3 +312,17 @@ config MPFS_DMA menu "MPFS Others" endmenu + +# Override the default values for MPU / PMP parameters here + +config ARCH_MPU_MIN_BLOCK_SIZE + default 4096 + +config ARCH_MPU_HAS_TOR + default n + +config ARCH_MPU_HAS_NO4 + default n + +config ARCH_MPU_HAS_NAPOT + default y diff --git a/arch/risc-v/src/mpfs/mpfs_userspace.c b/arch/risc-v/src/mpfs/mpfs_userspace.c index c69cb1c..c375d59 100755 --- a/arch/risc-v/src/mpfs/mpfs_userspace.c +++ b/arch/risc-v/src/mpfs/mpfs_userspace.c @@ -39,11 +39,20 @@ * Pre-processor Definitions ****************************************************************************/ +#define PMP_UFLASH_FLAGS (PMPCFG_A_NAPOT | PMPCFG_X | PMPCFG_R) +#define PMP_USRAM_FLAGS (PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R) + +#define UFLASH_START (uintptr_t)&__uflash_start +#define UFLASH_SIZE (uintptr_t)&__uflash_size +#define USRAM_START (uintptr_t)&__usram_start +#define USRAM_SIZE (uintptr_t)&__usram_size + /* Physical and virtual addresses to page tables (vaddr = paddr mapping) */ -#define PGT_BASE_PADDR (uint64_t)&m_l1_pgtable +#define PGT_L1_PBASE (uint64_t)&m_l1_pgtable #define PGT_L2_PBASE (uint64_t)&m_l2_pgtable #define PGT_L3_PBASE (uint64_t)&m_l3_pgtable +#define PGT_L1_VBASE PGT_L1_PBASE #define PGT_L2_VBASE PGT_L2_PBASE #define PGT_L3_VBASE PGT_L3_PBASE @@ -52,6 +61,11 @@ #define MMU_UFLASH_FLAGS (PTE_R | PTE_X | PTE_U | PTE_G) #define MMU_USRAM_FLAGS (PTE_R | PTE_W | PTE_U | PTE_G) +/* Kernel RAM needs to be opened (the page tables) */ + +#define KSRAM_START (uintptr_t)&__ksram_start +#define KSRAM_SIZE (uintptr_t)&__ksram_size + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -178,9 +192,8 @@ static void configure_mpu(void) /* Configure the PMP to permit user-space access to its ROM and RAM. * * Note: PMP by default revokes access, thus if different privilege modes - * are in use (mstatus.mprv is set), the the user space _must_ be granted - * access here, otherwise an exception will fire when the user space task - * is started. + * are in use, the user space _must_ be granted access here, otherwise + * an exception will fire when the user space task is started. * * Note: according to the Polarfire reference manual, address bits [1:0] * are not considered (due to 4 octet alignment), so strictly they don't @@ -198,19 +211,46 @@ static void configure_mpu(void) * */ - riscv_config_pmp_region(0, PMPCFG_A_NAPOT | PMPCFG_X | PMPCFG_R, - (uintptr_t)&__uflash_start, - (uintptr_t)&__uflash_size); + int ret; + int idx; + + /* First, test access to user flash */ + + ret = riscv_check_pmp_access(PMP_UFLASH_FLAGS, UFLASH_START, UFLASH_SIZE); + + /* No access or partial access means we must crash */ + + DEBUGASSERT(ret != PMP_ACCESS_DENIED); - riscv_config_pmp_region(1, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R, - (uintptr_t)&__usram_start, - (uintptr_t)&__usram_size); + if (ret == PMP_ACCESS_OFF) + { + idx = riscv_next_free_pmp_region(); + DEBUGASSERT(idx >= 0); + riscv_config_pmp_region(idx, PMP_UFLASH_FLAGS, UFLASH_START, + UFLASH_SIZE); + } + + /* Then, test access to user RAM */ + + ret = riscv_check_pmp_access(PMP_USRAM_FLAGS, USRAM_START, USRAM_SIZE); + DEBUGASSERT(ret != PMP_ACCESS_DENIED); + if (ret == PMP_ACCESS_OFF) + { + idx = riscv_next_free_pmp_region(); + DEBUGASSERT(idx >= 0); + riscv_config_pmp_region(idx, PMP_USRAM_FLAGS, USRAM_START, USRAM_SIZE); + } /* The supervisor must have access to the page tables */ - riscv_config_pmp_region(2, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R, - (uintptr_t)&__ksram_start, - (uintptr_t)&__ksram_size); + ret = riscv_check_pmp_access(PMP_USRAM_FLAGS, KSRAM_START, KSRAM_SIZE); + DEBUGASSERT(ret != PMP_ACCESS_DENIED); + if (ret == PMP_ACCESS_OFF) + { + idx = riscv_next_free_pmp_region(); + DEBUGASSERT(idx >= 0); + riscv_config_pmp_region(idx, PMP_USRAM_FLAGS, KSRAM_START, KSRAM_SIZE); + } } /**************************************************************************** @@ -228,24 +268,22 @@ static void configure_mmu(void) /* Setup the L3 references for executable memory */ - mmu_ln_map_region(3, PGT_L3_VBASE, (uintptr_t)&__uflash_start, - (uintptr_t)&__uflash_start, (uintptr_t)&__uflash_size, - MMU_UFLASH_FLAGS); + mmu_ln_map_region(3, PGT_L3_VBASE, UFLASH_START, UFLASH_START, + UFLASH_SIZE, MMU_UFLASH_FLAGS); /* Setup the L3 references for data memory */ - mmu_ln_map_region(3, PGT_L3_VBASE, (uintptr_t)&__usram_start, - (uintptr_t)&__usram_start, (uintptr_t)&__usram_size, - MMU_USRAM_FLAGS); + mmu_ln_map_region(3, PGT_L3_VBASE, USRAM_START, USRAM_START, + USRAM_SIZE, MMU_USRAM_FLAGS); /* Setup the L2 and L1 references */ mmu_ln_setentry(2, PGT_L2_VBASE, PGT_L3_PBASE, PGT_L3_VBASE, PTE_G); - mmu_ln_setentry(1, PGT_BASE_PADDR, PGT_L2_PBASE, PGT_L2_VBASE, PTE_G); + mmu_ln_setentry(1, PGT_L1_VBASE, PGT_L2_PBASE, PGT_L2_VBASE, PTE_G); /* Enable MMU */ - mmu_enable(PGT_BASE_PADDR, 0); + mmu_enable(PGT_L1_PBASE, 0); } #endif /* CONFIG_BUILD_PROTECTED */
