[Priv] overhauled instruction architecture
This commit is contained in:
parent
c963fe3989
commit
de261c4c43
@ -1,7 +1,7 @@
|
||||
from typing import Dict, Union, Callable, Optional
|
||||
from collections import defaultdict
|
||||
from .privmodes import PrivModes
|
||||
from .Exceptions import IllegalInstructionTrap
|
||||
from .Exceptions import InstructionAccessFault
|
||||
from ..helpers import to_unsigned
|
||||
|
||||
MSTATUS_OFFSETS = {
|
||||
|
@ -1,5 +1,16 @@
|
||||
from typing import Optional
|
||||
from typing import Optional, NewType
|
||||
from enum import Enum
|
||||
from .privmodes import PrivModes
|
||||
|
||||
import typing
|
||||
if typing.TYPE_CHECKING:
|
||||
from .ElfLoader import ElfInstruction
|
||||
|
||||
class CpuTrapType(Enum):
|
||||
TIMER = 1
|
||||
SOFTWARE = 2
|
||||
EXTERNAL = 3
|
||||
EXCEPTION = 4
|
||||
|
||||
class CpuTrap(BaseException):
|
||||
code: int
|
||||
@ -10,17 +21,28 @@ class CpuTrap(BaseException):
|
||||
"""
|
||||
The isInterrupt bit in the mstatus register
|
||||
"""
|
||||
|
||||
mtval: int
|
||||
"""
|
||||
contents of the mtval register
|
||||
"""
|
||||
|
||||
def __init__(self, interrupt: int, code: int, mtval=0):
|
||||
assert 0 <= interrupt <= 1
|
||||
type: CpuTrapType
|
||||
"""
|
||||
The type (timer, external, software) of the trap
|
||||
"""
|
||||
|
||||
self.interrupt = interrupt
|
||||
priv: PrivModes
|
||||
"""
|
||||
The privilege level this trap targets
|
||||
"""
|
||||
|
||||
def __init__(self, code: int, mtval, type: CpuTrapType, priv: PrivModes = PrivModes.MACHINE):
|
||||
self.interrupt = 0 if type == CpuTrapType.EXCEPTION else 1
|
||||
self.code = code
|
||||
self.mtval = mtval
|
||||
self.priv = priv
|
||||
self.type = type
|
||||
|
||||
@property
|
||||
def mcause(self):
|
||||
@ -28,17 +50,20 @@ class CpuTrap(BaseException):
|
||||
|
||||
|
||||
class IllegalInstructionTrap(CpuTrap):
|
||||
def __init__(self):
|
||||
super().__init__(0, 2, 0)
|
||||
def __init__(self, ins: 'ElfInstruction'):
|
||||
super().__init__(2, ins.encoded, CpuTrapType.EXCEPTION)
|
||||
|
||||
|
||||
class InstructionAddressMisalignedTrap(CpuTrap):
|
||||
def __init__(self, addr: int):
|
||||
super().__init__(0, 0, addr)
|
||||
super().__init__(0, addr, CpuTrapType.EXCEPTION)
|
||||
|
||||
|
||||
class InstructionAccessFault(CpuTrap):
|
||||
def __init__(self, addr: int):
|
||||
super().__init__(0, 1, addr)
|
||||
super().__init__(1, addr, CpuTrapType.EXCEPTION)
|
||||
|
||||
|
||||
class TimerInterrupt(CpuTrap):
|
||||
def __init(self):
|
||||
super().__init__(7, 0, CpuTrapType.TIMER)
|
||||
|
@ -169,7 +169,7 @@ class PrivCPU(CPU):
|
||||
if not self._time_interrupt_enabled:
|
||||
return
|
||||
if self._time_timecmp < (time.perf_counter_ns() // self.TIME_RESOLUTION_NS) - self._time_start:
|
||||
self.pending_traps.append(CpuTrap(1, 7, 0))
|
||||
self.pending_traps.append(TimerInterrupt())
|
||||
self._time_interrupt_enabled = False
|
||||
|
||||
def _check_interrupt(self):
|
||||
|
@ -49,7 +49,7 @@ class PrivRV32I(RV32I):
|
||||
def instruction_mret(self, ins: 'LoadedInstruction'):
|
||||
if self.cpu.mode != PrivModes.MACHINE:
|
||||
print("MRET not inside machine level code!")
|
||||
raise IllegalInstructionTrap()
|
||||
raise IllegalInstructionTrap(ins)
|
||||
# retore mie
|
||||
mpie = self.cpu.csr.get_mstatus('mpie')
|
||||
self.cpu.csr.set_mstatus('mie', mpie)
|
||||
@ -61,21 +61,21 @@ class PrivRV32I(RV32I):
|
||||
self.cpu.pc = mepc
|
||||
|
||||
def instruction_uret(self, ins: 'LoadedInstruction'):
|
||||
raise IllegalInstructionTrap()
|
||||
raise IllegalInstructionTrap(ins)
|
||||
|
||||
def instruction_sret(self, ins: 'LoadedInstruction'):
|
||||
raise IllegalInstructionTrap()
|
||||
raise IllegalInstructionTrap(ins)
|
||||
|
||||
def instruction_scall(self, ins: 'LoadedInstruction'):
|
||||
"""
|
||||
Overwrite the scall from userspace RV32I
|
||||
"""
|
||||
if self.cpu.mode == PrivModes.USER:
|
||||
raise CpuTrap(0, 8) # ecall from U mode
|
||||
raise CpuTrap(8, 0, CpuTrapType.SOFTWARE, self.cpu.mode) # ecall from U mode
|
||||
elif self.cpu.mode == PrivModes.SUPER:
|
||||
raise CpuTrap(0, 9) # ecall from S mode - should not happen
|
||||
raise CpuTrap(9, 0, CpuTrapType.SOFTWARE, self.cpu.mode) # ecall from S mode - should not happen
|
||||
elif self.cpu.mode == PrivModes.MACHINE:
|
||||
raise CpuTrap(0, 11) # ecall from M mode
|
||||
raise CpuTrap(11, 0, CpuTrapType.SOFTWARE, self.cpu.mode) # ecall from M mode
|
||||
|
||||
def instruction_beq(self, ins: 'LoadedInstruction'):
|
||||
rs1, rs2, dst = self.parse_rs_rs_imm(ins)
|
||||
|
Loading…
Reference in New Issue
Block a user