[arch][arm64] add support for 16k pages

This commit is contained in:
Travis Geiselbrecht
2025-08-31 20:54:56 -07:00
parent cc9c3a053c
commit fff0f2a740
8 changed files with 180 additions and 148 deletions

View File

@@ -18,6 +18,7 @@
#include <lk/main.h> #include <lk/main.h>
#include <platform.h> #include <platform.h>
#include <lk/trace.h> #include <lk/trace.h>
#include <assert.h>
#define LOCAL_TRACE 0 #define LOCAL_TRACE 0

View File

@@ -11,18 +11,19 @@
#include <arch/defines.h> #include <arch/defines.h>
#define IFTE(c,t,e) (!!(c) * (t) | !(c) * (e)) #define IFTE(c, t, e) (!!(c) * (t) | !(c) * (e))
#define NBITS01(n) IFTE(n, 1, 0) #define NBITS01(n) IFTE(n, 1, 0)
#define NBITS02(n) IFTE((n) >> 1, 1 + NBITS01((n) >> 1), NBITS01(n)) #define NBITS02(n) IFTE((n) >> 1, 1 + NBITS01((n) >> 1), NBITS01(n))
#define NBITS04(n) IFTE((n) >> 2, 2 + NBITS02((n) >> 2), NBITS02(n)) #define NBITS04(n) IFTE((n) >> 2, 2 + NBITS02((n) >> 2), NBITS02(n))
#define NBITS08(n) IFTE((n) >> 4, 4 + NBITS04((n) >> 4), NBITS04(n)) #define NBITS08(n) IFTE((n) >> 4, 4 + NBITS04((n) >> 4), NBITS04(n))
#define NBITS16(n) IFTE((n) >> 8, 8 + NBITS08((n) >> 8), NBITS08(n)) #define NBITS16(n) IFTE((n) >> 8, 8 + NBITS08((n) >> 8), NBITS08(n))
#define NBITS32(n) IFTE((n) >> 16, 16 + NBITS16((n) >> 16), NBITS16(n)) #define NBITS32(n) IFTE((n) >> 16, 16 + NBITS16((n) >> 16), NBITS16(n))
#define NBITS(n) IFTE((n) >> 32, 32 + NBITS32((n) >> 32), NBITS32(n)) #define NBITS(n) IFTE((n) >> 32, 32 + NBITS32((n) >> 32), NBITS32(n))
// TODO: perhaps pass KERNEL_SIZE_SHIFT in from rules.mk and compute the size from that
#ifndef MMU_KERNEL_SIZE_SHIFT #ifndef MMU_KERNEL_SIZE_SHIFT
#define KERNEL_ASPACE_BITS (NBITS(0xffffffffffffffff-KERNEL_ASPACE_BASE)) #define KERNEL_ASPACE_BITS (NBITS(0xffffffffffffffff - KERNEL_ASPACE_BASE))
#define KERNEL_BASE_BITS (NBITS(0xffffffffffffffff-KERNEL_BASE)) #define KERNEL_BASE_BITS (NBITS(0xffffffffffffffff - KERNEL_BASE))
#if KERNEL_BASE_BITS > KERNEL_ASPACE_BITS #if KERNEL_BASE_BITS > KERNEL_ASPACE_BITS
#define KERNEL_ASPACE_BITS KERNEL_BASE_BITS /* KERNEL_BASE should not be below KERNEL_ASPACE_BASE */ #define KERNEL_ASPACE_BITS KERNEL_BASE_BITS /* KERNEL_BASE should not be below KERNEL_ASPACE_BASE */
#endif #endif
@@ -35,11 +36,11 @@
#endif #endif
#ifndef MMU_USER_SIZE_SHIFT #ifndef MMU_USER_SIZE_SHIFT
#define MMU_USER_SIZE_SHIFT 48 #define MMU_USER_SIZE_SHIFT MMU_KERNEL_SIZE_SHIFT
#endif #endif
#define MMU_KERNEL_PAGE_SIZE_SHIFT (PAGE_SIZE_SHIFT) #define MMU_KERNEL_PAGE_SIZE_SHIFT (PAGE_SIZE_SHIFT)
#define MMU_USER_PAGE_SIZE_SHIFT (USER_PAGE_SIZE_SHIFT) #define MMU_USER_PAGE_SIZE_SHIFT (USER_PAGE_SIZE_SHIFT)
/* /*
* TCR TGx values * TCR TGx values
@@ -53,8 +54,8 @@
((page_size_shift == 16) & 1)) ((page_size_shift == 16) & 1))
#define MMU_TG1(page_size_shift) ((((page_size_shift == 12) & 1) << 1) | \ #define MMU_TG1(page_size_shift) ((((page_size_shift == 12) & 1) << 1) | \
((page_size_shift == 14) & 1) | \ ((page_size_shift == 14) & 1) | \
((page_size_shift == 16) & 1) | \ ((page_size_shift == 16) & 1) | \
(((page_size_shift == 16) & 1) << 1)) (((page_size_shift == 16) & 1) << 1))
#define MMU_LX_X(page_shift, level) ((4 - (level)) * ((page_shift) - 3) + 3) #define MMU_LX_X(page_shift, level) ((4 - (level)) * ((page_shift) - 3) + 3)
@@ -85,7 +86,7 @@
#endif #endif
#define MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP (0x1 << (MMU_KERNEL_SIZE_SHIFT - MMU_KERNEL_TOP_SHIFT)) #define MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP (0x1 << (MMU_KERNEL_SIZE_SHIFT - MMU_KERNEL_TOP_SHIFT))
#define MMU_PTE_DESCRIPTOR_BLOCK_MAX_SHIFT (30) #define MMU_PTE_DESCRIPTOR_BLOCK_MAX_SHIFT (30)
#ifndef ASSEMBLY #ifndef ASSEMBLY
#define BM(base, count, val) (((val) & ((1UL << (count)) - 1)) << (base)) #define BM(base, count, val) (((val) & ((1UL << (count)) - 1)) << (base))
@@ -93,181 +94,179 @@
#define BM(base, count, val) (((val) & ((0x1 << (count)) - 1)) << (base)) #define BM(base, count, val) (((val) & ((0x1 << (count)) - 1)) << (base))
#endif #endif
#define MMU_SH_NON_SHAREABLE (0) #define MMU_SH_NON_SHAREABLE (0)
#define MMU_SH_OUTER_SHAREABLE (2) #define MMU_SH_OUTER_SHAREABLE (2)
#define MMU_SH_INNER_SHAREABLE (3) #define MMU_SH_INNER_SHAREABLE (3)
#define MMU_RGN_NON_CACHEABLE (0) #define MMU_RGN_NON_CACHEABLE (0)
#define MMU_RGN_WRITE_BACK_ALLOCATE (1) #define MMU_RGN_WRITE_BACK_ALLOCATE (1)
#define MMU_RGN_WRITE_THROUGH_NO_ALLOCATE (2) #define MMU_RGN_WRITE_THROUGH_NO_ALLOCATE (2)
#define MMU_RGN_WRITE_BACK_NO_ALLOCATE (3) #define MMU_RGN_WRITE_BACK_NO_ALLOCATE (3)
#define MMU_TCR_TBI1 BM(38, 1, 1) #define MMU_TCR_TBI1 BM(38, 1, 1)
#define MMU_TCR_TBI0 BM(37, 1, 1) #define MMU_TCR_TBI0 BM(37, 1, 1)
#define MMU_TCR_AS BM(36, 1, 1) #define MMU_TCR_AS BM(36, 1, 1)
#define MMU_TCR_IPS(size) BM(32, 3, (size)) #define MMU_TCR_IPS(size) BM(32, 3, (size))
#define MMU_TCR_TG1(granule_size) BM(30, 2, (granule_size)) #define MMU_TCR_TG1(granule_size) BM(30, 2, (granule_size))
#define MMU_TCR_SH1(shareability_flags) BM(28, 2, (shareability_flags)) #define MMU_TCR_SH1(shareability_flags) BM(28, 2, (shareability_flags))
#define MMU_TCR_ORGN1(cache_flags) BM(26, 2, (cache_flags)) #define MMU_TCR_ORGN1(cache_flags) BM(26, 2, (cache_flags))
#define MMU_TCR_IRGN1(cache_flags) BM(24, 2, (cache_flags)) #define MMU_TCR_IRGN1(cache_flags) BM(24, 2, (cache_flags))
#define MMU_TCR_EPD1 BM(23, 1, 1) #define MMU_TCR_EPD1 BM(23, 1, 1)
#define MMU_TCR_A1 BM(22, 1, 1) #define MMU_TCR_A1 BM(22, 1, 1)
#define MMU_TCR_T1SZ(size) BM(16, 6, (size)) #define MMU_TCR_T1SZ(size) BM(16, 6, (size))
#define MMU_TCR_TG0(granule_size) BM(14, 2, (granule_size)) #define MMU_TCR_TG0(granule_size) BM(14, 2, (granule_size))
#define MMU_TCR_SH0(shareability_flags) BM(12, 2, (shareability_flags)) #define MMU_TCR_SH0(shareability_flags) BM(12, 2, (shareability_flags))
#define MMU_TCR_ORGN0(cache_flags) BM(10, 2, (cache_flags)) #define MMU_TCR_ORGN0(cache_flags) BM(10, 2, (cache_flags))
#define MMU_TCR_IRGN0(cache_flags) BM( 8, 2, (cache_flags)) #define MMU_TCR_IRGN0(cache_flags) BM(8, 2, (cache_flags))
#define MMU_TCR_EPD0 BM( 7, 1, 1) #define MMU_TCR_EPD0 BM(7, 1, 1)
#define MMU_TCR_T0SZ(size) BM( 0, 6, (size)) #define MMU_TCR_T0SZ(size) BM(0, 6, (size))
#define MMU_MAIR_ATTR(index, attr) BM(index * 8, 8, (attr))
#define MMU_MAIR_ATTR(index, attr) BM(index * 8, 8, (attr))
/* L0/L1/L2/L3 descriptor types */ /* L0/L1/L2/L3 descriptor types */
#define MMU_PTE_DESCRIPTOR_INVALID BM(0, 2, 0) #define MMU_PTE_DESCRIPTOR_INVALID BM(0, 2, 0)
#define MMU_PTE_DESCRIPTOR_MASK BM(0, 2, 3) #define MMU_PTE_DESCRIPTOR_MASK BM(0, 2, 3)
/* L0/L1/L2 descriptor types */ /* L0/L1/L2 descriptor types */
#define MMU_PTE_L012_DESCRIPTOR_BLOCK BM(0, 2, 1) #define MMU_PTE_L012_DESCRIPTOR_BLOCK BM(0, 2, 1)
#define MMU_PTE_L012_DESCRIPTOR_TABLE BM(0, 2, 3) #define MMU_PTE_L012_DESCRIPTOR_TABLE BM(0, 2, 3)
/* L3 descriptor types */ /* L3 descriptor types */
#define MMU_PTE_L3_DESCRIPTOR_PAGE BM(0, 2, 3) #define MMU_PTE_L3_DESCRIPTOR_PAGE BM(0, 2, 3)
/* Output address mask */ /* Output address mask */
#define MMU_PTE_OUTPUT_ADDR_MASK BM(12, 36, 0xfffffffff) #define MMU_PTE_OUTPUT_ADDR_MASK BM(12, 36, 0xfffffffff)
/* Table attrs */ /* Table attrs */
#define MMU_PTE_ATTR_NS_TABLE BM(63, 1, 1) #define MMU_PTE_ATTR_NS_TABLE BM(63, 1, 1)
#define MMU_PTE_ATTR_AP_TABLE_NO_WRITE BM(62, 1, 1) #define MMU_PTE_ATTR_AP_TABLE_NO_WRITE BM(62, 1, 1)
#define MMU_PTE_ATTR_AP_TABLE_NO_EL0 BM(61, 1, 1) #define MMU_PTE_ATTR_AP_TABLE_NO_EL0 BM(61, 1, 1)
#define MMU_PTE_ATTR_UXN_TABLE BM(60, 1, 1) #define MMU_PTE_ATTR_UXN_TABLE BM(60, 1, 1)
#define MMU_PTE_ATTR_PXN_TABLE BM(59, 1, 1) #define MMU_PTE_ATTR_PXN_TABLE BM(59, 1, 1)
/* Block/Page attrs */ /* Block/Page attrs */
#define MMU_PTE_ATTR_RES_SOFTWARE BM(55, 4, 0xf) #define MMU_PTE_ATTR_RES_SOFTWARE BM(55, 4, 0xf)
#define MMU_PTE_ATTR_UXN BM(54, 1, 1) #define MMU_PTE_ATTR_UXN BM(54, 1, 1)
#define MMU_PTE_ATTR_PXN BM(53, 1, 1) #define MMU_PTE_ATTR_PXN BM(53, 1, 1)
#define MMU_PTE_ATTR_CONTIGUOUS BM(52, 1, 1) #define MMU_PTE_ATTR_CONTIGUOUS BM(52, 1, 1)
#define MMU_PTE_ATTR_NON_GLOBAL BM(11, 1, 1) #define MMU_PTE_ATTR_NON_GLOBAL BM(11, 1, 1)
#define MMU_PTE_ATTR_AF BM(10, 1, 1) #define MMU_PTE_ATTR_AF BM(10, 1, 1)
#define MMU_PTE_ATTR_SH_NON_SHAREABLE BM(8, 2, 0) #define MMU_PTE_ATTR_SH_NON_SHAREABLE BM(8, 2, 0)
#define MMU_PTE_ATTR_SH_OUTER_SHAREABLE BM(8, 2, 2) #define MMU_PTE_ATTR_SH_OUTER_SHAREABLE BM(8, 2, 2)
#define MMU_PTE_ATTR_SH_INNER_SHAREABLE BM(8, 2, 3) #define MMU_PTE_ATTR_SH_INNER_SHAREABLE BM(8, 2, 3)
#define MMU_PTE_ATTR_AP_P_RW_U_NA BM(6, 2, 0) #define MMU_PTE_ATTR_AP_P_RW_U_NA BM(6, 2, 0)
#define MMU_PTE_ATTR_AP_P_RW_U_RW BM(6, 2, 1) #define MMU_PTE_ATTR_AP_P_RW_U_RW BM(6, 2, 1)
#define MMU_PTE_ATTR_AP_P_RO_U_NA BM(6, 2, 2) #define MMU_PTE_ATTR_AP_P_RO_U_NA BM(6, 2, 2)
#define MMU_PTE_ATTR_AP_P_RO_U_RO BM(6, 2, 3) #define MMU_PTE_ATTR_AP_P_RO_U_RO BM(6, 2, 3)
#define MMU_PTE_ATTR_AP_MASK BM(6, 2, 3) #define MMU_PTE_ATTR_AP_MASK BM(6, 2, 3)
#define MMU_PTE_ATTR_NON_SECURE BM(5, 1, 1) #define MMU_PTE_ATTR_NON_SECURE BM(5, 1, 1)
#define MMU_PTE_ATTR_ATTR_INDEX(attrindex) BM(2, 3, attrindex) #define MMU_PTE_ATTR_ATTR_INDEX(attrindex) BM(2, 3, attrindex)
#define MMU_PTE_ATTR_ATTR_INDEX_MASK MMU_PTE_ATTR_ATTR_INDEX(7) #define MMU_PTE_ATTR_ATTR_INDEX_MASK MMU_PTE_ATTR_ATTR_INDEX(7)
/* Default configuration for main kernel page table: /* Default configuration for main kernel page table:
* - do cached translation walks * - do cached translation walks
*/ */
/* Device-nGnRnE memory */ /* Device-nGnRnE memory */
#define MMU_MAIR_ATTR0 MMU_MAIR_ATTR(0, 0x00) #define MMU_MAIR_ATTR0 MMU_MAIR_ATTR(0, 0x00)
#define MMU_PTE_ATTR_STRONGLY_ORDERED MMU_PTE_ATTR_ATTR_INDEX(0) #define MMU_PTE_ATTR_STRONGLY_ORDERED MMU_PTE_ATTR_ATTR_INDEX(0)
/* Device-nGnRE memory */ /* Device-nGnRE memory */
#define MMU_MAIR_ATTR1 MMU_MAIR_ATTR(1, 0x04) #define MMU_MAIR_ATTR1 MMU_MAIR_ATTR(1, 0x04)
#define MMU_PTE_ATTR_DEVICE MMU_PTE_ATTR_ATTR_INDEX(1) #define MMU_PTE_ATTR_DEVICE MMU_PTE_ATTR_ATTR_INDEX(1)
/* Normal Memory, Outer Write-back non-transient Read/Write allocate, /* Normal Memory, Outer Write-back non-transient Read/Write allocate,
* Inner Write-back non-transient Read/Write allocate * Inner Write-back non-transient Read/Write allocate
*/ */
#define MMU_MAIR_ATTR2 MMU_MAIR_ATTR(2, 0xff) #define MMU_MAIR_ATTR2 MMU_MAIR_ATTR(2, 0xff)
#define MMU_PTE_ATTR_NORMAL_MEMORY MMU_PTE_ATTR_ATTR_INDEX(2) #define MMU_PTE_ATTR_NORMAL_MEMORY MMU_PTE_ATTR_ATTR_INDEX(2)
#define MMU_MAIR_ATTR3 (0) #define MMU_MAIR_ATTR3 (0)
#define MMU_MAIR_ATTR4 (0) #define MMU_MAIR_ATTR4 (0)
#define MMU_MAIR_ATTR5 (0) #define MMU_MAIR_ATTR5 (0)
#define MMU_MAIR_ATTR6 (0) #define MMU_MAIR_ATTR6 (0)
#define MMU_MAIR_ATTR7 (0) #define MMU_MAIR_ATTR7 (0)
#define MMU_MAIR_VAL (MMU_MAIR_ATTR0 | MMU_MAIR_ATTR1 | \ #define MMU_MAIR_VAL (MMU_MAIR_ATTR0 | MMU_MAIR_ATTR1 | \
MMU_MAIR_ATTR2 | MMU_MAIR_ATTR3 | \ MMU_MAIR_ATTR2 | MMU_MAIR_ATTR3 | \
MMU_MAIR_ATTR4 | MMU_MAIR_ATTR5 | \ MMU_MAIR_ATTR4 | MMU_MAIR_ATTR5 | \
MMU_MAIR_ATTR6 | MMU_MAIR_ATTR7 ) MMU_MAIR_ATTR6 | MMU_MAIR_ATTR7)
/* Enable cached page table walks: /* Enable cached page table walks:
* inner/outer (IRGN/ORGN): write-back + write-allocate * inner/outer (IRGN/ORGN): write-back + write-allocate
*/ */
#define MMU_TCR_FLAGS1 (MMU_TCR_TG1(MMU_TG1(MMU_KERNEL_PAGE_SIZE_SHIFT)) | \ #define MMU_TCR_FLAGS1 (MMU_TCR_TG1(MMU_TG1(MMU_KERNEL_PAGE_SIZE_SHIFT)) | \
MMU_TCR_SH1(MMU_SH_INNER_SHAREABLE) | \ MMU_TCR_SH1(MMU_SH_INNER_SHAREABLE) | \
MMU_TCR_ORGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \ MMU_TCR_ORGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \
MMU_TCR_IRGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \ MMU_TCR_IRGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \
MMU_TCR_T1SZ(64 - MMU_KERNEL_SIZE_SHIFT)) MMU_TCR_T1SZ(64 - MMU_KERNEL_SIZE_SHIFT))
#define MMU_TCR_FLAGS0 (MMU_TCR_TG0(MMU_TG0(MMU_USER_PAGE_SIZE_SHIFT)) | \ #define MMU_TCR_FLAGS0 (MMU_TCR_TG0(MMU_TG0(MMU_USER_PAGE_SIZE_SHIFT)) | \
MMU_TCR_SH0(MMU_SH_INNER_SHAREABLE) | \ MMU_TCR_SH0(MMU_SH_INNER_SHAREABLE) | \
MMU_TCR_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \ MMU_TCR_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \ MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
MMU_TCR_T0SZ(64 - MMU_USER_SIZE_SHIFT)) MMU_TCR_T0SZ(64 - MMU_USER_SIZE_SHIFT))
#define MMU_TCR_FLAGS_BASE (MMU_TCR_FLAGS1 | MMU_TCR_FLAGS0) #define MMU_TCR_FLAGS_BASE (MMU_TCR_FLAGS1 | MMU_TCR_FLAGS0)
#define MMU_TCR_FLAGS_KERNEL (MMU_TCR_EPD0) #define MMU_TCR_FLAGS_KERNEL (MMU_TCR_EPD0)
#define MMU_TCR_FLAGS_USER (0) #define MMU_TCR_FLAGS_USER (0)
#define MMU_PTE_KERNEL_RO_FLAGS \ #define MMU_PTE_KERNEL_RO_FLAGS \
(MMU_PTE_ATTR_UXN | \ (MMU_PTE_ATTR_UXN | \
MMU_PTE_ATTR_AF | \ MMU_PTE_ATTR_AF | \
MMU_PTE_ATTR_SH_INNER_SHAREABLE | \ MMU_PTE_ATTR_SH_INNER_SHAREABLE | \
MMU_PTE_ATTR_NORMAL_MEMORY | \ MMU_PTE_ATTR_NORMAL_MEMORY | \
MMU_PTE_ATTR_AP_P_RO_U_NA) MMU_PTE_ATTR_AP_P_RO_U_NA)
#define MMU_PTE_KERNEL_DATA_FLAGS \ #define MMU_PTE_KERNEL_DATA_FLAGS \
(MMU_PTE_ATTR_UXN | \ (MMU_PTE_ATTR_UXN | \
MMU_PTE_ATTR_PXN | \ MMU_PTE_ATTR_PXN | \
MMU_PTE_ATTR_AF | \ MMU_PTE_ATTR_AF | \
MMU_PTE_ATTR_SH_INNER_SHAREABLE | \ MMU_PTE_ATTR_SH_INNER_SHAREABLE | \
MMU_PTE_ATTR_NORMAL_MEMORY | \ MMU_PTE_ATTR_NORMAL_MEMORY | \
MMU_PTE_ATTR_AP_P_RW_U_NA) MMU_PTE_ATTR_AP_P_RW_U_NA)
#define MMU_INITIAL_MAP_STRONGLY_ORDERED \ #define MMU_INITIAL_MAP_STRONGLY_ORDERED \
(MMU_PTE_ATTR_UXN | \ (MMU_PTE_ATTR_UXN | \
MMU_PTE_ATTR_PXN | \ MMU_PTE_ATTR_PXN | \
MMU_PTE_ATTR_AF | \ MMU_PTE_ATTR_AF | \
MMU_PTE_ATTR_STRONGLY_ORDERED | \ MMU_PTE_ATTR_STRONGLY_ORDERED | \
MMU_PTE_ATTR_AP_P_RW_U_NA) MMU_PTE_ATTR_AP_P_RW_U_NA)
#define MMU_INITIAL_MAP_DEVICE \ #define MMU_INITIAL_MAP_DEVICE \
(MMU_PTE_ATTR_UXN | \ (MMU_PTE_ATTR_UXN | \
MMU_PTE_ATTR_PXN | \ MMU_PTE_ATTR_PXN | \
MMU_PTE_ATTR_AF | \ MMU_PTE_ATTR_AF | \
MMU_PTE_ATTR_DEVICE | \ MMU_PTE_ATTR_DEVICE | \
MMU_PTE_ATTR_AP_P_RW_U_NA) MMU_PTE_ATTR_AP_P_RW_U_NA)
#ifndef ASSEMBLY #ifndef ASSEMBLY
#include <sys/types.h>
#include <assert.h>
#include <lk/compiler.h>
#include <arch/arm64.h> #include <arch/arm64.h>
#include <lk/compiler.h>
#include <sys/types.h>
typedef uint64_t pte_t; typedef uint64_t pte_t;
__BEGIN_CDECLS __BEGIN_CDECLS
#define ARM64_TLBI_NOADDR(op) \ #define ARM64_TLBI_NOADDR(op) \
({ \ ({ \
__asm__ volatile("tlbi " #op::); \ __asm__ volatile("tlbi " #op::); \
ISB; \ ISB; \
}) })
#define ARM64_TLBI(op, val) \ #define ARM64_TLBI(op, val) \
({ \ ({ \
__asm__ volatile("tlbi " #op ", %0" :: "r" (val)); \ __asm__ volatile("tlbi " #op ", %0" ::"r"(val)); \
ISB; \ ISB; \
}) })
#define MMU_ARM64_GLOBAL_ASID (~0U) #define MMU_ARM64_GLOBAL_ASID (~0U)
#define MMU_ARM64_USER_ASID (0U) #define MMU_ARM64_USER_ASID (0U)
int arm64_mmu_map(vaddr_t vaddr, paddr_t paddr, size_t size, pte_t attrs, int arm64_mmu_map(vaddr_t vaddr, paddr_t paddr, size_t size, pte_t attrs,
vaddr_t vaddr_base, uint top_size_shift, vaddr_t vaddr_base, uint top_size_shift,
uint top_index_shift, uint page_size_shift, uint top_index_shift, uint page_size_shift,

View File

@@ -18,14 +18,8 @@ MODULE_SRCS += \
$(LOCAL_DIR)/start.S \ $(LOCAL_DIR)/start.S \
$(LOCAL_DIR)/cache-ops.S \ $(LOCAL_DIR)/cache-ops.S \
# $(LOCAL_DIR)/arm/start.S \ # if its requested we build with SMP, default to 4 cpus
$(LOCAL_DIR)/arm/cache.c \ ifeq (true,$(call TOBOOL,$(WITH_SMP)))
$(LOCAL_DIR)/arm/ops.S \
$(LOCAL_DIR)/arm/faults.c \
$(LOCAL_DIR)/arm/dcc.S
# if its requested we build with SMP, arm generically supports 4 cpus
ifeq ($(WITH_SMP),1)
SMP_MAX_CPUS ?= 4 SMP_MAX_CPUS ?= 4
SMP_CPU_CLUSTER_SHIFT ?= 8 SMP_CPU_CLUSTER_SHIFT ?= 8
SMP_CPU_ID_BITS ?= 24 # Ignore aff3 bits for now since they are not next to aff2 SMP_CPU_ID_BITS ?= 24 # Ignore aff3 bits for now since they are not next to aff2
@@ -48,15 +42,32 @@ ARCH_OPTFLAGS := -O2
# we have a mmu and want the vmm/pmm # we have a mmu and want the vmm/pmm
WITH_KERNEL_VM ?= 1 WITH_KERNEL_VM ?= 1
ifeq ($(WITH_KERNEL_VM),1) ifeq (true,$(call TOBOOL,$(WITH_KERNEL_VM)))
MODULE_SRCS += \ MODULE_SRCS += \
$(LOCAL_DIR)/mmu.c $(LOCAL_DIR)/mmu.c
ARM64_PAGE_SIZE ?= 4096
# platform/target/project is allowed to override the page size the kernel
# and user space will run at.
ifeq ($(ARM64_PAGE_SIZE), 4096)
KERNEL_ASPACE_BASE ?= 0xffff000000000000 KERNEL_ASPACE_BASE ?= 0xffff000000000000
KERNEL_ASPACE_SIZE ?= 0x0001000000000000 KERNEL_ASPACE_SIZE ?= 0x0001000000000000
USER_ASPACE_BASE ?= 0x0000000001000000 USER_ASPACE_BASE ?= 0x0000000001000000
USER_ASPACE_SIZE ?= 0x0000fffffe000000 USER_ASPACE_SIZE ?= 0x0000fffffe000000
else ifeq ($(ARM64_PAGE_SIZE), 16384)
GLOBAL_DEFINES += ARM64_LARGE_PAGESIZE_16K=1
KERNEL_ASPACE_BASE ?= 0xffff800000000000
KERNEL_ASPACE_SIZE ?= 0x0000800000000000
USER_ASPACE_BASE ?= 0x0000000001000000
USER_ASPACE_SIZE ?= 0x00007ffffe000000
else ifeq ($(ARM64_PAGE_SIZE), 65536)
GLOBAL_DEFINES += ARM64_LARGE_PAGESIZE_64K=1
$(error fix for 64k)
else
$(error unsupported ARM64_PAGE_SIZE)
endif
GLOBAL_DEFINES += \ GLOBAL_DEFINES += \
KERNEL_ASPACE_BASE=$(KERNEL_ASPACE_BASE) \ KERNEL_ASPACE_BASE=$(KERNEL_ASPACE_BASE) \
@@ -68,17 +79,17 @@ GLOBAL_DEFINES += \
KERNEL_BASE ?= $(KERNEL_ASPACE_BASE) KERNEL_BASE ?= $(KERNEL_ASPACE_BASE)
KERNEL_LOAD_OFFSET ?= 0 KERNEL_LOAD_OFFSET ?= 0
GLOBAL_DEFINES += \ else # !WITH_KERNEL_VM
KERNEL_BASE=$(KERNEL_BASE) \
KERNEL_LOAD_OFFSET=$(KERNEL_LOAD_OFFSET)
else
KERNEL_BASE ?= $(MEMBASE) KERNEL_BASE ?= $(MEMBASE)
KERNEL_LOAD_OFFSET ?= 0 KERNEL_LOAD_OFFSET ?= 0
endif endif
GLOBAL_DEFINES += \
KERNEL_BASE=$(KERNEL_BASE) \
KERNEL_LOAD_OFFSET=$(KERNEL_LOAD_OFFSET)
GLOBAL_DEFINES += \ GLOBAL_DEFINES += \
MEMBASE=$(MEMBASE) \ MEMBASE=$(MEMBASE) \
MEMSIZE=$(MEMSIZE) MEMSIZE=$(MEMSIZE)
@@ -92,7 +103,7 @@ ARCH_COMPILEFLAGS += -fno-omit-frame-pointer
ARCH_COMPILEFLAGS_NOFLOAT := -mgeneral-regs-only ARCH_COMPILEFLAGS_NOFLOAT := -mgeneral-regs-only
ARCH_COMPILEFLAGS_FLOAT := ARCH_COMPILEFLAGS_FLOAT :=
ARCH_LDFLAGS += -z max-page-size=4096 ARCH_LDFLAGS += -z max-page-size=$(ARM64_PAGE_SIZE)
LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) -print-libgcc-file-name) LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) -print-libgcc-file-name)

