From fff0f2a74053bee376c7e98eeaa1efba32d8ec1a Mon Sep 17 00:00:00 2001 From: Travis Geiselbrecht Date: Sun, 31 Aug 2025 20:54:56 -0700 Subject: [PATCH] [arch][arm64] add support for 16k pages --- arch/arm64/arch.c | 1 + arch/arm64/include/arch/arm64/mmu.h | 247 ++++++++++++++-------------- arch/arm64/rules.mk | 41 +++-- arch/arm64/system-onesegment.ld | 8 +- lib/uefi/io_stack.cpp | 1 + project/qemu-virt-arm64-16k-test.mk | 12 ++ project/qemu-virt-arm64-test.mk | 2 +- scripts/do-qemuarm | 16 +- 8 files changed, 180 insertions(+), 148 deletions(-) create mode 100644 project/qemu-virt-arm64-16k-test.mk diff --git a/arch/arm64/arch.c b/arch/arm64/arch.c index 5aef7c3f..4365dffb 100644 --- a/arch/arm64/arch.c +++ b/arch/arm64/arch.c @@ -18,6 +18,7 @@ #include #include #include +#include #define LOCAL_TRACE 0 diff --git a/arch/arm64/include/arch/arm64/mmu.h b/arch/arm64/include/arch/arm64/mmu.h index 35bb3ca8..4655c174 100644 --- a/arch/arm64/include/arch/arm64/mmu.h +++ b/arch/arm64/include/arch/arm64/mmu.h @@ -11,18 +11,19 @@ #include -#define IFTE(c,t,e) (!!(c) * (t) | !(c) * (e)) -#define NBITS01(n) IFTE(n, 1, 0) -#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 NBITS08(n) IFTE((n) >> 4, 4 + NBITS04((n) >> 4), NBITS04(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 NBITS(n) IFTE((n) >> 32, 32 + NBITS32((n) >> 32), NBITS32(n)) +#define IFTE(c, t, e) (!!(c) * (t) | !(c) * (e)) +#define NBITS01(n) IFTE(n, 1, 0) +#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 NBITS08(n) IFTE((n) >> 4, 4 + NBITS04((n) >> 4), NBITS04(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 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 -#define KERNEL_ASPACE_BITS (NBITS(0xffffffffffffffff-KERNEL_ASPACE_BASE)) -#define KERNEL_BASE_BITS (NBITS(0xffffffffffffffff-KERNEL_BASE)) +#define KERNEL_ASPACE_BITS (NBITS(0xffffffffffffffff - KERNEL_ASPACE_BASE)) +#define KERNEL_BASE_BITS (NBITS(0xffffffffffffffff - KERNEL_BASE)) #if KERNEL_BASE_BITS > KERNEL_ASPACE_BITS #define KERNEL_ASPACE_BITS KERNEL_BASE_BITS /* KERNEL_BASE should not be below KERNEL_ASPACE_BASE */ #endif @@ -35,11 +36,11 @@ #endif #ifndef MMU_USER_SIZE_SHIFT -#define MMU_USER_SIZE_SHIFT 48 +#define MMU_USER_SIZE_SHIFT MMU_KERNEL_SIZE_SHIFT #endif -#define MMU_KERNEL_PAGE_SIZE_SHIFT (PAGE_SIZE_SHIFT) -#define MMU_USER_PAGE_SIZE_SHIFT (USER_PAGE_SIZE_SHIFT) +#define MMU_KERNEL_PAGE_SIZE_SHIFT (PAGE_SIZE_SHIFT) +#define MMU_USER_PAGE_SIZE_SHIFT (USER_PAGE_SIZE_SHIFT) /* * TCR TGx values @@ -53,8 +54,8 @@ ((page_size_shift == 16) & 1)) #define MMU_TG1(page_size_shift) ((((page_size_shift == 12) & 1) << 1) | \ - ((page_size_shift == 14) & 1) | \ - ((page_size_shift == 16) & 1) | \ + ((page_size_shift == 14) & 1) | \ + ((page_size_shift == 16) & 1) | \ (((page_size_shift == 16) & 1) << 1)) #define MMU_LX_X(page_shift, level) ((4 - (level)) * ((page_shift) - 3) + 3) @@ -85,7 +86,7 @@ #endif #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 #define BM(base, count, val) (((val) & ((1UL << (count)) - 1)) << (base)) @@ -93,181 +94,179 @@ #define BM(base, count, val) (((val) & ((0x1 << (count)) - 1)) << (base)) #endif -#define MMU_SH_NON_SHAREABLE (0) -#define MMU_SH_OUTER_SHAREABLE (2) -#define MMU_SH_INNER_SHAREABLE (3) +#define MMU_SH_NON_SHAREABLE (0) +#define MMU_SH_OUTER_SHAREABLE (2) +#define MMU_SH_INNER_SHAREABLE (3) -#define MMU_RGN_NON_CACHEABLE (0) -#define MMU_RGN_WRITE_BACK_ALLOCATE (1) -#define MMU_RGN_WRITE_THROUGH_NO_ALLOCATE (2) -#define MMU_RGN_WRITE_BACK_NO_ALLOCATE (3) +#define MMU_RGN_NON_CACHEABLE (0) +#define MMU_RGN_WRITE_BACK_ALLOCATE (1) +#define MMU_RGN_WRITE_THROUGH_NO_ALLOCATE (2) +#define MMU_RGN_WRITE_BACK_NO_ALLOCATE (3) -#define MMU_TCR_TBI1 BM(38, 1, 1) -#define MMU_TCR_TBI0 BM(37, 1, 1) -#define MMU_TCR_AS BM(36, 1, 1) -#define MMU_TCR_IPS(size) BM(32, 3, (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_ORGN1(cache_flags) BM(26, 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_A1 BM(22, 1, 1) -#define MMU_TCR_T1SZ(size) BM(16, 6, (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_ORGN0(cache_flags) BM(10, 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_T0SZ(size) BM( 0, 6, (size)) - -#define MMU_MAIR_ATTR(index, attr) BM(index * 8, 8, (attr)) +#define MMU_TCR_TBI1 BM(38, 1, 1) +#define MMU_TCR_TBI0 BM(37, 1, 1) +#define MMU_TCR_AS BM(36, 1, 1) +#define MMU_TCR_IPS(size) BM(32, 3, (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_ORGN1(cache_flags) BM(26, 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_A1 BM(22, 1, 1) +#define MMU_TCR_T1SZ(size) BM(16, 6, (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_ORGN0(cache_flags) BM(10, 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_T0SZ(size) BM(0, 6, (size)) +#define MMU_MAIR_ATTR(index, attr) BM(index * 8, 8, (attr)) /* L0/L1/L2/L3 descriptor types */ -#define MMU_PTE_DESCRIPTOR_INVALID BM(0, 2, 0) -#define MMU_PTE_DESCRIPTOR_MASK BM(0, 2, 3) +#define MMU_PTE_DESCRIPTOR_INVALID BM(0, 2, 0) +#define MMU_PTE_DESCRIPTOR_MASK BM(0, 2, 3) /* L0/L1/L2 descriptor types */ -#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_BLOCK BM(0, 2, 1) +#define MMU_PTE_L012_DESCRIPTOR_TABLE BM(0, 2, 3) /* 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 */ -#define MMU_PTE_OUTPUT_ADDR_MASK BM(12, 36, 0xfffffffff) +#define MMU_PTE_OUTPUT_ADDR_MASK BM(12, 36, 0xfffffffff) /* Table attrs */ -#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_EL0 BM(61, 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_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_EL0 BM(61, 1, 1) +#define MMU_PTE_ATTR_UXN_TABLE BM(60, 1, 1) +#define MMU_PTE_ATTR_PXN_TABLE BM(59, 1, 1) /* Block/Page attrs */ -#define MMU_PTE_ATTR_RES_SOFTWARE BM(55, 4, 0xf) -#define MMU_PTE_ATTR_UXN BM(54, 1, 1) -#define MMU_PTE_ATTR_PXN BM(53, 1, 1) -#define MMU_PTE_ATTR_CONTIGUOUS BM(52, 1, 1) +#define MMU_PTE_ATTR_RES_SOFTWARE BM(55, 4, 0xf) +#define MMU_PTE_ATTR_UXN BM(54, 1, 1) +#define MMU_PTE_ATTR_PXN BM(53, 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_AF BM(10, 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_SH_NON_SHAREABLE BM(8, 2, 0) -#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_NON_SHAREABLE BM(8, 2, 0) +#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_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_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_MASK BM(6, 2, 3) +#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_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_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_MASK MMU_PTE_ATTR_ATTR_INDEX(7) +#define MMU_PTE_ATTR_ATTR_INDEX(attrindex) BM(2, 3, attrindex) +#define MMU_PTE_ATTR_ATTR_INDEX_MASK MMU_PTE_ATTR_ATTR_INDEX(7) /* Default configuration for main kernel page table: * - do cached translation walks */ /* Device-nGnRnE memory */ -#define MMU_MAIR_ATTR0 MMU_MAIR_ATTR(0, 0x00) -#define MMU_PTE_ATTR_STRONGLY_ORDERED MMU_PTE_ATTR_ATTR_INDEX(0) +#define MMU_MAIR_ATTR0 MMU_MAIR_ATTR(0, 0x00) +#define MMU_PTE_ATTR_STRONGLY_ORDERED MMU_PTE_ATTR_ATTR_INDEX(0) /* Device-nGnRE memory */ -#define MMU_MAIR_ATTR1 MMU_MAIR_ATTR(1, 0x04) -#define MMU_PTE_ATTR_DEVICE MMU_PTE_ATTR_ATTR_INDEX(1) +#define MMU_MAIR_ATTR1 MMU_MAIR_ATTR(1, 0x04) +#define MMU_PTE_ATTR_DEVICE MMU_PTE_ATTR_ATTR_INDEX(1) /* Normal Memory, Outer 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_PTE_ATTR_NORMAL_MEMORY MMU_PTE_ATTR_ATTR_INDEX(2) +#define MMU_MAIR_ATTR2 MMU_MAIR_ATTR(2, 0xff) +#define MMU_PTE_ATTR_NORMAL_MEMORY MMU_PTE_ATTR_ATTR_INDEX(2) -#define MMU_MAIR_ATTR3 (0) -#define MMU_MAIR_ATTR4 (0) -#define MMU_MAIR_ATTR5 (0) -#define MMU_MAIR_ATTR6 (0) -#define MMU_MAIR_ATTR7 (0) +#define MMU_MAIR_ATTR3 (0) +#define MMU_MAIR_ATTR4 (0) +#define MMU_MAIR_ATTR5 (0) +#define MMU_MAIR_ATTR6 (0) +#define MMU_MAIR_ATTR7 (0) -#define MMU_MAIR_VAL (MMU_MAIR_ATTR0 | MMU_MAIR_ATTR1 | \ - MMU_MAIR_ATTR2 | MMU_MAIR_ATTR3 | \ - MMU_MAIR_ATTR4 | MMU_MAIR_ATTR5 | \ - MMU_MAIR_ATTR6 | MMU_MAIR_ATTR7 ) +#define MMU_MAIR_VAL (MMU_MAIR_ATTR0 | MMU_MAIR_ATTR1 | \ + MMU_MAIR_ATTR2 | MMU_MAIR_ATTR3 | \ + MMU_MAIR_ATTR4 | MMU_MAIR_ATTR5 | \ + MMU_MAIR_ATTR6 | MMU_MAIR_ATTR7) /* Enable cached page table walks: * inner/outer (IRGN/ORGN): write-back + write-allocate */ #define MMU_TCR_FLAGS1 (MMU_TCR_TG1(MMU_TG1(MMU_KERNEL_PAGE_SIZE_SHIFT)) | \ - MMU_TCR_SH1(MMU_SH_INNER_SHAREABLE) | \ - MMU_TCR_ORGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \ - MMU_TCR_IRGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \ + MMU_TCR_SH1(MMU_SH_INNER_SHAREABLE) | \ + MMU_TCR_ORGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \ + MMU_TCR_IRGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \ MMU_TCR_T1SZ(64 - MMU_KERNEL_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_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \ - MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \ + MMU_TCR_SH0(MMU_SH_INNER_SHAREABLE) | \ + MMU_TCR_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \ + MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \ 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_USER (0) +#define MMU_TCR_FLAGS_USER (0) -#define MMU_PTE_KERNEL_RO_FLAGS \ - (MMU_PTE_ATTR_UXN | \ - MMU_PTE_ATTR_AF | \ +#define MMU_PTE_KERNEL_RO_FLAGS \ + (MMU_PTE_ATTR_UXN | \ + MMU_PTE_ATTR_AF | \ MMU_PTE_ATTR_SH_INNER_SHAREABLE | \ - MMU_PTE_ATTR_NORMAL_MEMORY | \ + MMU_PTE_ATTR_NORMAL_MEMORY | \ MMU_PTE_ATTR_AP_P_RO_U_NA) -#define MMU_PTE_KERNEL_DATA_FLAGS \ - (MMU_PTE_ATTR_UXN | \ - MMU_PTE_ATTR_PXN | \ - MMU_PTE_ATTR_AF | \ +#define MMU_PTE_KERNEL_DATA_FLAGS \ + (MMU_PTE_ATTR_UXN | \ + MMU_PTE_ATTR_PXN | \ + MMU_PTE_ATTR_AF | \ MMU_PTE_ATTR_SH_INNER_SHAREABLE | \ - MMU_PTE_ATTR_NORMAL_MEMORY | \ + MMU_PTE_ATTR_NORMAL_MEMORY | \ MMU_PTE_ATTR_AP_P_RW_U_NA) #define MMU_INITIAL_MAP_STRONGLY_ORDERED \ - (MMU_PTE_ATTR_UXN | \ - MMU_PTE_ATTR_PXN | \ - MMU_PTE_ATTR_AF | \ - MMU_PTE_ATTR_STRONGLY_ORDERED | \ + (MMU_PTE_ATTR_UXN | \ + MMU_PTE_ATTR_PXN | \ + MMU_PTE_ATTR_AF | \ + MMU_PTE_ATTR_STRONGLY_ORDERED | \ MMU_PTE_ATTR_AP_P_RW_U_NA) #define MMU_INITIAL_MAP_DEVICE \ - (MMU_PTE_ATTR_UXN | \ - MMU_PTE_ATTR_PXN | \ - MMU_PTE_ATTR_AF | \ - MMU_PTE_ATTR_DEVICE | \ + (MMU_PTE_ATTR_UXN | \ + MMU_PTE_ATTR_PXN | \ + MMU_PTE_ATTR_AF | \ + MMU_PTE_ATTR_DEVICE | \ MMU_PTE_ATTR_AP_P_RW_U_NA) #ifndef ASSEMBLY -#include -#include -#include #include +#include +#include typedef uint64_t pte_t; __BEGIN_CDECLS -#define ARM64_TLBI_NOADDR(op) \ -({ \ - __asm__ volatile("tlbi " #op::); \ - ISB; \ -}) +#define ARM64_TLBI_NOADDR(op) \ + ({ \ + __asm__ volatile("tlbi " #op::); \ + ISB; \ + }) -#define ARM64_TLBI(op, val) \ -({ \ - __asm__ volatile("tlbi " #op ", %0" :: "r" (val)); \ - ISB; \ -}) +#define ARM64_TLBI(op, val) \ + ({ \ + __asm__ volatile("tlbi " #op ", %0" ::"r"(val)); \ + ISB; \ + }) #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, vaddr_t vaddr_base, uint top_size_shift, uint top_index_shift, uint page_size_shift, diff --git a/arch/arm64/rules.mk b/arch/arm64/rules.mk index fbeb3fa7..deb01ab1 100644 --- a/arch/arm64/rules.mk +++ b/arch/arm64/rules.mk @@ -18,14 +18,8 @@ MODULE_SRCS += \ $(LOCAL_DIR)/start.S \ $(LOCAL_DIR)/cache-ops.S \ -# $(LOCAL_DIR)/arm/start.S \ - $(LOCAL_DIR)/arm/cache.c \ - $(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) +# if its requested we build with SMP, default to 4 cpus +ifeq (true,$(call TOBOOL,$(WITH_SMP))) SMP_MAX_CPUS ?= 4 SMP_CPU_CLUSTER_SHIFT ?= 8 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 WITH_KERNEL_VM ?= 1 -ifeq ($(WITH_KERNEL_VM),1) +ifeq (true,$(call TOBOOL,$(WITH_KERNEL_VM))) MODULE_SRCS += \ $(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_SIZE ?= 0x0001000000000000 USER_ASPACE_BASE ?= 0x0000000001000000 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 += \ KERNEL_ASPACE_BASE=$(KERNEL_ASPACE_BASE) \ @@ -68,17 +79,17 @@ GLOBAL_DEFINES += \ KERNEL_BASE ?= $(KERNEL_ASPACE_BASE) KERNEL_LOAD_OFFSET ?= 0 -GLOBAL_DEFINES += \ - KERNEL_BASE=$(KERNEL_BASE) \ - KERNEL_LOAD_OFFSET=$(KERNEL_LOAD_OFFSET) - -else +else # !WITH_KERNEL_VM KERNEL_BASE ?= $(MEMBASE) KERNEL_LOAD_OFFSET ?= 0 endif +GLOBAL_DEFINES += \ + KERNEL_BASE=$(KERNEL_BASE) \ + KERNEL_LOAD_OFFSET=$(KERNEL_LOAD_OFFSET) + GLOBAL_DEFINES += \ MEMBASE=$(MEMBASE) \ MEMSIZE=$(MEMSIZE) @@ -92,7 +103,7 @@ ARCH_COMPILEFLAGS += -fno-omit-frame-pointer ARCH_COMPILEFLAGS_NOFLOAT := -mgeneral-regs-only 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) diff --git a/arch/arm64/system-onesegment.ld b/arch/arm64/system-onesegment.ld index 41aa397a..0ccf092c 100644 --- a/arch/arm64/system-onesegment.ld +++ b/arch/arm64/system-onesegment.ld @@ -51,7 +51,7 @@ SECTIONS __code_end = .; } - .rodata : ALIGN(4096) { + .rodata : ALIGN(CONSTANT(MAXPAGESIZE)) { __rodata_start = .; __fault_handler_table_start = .; KEEP(*(.rodata.fault_handler_table)) @@ -68,7 +68,7 @@ SECTIONS __rodata_end = .; } - .data : ALIGN(4096) { + .data : ALIGN(CONSTANT(MAXPAGESIZE)) { /* writable data */ __data_start_rom = .; /* 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) */ - .bss : ALIGN(4096) { + .bss : ALIGN(CONSTANT(MAXPAGESIZE)) { __bss_start = .; KEEP(*(.bss.prebss.*)) . = ALIGN(8); @@ -112,7 +112,7 @@ SECTIONS } /* Align the end to ensure anything after the kernel ends up on its own pages */ - . = ALIGN(4096); + . = ALIGN(CONSTANT(MAXPAGESIZE)); _end = .; . = %KERNEL_BASE% + %MEMSIZE%; diff --git a/lib/uefi/io_stack.cpp b/lib/uefi/io_stack.cpp index 69c29303..543007ae 100644 --- a/lib/uefi/io_stack.cpp +++ b/lib/uefi/io_stack.cpp @@ -18,6 +18,7 @@ #include "io_stack.h" #include +#include void *get_io_stack() { static void *io_stack = nullptr; diff --git a/project/qemu-virt-arm64-16k-test.mk b/project/qemu-virt-arm64-16k-test.mk new file mode 100644 index 00000000..6da4afe7 --- /dev/null +++ b/project/qemu-virt-arm64-16k-test.mk @@ -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 + diff --git a/project/qemu-virt-arm64-test.mk b/project/qemu-virt-arm64-test.mk index bec3098c..d3dd6cef 100644 --- a/project/qemu-virt-arm64-test.mk +++ b/project/qemu-virt-arm64-test.mk @@ -1,7 +1,7 @@ # main project for qemu-aarch64 MODULES += \ app/shell \ - lib/uefi \ + lib/uefi \ include project/virtual/test.mk include project/virtual/fs.mk diff --git a/scripts/do-qemuarm b/scripts/do-qemuarm index e553567d..a574a686 100755 --- a/scripts/do-qemuarm +++ b/scripts/do-qemuarm @@ -22,8 +22,10 @@ esac function HELP { echo "help:" + echo "-p : specify the project to build (default qemu-virt-arm32-test, qemu-virt-arm64-test or lm3s6965evb-test)" echo "-6 : 64bit arm" echo "-3 : cortex-m3 based platform" + echo "-P : set the page size (default: 4K)" echo "-v : boot kernel at EL2" echo "-k : use KVM or HVF acceleration if present (only on 64bit)" echo "-m " @@ -46,7 +48,7 @@ function HELP { DO_NET=0 DO_NET_TAP=0 DO_DISK=0 -DO_DISK_IMAGE="" +DISK_IMAGE="" DO_64BIT=0 DO_VIRT=0 DO_CORTEX_M3=0 @@ -56,12 +58,13 @@ DO_CMPCTMALLOC=0 DO_MINIHEAP=0 DO_V9P=0 DO_V9P_DIR="" +PAGE_SIZE=4096 SMP=1 MEMSIZE=512 SUDO="" PROJECT="" -while getopts cd:ghkm:Mnt36vp:s:f: FLAG; do +while getopts cd:ghkm:Mnt36vp:P:s:f: FLAG; do case $FLAG in c) DO_CMPCTMALLOC=1;; d) DO_DISK=1; DISK_IMAGE=$OPTARG;; @@ -77,6 +80,7 @@ while getopts cd:ghkm:Mnt36vp:s:f: FLAG; do m) MEMSIZE=$OPTARG;; s) SMP=$OPTARG;; p) PROJECT=$OPTARG;; + P) PAGE_SIZE=$OPTARG;; h) HELP;; \?) echo unrecognized option @@ -89,7 +93,7 @@ shift $((OPTIND-1)) # pick the appropriate qemu and project if [ $DO_64BIT == 1 ]; then QEMU="qemu-system-aarch64" - CPU="cortex-a53" + CPU="cortex-a76" MACHINE="virt" if [ $DO_KVM == 1 ]; then CPU="host" @@ -101,7 +105,11 @@ if [ $DO_64BIT == 1 ]; then elif [ $DO_VIRT == 1 ]; then MACHINE+=",virtualization=on" 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 QEMU="qemu-system-arm" CPU="cortex-m3"