diff --git a/core/arm64/guest.h b/core/arm64/guest.h index 7eca1b0..9bf333a 100644 --- a/core/arm64/guest.h +++ b/core/arm64/guest.h @@ -1,6 +1,6 @@ #pragma once -#include "Base/Assert.h" +#include namespace pound::arm64::memory { @@ -41,9 +41,9 @@ typedef struct */ static inline uint8_t* gpa_to_hva(guest_memory_t* memory, uint64_t gpa) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT(gpa < memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert(gpa < memory->size); uint8_t* hva = memory->base + gpa; return hva; } @@ -64,9 +64,9 @@ static inline uint8_t* gpa_to_hva(guest_memory_t* memory, uint64_t gpa) */ static inline uint8_t guest_mem_readb(guest_memory_t* memory, uint64_t gpa) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT(gpa <= memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert(gpa <= memory->size); uint8_t* hva = gpa_to_hva(memory, gpa); return *hva; } @@ -79,11 +79,11 @@ static inline uint8_t guest_mem_readb(guest_memory_t* memory, uint64_t gpa) */ static inline uint16_t guest_mem_readw(guest_memory_t* memory, uint64_t gpa) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT((gpa + sizeof(uint16_t)) <= memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert((gpa + sizeof(uint16_t)) <= memory->size); // Check if gpa is aligned to 2 bytes. - ASSERT((gpa & 1) == 0); + assert((gpa & 1) == 0); uint16_t* hva = (uint16_t*)gpa_to_hva(memory, gpa); return *hva; } @@ -96,11 +96,11 @@ static inline uint16_t guest_mem_readw(guest_memory_t* memory, uint64_t gpa) */ static inline uint32_t guest_mem_readl(guest_memory_t* memory, uint64_t gpa) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT((gpa + sizeof(uint32_t)) <= memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert((gpa + sizeof(uint32_t)) <= memory->size); // Check if gpa is aligned to 4 bytes. - ASSERT((gpa & 3) == 0); + assert((gpa & 3) == 0); uint32_t* hva = (uint32_t*)gpa_to_hva(memory, gpa); return *hva; } @@ -113,11 +113,11 @@ static inline uint32_t guest_mem_readl(guest_memory_t* memory, uint64_t gpa) */ static inline uint64_t guest_mem_readq(guest_memory_t* memory, uint64_t gpa) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT((gpa + sizeof(uint64_t)) <= memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert((gpa + sizeof(uint64_t)) <= memory->size); // Check if gpa is aligned to 8 bytes. - ASSERT((gpa & 7) == 0); + assert((gpa & 7) == 0); uint64_t* hva = (uint64_t*)gpa_to_hva(memory, gpa); return *hva; } @@ -136,9 +136,9 @@ static inline uint64_t guest_mem_readq(guest_memory_t* memory, uint64_t gpa) */ static inline void guest_mem_writeb(guest_memory_t* memory, uint64_t gpa, uint8_t val) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT(gpa <= memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert(gpa <= memory->size); uint8_t* hva = gpa_to_hva(memory, gpa); *hva = val; } @@ -151,11 +151,11 @@ static inline void guest_mem_writeb(guest_memory_t* memory, uint64_t gpa, uint8_ */ static inline void guest_mem_writew(guest_memory_t* memory, uint64_t gpa, uint16_t val) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT((gpa + sizeof(uint16_t)) <= memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert((gpa + sizeof(uint16_t)) <= memory->size); // Check if gpa is aligned to 2 bytes. - ASSERT((gpa & 1) == 0); + assert((gpa & 1) == 0); uint16_t* hva = (uint16_t*)gpa_to_hva(memory, gpa); *hva = val; } @@ -168,10 +168,10 @@ static inline void guest_mem_writew(guest_memory_t* memory, uint64_t gpa, uint16 */ static inline void guest_mem_writel(guest_memory_t* memory, uint64_t gpa, uint32_t val) { - ASSERT(nullptr != memory->base); - ASSERT((gpa + sizeof(uint32_t)) <= memory->size); + assert(nullptr != memory->base); + assert((gpa + sizeof(uint32_t)) <= memory->size); // Check if gpa is aligned to 4 bytes. - ASSERT((gpa & 3) == 0); + assert((gpa & 3) == 0); uint32_t* hva = (uint32_t*)gpa_to_hva(memory, gpa); *hva = val; } @@ -184,11 +184,11 @@ static inline void guest_mem_writel(guest_memory_t* memory, uint64_t gpa, uint32 */ static inline void guest_mem_writeq(guest_memory_t* memory, uint64_t gpa, uint64_t val) { - ASSERT(nullptr != memory); - ASSERT(nullptr != memory->base); - ASSERT((gpa + sizeof(uint64_t)) <= memory->size); + assert(nullptr != memory); + assert(nullptr != memory->base); + assert((gpa + sizeof(uint64_t)) <= memory->size); // Check if gpa is aligned to 8 bytes. - ASSERT((gpa & 7) == 0); + assert((gpa & 7) == 0); uint64_t* hva = (uint64_t*)gpa_to_hva(memory, gpa); *hva = val; } diff --git a/core/arm64/isa.cpp b/core/arm64/isa.cpp index 1cb8c4a..7cffc9e 100644 --- a/core/arm64/isa.cpp +++ b/core/arm64/isa.cpp @@ -1,17 +1,18 @@ #include "isa.h" -#include "Base/Assert.h" #include "guest.h" +#include "mmu.h" #include "memory/arena.h" +#include namespace pound::arm64 { void take_synchronous_exception(vcpu_state_t* vcpu, uint8_t exception_class, uint32_t iss, uint64_t faulting_address) { - ASSERT(nullptr != vcpu); + assert(nullptr != vcpu); /* An EC holds 6 bits.*/ - ASSERT(0 == (exception_class & 11000000)); + assert(0 == (exception_class & 11000000)); /* An ISS holds 25 bits */ - ASSERT(0 == (iss & 0xFE000000)); + assert(0 == (iss & 0xFE000000)); vcpu->elr_el1 = vcpu->pc; vcpu->spsr_el1 = vcpu->pstate; @@ -156,12 +157,16 @@ void cpuTest() { vcpu_state_t vcpu_states[CPU_CORES] = {}; pound::memory::arena_t guest_memory_arena = pound::memory::arena_init(GUEST_RAM_SIZE); - ASSERT(nullptr != guest_memory_arena.data); + assert(nullptr != guest_memory_arena.data); pound::arm64::memory::guest_memory_t guest_ram = {}; guest_ram.base = static_cast(guest_memory_arena.data); guest_ram.size = guest_memory_arena.capacity; (void)test_guest_ram_access(&guest_ram); + vcpu_states[0].sctlr_el1 = 3; + uint64_t out = 0; + uint64_t gva = 2636; + assert(0 == pound::arm64::memory::mmu_gva_to_gpa(&vcpu_states[0], gva, &out)); } } // namespace pound::armv64 diff --git a/core/arm64/isa.h b/core/arm64/isa.h index 3a21dda..745f319 100644 --- a/core/arm64/isa.h +++ b/core/arm64/isa.h @@ -41,6 +41,7 @@ namespace pound::arm64 * @esr_el1: Exception Syndrome Register. * @far_el1: Fault Address Register. * @vbar_el1: Vector Base Address Register. + * @sctlr_el1: System Control Register. * @spsr_el1: Saved Program Status Register. * @ctr_el0: Cache-Type. * @cntv_ctl_el0: Virtual Timer Control. @@ -82,6 +83,9 @@ typedef struct alignas(CACHE_LINE_SIZE) /* The memory address that caused a Data Abort exception. */ uint64_t far_el1; + /* SCTLR_EL1[0] bit enables the MMU. */ + uint64_t sctlr_el1; + /* * A snapshot of the current PSTATE register before the exception. * This is for restoring the program's state when returning from an diff --git a/core/memory/arena.cpp b/core/memory/arena.cpp index da21688..001918a 100644 --- a/core/memory/arena.cpp +++ b/core/memory/arena.cpp @@ -1,5 +1,5 @@ #include "arena.h" -#include "Base/Assert.h" +#include #ifndef WIN32 #include #endif @@ -31,22 +31,22 @@ arena_t arena_init(size_t capacity) const void* arena_allocate(memory::arena_t* arena, const std::size_t size) { - ASSERT(arena != nullptr); - ASSERT(arena->size + size <= arena->capacity); + assert(arena != nullptr); + assert(arena->size + size <= arena->capacity); const void* const data = static_cast(arena->data) + arena->size; arena->size += size; return data; } void arena_reset(memory::arena_t* arena) { - ASSERT(nullptr != arena); - ASSERT(nullptr != arena->data); + assert(nullptr != arena); + assert(nullptr != arena->data); arena->size = 0; (void)std::memset(arena->data, POISON_PATTERN, arena->capacity); } void arena_free(memory::arena_t* arena) { - ASSERT(arena != nullptr); + assert(arena != nullptr); arena->capacity = 0; arena->size = 0; // TODO(GloriousTaco:memory): Replace free with a memory safe alternative.