Browse Source

[sim] fault on failed addr translations

previously, a bad PTE would segfault the simulator, rather than sending
the fault to the OS.
cs250
Andrew Waterman 15 years ago
parent
commit
f1bb8270a1
  1. 22
      riscv/mmu.h

22
riscv/mmu.h

@ -49,7 +49,10 @@ public:
#define load_func(type) \
type##_t load_##type(reg_t addr) { \
if(unlikely(addr % sizeof(type##_t))) \
{ \
badvaddr = addr; \
throw trap_load_address_misaligned; \
} \
addr = translate(addr, false, false); \
dcsim_tick(dcsim, dtlbsim, addr, sizeof(type##_t), false); \
return *(type##_t*)(mem+addr); \
@ -58,7 +61,10 @@ public:
#define store_func(type) \
void store_##type(reg_t addr, type##_t val) { \
if(unlikely(addr % sizeof(type##_t))) \
{ \
badvaddr = addr; \
throw trap_store_address_misaligned; \
} \
addr = translate(addr, true, false); \
dcsim_tick(dcsim, dtlbsim, addr, sizeof(type##_t), true); \
*(type##_t*)(mem+addr) = val; \
@ -89,7 +95,10 @@ public:
#endif
{
if(unlikely(addr % 4))
{
badvaddr = addr;
throw trap_instruction_address_misaligned;
}
reg_t paddr = translate(addr, false, true);
insn = *(insn_t*)(mem+paddr);
@ -174,7 +183,10 @@ private:
{
pte = walk(addr);
if(!(pte & PTE_E))
{
badvaddr = addr;
throw trap;
}
tlb_data[idx] = pte;
tlb_tag[idx] = addr >> PGSHIFT;
@ -184,7 +196,10 @@ private:
if(supervisor)
access_type <<= 3;
if(unlikely(!(access_type & pte & PTE_PERM)))
{
badvaddr = addr;
throw trap;
}
return (addr & (PGSIZE-1)) | ((pte >> PTE_PPN_SHIFT) << PGSHIFT);
}
@ -218,7 +233,12 @@ private:
// if this PTE is from a larger PT, fake a leaf
// PTE so the TLB will work right
reg_t vpn = addr >> PGSHIFT;
pte |= ptd | (vpn & ((1<<(ptshift))-1)) << PTE_PPN_SHIFT;
ptd |= (vpn & ((1<<(ptshift))-1)) << PTE_PPN_SHIFT;
// fault if physical addr is invalid
reg_t ppn = ptd >> PTE_PPN_SHIFT;
if((ppn << PGSHIFT) + (addr & (PGSIZE-1)) < memsz)
pte = ptd;
break;
}
else if(!(ptd & PTE_T))

Loading…
Cancel
Save