[CSR] adding virtual csr registers

kernel-mode
Anton Lydike 4 years ago
parent 6653ef7e7c
commit 7239212729

@ -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

Loading…
Cancel
Save