|
|
|
@ -41,6 +41,11 @@ class CSR:
|
|
|
|
|
All Control and Status Registers are stored here
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
virtual_regs: Dict[int, Callable[[], int]]
|
|
|
|
|
"""
|
|
|
|
|
list of virtual CSR registers, with values computed on read
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
name_to_addr: Dict[str, int] = {
|
|
|
|
|
'mstatus': 0x300,
|
|
|
|
|
'misa': 0x301,
|
|
|
|
@ -56,7 +61,9 @@ class CSR:
|
|
|
|
|
'mhartid': 0xF14,
|
|
|
|
|
'time': 0xc01,
|
|
|
|
|
'timeh': 0xc81,
|
|
|
|
|
'halt': 0x789
|
|
|
|
|
'halt': 0x789,
|
|
|
|
|
'mtimecmp': 0x780,
|
|
|
|
|
'mtimecmph': 0x781,
|
|
|
|
|
}
|
|
|
|
|
"""
|
|
|
|
|
Translation for named registers
|
|
|
|
@ -67,6 +74,7 @@ class CSR:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.regs = defaultdict(lambda: 0)
|
|
|
|
|
self.listeners = defaultdict(lambda: (lambda x, y: None))
|
|
|
|
|
#TODO: implement write masks (bitmasks which control writeable bits in registers
|
|
|
|
|
|
|
|
|
|
def set(self, addr: Union[str, int], val: int):
|
|
|
|
|
addr = self._addr_to_name(addr)
|
|
|
|
@ -75,15 +83,18 @@ class CSR:
|
|
|
|
|
self.listeners[addr](self.regs[addr], val)
|
|
|
|
|
self.regs[addr] = val
|
|
|
|
|
|
|
|
|
|
def get(self, addr: Union[str, int]):
|
|
|
|
|
def get(self, addr: Union[str, int]) -> int:
|
|
|
|
|
addr = self._addr_to_name(addr)
|
|
|
|
|
if addr is None:
|
|
|
|
|
return
|
|
|
|
|
if addr in self.virtual_regs:
|
|
|
|
|
return self.virtual_regs[addr]()
|
|
|
|
|
return self.regs[addr]
|
|
|
|
|
|
|
|
|
|
def set_listener(self, addr: Union[str, int], listener: Callable[[int, int], None]):
|
|
|
|
|
addr = self._addr_to_name(addr)
|
|
|
|
|
if addr is None:
|
|
|
|
|
print("unknown csr address name: {}".format(addr))
|
|
|
|
|
return
|
|
|
|
|
self.listeners[addr] = listener
|
|
|
|
|
|
|
|
|
@ -107,7 +118,7 @@ class CSR:
|
|
|
|
|
new_val = erased | (val << off)
|
|
|
|
|
self.set('mstatus', new_val)
|
|
|
|
|
|
|
|
|
|
def get_mstatus(self, name):
|
|
|
|
|
def get_mstatus(self, name) -> int:
|
|
|
|
|
size = 2 if name in MSTATUS_LEN_2 else 1
|
|
|
|
|
off = MSTATUS_OFFSETS[name]
|
|
|
|
|
mask = (2**size - 1) << off
|
|
|
|
@ -134,3 +145,14 @@ class CSR:
|
|
|
|
|
return None
|
|
|
|
|
return self.name_to_addr[addr]
|
|
|
|
|
return addr
|
|
|
|
|
|
|
|
|
|
def virtual_register(self, addr: Union[str, int]):
|
|
|
|
|
addr = self._addr_to_name(addr)
|
|
|
|
|
if addr is None:
|
|
|
|
|
print("unknown csr address name: {}".format(addr))
|
|
|
|
|
|
|
|
|
|
def inner(func: Callable[[], int]):
|
|
|
|
|
self.virtual_regs[addr] = func
|
|
|
|
|
return func
|
|
|
|
|
|
|
|
|
|
return inner
|
|
|
|
|