View File

@@ -51,7 +51,7 @@ SECTIONS
__code_end = .; __code_end = .;
} }
.rodata : ALIGN(4096) { .rodata : ALIGN(CONSTANT(MAXPAGESIZE)) {
__rodata_start = .; __rodata_start = .;
__fault_handler_table_start = .; __fault_handler_table_start = .;
KEEP(*(.rodata.fault_handler_table)) KEEP(*(.rodata.fault_handler_table))
@@ -68,7 +68,7 @@ SECTIONS
__rodata_end = .; __rodata_end = .;
} }
.data : ALIGN(4096) { .data : ALIGN(CONSTANT(MAXPAGESIZE)) {
/* writable data */ /* writable data */
__data_start_rom = .; __data_start_rom = .;
/* in one segment binaries, the rom data address is on top of the ram data address */ /* in one segment binaries, the rom data address is on top of the ram data address */
@@ -99,7 +99,7 @@ SECTIONS
} }
/* unintialized data (in same segment as writable data) */ /* unintialized data (in same segment as writable data) */
.bss : ALIGN(4096) { .bss : ALIGN(CONSTANT(MAXPAGESIZE)) {
__bss_start = .; __bss_start = .;
KEEP(*(.bss.prebss.*)) KEEP(*(.bss.prebss.*))
. = ALIGN(8); . = ALIGN(8);
@@ -112,7 +112,7 @@ SECTIONS
} }
/* Align the end to ensure anything after the kernel ends up on its own pages */ /* Align the end to ensure anything after the kernel ends up on its own pages */
. = ALIGN(4096); . = ALIGN(CONSTANT(MAXPAGESIZE));
_end = .; _end = .;
. = %KERNEL_BASE% + %MEMSIZE%; . = %KERNEL_BASE% + %MEMSIZE%;

