diff --git a/headers/private/system/arch/arm/arch_cpu_defs.h b/headers/private/system/arch/arm/arch_cpu_defs.h index c7c6f17ece..53c580a089 100644 --- a/headers/private/system/arch/arm/arch_cpu_defs.h +++ b/headers/private/system/arch/arm/arch_cpu_defs.h @@ -24,6 +24,8 @@ #define CPSR_F 0x40 #define CPSR_I 0x80 +#define SCTLR_HIGH_VECTORS 0x00002000 + #define FSR_WNR 0x800 #define FSR_LPAE 0x200 diff --git a/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp b/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp index 57cf3abb48..38fd96cf4f 100644 --- a/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp @@ -35,6 +35,8 @@ static constexpr bool kTracePageDirectory = false; #define PHYSICAL_MEMORY_LOW 0x00000000 #define PHYSICAL_MEMORY_HIGH 0x8000000000ull +#define USER_VECTOR_ADDR_HIGH 0xffff0000 + #define ALIGN_PAGEDIR (1024 * 16) #define MAX_PAGE_TABLES 192 #define PAGE_TABLE_AREA_SIZE (MAX_PAGE_TABLES * ARM_MMU_L2_COARSE_TABLE_SIZE) @@ -42,6 +44,7 @@ static constexpr bool kTracePageDirectory = false; static uint32_t *sPageDirectory = NULL; static uint32_t *sNextPageTable = NULL; static uint32_t *sLastPageTable = NULL; +static uint32_t *sVectorTable = (uint32_t*)USER_VECTOR_ADDR_HIGH; static void @@ -232,12 +235,23 @@ arch_mmu_allocate_page_tables(void) } +static void +arch_mmu_allocate_vector_table(void) +{ + if (platform_allocate_region((void **)&sVectorTable, B_PAGE_SIZE, 0, false) != B_OK) + panic("Failed to allocate vector table."); + + memset(sVectorTable, 0, B_PAGE_SIZE); +} + + uint32_t arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize, efi_memory_descriptor *memoryMap, size_t descriptorSize, uint32_t descriptorVersion) { arch_mmu_allocate_page_tables(); + arch_mmu_allocate_vector_table(); build_physical_memory_list(memoryMapSize, memoryMap, descriptorSize, descriptorVersion, diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp index 872f63cbfb..31be5687f6 100644 --- a/src/system/kernel/arch/arm/arch_int.cpp +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -60,8 +60,6 @@ extern int _vectors_start; extern int _vectors_end; -static area_id sVectorPageArea; -static void *sVectorPageAddress; static area_id sUserVectorPageArea; static void *sUserVectorPageAddress; //static fdt_module_info *sFdtModule; @@ -120,52 +118,40 @@ print_iframe(const char *event, struct iframe *frame) } +extern "C" void arm_vector_init(void); + + status_t arch_int_init(kernel_args *args) { + TRACE("arch_int_init\n"); + + // copy vector code to vector page + memcpy((void*)USER_VECTOR_ADDR_HIGH, &_vectors_start, VECTORPAGE_SIZE); + + // initialize stack for vectors + arm_vector_init(); + + // enable high vectors + arm_set_sctlr(arm_get_sctlr() | SCTLR_HIGH_VECTORS); + return B_OK; } -extern "C" void arm_vector_init(void); - - status_t arch_int_init_post_vm(kernel_args *args) { - // create a read/write kernel area - sVectorPageArea = create_area("vectorpage", (void **)&sVectorPageAddress, - B_ANY_ADDRESS, VECTORPAGE_SIZE, B_FULL_LOCK, - B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA); - if (sVectorPageArea < 0) - panic("vector page could not be created!"); + TRACE("arch_int_init_post_vm\n"); - // clone it at a fixed address with user read/only permissions sUserVectorPageAddress = (addr_t*)USER_VECTOR_ADDR_HIGH; - sUserVectorPageArea = clone_area("user_vectorpage", + sUserVectorPageArea = create_area("user_vectorpage", (void **)&sUserVectorPageAddress, B_EXACT_ADDRESS, - B_READ_AREA | B_EXECUTE_AREA, sVectorPageArea); + B_PAGE_SIZE, B_ALREADY_WIRED, B_READ_AREA | B_EXECUTE_AREA); if (sUserVectorPageArea < 0) panic("user vector page @ %p could not be created (%x)!", - sVectorPageAddress, sUserVectorPageArea); - - // copy vectors into the newly created area - memcpy(sVectorPageAddress, &_vectors_start, VECTORPAGE_SIZE); - - arm_vector_init(); - - // see if high vectors are enabled - if ((arm_get_sctlr() & (1 << 13)) != 0) - dprintf("High vectors already enabled\n"); - else { - arm_set_sctlr(arm_get_sctlr() | (1 << 13)); - - if ((arm_get_sctlr() & (1 << 13)) == 0) - dprintf("Unable to enable high vectors!\n"); - else - dprintf("Enabled high vectors\n"); - } + sUserVectorPageAddress, sUserVectorPageArea); if (strncmp(args->arch_args.interrupt_controller.kind, INTC_KIND_GICV2, sizeof(args->arch_args.interrupt_controller.kind)) == 0) { diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp index 05fdc35c87..2b852e9947 100644 --- a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp +++ b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp @@ -408,7 +408,7 @@ ARMPagingMethod32Bit::MapEarly(kernel_args* args, addr_t virtualAddress, // now, fill in the pentry PutPageTableEntryInTable(ptEntry, - physicalAddress, attributes, 0, IS_KERNEL_ADDRESS(virtualAddress)); + physicalAddress, attributes | PAGE_ACCESSED, 0, IS_KERNEL_ADDRESS(virtualAddress)); return B_OK; } @@ -502,7 +502,6 @@ ARMPagingMethod32Bit::PutPageTableEntryInTable(page_table_entry* entry, | ARM_MMU_L2_TYPE_SMALLNEW | MemoryTypeToPageTableEntryFlags(memoryType) | AttributesToPageTableEntryFlags(attributes) - | ARM_MMU_L2_FLAG_AP0 | (globalPage ? 0 : ARM_MMU_L2_FLAG_NG); // put it in the page table diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.h b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.h index f0016d859e..bb9a5d2f60 100644 --- a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.h +++ b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.h @@ -169,6 +169,9 @@ ARMPagingMethod32Bit::AttributesToPageTableEntryFlags(uint32 attributes) apFlags |= ARM_MMU_L2_FLAG_XN; } + if ((attributes & PAGE_ACCESSED) != 0) + apFlags |= ARM_MMU_L2_FLAG_AP0; + return apFlags; }