diff --git a/src/memory/mmu.c b/src/memory/mmu.c index ee70ad8..8475d42 100644 --- a/src/memory/mmu.c +++ b/src/memory/mmu.c @@ -89,6 +89,18 @@ uint32_t mmu_resolve(rv32_cpu_t* cpu, memory_access_type_t access_type, uint32_t // Leaf PTE, we are ready to resolve the mapping // This is a 4 MiB megapage + // For an execute, check if we are allowed to execute + if(access_type == INSTRUCTION_FETCH && !(pte & PTE_X)) + exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr); + + // For a write, check if we are allowed to write + if(access_type == WRITE && !(pte & PTE_W)) + exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr); + + // For a read, check if we are allowed to read + if(access_type == READ && !(pte & PTE_R)) + exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr); + // Physical Address: [PPN[1] = pte.PPN[1], PPN[0] = vaddr.VPN[0], offset] uint32_t paddr = 0; paddr |= (PTE_PPN_1(pte) << 22); @@ -120,6 +132,18 @@ uint32_t mmu_resolve(rv32_cpu_t* cpu, memory_access_type_t access_type, uint32_t exit(EXIT_FAILURE); } + // For an execute, check if we are allowed to execute + if(access_type == INSTRUCTION_FETCH && !(pte & PTE_X)) + exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr); + + // For a write, check if we are allowed to write + if(access_type == WRITE && !(pte & PTE_W)) + exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr); + + // For a read, check if we are allowed to read + if(access_type == READ && !(pte & PTE_R)) + exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr); + // Physical Address: [PPN[1] = pte.PPN[1], PPN[0] = pte.PPN[0], offset] uint32_t paddr = 0; paddr |= (PTE_PPN_1(pte) << 22);