View File

@@ -18,6 +18,7 @@
#include "io_stack.h" #include "io_stack.h"
#include <kernel/vm.h> #include <kernel/vm.h>
#include <stdio.h>
void *get_io_stack() { void *get_io_stack() {
static void *io_stack = nullptr; static void *io_stack = nullptr;

View File

@@ -0,0 +1,12 @@
# main project for qemu-aarch64
MODULES += \
app/shell \
lib/uefi \
ARM64_PAGE_SIZE := 16384
include project/virtual/test.mk
include project/virtual/fs.mk
include project/virtual/minip.mk
include project/target/qemu-virt-arm64.mk

View File

@@ -1,7 +1,7 @@
# main project for qemu-aarch64 # main project for qemu-aarch64
MODULES += \ MODULES += \
app/shell \ app/shell \
lib/uefi \ lib/uefi \
include project/virtual/test.mk include project/virtual/test.mk
include project/virtual/fs.mk include project/virtual/fs.mk

View File

@@ -22,8 +22,10 @@ esac
function HELP { function HELP {
echo "help:" echo "help:"
echo "-p <project> : specify the project to build (default qemu-virt-arm32-test, qemu-virt-arm64-test or lm3s6965evb-test)"
echo "-6 : 64bit arm" echo "-6 : 64bit arm"
echo "-3 : cortex-m3 based platform" echo "-3 : cortex-m3 based platform"
echo "-P <page size> : set the page size (default: 4K)"
echo "-v : boot kernel at EL2" echo "-v : boot kernel at EL2"
echo "-k : use KVM or HVF acceleration if present (only on 64bit)" echo "-k : use KVM or HVF acceleration if present (only on 64bit)"
echo "-m <memory in MB>" echo "-m <memory in MB>"
@@ -46,7 +48,7 @@ function HELP {
DO_NET=0 DO_NET=0
DO_NET_TAP=0 DO_NET_TAP=0
DO_DISK=0 DO_DISK=0
DO_DISK_IMAGE="" DISK_IMAGE=""
DO_64BIT=0 DO_64BIT=0
DO_VIRT=0 DO_VIRT=0
DO_CORTEX_M3=0 DO_CORTEX_M3=0
@@ -56,12 +58,13 @@ DO_CMPCTMALLOC=0
DO_MINIHEAP=0 DO_MINIHEAP=0
DO_V9P=0 DO_V9P=0
DO_V9P_DIR="" DO_V9P_DIR=""
PAGE_SIZE=4096
SMP=1 SMP=1
MEMSIZE=512 MEMSIZE=512
SUDO="" SUDO=""
PROJECT="" PROJECT=""
while getopts cd:ghkm:Mnt36vp:s:f: FLAG; do while getopts cd:ghkm:Mnt36vp:P:s:f: FLAG; do
case $FLAG in case $FLAG in
c) DO_CMPCTMALLOC=1;; c) DO_CMPCTMALLOC=1;;
d) DO_DISK=1; DISK_IMAGE=$OPTARG;; d) DO_DISK=1; DISK_IMAGE=$OPTARG;;
@@ -77,6 +80,7 @@ while getopts cd:ghkm:Mnt36vp:s:f: FLAG; do
m) MEMSIZE=$OPTARG;; m) MEMSIZE=$OPTARG;;
s) SMP=$OPTARG;; s) SMP=$OPTARG;;
p) PROJECT=$OPTARG;; p) PROJECT=$OPTARG;;
P) PAGE_SIZE=$OPTARG;;
h) HELP;; h) HELP;;
\?) \?)
echo unrecognized option echo unrecognized option
@@ -89,7 +93,7 @@ shift $((OPTIND-1))
# pick the appropriate qemu and project # pick the appropriate qemu and project
if [ $DO_64BIT == 1 ]; then if [ $DO_64BIT == 1 ]; then
QEMU="qemu-system-aarch64" QEMU="qemu-system-aarch64"
CPU="cortex-a53" CPU="cortex-a76"
MACHINE="virt" MACHINE="virt"
if [ $DO_KVM == 1 ]; then if [ $DO_KVM == 1 ]; then
CPU="host" CPU="host"
@@ -101,7 +105,11 @@ if [ $DO_64BIT == 1 ]; then
elif [ $DO_VIRT == 1 ]; then elif [ $DO_VIRT == 1 ]; then
MACHINE+=",virtualization=on" MACHINE+=",virtualization=on"
fi fi
_PROJECT="qemu-virt-arm64-test" if [ $PAGE_SIZE == 16384 ]; then
_PROJECT="qemu-virt-arm64-16k-test"
else
_PROJECT="qemu-virt-arm64-test"
fi
elif [ $DO_CORTEX_M3 == 1 ]; then elif [ $DO_CORTEX_M3 == 1 ]; then
QEMU="qemu-system-arm" QEMU="qemu-system-arm"
CPU="cortex-m3" CPU="cortex-m3"