Skip to content

Commit 168c412

Browse files
committed
MRET now traps on unaligned MEPC. No longer mask mode bits when writing MEPC via CSRRW/CSRRWI.
1 parent 77427d9 commit 168c412

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

cpu.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,17 @@ def exec_SYSTEM(cpu, ram, inst, rd, funct3, rs1, rs2, funct7):
198198
raise MachineError("No trap handler and no Python ecall handler installed: cannot process ECALL instruction")
199199

200200
elif inst == 0x30200073: # MRET
201-
cpu.next_pc = cpu.csrs[0x341] # return address <- mepc
201+
mepc = cpu.csrs[0x341]
202+
if mepc & 0x3:
203+
cpu.trap(cause=0, mtval=mepc) # unaligned address
204+
else:
205+
cpu.next_pc = mepc # return address <- mepc
202206

203-
mstatus = cpu.csrs[0x300] # mstatus
204-
mpie = (mstatus >> 7) & 1 # extract MPIE
205-
mstatus = (mstatus & ~(1 << 3)) | (mpie << 3) # MIE <- MPIE
206-
mstatus |= (1 << 7) # MPIE = 1 (re-arm)
207-
cpu.csrs[0x300] = mstatus
207+
mstatus = cpu.csrs[0x300] # mstatus
208+
mpie = (mstatus >> 7) & 1 # extract MPIE
209+
mstatus = (mstatus & ~(1 << 3)) | (mpie << 3) # MIE <- MPIE
210+
mstatus |= (1 << 7) # MPIE = 1 (re-arm)
211+
cpu.csrs[0x300] = mstatus
208212

209213
elif inst == 0x00100073: # EBREAK
210214
# syscalls >= 0xFFFF0000 bypass the rest of the EBREAK logic and are used for logging.
@@ -249,9 +253,7 @@ def exec_SYSTEM(cpu, ram, inst, rd, funct3, rs1, rs2, funct7):
249253
cpu.trap(cause=2, mtval=inst) # 2 = illegal instruction
250254

251255
if funct3 in (0b001, 0b101): # CSRRW / CSRRWI
252-
if csr == 0x305: # we don't support vectored interrupts, so mask away lower 2 bits of mtvect
253-
cpu.csrs[csr] = rs1_val & ~0x3
254-
elif not (csr in cpu.CSR_NOWRITE):
256+
if not (csr in cpu.CSR_NOWRITE):
255257
cpu.csrs[csr] = rs1_val
256258

257259
# Atomic update of mtime

0 commit comments

Comments
 (0)