From bb899145ae19311530be1357159a6f7f1ce0aa17 Mon Sep 17 00:00:00 2001 From: colby-nyce Date: Tue, 17 Sep 2024 14:22:30 -0500 Subject: [PATCH] Create registers from JSON definition (#524) --- sparta/scripts/GenRegisterJSON.py | 463 ++++++++++ sparta/scripts/RV32_CSR.py | 798 ++++++++++++++++++ sparta/scripts/RV64_CONSTANT.py | 22 + sparta/scripts/RV64_CSR.py | 791 +++++++++++++++++ .../sparta/functional/RegisterDefnsJSON.hpp | 235 ++++++ sparta/sparta/functional/RegisterSet.hpp | 75 ++ sparta/test/Register/Register_test.cpp | 84 +- 7 files changed, 2462 insertions(+), 6 deletions(-) create mode 100755 sparta/scripts/GenRegisterJSON.py create mode 100644 sparta/scripts/RV32_CSR.py create mode 100644 sparta/scripts/RV64_CONSTANT.py create mode 100644 sparta/scripts/RV64_CSR.py create mode 100644 sparta/sparta/functional/RegisterDefnsJSON.hpp diff --git a/sparta/scripts/GenRegisterJSON.py b/sparta/scripts/GenRegisterJSON.py new file mode 100755 index 0000000000..bcaed23b33 --- /dev/null +++ b/sparta/scripts/GenRegisterJSON.py @@ -0,0 +1,463 @@ +#!/usr/bin/env python3 +"""Helper script for regenerating register definition JSON files. +""" + +from enum import IntEnum +import json +import math +import sys +import pdb + +from RV64_CSR import CSR64_DEFS +from RV32_CSR import CSR32_DEFS + +from RV64_CONSTANT import RV64_CONSTS +from RV64_CONSTANT import ATHENA_INTERNAL_REGISTERS + +class RegisterGroup(IntEnum): + INT = 0 + FP = 1 + VEC = 2 + CSR = 3 + +def GetGroupName(group): + if group == RegisterGroup.INT: + return "INT" + elif group == RegisterGroup.FP: + return "FP" + elif group == RegisterGroup.VEC: + return "VEC" + elif group == RegisterGroup.CSR: + return "CSR" + else: + return "UNKNOWN" + +INT_ALIASES = { + "x0": ["zero"], + "x1": ["ra"], + "x2": ["sp"], + "x3": ["gp"], + "x4": ["tp"], + "x5": ["t0"], + "x6": ["t1"], + "x7": ["t2"], + "x8": ["s0", "fp"], + "x9": ["s1"], + "x10": ["a0"], + "x11": ["a1"], + "x12": ["a2"], + "x13": ["a3"], + "x14": ["a4"], + "x15": ["a5"], + "x16": ["a6"], + "x17": ["a7"], + "x18": ["s2"], + "x19": ["s3"], + "x20": ["s4"], + "x21": ["s5"], + "x22": ["s6"], + "x23": ["s7"], + "x24": ["s8"], + "x25": ["s9"], + "x26": ["s10"], + "x27": ["s11"], + "x28": ["t3"], + "x29": ["t4"], + "x30": ["t5"], + "x31": ["t6"], +} +FP_ALIASES = { + "f0": ["ft0"], + "f1": ["ft1"], + "f2": ["ft2"], + "f3": ["ft3"], + "f4": ["ft4"], + "f5": ["ft5"], + "f6": ["ft6"], + "f7": ["ft7"], + "f8": ["fs0"], + "f9": ["fs1"], + "f10": ["fa0"], + "f11": ["fa1"], + "f12": ["fa2"], + "f13": ["fa3"], + "f14": ["fa4"], + "f15": ["fa5"], + "f16": ["fa6"], + "f17": ["fa7"], + "f18": ["fs2"], + "f19": ["fs3"], + "f20": ["fs4"], + "f21": ["fs5"], + "f22": ["fs6"], + "f23": ["fs7"], + "f24": ["fs8"], + "f25": ["fs9"], + "f26": ["fs10"], + "f27": ["fs11"], + "f28": ["ft8"], + "f29": ["ft9"], + "f30": ["ft10"], + "f31": ["ft11"], +} +VEC_ALIASES = { + "v0": [], + "v1": [], + "v2": [], + "v3": [], + "v4": [], + "v5": [], + "v6": [], + "v7": [], + "v8": [], + "v9": [], + "v10": [], + "v11": [], + "v12": [], + "v13": [], + "v14": [], + "v15": [], + "v16": [], + "v17": [], + "v18": [], + "v19": [], + "v20": [], + "v21": [], + "v22": [], + "v23": [], + "v24": [], + "v25": [], + "v26": [], + "v27": [], + "v28": [], + "v29": [], + "v30": [], + "v31": [], +} + +CSR_BF_HEADER_FILE_NAME = "CSRBitMasks{reg_size}.hpp" + +CSR_HEADER_FILE_NAME = "CSRNums.hpp" +CSR_NUM_FILE_HEADER = """ +#pragma once + +#include + +// +// This is generated file from scripts/GenRegisterJSON.py +// +// DO NOT MODIFY THIS FILE BY HAND +// + +namespace athena +{ +""" + +CSR_NUM_FILE_CSRNUM_COMMENT = """ + // CSR Nums +""" + +CSR_NUM_FILE_CONSTANT_COMMENT = """ + // Constants defined for RISC-V +""" + +CSR_NUM_FILE_INTERNAL_REGS_COMMENT = """ + // Constants defined for RISC-V +""" + +CSR_NUM_FILE_FOOTER = """ +} +""" + +class GenRegisterJSON(): + """Generates register definition JSON files. + + Args: + group_name (RegisterGroup): Name of register group. + num_regs (int): Number of registers in the group. + reg_size (int): Size of the registers in bytes (must be power of 2) + """ + + def __init__(self, group_num, num_regs, reg_size): + self.group_num = int(group_num) + self.group_name = GetGroupName(group_num) + self.num_regs = num_regs + assert math.log(reg_size, 2).is_integer(), 'reg_size must be a power of 2!' + self.reg_size = reg_size + self.reg_defs = [] + + self.readonly_fields = {} + self.readonly_fields["b31_00"] = {"desc": "read-only", + "low_bit": 0, + "high_bit": 31, + "readonly": True} + self.readonly_fields["b63_00"] = {"desc": "read-only", + "low_bit": 0, + "high_bit": 63, + "readonly": True} + + for num in range(0, self.num_regs): + name = self.get_int_reg_name(num) + if group_num is RegisterGroup.INT: + self.gen_int_reg_defs() + elif group_num is RegisterGroup.FP: + self.gen_fp_reg_defs() + elif group_num is RegisterGroup.CSR: + self.gen_csr_reg_defs() + self.gen_csr_header_file() + self.gen_csr_bit_fields() + elif group_num is RegisterGroup.VEC: + self.gen_vec_reg_defs() + + def get_int_reg_name(self, num): + """Returns int register name from register number""" + return "x"+str(num) + + def get_int_reg_desc(self, num): + """Returns int register description from register number""" + return "int register "+str(num) + + def gen_int_reg_defs(self): + """Generates integer register definitions + """ + for num in range(0, self.num_regs): + name = self.get_int_reg_name(num) + alias = INT_ALIASES[name] if (name in INT_ALIASES.keys()) else [] + fields = {} + if (num == 0): + if (self.reg_size == 4): + fields["b31_00"] = self.readonly_fields["b31_00"] + else: + fields["b63_00"] = self.readonly_fields["b63_00"] + + self.reg_defs.append(self.__CreateRegDict({ + "name": name, + "num": num, + "desc": self.get_int_reg_desc(num), + "size": self.reg_size, + "aliases": alias, + "fields": fields, + "initial_value": 0, + "enabled": True})) + + def get_fp_reg_name(self, num): + """Returns fp register name from register number""" + return "f"+str(num) + + def get_fp_reg_desc(self, num): + """Returns fp register description from register number""" + return "floating point register "+str(num) + + def gen_fp_reg_defs(self): + """Generates floating point register definitions + """ + + fields = {} + fields["sp"] = {"desc": "single precision", + "low_bit": 0, + "high_bit": 31, + "readonly": False} + fields["dp"] = {"desc": "double precision", + "low_bit": 0, + "high_bit": 63, + "readonly": False} + + for num in range(0, self.num_regs): + name = self.get_fp_reg_name(num) + alias = FP_ALIASES[name] if (name in FP_ALIASES.keys()) else [] + self.reg_defs.append(self.__CreateRegDict({ + "name": name, + "num": num, + "desc": self.get_fp_reg_desc(num), + "size": 8, + "aliases": alias, + "fields": fields, + "initial_value": 0, + "enabled": True})) + + def gen_csr_reg_defs(self): + """Generate control and status register definitions + """ + CSR_DEFS = CSR32_DEFS if (self.reg_size == 4) else CSR64_DEFS + + for k, v in CSR_DEFS.items(): + self.reg_defs.append(self.__CreateRegDict({ + "name": v[0], + "num": k, + "desc": v[1], + "size": 8, + "aliases": ["csr"+str(k)], + "fields": v[2], + "initial_value": v[3], + "enabled": True})) + + def gen_csr_header_file(self): + """Generate the CSR CPP header file + """ + + csr_header_file = open(CSR_HEADER_FILE_NAME, "w") + csr_header_file.write(CSR_NUM_FILE_HEADER) + + # TODO: Can we get keys in JSON to be printed in hex? + CSR_DEFS = CSR32_DEFS.copy() + CSR_DEFS.update(CSR64_DEFS) + CONST = RV64_CONSTS + + csr_header_file.write(CSR_NUM_FILE_CSRNUM_COMMENT) + csr_largest_value = -1; + for k, v in CSR_DEFS.items(): + csr_header_file.write(" static constexpr uint32_t "+ + (v[0]).upper()+ + " = "+ + str(hex(k))+ + "; // "+ + str(k)+ + "\n") + csr_largest_value = max(csr_largest_value, k) + + csr_header_file.write(" static constexpr uint32_t CSR_LARGEST_VALUE = "+ + str(hex(csr_largest_value)) + + ";\n") + + csr_header_file.write(CSR_NUM_FILE_CONSTANT_COMMENT) + for k, v in CONST.items(): + csr_header_file.write(" static constexpr uint64_t "+ + k.upper()+ + " = "+ + str(hex(v[0]))+ + "; // "+ + str(v[1])+ + "\n") + + csr_header_file.write(CSR_NUM_FILE_INTERNAL_REGS_COMMENT) + for k, v in ATHENA_INTERNAL_REGISTERS.items(): + csr_header_file.write(" static constexpr uint64_t "+ + k.upper()+ + " = "+ + str(hex(v[0]))+ + "; // "+ + str(v[1])+ + "\n") + + csr_header_file.write(CSR_NUM_FILE_FOOTER) + csr_header_file.close() + + def gen_csr_bit_fields(self): + """Generate the CSR header file with bitfields + """ + data_width = self.reg_size*8 + csr_bf_header_file = open(CSR_BF_HEADER_FILE_NAME.format(reg_size=data_width), "w") + csr_bf_header_file.write(CSR_NUM_FILE_HEADER) + + CSR_DEFS = CSR32_DEFS if (self.reg_size == 4) else CSR64_DEFS + FILL_MASK = 0xffffffffffffffff + SIZE = 64 + + for k, v in CSR_DEFS.items(): + # Print only if there are bit flags + if v[2]: + csr_bf_header_file.write(" namespace "+ + (v[0]).upper()+ + "_" + str(data_width) + "_bitmasks {\n") + fields = v[2] + for name in fields: + if name.lower() != "resv" and name.lower() != "wpri": + high_bit = fields[name]['high_bit'] + low_bit = fields[name]['low_bit'] + mask = (FILL_MASK >> (SIZE - (high_bit - low_bit + 1))) << low_bit + csr_bf_header_file.write(" static constexpr uint64_t " + + name + " = " + hex(mask) + ";\n") + + csr_bf_header_file.write(" } // namespace "+ + (v[0]).upper()+ + "_" + str(data_width) + "_bitfield\n\n") + + + + csr_bf_header_file.write(CSR_NUM_FILE_FOOTER) + csr_bf_header_file.close() + + + def get_vec_reg_name(self, num): + """Returns v register name from register number""" + return "v"+str(num) + + def get_vec_reg_desc(self, num): + """Returns v register description from register number""" + return "vector register "+str(num) + + def gen_vec_reg_defs(self): + """Generates vector register definitions + """ + + fields = {} + alias = [] + + for num in range(0, self.num_regs): + name = self.get_vec_reg_name(num) + self.reg_defs.append(self.__CreateRegDict({ + "name": name, + "num": num, + "desc": self.get_vec_reg_desc(num), + "size": self.reg_size, + "aliases": alias, + "fields": fields, + "initial_value": 0, + "enabled": True})) + + def write_json(self, filename): + """Write register definitions to a JSON file""" + with open(filename,"w") as fh: + json.dump(self.reg_defs, fh, indent=4) + + def __CreateRegDict(self, reg_dict): + # Remove the 'fields' key if it is empty + if not reg_dict["fields"]: + del reg_dict["fields"] + + # Format the 'initial_value' to hex, or remove it if it is 0 + if reg_dict["initial_value"]: + reg_dict["initial_value"] = hex(reg_dict["initial_value"]) + else: + del reg_dict["initial_value"] + + # Remove the 'enabled' key if it is True + if reg_dict["enabled"]: + del reg_dict["enabled"] + + # Add group num and group name + reg_dict["group_num"] = self.group_num + reg_dict["group_name"] = self.group_name + + return reg_dict + +def main(): + + if len(sys.argv) != 2: + print("Usage: GenRegisterJSON.py ") + exit(1) + + isa_string = sys.argv[1] + + if isa_string not in ["rv32", "rv64"]: + print("Usage: GenRegisterJSON.py ") + exit(1) + + # Default to RV64 + xlen = 4 if "32" in isa_string else 8 + vlen = 32 + + # Generate rv64g int, fp and CSR registers + reg_int = GenRegisterJSON(RegisterGroup.INT, 32, xlen); + reg_fp = GenRegisterJSON(RegisterGroup.FP, 32, xlen); + reg_vec = GenRegisterJSON(RegisterGroup.VEC, 32, vlen) + reg_csr = GenRegisterJSON(RegisterGroup.CSR, 0, xlen); + + isa_string = ''.join(i for i in isa_string if not i.isdigit()) + reg_int.write_json("reg_int.json"); + reg_fp.write_json("reg_fp.json"); + reg_vec.write_json("reg_vec.json") + reg_csr.write_json("reg_csr.json"); + +if __name__ == "__main__": + main() diff --git a/sparta/scripts/RV32_CSR.py b/sparta/scripts/RV32_CSR.py new file mode 100644 index 0000000000..7496a00181 --- /dev/null +++ b/sparta/scripts/RV32_CSR.py @@ -0,0 +1,798 @@ +# + +CSR32_DEFS = { + # User Trap Setup + 0x000: ["ustatus", "User status register.", {}, 0], + 0x004: ["uie", "User interrupt-enable register.", {}, 0], + 0x005: ["utvec", "User trap handler base address.", {}, 0], + + # Debug + 0x010: ["dmcontrol", "Debug module control", { + "haltreq" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Halt request for currently selected harts" }, + "resumereq" : { "high_bit" : 30, "low_bit" : 30, "readonly" : False, "desc" : "Resume request for currently selected harts" }, + "hartreset" : { "high_bit" : 29, "low_bit" : 29, "readonly" : False, "desc" : "Writes reset bit for all currently selected harts" }, + "ackhavereset" : { "high_bit" : 28, "low_bit" : 28, "readonly" : False, "desc" : "If set, clears havereset for any selected harts" }, + "Resv" : { "high_bit" : 27, "low_bit" : 27, "readonly" : True, "desc" : "undocumented" }, + "hasel" : { "high_bit" : 26, "low_bit" : 26, "readonly" : True, "desc" : "Selects the definition of hartsel" }, + "hartsello" : { "high_bit" : 25, "low_bit" : 16, "readonly" : False, "desc" : "Low 10 bits of hartsel" }, + "hartselhi" : { "high_bit" : 15, "low_bit" : 6, "readonly" : False, "desc" : "High 10 bits of hartsel" }, + "Resv" : { "high_bit" : 5, "low_bit" : 4, "readonly" : True, "desc" : "undocumented" }, + "setresethartreq" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Writes halt-on-reset request bit for all currently selected harts" }, + "clrresethaltreq" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Clears halt-on-reset request bit for all currently selected harts" }, + "ndmreset" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Controls the reset signal from the DM to the rest of the system" }, + "dmactive" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Reset signal for the Debug Module itself" }, + }, 0], + 0x011: ["dmstatus", "Debug module status", { + "Resv" : { "high_bit" : 31, "low_bit" : 23, "readonly" : True, "desc" : "undocumented" }, + "impebreak" : { "high_bit" : 22, "low_bit" : 22, "readonly" : False, "desc" : "undocumented" }, + "Resv" : { "high_bit" : 21, "low_bit" : 20, "readonly" : True, "desc" : "undocumented" }, + "allhavereset" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "undocumented" }, + "anyhavereset" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "undocumented" }, + "allresumeack" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "undocumented" }, + "anyresumeack" : { "high_bit" : 16, "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "allnonexistent" : { "high_bit" : 15, "low_bit" : 15, "readonly" : False, "desc" : "undocumented" }, + "anynonexistent" : { "high_bit" : 14, "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "allunavail" : { "high_bit" : 13, "low_bit" : 13, "readonly" : False, "desc" : "undocumented" }, + "anyunavail" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "undocumented" }, + "allrunning" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "undocumented" }, + "anyrunning" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "undocumented" }, + "allhalted" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "undocumented" }, + "anyhalted" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "undocumented" }, + "authenticated" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "Status of authentication (set to 1 if DM doesn't implement authentication)" }, + "authbusy" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Authentication module is ready to process the next read/write to authdata" }, + "hasresethaltreq" : { "high_bit" : 5, "low_bit" : 5, "readonly" : True, "desc" : "If set, this Debug Module supports halt-on-reset" }, + "confstrptrvalid" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "If set, confstrptr0-confstrptr3 hold the address of the configuration string" }, + "version" : { "high_bit" : 3, "low_bit" : 0, "readonly" : True, "desc" : "Version of Debug Module spec supported" }, + }, 143], + + # User Trap Setup + 0x040: ["uscratch", "Scratch register for user trap handlers.", {}, 0], + 0x041: ["uepc", "User exception program counter.", {}, 0], + 0x042: ["ucause", "Scratch register for user trap handlers.", {}, 0], + 0x043: ["utval", "User bad address or instruction.", {}, 0], + 0x044: ["uip", "User interrupt pending.", {}, 0], + + # User Floating-Point CSRs + 0x001: ["fflags", "Floating-Point Accrued Exceptions.", { + "Resv" : { "high_bit" : 31, "low_bit" : 5, "readonly" : True, "desc" : "undocumented" }, + "NV" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Invalid operation" }, + "DZ" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Divide by zero" }, + "OF" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Overflow" }, + "UF" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Underflow" }, + "NX" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Inexact" }, + }, 0], + 0x002: ["frm", "Floating-Point Dynamic Rounding Mode.", {}, 0], + 0x003: ["fcsr", "Floating-Point Control and Status Register (frm + fflags).", { + "Resv" : { "high_bit" : 31, "low_bit" : 8, "readonly" : True, "desc" : "undocumented" }, + "frm" : { "high_bit" : 7, "low_bit" : 5, "readonly" : False, "desc" : "Rounding Mode" }, + "NV" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Invalid Operation" }, + "DZ" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Divide by zero" }, + "OF" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Overflow" }, + "UF" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Underflow" }, + "NX" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Inexact" }, + "fflags" : { "high_bit" : 4, "low_bit" : 0, "readonly" : False, "desc" : "Accured Exceptions" } + }, 0], + + # User Vector CSRs + 0x008: ["vstart", "The index of the first element to be executed by a vector instruction.", {}, 0], + 0x009: ["vxsat", "To indicate whether a fixed-point instruction needs to saturate.", { + "vxsat" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Saturate" }, + "Resv" : { "high_bit" : 31, "low_bit" : 1, "readonly" : True, "desc" : "undocumented" }, + }, 0], + 0x00A: ["vxrm", "Vector fixed-point rounding-mode register.", { + "vxrm" : { "high_bit" : 1, "low_bit" : 0, "readonly" : False, "desc" : "Rounding mode" }, + "Resv" : { "high_bit" : 31, "low_bit" : 2, "readonly" : True, "desc" : "undocumented" }, + }, 0], + 0x00F: ["vcsr", "Vector control and status register.", { + "vxsat" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fixed-point accrued saturation flag" }, + "vxrm" : { "high_bit" : 2, "low_bit" : 1, "readonly" : False, "desc" : "Fixed-point rounding mode" }, + "Resv" : { "high_bit" : 31, "low_bit" : 3, "readonly" : True, "desc" : "undocumented" }, + }, 0], + 0xC20: ["vl", "Vector legnth register.", {}, 0], + 0xC21: ["vtype", "Vector type register.", { + "vlmul" : { "high_bit" : 2, "low_bit" : 0, "readonly" : False, "desc" : "Vector register group multiplier" }, + "vsew" : { "high_bit" : 5, "low_bit" : 3, "readonly" : False, "desc" : "Selected element width" }, + "vta" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Vector tail agnostic mode" }, + "vma" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Vector mask agnostic mode" }, + "Resv" : { "high_bit" : 30, "low_bit" : 8, "readonly" : True, "desc" : "undocumented" }, + "vill" : { "high_bit" : 31, "low_bit" : 31,"readonly" : False, "desc" : "Illegal value if set" } + }, 0], + 0xC22: ["vlenb", "Vector byte length.", {}, 0], + + # User Counter/Timers + 0xC00: ["cycle", "Cycle counter for RDCYCLE instruction.", {}, 0], + 0xC01: ["time", "Timer for RDTIME instruction.", {}, 0], + 0xC02: ["instret", "Instructions-retired counter for RDINSTRET instruction.", {}, 0], + 0xC03: ["hpmcounter3", "Performance-monitoring counter.", {}, 0], + 0xC04: ["hpmcounter4", "Performance-monitoring counter.", {}, 0], + 0xC05: ["hpmcounter5", "Performance-monitoring counter.", {}, 0], + 0xC06: ["hpmcounter6", "Performance-monitoring counter.", {}, 0], + 0xC07: ["hpmcounter7", "Performance-monitoring counter.", {}, 0], + 0xC08: ["hpmcounter8", "Performance-monitoring counter.", {}, 0], + 0xC09: ["hpmcounter9", "Performance-monitoring counter.", {}, 0], + 0xC0A: ["hpmcounter10", "Performance-monitoring counter.", {}, 0], + 0xC0B: ["hpmcounter11", "Performance-monitoring counter.", {}, 0], + 0xC0C: ["hpmcounter12", "Performance-monitoring counter.", {}, 0], + 0xC0D: ["hpmcounter13", "Performance-monitoring counter.", {}, 0], + 0xC0E: ["hpmcounter14", "Performance-monitoring counter.", {}, 0], + 0xC0F: ["hpmcounter15", "Performance-monitoring counter.", {}, 0], + 0xC10: ["hpmcounter16", "Performance-monitoring counter.", {}, 0], + 0xC11: ["hpmcounter17", "Performance-monitoring counter.", {}, 0], + 0xC12: ["hpmcounter18", "Performance-monitoring counter.", {}, 0], + 0xC13: ["hpmcounter19", "Performance-monitoring counter.", {}, 0], + 0xC14: ["hpmcounter20", "Performance-monitoring counter.", {}, 0], + 0xC15: ["hpmcounter21", "Performance-monitoring counter.", {}, 0], + 0xC16: ["hpmcounter22", "Performance-monitoring counter.", {}, 0], + 0xC17: ["hpmcounter23", "Performance-monitoring counter.", {}, 0], + 0xC18: ["hpmcounter24", "Performance-monitoring counter.", {}, 0], + 0xC19: ["hpmcounter25", "Performance-monitoring counter.", {}, 0], + 0xC1A: ["hpmcounter26", "Performance-monitoring counter.", {}, 0], + 0xC1B: ["hpmcounter27", "Performance-monitoring counter.", {}, 0], + 0xC1C: ["hpmcounter28", "Performance-monitoring counter.", {}, 0], + 0xC1D: ["hpmcounter29", "Performance-monitoring counter.", {}, 0], + 0xC1E: ["hpmcounter30", "Performance-monitoring counter.", {}, 0], + 0xC1F: ["hpmcounter31", "Performance-monitoring counter.", {}, 0], + + # Supervisor Trap Setup + 0x100: ["sstatus", "Supervisor status register.", { + "SD" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Fast-check bit: summarizes either FS/XS/VS set" }, + "WPRI" : { "high_bit" : 30, "low_bit" : 20, "readonly" : True, "desc" : "resv" }, + "MXR" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "Make executable readable" }, + "SUM" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "Permit supervisor user memory access" }, + "WPRI" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "resv" }, + "XS" : { "high_bit" : 16, "low_bit" : 15, "readonly" : False, "desc" : "Extension status" }, + "FS" : { "high_bit" : 14, "low_bit" : 13, "readonly" : False, "desc" : "Floating-point status" }, + "WPRI" : { "high_bit" : 12, "low_bit" : 11, "readonly" : True, "desc" : "resv" }, + "VS" : { "high_bit" : 10, "low_bit" : 9, "readonly" : False, "desc" : "Vector status" }, + "SPP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor previous privilege mode" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "resv" }, + "UBE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from U-mode" }, + "SPIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Indicates whether S-mode interrupts were enabled prior to trapping into S-mode" }, + "UPIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "indicates whether U-mode interrupts were enabled prior to trapping into U-mode" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : True, "desc" : "resv" }, + "SIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable/Disable interrupts in S-mode" }, + "UIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable/disable interrupts in U-mode" } + }, 0], + 0x102: ["sedeleg", "Supervisor exception delegation register.", {}, 0], + 0x103: ["sideleg", "Supervisor interrupt delegation register.", {}, 0], + 0x104: ["sie", "Supervisor interrupt-enable register.", { + "SEIE" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enable supervisor-mode external interrupts" }, + "UEIE" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Enable user-mode external interrupts" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "STIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Enable supervisor-mode timer interrupts" }, + "UTIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Enable user-mode timer interrupts" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "SSIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable supervisor-mode software interrupts" }, + "USIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable user-mode software interrupts" } + }, 0], + 0x105: ["stvec", "Supervisor trap handler base address.", { + "BASE" : { "high_bit" : 31, "low_bit" : 2, "readonly" : False, "desc" : "Vector base address" }, + "MODE" : { "high_bit" : 1 , "low_bit" : 0, "readonly" : False, "desc" : "0 - Direct, 1 - Vectored" } + }, 0], + 0x106: ["scounteren", "Supervisor counter enable.", {}, 0], + + # Supervisor Configuration + 0x10a: ["senvcfg", "Supervisor environment configuration register.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 8, "readonly" : False, "desc" : "reserved" }, + "CBZE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Cache block zero instruction enable" }, + "CBCFE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Cache block clean and flush instruction enable" }, + "CBIE" : { "high_bit" : 5, "low_bit" : 4, "readonly" : False, "desc" : "Cache block invalidate instruction enable" }, + "FIOM" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fence of I/O implies Memory" }, + }, 0 ], + + # Supervisor Trap Handling + 0x140: ["sscratch", "Scratch register for supervisor trap handlers.", {}, 0], + 0x141: ["sepc", "Supervisor exception program counter.", {}, 0], + 0x142: ["scause", "Supervisor trap cause.", { + "Interrupt" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Bit to set a trap" }, + "Code" : { "high_bit" : 30, "low_bit" : 0, "readonly" : False, "desc" : "The exception code" } + }, 0], + 0x143: ["stval", "Supervisor bad address or instruction.", {}, 0], + 0x144: ["sip", "Supervisor interrupt pending.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "SEIP" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupt pending" }, + "UEIP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "User-mode external interrupts pending" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "STIP" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupt pending" }, + "UTIP" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "User-mode Machine timer interrupt pending" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "SSIP" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupt pending" }, + "USIP" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "User-mode software interrupt pending" } + }, 0], + + # Supervisor Protection and Translation + 0x180: ["satp", "Supervisor address translation and protection.", { + "MODE" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Type of translation" }, + "ASID" : { "high_bit" : 30, "low_bit" : 22, "readonly" : False, "desc" : "Address space identifier" }, + "PPN" : { "high_bit" : 21, "low_bit" : 0, "readonly" : False, "desc" : "Physical page number" } + }, 0], + + # Machine Information Registers + 0xf11: ["mvendorid", "Vendor ID.", { + "Bank" : { "high_bit" : 31, "low_bit" : 7, "readonly" : False, "desc" : "The number of one-byte continuation codes" }, + "Offset" : { "high_bit" : 6, "low_bit" : 0, "readonly" : True, "desc" : "Encodes the final byte" }, + }, 0], + 0xf12: ["marchid", "Architecture ID.", {}, 5], + 0xf13: ["mimpid", "Implementation ID.", {}, 0], + 0xf14: ["mhartid", "Hardware thread ID.", {}, 0], + 0xf15: ["mconfigptr", "Pointer to configuration data structure", {}, 0], + + # Machine Trap Setup + 0x300: ["mstatus", "Machine status register.", { + "SD" : { "high_bit" : 31, "low_bit" : 31, "readonly" : True, "desc" : "Fast-check bit: summarizes either FS/XS/VS set" }, + "WPRI" : { "high_bit" : 30, "low_bit" : 23, "readonly" : True, "desc" : "reserved" }, + "TSR" : { "high_bit" : 22, "low_bit" : 22, "readonly" : False, "desc" : "Trap SRET" }, + "TW" : { "high_bit" : 21, "low_bit" : 21, "readonly" : False, "desc" : "Timeout Wait" }, + "TVM" : { "high_bit" : 20, "low_bit" : 20, "readonly" : False, "desc" : "Trap Virtual Memory" }, + "MXR" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "Make executable readable" }, + "SUM" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "Permit supervisor user memory access" }, + "MPRV" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "Modify Privilege" }, + "XS" : { "high_bit" : 16, "low_bit" : 15, "readonly" : False, "desc" : "Extension status" }, + "FS" : { "high_bit" : 14, "low_bit" : 13, "readonly" : False, "desc" : "Floating-point status" }, + "MPP" : { "high_bit" : 12, "low_bit" : 11, "readonly" : False, "desc" : "Machine previous privilege mode" }, + "VS" : { "high_bit" : 10, "low_bit" : 9, "readonly" : False, "desc" : "Vector status" }, + "SPP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor previous privilege mode" }, + "MPIE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Indicates whether M-mode interrupts were enabled prior to trapping into M-mode" }, + "UBE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from U-mode" }, + "SPIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Indicates whether S-mode interrupts were enabled prior to trapping into S-mode" }, + "UPIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "indicates whether U-mode interrupts were enabled prior to trapping into U-mode" }, + "MIE" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Enable/Disable interrupts in M-mode" }, + "WPRI" : { "high_bit" : 2, "low_bit" : 2, "readonly" : True, "desc" : "reserved" }, + "SIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable/Disable interrupts in S-mode" }, + "UIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable/disable interrupts in U-mode" } + }, 0], + 0x301: ["misa", "ISA and extension.", { + "MXL" : { 'high_bit' : 31, 'low_bit' : 30, 'readonly' : False, "desc" : "Machine XLEN" }, + "WLRL" : { 'high_bit' : 29, 'low_bit' : 26, 'readonly' : False, "desc" : "Unknown" }, + "Extensions" : { 'high_bit' : 25, 'low_bit' : 0, 'readonly' : False, "desc" : "Encodes the native base integer ISA" }, + "A" : { 'high_bit' : 0 , 'low_bit' : 0 , 'readonly' : False, "desc" : "Atomic extension" }, + "B" : { 'high_bit' : 1 , 'low_bit' : 1 , 'readonly' : True, "desc" : "Bit Manipulation extension" }, + "C" : { 'high_bit' : 2 , 'low_bit' : 2 , 'readonly' : False, "desc" : "Compressed extension" }, + "D" : { 'high_bit' : 3 , 'low_bit' : 3 , 'readonly' : False, "desc" : "Double-precision extension" }, + "E" : { 'high_bit' : 4 , 'low_bit' : 4 , 'readonly' : True, "desc" : "RV32E extension" }, + "F" : { 'high_bit' : 5 , 'low_bit' : 5 , 'readonly' : False, "desc" : "Single-precision extension" }, + "G" : { 'high_bit' : 6 , 'low_bit' : 6 , 'readonly' : True, "desc" : "Additional standards extension" }, + "H" : { 'high_bit' : 7 , 'low_bit' : 7 , 'readonly' : True, "desc" : "Hypervisor extension" }, + "I" : { 'high_bit' : 8 , 'low_bit' : 8 , 'readonly' : True, "desc" : "RV32I/64I/128I base ISA extension" }, + "J" : { 'high_bit' : 9 , 'low_bit' : 9 , 'readonly' : True, "desc" : "Reserved" }, + "K" : { 'high_bit' : 10, 'low_bit' : 10, 'readonly' : True, "desc" : "Reserved" }, + "L" : { 'high_bit' : 11, 'low_bit' : 11, 'readonly' : True, "desc" : "Reserved" }, + "M" : { 'high_bit' : 12, 'low_bit' : 12, 'readonly' : False, "desc" : "Integer Multiply/Divide extension" }, + "N" : { 'high_bit' : 13, 'low_bit' : 13, 'readonly' : True, "desc" : "User-level interrupts extension" }, + "O" : { 'high_bit' : 14, 'low_bit' : 14, 'readonly' : True, "desc" : "Reserved" }, + "P" : { 'high_bit' : 15, 'low_bit' : 15, 'readonly' : True, "desc" : "Reserved" }, + "Q" : { 'high_bit' : 16, 'low_bit' : 16, 'readonly' : True, "desc" : "Quad-precision floating-point extension" }, + "R" : { 'high_bit' : 17, 'low_bit' : 17, 'readonly' : True, "desc" : "Reserved" }, + "S" : { 'high_bit' : 18, 'low_bit' : 18, 'readonly' : True, "desc" : "Supervisor mode implemented extension" }, + "T" : { 'high_bit' : 19, 'low_bit' : 19, 'readonly' : True, "desc" : "Reserved" }, + "U" : { 'high_bit' : 20, 'low_bit' : 20, 'readonly' : True, "desc" : "User mode implemented extension" }, + "V" : { 'high_bit' : 21, 'low_bit' : 21, 'readonly' : True, "desc" : "Vector extension" }, + "W" : { 'high_bit' : 22, 'low_bit' : 22, 'readonly' : True, "desc" : "Reserved" }, + "X" : { 'high_bit' : 23, 'low_bit' : 23, 'readonly' : True, "desc" : "Non-standard extensions" }, + "Y" : { 'high_bit' : 24, 'low_bit' : 24, 'readonly' : True, "desc" : "Reserved" }, + "Z" : { 'high_bit' : 25, 'low_bit' : 25, 'readonly' : True, "desc" : "Reserved" }, + }, 1075056941], + 0x302: ["medeleg", "Machine exception delegation register.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 24, "readonly" : True, "desc" : "reserved" }, + "MECALL" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode environment call" }, + }, 0], + 0x303: ["mideleg", "Machine interrupt delegation register.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEI" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Supervisor guest external interrupts" }, + "MEI" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode external interrupts" }, + "VSEI" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtuall supervisor-mode external interrupts" }, + "SEI" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupts" }, + "UEI" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "User-mode external interrupts" }, + "MTI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "Machine-mode timer interrupts" }, + "VSTI" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtuall supervisor-mode timer interrupts" }, + "STI" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupts" }, + "UTI" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "User-mode timer interrupts" }, + "MSI" : { "high_bit" : 3, "low_bit" : 3, "readonly" : True, "desc" : "Machine-mode software interrupts" }, + "VSSI" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupts" }, + "SSI" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupts" }, + "USI" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "User-mode software interrupts" } + }, 0], + 0x304: ["mie", "Machine interrupt-enable register.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEIE" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Enable supervisor guest external interrupts" }, + "MEIE" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "Enable machine-mode external interrupts" }, + "VSEIE" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Enable virtuall supervisor-mode external interrupts" }, + "SEIE" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enable supervisor-mode external interrupts" }, + "UEIE" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Enable user-mode external interrupts" }, + "MTIE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Enable machine-mode timer interrupts" }, + "VSTIE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enable virtuall supervisor-mode timer interrupts" }, + "STIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Enable supervisor-mode timer interrupts" }, + "UTIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Enable user-mode timer interrupts" }, + "MSIE" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Enable machine-mode software interrupts" }, + "VSSIE" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Enable virtual supervisor-mode software interrupts" }, + "SSIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable supervisor-mode software interrupts" }, + "USIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable user-mode software interrupts" } + }, 0], + 0x305: ["mtvec", "Machine trap-handler base address.", { + "BASE" : { "high_bit" : 31, "low_bit" : 2, "readonly" : False, "desc" : "Vector base address" }, + "MODE" : { "high_bit" : 1, "low_bit" : 0, "readonly" : False, "desc" : "0 - Direct, 1 - Vectored" } + }, 0], + 0x306: ["mcounteren", "Machine counter enable.", { + "HPM31" : { "high_bit" : 31 , "low_bit" : 31, "readonly" : False, "desc" : "undocumented" }, + "HPM30" : { "high_bit" : 30 , "low_bit" : 30, "readonly" : False, "desc" : "undocumented" }, + "HPM29" : { "high_bit" : 29 , "low_bit" : 29, "readonly" : False, "desc" : "undocumented" }, + "HPM28" : { "high_bit" : 28 , "low_bit" : 28, "readonly" : False, "desc" : "undocumented" }, + "HPM27" : { "high_bit" : 27 , "low_bit" : 27, "readonly" : False, "desc" : "undocumented" }, + "HPM26" : { "high_bit" : 26 , "low_bit" : 26, "readonly" : False, "desc" : "undocumented" }, + "HPM25" : { "high_bit" : 25 , "low_bit" : 25, "readonly" : False, "desc" : "undocumented" }, + "HPM24" : { "high_bit" : 24 , "low_bit" : 24, "readonly" : False, "desc" : "undocumented" }, + "HPM23" : { "high_bit" : 23 , "low_bit" : 23, "readonly" : False, "desc" : "undocumented" }, + "HPM22" : { "high_bit" : 22 , "low_bit" : 22, "readonly" : False, "desc" : "undocumented" }, + "HPM21" : { "high_bit" : 21 , "low_bit" : 21, "readonly" : False, "desc" : "undocumented" }, + "HPM20" : { "high_bit" : 20 , "low_bit" : 20, "readonly" : False, "desc" : "undocumented" }, + "HPM19" : { "high_bit" : 19 , "low_bit" : 19, "readonly" : False, "desc" : "undocumented" }, + "HPM18" : { "high_bit" : 18 , "low_bit" : 18, "readonly" : False, "desc" : "undocumented" }, + "HPM17" : { "high_bit" : 17 , "low_bit" : 17, "readonly" : False, "desc" : "undocumented" }, + "HPM16" : { "high_bit" : 16 , "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "HPM15" : { "high_bit" : 15 , "low_bit" : 15, "readonly" : False, "desc" : "undocumented" }, + "HPM14" : { "high_bit" : 14 , "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "HPM13" : { "high_bit" : 13 , "low_bit" : 13, "readonly" : False, "desc" : "undocumented" }, + "HPM12" : { "high_bit" : 12 , "low_bit" : 12, "readonly" : False, "desc" : "undocumented" }, + "HPM11" : { "high_bit" : 11 , "low_bit" : 11, "readonly" : False, "desc" : "undocumented" }, + "HPM10" : { "high_bit" : 10 , "low_bit" : 10, "readonly" : False, "desc" : "undocumented" }, + "HPM9" : { "high_bit" : 9 , "low_bit" : 9, "readonly" : False, "desc" : "undocumented" }, + "HPM8" : { "high_bit" : 8 , "low_bit" : 8, "readonly" : False, "desc" : "undocumented" }, + "HPM7" : { "high_bit" : 7 , "low_bit" : 7, "readonly" : False, "desc" : "undocumented" }, + "HPM6" : { "high_bit" : 6 , "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "HPM5" : { "high_bit" : 5 , "low_bit" : 5, "readonly" : False, "desc" : "undocumented" }, + "HPM4" : { "high_bit" : 4 , "low_bit" : 4, "readonly" : False, "desc" : "undocumented" }, + "HPM3" : { "high_bit" : 3 , "low_bit" : 3, "readonly" : False, "desc" : "undocumented" }, + "IR" : { "high_bit" : 2 , "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "TM" : { "high_bit" : 1 , "low_bit" : 1, "readonly" : False, "desc" : "undocumented" }, + "CY" : { "high_bit" : 0 , "low_bit" : 0, "readonly" : False, "desc" : "undocumented" } + }, 0], + 0x310: ["mstatush", "Additional machine status register, RV32 only", { + "WPRI" : { "high_bit" : 31, "low_bit" : 6, "readonly" : True, "desc" : "reserved" }, + "MPV" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Machine previous virtualization mode" }, + "GVA" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Guest virtual address" }, + "MBE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from M-mode" }, + "SBE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from S-mode" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 0, "readonly" : True, "desc" : "reserved" } + }, 0], + + # Machine Trap Handling + 0x340: ["mscratch", "Scratch register for machine trap handlers.", {}, 0], + 0x341: ["mepc", "Machine exception program counter.", {}, 0], + 0x342: ["mcause", "Machine trap cause.", { + "Interrupt" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Bit to set a trap" }, + "Code" : { "high_bit" : 30, "low_bit" : 0, "readonly" : False, "desc" : "The exception code" } + }, 0], + 0x343: ["mtval", "Machine bad address or instruction.", {}, 0], + 0x344: ["mip", "Machine interrupt pending.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 13, "readonly" : True, "desc" : "undocumented" }, + "SGEIP" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Supervisor guest external interrupt pending" }, + "MEIP" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "Machine-mode external interrupt pending" }, + "VSEIP" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtual supervisor-mode external interrupt pending" }, + "SEIP" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupt pending" }, + "UEIP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "User-mode external interrupts pending" }, + "MTIP" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Machine-mode timer interrupt pending" }, + "VSTIP" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtual supervisor-mode timer interrupt pending" }, + "STIP" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupt pending" }, + "UTIP" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "User-mode Machine timer interrupt pending" }, + "MSIP" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Machine-mode software interrupt pending" }, + "VSSIP" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupt pending" }, + "SSIP" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupt pending" }, + "USIP" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "User-mode software interrupt pending" } + }, 0], + 0x34a: ["mtinst", "Machine trap instruction (transformed).", {}, 0], + 0x34b: ["mtval2", "Machine bad guest physical address.", {}, 0], + + # Machine Configuration + 0x30a: ["menvcfg", "Machine environment configuration register.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 8, "readonly" : False, "desc" : "reserved" }, + "CBZE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Cache block zero instruction enable" }, + "CBCFE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Cache block clean and flush instruction enable" }, + "CBIE" : { "high_bit" : 5, "low_bit" : 4, "readonly" : False, "desc" : "Cache block invalidate instruction enable" }, + "FIOM" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fence of I/O implies Memory" }, + }, 0], + 0x31a: ["menvcfgh", "Additional machine environment configuration register, RV32 only.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 0, "readonly" : False, "desc" : "reserved" }, + }, 0], + 0x747: ["mseccfg", "Machine security configuration register.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 0, "readonly" : False, "desc" : "reserved" }, + }, 0], + 0x757: ["mseccfgh", "Additional machine security configuration register, RV32 only.", { + "WPRI" : { "high_bit" : 31, "low_bit" : 0, "readonly" : False, "desc" : "reserved" }, + }, 0], + + # Machine Memory Protection + 0x3a0: ["pmpcfg0", "Physical memory protection configuration.", {}, 0], + 0x3a1: ["pmpcfg1", "Physical memory protection configuration.", {}, 0], + 0x3a2: ["pmpcfg2", "Physical memory protection configuration.", {}, 0], + 0x3a3: ["pmpcfg3", "Physical memory protection configuration.", {}, 0], + 0x3a4: ["pmpcfg4", "Physical memory protection configuration.", {}, 0], + 0x3a5: ["pmpcfg5", "Physical memory protection configuration.", {}, 0], + 0x3a6: ["pmpcfg6", "Physical memory protection configuration.", {}, 0], + 0x3a7: ["pmpcfg7", "Physical memory protection configuration.", {}, 0], + 0x3a8: ["pmpcfg8", "Physical memory protection configuration.", {}, 0], + 0x3a9: ["pmpcfg9", "Physical memory protection configuration.", {}, 0], + 0x3aa: ["pmpcfg10", "Physical memory protection configuration.", {}, 0], + 0x3ab: ["pmpcfg11", "Physical memory protection configuration.", {}, 0], + 0x3ac: ["pmpcfg12", "Physical memory protection configuration.", {}, 0], + 0x3ad: ["pmpcfg13", "Physical memory protection configuration.", {}, 0], + 0x3ae: ["pmpcfg14", "Physical memory protection configuration.", {}, 0], + 0x3af: ["pmpcfg15", "Physical memory protection configuration.", {}, 0], + 0x3b0: ["pmpaddr0", "Physical memory protection address register.", {}, 0], + 0x3b1: ["pmpaddr1", "Physical memory protection address register.", {}, 0], + 0x3b2: ["pmpaddr2", "Physical memory protection address register.", {}, 0], + 0x3b3: ["pmpaddr3", "Physical memory protection address register.", {}, 0], + 0x3b4: ["pmpaddr4", "Physical memory protection address register.", {}, 0], + 0x3b5: ["pmpaddr5", "Physical memory protection address register.", {}, 0], + 0x3b6: ["pmpaddr6", "Physical memory protection address register.", {}, 0], + 0x3b7: ["pmpaddr7", "Physical memory protection address register.", {}, 0], + 0x3b8: ["pmpaddr8", "Physical memory protection address register.", {}, 0], + 0x3b9: ["pmpaddr9", "Physical memory protection address register.", {}, 0], + 0x3ba: ["pmpaddr10", "Physical memory protection address register.", {}, 0], + 0x3bb: ["pmpaddr11", "Physical memory protection address register.", {}, 0], + 0x3bc: ["pmpaddr12", "Physical memory protection address register.", {}, 0], + 0x3bd: ["pmpaddr13", "Physical memory protection address register.", {}, 0], + 0x3be: ["pmpaddr14", "Physical memory protection address register.", {}, 0], + 0x3bf: ["pmpaddr15", "Physical memory protection address register.", {}, 0], + 0x3c0: ["pmpaddr16", "Physical memory protection address register.", {}, 0], + 0x3c1: ["pmpaddr17", "Physical memory protection address register.", {}, 0], + 0x3c2: ["pmpaddr18", "Physical memory protection address register.", {}, 0], + 0x3c3: ["pmpaddr19", "Physical memory protection address register.", {}, 0], + 0x3c4: ["pmpaddr20", "Physical memory protection address register.", {}, 0], + 0x3c5: ["pmpaddr21", "Physical memory protection address register.", {}, 0], + 0x3c6: ["pmpaddr22", "Physical memory protection address register.", {}, 0], + 0x3c7: ["pmpaddr23", "Physical memory protection address register.", {}, 0], + 0x3c8: ["pmpaddr24", "Physical memory protection address register.", {}, 0], + 0x3c9: ["pmpaddr25", "Physical memory protection address register.", {}, 0], + 0x3ca: ["pmpaddr26", "Physical memory protection address register.", {}, 0], + 0x3cb: ["pmpaddr27", "Physical memory protection address register.", {}, 0], + 0x3cc: ["pmpaddr28", "Physical memory protection address register.", {}, 0], + 0x3cd: ["pmpaddr29", "Physical memory protection address register.", {}, 0], + 0x3ce: ["pmpaddr30", "Physical memory protection address register.", {}, 0], + 0x3cf: ["pmpaddr31", "Physical memory protection address register.", {}, 0], + 0x3d0: ["pmpaddr32", "Physical memory protection address register.", {}, 0], + 0x3d1: ["pmpaddr33", "Physical memory protection address register.", {}, 0], + 0x3d2: ["pmpaddr34", "Physical memory protection address register.", {}, 0], + 0x3d3: ["pmpaddr35", "Physical memory protection address register.", {}, 0], + 0x3d4: ["pmpaddr36", "Physical memory protection address register.", {}, 0], + 0x3d5: ["pmpaddr37", "Physical memory protection address register.", {}, 0], + 0x3d6: ["pmpaddr38", "Physical memory protection address register.", {}, 0], + 0x3d7: ["pmpaddr39", "Physical memory protection address register.", {}, 0], + 0x3d8: ["pmpaddr40", "Physical memory protection address register.", {}, 0], + 0x3d9: ["pmpaddr41", "Physical memory protection address register.", {}, 0], + 0x3da: ["pmpaddr42", "Physical memory protection address register.", {}, 0], + 0x3db: ["pmpaddr43", "Physical memory protection address register.", {}, 0], + 0x3dc: ["pmpaddr44", "Physical memory protection address register.", {}, 0], + 0x3dd: ["pmpaddr45", "Physical memory protection address register.", {}, 0], + 0x3de: ["pmpaddr46", "Physical memory protection address register.", {}, 0], + 0x3df: ["pmpaddr47", "Physical memory protection address register.", {}, 0], + 0x3e0: ["pmpaddr48", "Physical memory protection address register.", {}, 0], + 0x3e1: ["pmpaddr49", "Physical memory protection address register.", {}, 0], + 0x3e2: ["pmpaddr50", "Physical memory protection address register.", {}, 0], + 0x3e3: ["pmpaddr51", "Physical memory protection address register.", {}, 0], + 0x3e4: ["pmpaddr52", "Physical memory protection address register.", {}, 0], + 0x3e5: ["pmpaddr53", "Physical memory protection address register.", {}, 0], + 0x3e6: ["pmpaddr54", "Physical memory protection address register.", {}, 0], + 0x3e7: ["pmpaddr55", "Physical memory protection address register.", {}, 0], + 0x3e8: ["pmpaddr56", "Physical memory protection address register.", {}, 0], + 0x3e9: ["pmpaddr57", "Physical memory protection address register.", {}, 0], + 0x3ea: ["pmpaddr58", "Physical memory protection address register.", {}, 0], + 0x3eb: ["pmpaddr59", "Physical memory protection address register.", {}, 0], + 0x3ec: ["pmpaddr60", "Physical memory protection address register.", {}, 0], + 0x3ed: ["pmpaddr61", "Physical memory protection address register.", {}, 0], + 0x3ee: ["pmpaddr62", "Physical memory protection address register.", {}, 0], + 0x3ef: ["pmpaddr63", "Physical memory protection address register.", {}, 0], + + # Machine Counter/Timers + 0xB00: ["mcycle", "Machine cycle counter.", {}, 0], + 0xB02: ["minstret", "Machine instructions-retired counter.", {}, 0], + 0xB03: ["mhpmcounter3", "Machine performance-monitoring counter.", {}, 0], + 0xB04: ["mhpmcounter4", "Machine performance-monitoring counter.", {}, 0], + 0xB05: ["mhpmcounter5", "Machine performance-monitoring counter.", {}, 0], + 0xB06: ["mhpmcounter6", "Machine performance-monitoring counter.", {}, 0], + 0xB07: ["mhpmcounter7", "Machine performance-monitoring counter.", {}, 0], + 0xB08: ["mhpmcounter8", "Machine performance-monitoring counter.", {}, 0], + 0xB09: ["mhpmcounter9", "Machine performance-monitoring counter.", {}, 0], + 0xB0A: ["mhpmcounter10", "Machine performance-monitoring counter.", {}, 0], + 0xB0B: ["mhpmcounter11", "Machine performance-monitoring counter.", {}, 0], + 0xB0C: ["mhpmcounter12", "Machine performance-monitoring counter.", {}, 0], + 0xB0D: ["mhpmcounter13", "Machine performance-monitoring counter.", {}, 0], + 0xB0E: ["mhpmcounter14", "Machine performance-monitoring counter.", {}, 0], + 0xB0F: ["mhpmcounter15", "Machine performance-monitoring counter.", {}, 0], + 0xB10: ["mhpmcounter16", "Machine performance-monitoring counter.", {}, 0], + 0xB11: ["mhpmcounter17", "Machine performance-monitoring counter.", {}, 0], + 0xB12: ["mhpmcounter18", "Machine performance-monitoring counter.", {}, 0], + 0xB13: ["mhpmcounter19", "Machine performance-monitoring counter.", {}, 0], + 0xB14: ["mhpmcounter20", "Machine performance-monitoring counter.", {}, 0], + 0xB15: ["mhpmcounter21", "Machine performance-monitoring counter.", {}, 0], + 0xB16: ["mhpmcounter22", "Machine performance-monitoring counter.", {}, 0], + 0xB17: ["mhpmcounter23", "Machine performance-monitoring counter.", {}, 0], + 0xB18: ["mhpmcounter24", "Machine performance-monitoring counter.", {}, 0], + 0xB19: ["mhpmcounter25", "Machine performance-monitoring counter.", {}, 0], + 0xB1A: ["mhpmcounter26", "Machine performance-monitoring counter.", {}, 0], + 0xB1B: ["mhpmcounter27", "Machine performance-monitoring counter.", {}, 0], + 0xB1C: ["mhpmcounter28", "Machine performance-monitoring counter.", {}, 0], + 0xB1D: ["mhpmcounter29", "Machine performance-monitoring counter.", {}, 0], + 0xB1E: ["mhpmcounter30", "Machine performance-monitoring counter.", {}, 0], + 0xB1F: ["mhpmcounter31", "Machine performance-monitoring counter.", {}, 0], + + # Machine Counter Setup + 0x320: ["mcountinhibit", "Machine counter-inhibit register.", { + "HPM31" : { "high_bit" : 31 , "low_bit" : 31, "readonly" : False, "desc" : "undocumented" }, + "HPM30" : { "high_bit" : 30 , "low_bit" : 30, "readonly" : False, "desc" : "undocumented" }, + "HPM29" : { "high_bit" : 29 , "low_bit" : 29, "readonly" : False, "desc" : "undocumented" }, + "HPM28" : { "high_bit" : 28 , "low_bit" : 28, "readonly" : False, "desc" : "undocumented" }, + "HPM27" : { "high_bit" : 27 , "low_bit" : 27, "readonly" : False, "desc" : "undocumented" }, + "HPM26" : { "high_bit" : 26 , "low_bit" : 26, "readonly" : False, "desc" : "undocumented" }, + "HPM25" : { "high_bit" : 25 , "low_bit" : 25, "readonly" : False, "desc" : "undocumented" }, + "HPM24" : { "high_bit" : 24 , "low_bit" : 24, "readonly" : False, "desc" : "undocumented" }, + "HPM23" : { "high_bit" : 23 , "low_bit" : 23, "readonly" : False, "desc" : "undocumented" }, + "HPM22" : { "high_bit" : 22 , "low_bit" : 22, "readonly" : False, "desc" : "undocumented" }, + "HPM21" : { "high_bit" : 21 , "low_bit" : 21, "readonly" : False, "desc" : "undocumented" }, + "HPM20" : { "high_bit" : 20 , "low_bit" : 20, "readonly" : False, "desc" : "undocumented" }, + "HPM19" : { "high_bit" : 19 , "low_bit" : 19, "readonly" : False, "desc" : "undocumented" }, + "HPM18" : { "high_bit" : 18 , "low_bit" : 18, "readonly" : False, "desc" : "undocumented" }, + "HPM17" : { "high_bit" : 17 , "low_bit" : 17, "readonly" : False, "desc" : "undocumented" }, + "HPM16" : { "high_bit" : 16 , "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "HPM15" : { "high_bit" : 15 , "low_bit" : 15, "readonly" : False, "desc" : "undocumented" }, + "HPM14" : { "high_bit" : 14 , "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "HPM13" : { "high_bit" : 13 , "low_bit" : 13, "readonly" : False, "desc" : "undocumented" }, + "HPM12" : { "high_bit" : 12 , "low_bit" : 12, "readonly" : False, "desc" : "undocumented" }, + "HPM11" : { "high_bit" : 11 , "low_bit" : 11, "readonly" : False, "desc" : "undocumented" }, + "HPM10" : { "high_bit" : 10 , "low_bit" : 10, "readonly" : False, "desc" : "undocumented" }, + "HPM9" : { "high_bit" : 9 , "low_bit" : 9, "readonly" : False, "desc" : "undocumented" }, + "HPM8" : { "high_bit" : 8 , "low_bit" : 8, "readonly" : False, "desc" : "undocumented" }, + "HPM7" : { "high_bit" : 7 , "low_bit" : 7, "readonly" : False, "desc" : "undocumented" }, + "HPM6" : { "high_bit" : 6 , "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "HPM5" : { "high_bit" : 5 , "low_bit" : 5, "readonly" : False, "desc" : "undocumented" }, + "HPM4" : { "high_bit" : 4 , "low_bit" : 4, "readonly" : False, "desc" : "undocumented" }, + "HPM3" : { "high_bit" : 3 , "low_bit" : 3, "readonly" : False, "desc" : "undocumented" }, + "IR" : { "high_bit" : 2 , "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "RESV" : { "high_bit" : 1 , "low_bit" : 1, "readonly" : True, "desc" : "undocumented" }, + "CY" : { "high_bit" : 0 , "low_bit" : 0, "readonly" : False, "desc" : "undocumented" } + }, 0], + 0x323: ["mhpmevent3", "Machine performance-monitoring event selector.", {}, 0], + 0x324: ["mhpmevent4", "Machine performance-monitoring event selector.", {}, 0], + 0x325: ["mhpmevent5", "Machine performance-monitoring event selector.", {}, 0], + 0x326: ["mhpmevent6", "Machine performance-monitoring event selector.", {}, 0], + 0x327: ["mhpmevent7", "Machine performance-monitoring event selector.", {}, 0], + 0x328: ["mhpmevent8", "Machine performance-monitoring event selector.", {}, 0], + 0x329: ["mhpmevent9", "Machine performance-monitoring event selector.", {}, 0], + 0x32A: ["mhpmevent10", "Machine performance-monitoring event selector.", {}, 0], + 0x32B: ["mhpmevent11", "Machine performance-monitoring event selector.", {}, 0], + 0x32C: ["mhpmevent12", "Machine performance-monitoring event selector.", {}, 0], + 0x32D: ["mhpmevent13", "Machine performance-monitoring event selector.", {}, 0], + 0x32E: ["mhpmevent14", "Machine performance-monitoring event selector.", {}, 0], + 0x32F: ["mhpmevent15", "Machine performance-monitoring event selector.", {}, 0], + 0x330: ["mhpmevent16", "Machine performance-monitoring event selector.", {}, 0], + 0x331: ["mhpmevent17", "Machine performance-monitoring event selector.", {}, 0], + 0x332: ["mhpmevent18", "Machine performance-monitoring event selector.", {}, 0], + 0x333: ["mhpmevent19", "Machine performance-monitoring event selector.", {}, 0], + 0x334: ["mhpmevent20", "Machine performance-monitoring event selector.", {}, 0], + 0x335: ["mhpmevent21", "Machine performance-monitoring event selector.", {}, 0], + 0x336: ["mhpmevent22", "Machine performance-monitoring event selector.", {}, 0], + 0x337: ["mhpmevent23", "Machine performance-monitoring event selector.", {}, 0], + 0x338: ["mhpmevent24", "Machine performance-monitoring event selector.", {}, 0], + 0x339: ["mhpmevent25", "Machine performance-monitoring event selector.", {}, 0], + 0x33A: ["mhpmevent26", "Machine performance-monitoring event selector.", {}, 0], + 0x33B: ["mhpmevent27", "Machine performance-monitoring event selector.", {}, 0], + 0x33C: ["mhpmevent28", "Machine performance-monitoring event selector.", {}, 0], + 0x33D: ["mhpmevent29", "Machine performance-monitoring event selector.", {}, 0], + 0x33E: ["mhpmevent30", "Machine performance-monitoring event selector.", {}, 0], + 0x33F: ["mhpmevent31", "Machine performance-monitoring event selector.", {}, 0], + + # Hypervisor Registers + 0x200: ["vsstatus", "Virtual superviosr status register", { + "SD" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Fast-check bit: summarizes either FS/XS/VS set" }, + "WPRI" : { "high_bit" : 30, "low_bit" : 20, "readonly" : True, "desc" : "resv" }, + "MXR" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "Make executable readable" }, + "SUM" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "Permit supervisor user memory access" }, + "WPRI" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "resv" }, + "XS" : { "high_bit" : 16, "low_bit" : 15, "readonly" : False, "desc" : "Extension status" }, + "FS" : { "high_bit" : 14, "low_bit" : 13, "readonly" : False, "desc" : "Floating-point status" }, + "WPRI" : { "high_bit" : 12, "low_bit" : 11, "readonly" : True, "desc" : "resv" }, + "VS" : { "high_bit" : 10, "low_bit" : 9, "readonly" : False, "desc" : "Vector status" }, + "SPP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor previous privilege mode" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "resv" }, + "UBE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from U-mode" }, + "SPIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Indicates whether S-mode interrupts were enabled prior to trapping into S-mode" }, + "WPRI" : { "high_bit" : 4, "low_bit" : 2, "readonly" : True, "desc" : "resv" }, + "SIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable/Disable interrupts in S-mode" }, + "WPRI" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "resv" }, + }, 0], + 0x204: ["vsie", "Virtual supervisor interrupt-enable register", { + "SEIE" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enable supervisor-mode external interrupts" }, + "UEIE" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Enable user-mode external interrupts" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "STIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Enable supervisor-mode timer interrupts" }, + "UTIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Enable user-mode timer interrupts" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "SSIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable supervisor-mode software interrupts" }, + "USIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable user-mode software interrupts" } + }, 0], + 0x205: ["vstvec", "Virtual supervisor trap vector base address register", { + "BASE" : { "high_bit" : 31, "low_bit" : 2, "readonly" : False, "desc" : "Vector base address" }, + "MODE" : { "high_bit" : 1 , "low_bit" : 0, "readonly" : False, "desc" : "0 - Direct, 1 - Vectored" } + }, 0], + 0x240: ["vsscratch", "Virtual supervisor scratch register", {}, 0], + 0x241: ["vsepc", "Virtual supervisor exception program counter", {}, 0], + 0x242: ["vscause", "Virtual supervisor cause register", { + "Interrupt" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Bit to set a trap" }, + "Code" : { "high_bit" : 30, "low_bit" : 0 , "readonly" : False, "desc" : "The exception code" } + }, 0], + 0x243: ["vstval", "Virtual supervisor trap value register", {}, 0], + 0x244: ["vsip", "Virtual supervisor interrupt-pending register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "SEIP" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupt pending" }, + "UEIP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "User-mode external interrupts pending" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "STIP" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupt pending" }, + "UTIP" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "User-mode Machine timer interrupt pending" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "SSIP" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupt pending" }, + "USIP" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "User-mode software interrupt pending" } + }, 0], + 0x280: ["vsatp", "Virtual interrupt-pending register", { + "MODE" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Type of translation" }, + "ASID" : { "high_bit" : 30, "low_bit" : 22, "readonly" : False, "desc" : "Address space identifier" }, + "PPN" : { "high_bit" : 21, "low_bit" : 0, "readonly" : False, "desc" : "Physical page number" } + }, 0], + + 0x600: ["hstatus", "Hypervisor status register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 23, "readonly" : True, "desc" : "reserved" }, + "VTSR" : { "high_bit" : 22, "low_bit" : 22, "readonly" : False, "desc" : "Virtual Trap SRET" }, + "VTW" : { "high_bit" : 21, "low_bit" : 21, "readonly" : False, "desc" : "Virtual Timeout Wait" }, + "VTVM" : { "high_bit" : 20, "low_bit" : 20, "readonly" : False, "desc" : "Virtual Trap Virtual Memory" }, + "WPRI" : { "high_bit" : 19, "low_bit" : 18, "readonly" : True, "desc" : "reserved" }, + "VGEIN" : { "high_bit" : 17, "low_bit" : 12, "readonly" : False, "desc" : "Virtual Guest External Interrupt Number" }, + "WPRI" : { "high_bit" : 11, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "HU" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Hypervisor in U-mode" }, + "SPVP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor Previous Virtual Privilege" }, + "SPV" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Supervisor Previous Virtualization mode" }, + "GVA" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Guest Virtual Address" }, + "VSBE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : True, "desc" : "Controls endianness of explicit memory accesses made from VS-mode" }, + "WPRI" : { "high_bit" : 4, "low_bit" : 0, "readonly" : True, "desc" : "reserved" }, + }, 0], + 0x602: ["hedeleg", "Hypervisor exception delegation register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 24, "readonly" : True, "desc" : "reserved" }, + "SGPF" : { "high_bit" : 23, "low_bit" : 23, "readonly" : True, "desc" : "Store/AMO guest-page fault" }, + "VIRTINST" : { "high_bit" : 22, "low_bit" : 22, "readonly" : True, "desc" : "Virtual instruction" }, + "LGPF" : { "high_bit" : 21, "low_bit" : 21, "readonly" : True, "desc" : "Load guest-page fault" }, + "IGPF" : { "high_bit" : 20, "low_bit" : 20, "readonly" : True, "desc" : "Instruction guest-page fault" }, + "WPRI" : { "high_bit" : 19, "low_bit" : 16, "readonly" : True, "desc" : "reserved" }, + "WPRI" : { "high_bit" : 14, "low_bit" : 14, "readonly" : True, "desc" : "reserved" }, + "MECALL" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode environment call" }, + "VSECALL" : { "high_bit" : 10, "low_bit" : 10, "readonly" : True, "desc" : "Virtual supervisor-mode environment call" }, + "HSECALL" : { "high_bit" : 9, "low_bit" : 9, "readonly" : True, "desc" : "Supervisor-mode environment call" }, + }, 0], + 0x603: ["hideleg", "Hypervisor interrupt delegation register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEI" : { "high_bit" : 12, "low_bit" : 12, "readonly" : True, "desc" : "Supervisor guest external interrupts" }, + "MEI" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode external interrupts" }, + "VSEI" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtuall supervisor-mode external interrupts" }, + "SEI" : { "high_bit" : 9, "low_bit" : 9, "readonly" : True, "desc" : "Supervisor-mode external interrupts" }, + "UEI" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "User-mode external interrupts" }, + "MTI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "Machine-mode timer interrupts" }, + "VSTI" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtuall supervisor-mode timer interrupts" }, + "STI" : { "high_bit" : 5, "low_bit" : 5, "readonly" : True, "desc" : "Supervisor-mode timer interrupts" }, + "UTI" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "User-mode timer interrupts" }, + "MSI" : { "high_bit" : 3, "low_bit" : 3, "readonly" : True, "desc" : "Machine-mode software interrupts" }, + "VSSI" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupts" }, + "SSI" : { "high_bit" : 1, "low_bit" : 1, "readonly" : True, "desc" : "Supervisor-mode software interrupts" }, + "USI" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "User-mode software interrupts" } + }, 0], + 0x604: ["hie", "Hypervisor interrupt-enable register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEIE" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Enable supervisor guest external interrupts" }, + "VSEIE" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Enable virtuall supervisor-mode external interrupts" }, + "VSTIE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enable virtuall supervisor-mode timer interrupts" }, + "VSSIE" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Enable virtual supervisor-mode software interrupts" }, + }, 0], + 0x606: ["hcounteren", "Hypervisor counter-enable register", {}, 0], + 0x607: ["hgeie", "Hypervisor guest external interrupt-enable register", {}, 0], + 0x643: ["htval", "Hypervisor trap value register", {}, 0], + 0x644: ["hip", "Hypervisor interrupt-pending register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEIP" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Supervisor guest external interrupt pending" }, + "VSEIP" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtual supervisor-mode external interrupt pending" }, + "VSTIP" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtual supervisor-mode timer interrupt pending" }, + "VSSIP" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupt pending" }, + }, 0], + 0x645: ["hvip", "Hypervisor virtual-interrupt-pending register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 11, "readonly" : True, "desc" : "reserved" }, + "VSEIP" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtual supervisor-mode external interrupt pending" }, + "VSTIP" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtual supervisor-mode timer interrupt pending" }, + "VSSIP" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupt pending" }, + }, 0], + 0x64a: ["htinst", "Hypervisor trap instruction register", {}, 0], + 0xe12: ["hgeip", "Hypervisor guest external interrupt pending", {}, 0], + 0x680: ["hgatp", "Hypervisor guest address translation and protection register", { + "MODE" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Type of translation" }, + "WPRI" : { "high_bit" : 30, "low_bit" : 29, "readonly" : True, "desc" : "reserved" }, + "VMID" : { "high_bit" : 28, "low_bit" : 22, "readonly" : False, "desc" : "Virtual machine identifier" }, + "PPN" : { "high_bit" : 21, "low_bit" : 0, "readonly" : False, "desc" : "Physical page number" } + }, 0], + 0x60a: ["henvcfg", "Hypervisor environment configuration register", { + "WPRI" : { "high_bit" : 31, "low_bit" : 8, "readonly" : False, "desc" : "reserved" }, + "CBZE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Cache block zero instruction enable" }, + "CBCFE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Cache block clean and flush instruction enable" }, + "CBIE" : { "high_bit" : 5, "low_bit" : 4, "readonly" : False, "desc" : "Cache block invalidate instruction enable" }, + "FIOM" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fence of I/O implies Memory" }, + }, 0], + 0x61a: ["henvcfgh", "Additional hypervisor environment configuration register, RV32 only", {}, 0], + 0x605: ["htimedelta", "Hypervisor time delta register", {}, 0], + 0x615: ["htimedeltah", "Upper 32 bits of htimedelta, HSXLEN=32 only", {}, 0], + 0x6a8: ["hcontext", "Hypervisor mode context register", {}, 0], + + # Debug/Trace Registers (shared with Debug Mode) + 0x7a0: ["tselect", "Debug/Trace trigger register select.", {}, 0], + 0x7a1: ["tdata1", "First Debug/Trace trigger data register.", { + "type" : { "high_bit" : 31, "low_bit" : 28, "readonly" : False, "desc" : "Type of trigger" }, + "dmode" : { "high_bit" : 27, "low_bit" : 27, "readonly" : False, "desc" : "If bit is set, only Debug Mode can write to the tdata registers. Other writes are ignored." }, + "data" : { "high_bit" : 26, "low_bit" : 0, "readonly" : False, "desc" : "Trigger-specific data" }, + "mcontrol_maskmax" : { "high_bit" : 26, "low_bit" : 23, "readonly" : False, "desc" : "FIXME: Debug spec has a bug, not enough bits for RV32" }, + "mcontrol_sizehi" : { "high_bit" : 22, "low_bit" : 21, "readonly" : False, "desc" : "TODO" }, + "mcontrol_hit" : { "high_bit" : 20, "low_bit" : 20, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "mcontrol_select" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "TODO" }, + "mcontrol_timing" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "TODO" }, + "mcontrol_sizelo" : { "high_bit" : 17, "low_bit" : 16, "readonly" : False, "desc" : "TODO" }, + "mcontrol_action" : { "high_bit" : 15, "low_bit" : 12, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + "mcontrol_chain" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "TODO" }, + "mcontrol_match" : { "high_bit" : 10, "low_bit" : 7, "readonly" : False, "desc" : "TODO" }, + "mcontrol_m" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enables this trigger in M-mode" }, + "mcontrol_s" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Enables this trigger in S-mode" }, + "mcontrol_u" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Enables this trigger in U-mode" }, + "mcontrol_execute" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "When set, trigger fires on VA or opcode of instructions" }, + "mcontrol_store" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "When set, trigger fires on VA or data of stores" }, + "mcontrol_load" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "When set, trigger fires on VA or data of loads" }, + "icount_hit" : { "high_bit" : 24, "low_bit" : 24, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "icount_count" : { "high_bit" : 23, "low_bit" : 10, "readonly" : False, "desc" : "When count is decremented to 0, this trigger fires" }, + "icount_m" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Decrement count in M-mode" }, + "icount_s" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Decrement count in S-mode" }, + "icount_u" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Decrement count in U-mode" }, + "icount_action" : { "high_bit" : 5, "low_bit" : 0, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + "etrigger_hit" : { "high_bit" : 26, "low_bit" : 26, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "etrigger_m" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enables this trigger in M-mode" }, + "etrigger_s" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Enables this trigger in S-mode" }, + "etrigger_u" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enables this trigger in U-mode" }, + "etrigger_action" : { "high_bit" : 5, "low_bit" : 0, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + "itrigger_hit" : { "high_bit" : 26, "low_bit" : 26, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "itrigger_m" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enables this trigger in M-mode" }, + "itrigger_s" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Enables this trigger in S-mode" }, + "itrigger_u" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enables this trigger in U-mode" }, + "itrigger_action" : { "high_bit" : 5, "low_bit" : 0, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + }, 0], + 0x7a2: ["tdata2", "Second Debug/Trace trigger data register.", {}, 0], + 0x7a3: ["tdata3", "Third Debug/Trace trigger data register.", {}, 0], + 0x7a4: ["tinfo", "Trigger info", {}, 0], + 0x7a5: ["tcontrol", "Trigger control", { + "Resv" : { "high_bit" : 31, "low_bit" : 8, "readonly" : True, "desc" : "Tied to zero" }, + "mpte" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "M-mode previous trigger enable field" }, + "Resv" : { "high_bit" : 6, "low_bit" : 4, "readonly" : True, "desc" : "Tied to zero" }, + "mte" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "M-mode trigger enable field" }, + "Resv" : { "high_bit" : 2, "low_bit" : 0, "readonly" : True, "desc" : "Tied to zero" }, + }, 0], + 0x7a8: ["mcontext", "Machine context", {}, 0], + 0x7aa: ["scontext", "Supervisor context", {}, 0], + + #Debug Mode Registers + 0x7b0: ["dcsr", "Debug control and status register.", { + "xdebugver" : { "high_bit" : 31, "low_bit" : 28, "readonly" : True, "desc" : "External debug support available" }, + "RESV" : { "high_bit" : 27, "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "ebreakm" : { "high_bit" : 15, "low_bit" : 15, "readonly" : False, "desc" : "If set, M-mode ebreak instructions will enter debug mode" }, + "RESV" : { "high_bit" : 14, "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "ebreaks" : { "high_bit" : 13, "low_bit" : 13, "readonly" : False, "desc" : "If set, S-mode ebreak instructions will enter debug mode" }, + "ebreaku" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "If set, U-mode ebreak instructions will enter debug mode" }, + "stepie" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "Enables interrupts during single-stepping" }, + "stopcount" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "If set, don't increment any counters while in debug mode" }, + "stoptime" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "If set, don't increment any timers while in debug mode" }, + "cause" : { "high_bit" : 8, "low_bit" : 6, "readonly" : False, "desc" : "Explains why debug mode was entered" }, + "RESV" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "undocumented" }, + "mprven" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "If not set, ignore mstatus.mprv when in debug mode" }, + "nmip" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "When set, there is a non-maskable interrupt pending" }, + "step" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "When set and not in debug mode, execute a single execute then enter debug mode" }, + "prv" : { "high_bit" : 1, "low_bit" : 0, "readonly" : True, "desc" : "Previous privilege mode when entering debug mode" } + }, 0], + 0x7b1: ["dpc", "Debug PC", {}, 0], + 0x7b2: ["dscratch0", "Debug scratch register 0.", {}, 0], + 0x7b3: ["dscratch1", "Debug scratch register 1.", {}, 0], +} diff --git a/sparta/scripts/RV64_CONSTANT.py b/sparta/scripts/RV64_CONSTANT.py new file mode 100644 index 0000000000..476cef5bcf --- /dev/null +++ b/sparta/scripts/RV64_CONSTANT.py @@ -0,0 +1,22 @@ +# Created for recording constants + +RV64_CONSTS = { + "NUM_EXTENSION_CHARS" : [26, "Size of Extensions field in MISA (A-Z)"], + "PMP_BIT_R" : [1, "Bitfield of PMP_R (Read)"], + "PMP_BIT_W" : [2, "Bitfield of PMP_W (Write)"], + "PMP_BIT_X" : [4, "Bitfield of PMP_X (eXecute)"], + "PMP_BIT_A" : [24, "Bitfield of PMP_A (Access)"], + "PMP_BIT_L" : [128, "Bitfield of PMP_L (Lock)"], + "PMP_MODE_TOR" : [8, "Bitfield of PMP mode: TopOfRange"], + "PMP_MODE_NA4" : [16, "Bitfield of PMP mode: Naturally Aligned of 4"], + "PMP_MODE_NAPOT" : [24, "Bitfield of PMP mode: Naturally Aligned of Power Of Two"], + "PMP_MAX_NUM" : [64, "The maximum PMP entries supported"], + "PMP_MIN_GRANULARITY": [4, "The minimum PMP granularity"], + "PMP_MIN_GRANULARITY_SHIFT": [2, "The minimum PMP granularity (in shift values)"], +} + +ATHENA_INTERNAL_REGISTERS = { + "ATHENA_INTERNAL_PC": [0x20, "Athena internal register to hold the program counter"], + "ATHENA_INTERNAL_RESV_ADDR": [0x21, "Athena internal register to hold the load reservation address"], + "ATHENA_INTERNAL_RESV_VALID": [0x22, "Athena internal register to hold whether the load reservation is valid"], +} diff --git a/sparta/scripts/RV64_CSR.py b/sparta/scripts/RV64_CSR.py new file mode 100644 index 0000000000..f526794289 --- /dev/null +++ b/sparta/scripts/RV64_CSR.py @@ -0,0 +1,791 @@ +# + +CSR64_DEFS = { + # User Trap Setup + 0x000: ["ustatus", "User status register.", {}, 0], + 0x004: ["uie", "User interrupt-enable register.", {}, 0], + 0x005: ["utvec", "User trap handler base address.", {}, 0], + + # Debug + 0x010: ["dmcontrol", "Debug module control", { + "Resv" : { "high_bit" : 63, "low_bit" : 32, "readonly" : True, "desc" : "undocumented" }, + "haltreq" : { "high_bit" : 31, "low_bit" : 31, "readonly" : False, "desc" : "Halt request for currently selected harts" }, + "resumereq" : { "high_bit" : 30, "low_bit" : 30, "readonly" : False, "desc" : "Resume request for currently selected harts" }, + "hartreset" : { "high_bit" : 29, "low_bit" : 29, "readonly" : False, "desc" : "Writes reset bit for all currently selected harts" }, + "ackhavereset" : { "high_bit" : 28, "low_bit" : 28, "readonly" : False, "desc" : "If set, clears havereset for any selected harts" }, + "Resv" : { "high_bit" : 27, "low_bit" : 27, "readonly" : True, "desc" : "undocumented" }, + "hasel" : { "high_bit" : 26, "low_bit" : 26, "readonly" : True, "desc" : "Selects the definition of hartsel" }, + "hartsello" : { "high_bit" : 25, "low_bit" : 16, "readonly" : False, "desc" : "Low 10 bits of hartsel" }, + "hartselhi" : { "high_bit" : 15, "low_bit" : 6, "readonly" : False, "desc" : "High 10 bits of hartsel" }, + "Resv" : { "high_bit" : 5, "low_bit" : 4, "readonly" : True, "desc" : "undocumented" }, + "setresethartreq" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Writes halt-on-reset request bit for all currently selected harts" }, + "clrresethaltreq" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Clears halt-on-reset request bit for all currently selected harts" }, + "ndmreset" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Controls the reset signal from the DM to the rest of the system" }, + "dmactive" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Reset signal for the Debug Module itself" }, + }, 0], + 0x011: ["dmstatus", "Debug module status", { + "Resv" : { "high_bit" : 63, "low_bit" : 23, "readonly" : True, "desc" : "undocumented" }, + "impebreak" : { "high_bit" : 22, "low_bit" : 22, "readonly" : False, "desc" : "undocumented" }, + "Resv" : { "high_bit" : 21, "low_bit" : 20, "readonly" : True, "desc" : "undocumented" }, + "allhavereset" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "undocumented" }, + "anyhavereset" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "undocumented" }, + "allresumeack" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "undocumented" }, + "anyresumeack" : { "high_bit" : 16, "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "allnonexistent" : { "high_bit" : 15, "low_bit" : 15, "readonly" : False, "desc" : "undocumented" }, + "anynonexistent" : { "high_bit" : 14, "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "allunavail" : { "high_bit" : 13, "low_bit" : 13, "readonly" : False, "desc" : "undocumented" }, + "anyunavail" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "undocumented" }, + "allrunning" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "undocumented" }, + "anyrunning" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "undocumented" }, + "allhalted" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "undocumented" }, + "anyhalted" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "undocumented" }, + "authenticated" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "Status of authentication (set to 1 if DM doesn't implement authentication)" }, + "authbusy" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Authentication module is ready to process the next read/write to authdata" }, + "hasresethaltreq" : { "high_bit" : 5, "low_bit" : 5, "readonly" : True, "desc" : "If set, this Debug Module supports halt-on-reset" }, + "confstrptrvalid" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "If set, confstrptr0-confstrptr3 hold the address of the configuration string" }, + "version" : { "high_bit" : 3, "low_bit" : 0, "readonly" : True, "desc" : "Version of Debug Module spec supported" }, + }, 0], + + # User Trap Setup + 0x040: ["uscratch", "Scratch register for user trap handlers.", {}, 0], + 0x041: ["uepc", "User exception program counter.", {}, 0], + 0x042: ["ucause", "Scratch register for user trap handlers.", {}, 0], + 0x043: ["utval", "User bad address or instruction.", {}, 0], + 0x044: ["uip", "User interrupt pending.", {}, 0], + + # User Floating-Point CSRs + 0x001: ["fflags", "Floating-Point Accrued Exceptions.", { + "Resv" : { "high_bit" : 63, "low_bit" : 5, "readonly" : True, "desc" : "undocumented" }, + "NV" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Invalid operation" }, + "DZ" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Divide by zero" }, + "OF" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Overflow" }, + "UF" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Underflow" }, + "NX" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Inexact" }, + }, 0], + 0x002: ["frm", "Floating-Point Dynamic Rounding Mode.", {}, 0], + 0x003: ["fcsr", "Floating-Point Control and Status Register (frm + fflags).", { + "Resv" : { "high_bit" : 63, "low_bit" : 8, "readonly" : True, "desc" : "undocumented" }, + "frm" : { "high_bit" : 7, "low_bit" : 5, "readonly" : False, "desc" : "Rounding Mode" }, + "NV" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Invalid Operation" }, + "DZ" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Divide by zero" }, + "OF" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Overflow" }, + "UF" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Underflow" }, + "NX" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Inexact" }, + "fflags" : { "high_bit" : 4, "low_bit" : 0, "readonly" : False, "desc" : "Accured Exceptions" } + }, 0], + + # User Vector CSRs + 0x008: ["vstart", "The index of the first element to be executed by a vector instruction.", {}, 0], + 0x009: ["vxsat", "To indicate whether a fixed-point instruction needs to saturate.", { + "vxsat" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Saturate" }, + "Resv" : { "high_bit" : 63, "low_bit" : 1, "readonly" : True, "desc" : "undocumented" }, + }, 0], + 0x00A: ["vxrm", "Vector fixed-point rounding-mode register.", { + "vxrm" : { "high_bit" : 1, "low_bit" : 0, "readonly" : False, "desc" : "Rounding mode" }, + "Resv" : { "high_bit" : 63, "low_bit" : 2, "readonly" : True, "desc" : "undocumented" }, + }, 0], + 0x00F: ["vcsr", "Vector control and status register.", { + "vxsat" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fixed-point accrued saturation flag" }, + "vxrm" : { "high_bit" : 2, "low_bit" : 1, "readonly" : False, "desc" : "Fixed-point rounding mode" }, + "Resv" : { "high_bit" : 63, "low_bit" : 3, "readonly" : True, "desc" : "undocumented" }, + }, 0], + 0xC20: ["vl", "Vector length register.", {}, 0], + 0xC21: ["vtype", "Vector type register.", { + "vlmul" : { "high_bit" : 2, "low_bit" : 0, "readonly" : False, "desc" : "Vector register group multiplier" }, + "vsew" : { "high_bit" : 5, "low_bit" : 3, "readonly" : False, "desc" : "Selected element width" }, + "vta" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Vector tail agnostic mode" }, + "vma" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Vector mask agnostic mode" }, + "Resv" : { "high_bit" : 62, "low_bit" : 8, "readonly" : True, "desc" : "undocumented" }, + "vill" : { "high_bit" : 63, "low_bit" : 63,"readonly" : False, "desc" : "Illegal value if set" } + }, 0], + 0xC22: ["vlenb", "Vector byte length.", {}, 0], + + # User Counter/Timers + 0xC00: ["cycle", "Cycle counter for RDCYCLE instruction.", {}, 0], + 0xC01: ["time", "Timer for RDTIME instruction.", {}, 0], + 0xC02: ["instret", "Instructions-retired counter for RDINSTRET instruction.", {}, 0], + 0xC03: ["hpmcounter3", "Performance-monitoring counter.", {}, 0], + 0xC04: ["hpmcounter4", "Performance-monitoring counter.", {}, 0], + 0xC05: ["hpmcounter5", "Performance-monitoring counter.", {}, 0], + 0xC06: ["hpmcounter6", "Performance-monitoring counter.", {}, 0], + 0xC07: ["hpmcounter7", "Performance-monitoring counter.", {}, 0], + 0xC08: ["hpmcounter8", "Performance-monitoring counter.", {}, 0], + 0xC09: ["hpmcounter9", "Performance-monitoring counter.", {}, 0], + 0xC0A: ["hpmcounter10", "Performance-monitoring counter.", {}, 0], + 0xC0B: ["hpmcounter11", "Performance-monitoring counter.", {}, 0], + 0xC0C: ["hpmcounter12", "Performance-monitoring counter.", {}, 0], + 0xC0D: ["hpmcounter13", "Performance-monitoring counter.", {}, 0], + 0xC0E: ["hpmcounter14", "Performance-monitoring counter.", {}, 0], + 0xC0F: ["hpmcounter15", "Performance-monitoring counter.", {}, 0], + 0xC10: ["hpmcounter16", "Performance-monitoring counter.", {}, 0], + 0xC11: ["hpmcounter17", "Performance-monitoring counter.", {}, 0], + 0xC12: ["hpmcounter18", "Performance-monitoring counter.", {}, 0], + 0xC13: ["hpmcounter19", "Performance-monitoring counter.", {}, 0], + 0xC14: ["hpmcounter20", "Performance-monitoring counter.", {}, 0], + 0xC15: ["hpmcounter21", "Performance-monitoring counter.", {}, 0], + 0xC16: ["hpmcounter22", "Performance-monitoring counter.", {}, 0], + 0xC17: ["hpmcounter23", "Performance-monitoring counter.", {}, 0], + 0xC18: ["hpmcounter24", "Performance-monitoring counter.", {}, 0], + 0xC19: ["hpmcounter25", "Performance-monitoring counter.", {}, 0], + 0xC1A: ["hpmcounter26", "Performance-monitoring counter.", {}, 0], + 0xC1B: ["hpmcounter27", "Performance-monitoring counter.", {}, 0], + 0xC1C: ["hpmcounter28", "Performance-monitoring counter.", {}, 0], + 0xC1D: ["hpmcounter29", "Performance-monitoring counter.", {}, 0], + 0xC1E: ["hpmcounter30", "Performance-monitoring counter.", {}, 0], + 0xC1F: ["hpmcounter31", "Performance-monitoring counter.", {}, 0], + + # Supervisor Trap Setup + 0x100: ["sstatus", "Supervisor status register.", { + "SD" : { "high_bit" : 63, "low_bit" : 63, "readonly" : False, "desc" : "Fast-check bit: summarizes either FS/XS/VS set" }, + "WPRI" : { "high_bit" : 62, "low_bit" : 34, "readonly" : True, "desc" : "resv" }, + "UXL" : { "high_bit" : 33, "low_bit" : 32, "readonly" : True, "desc" : "Controls XLEN value for U-mode" }, + "WPRI" : { "high_bit" : 31, "low_bit" : 20, "readonly" : True, "desc" : "resv" }, + "MXR" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "Make executable readable" }, + "SUM" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "Permit supervisor user memory access" }, + "WPRI" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "resv" }, + "XS" : { "high_bit" : 16, "low_bit" : 15, "readonly" : False, "desc" : "Extension status" }, + "FS" : { "high_bit" : 14, "low_bit" : 13, "readonly" : False, "desc" : "Floating-point status" }, + "WPRI" : { "high_bit" : 12, "low_bit" : 11, "readonly" : True, "desc" : "resv" }, + "VS" : { "high_bit" : 10, "low_bit" : 9, "readonly" : False, "desc" : "Vector status" }, + "SPP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor previous privilege mode" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "resv" }, + "UBE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from U-mode" }, + "SPIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Indicates whether S-mode interrupts were enabled prior to trapping into S-mode" }, + "UPIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "indicates whether U-mode interrupts were enabled prior to trapping into U-mode" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : True, "desc" : "resv" }, + "SIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable/Disable interrupts in S-mode" }, + "UIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable/disable interrupts in U-mode" } + }, 0], + 0x102: ["sedeleg", "Supervisor exception delegation register.", {}, 0], + 0x103: ["sideleg", "Supervisor interrupt delegation register.", {}, 0], + 0x104: ["sie", "Supervisor interrupt-enable register.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "SEIE" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enable supervisor-mode external interrupts" }, + "UEIE" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "Enable user-mode external interrupts" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : True, "desc" : "undocumented" }, + "STIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Enable supervisor-mode timer interrupts" }, + "UTIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "Enable user-mode timer interrupts" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : True, "desc" : "undocumented" }, + "SSIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable supervisor-mode software interrupts" }, + "USIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "Enable user-mode software interrupts" } + }, 0], + 0x105: ["stvec", "Supervisor trap handler base address.", { + "BASE" : { "high_bit" : 63, "low_bit" : 2, "readonly" : False, "desc" : "Vector base address" }, + "MODE" : { "high_bit" : 1 , "low_bit" : 0, "readonly" : False, "desc" : "0 - Direct, 1 - Vectored" } + }, 0], + 0x106: ["scounteren", "Supervisor counter enable.", {}, 0], + + # Supervisor Configuration + 0x10a: ["senvcfg", "Supervisor environment configuration register.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 8, "readonly" : False, "desc" : "reserved" }, + "CBZE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Cache block zero instruction enable" }, + "CBCFE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Cache block clean and flush instruction enable" }, + "CBIE" : { "high_bit" : 5, "low_bit" : 4, "readonly" : False, "desc" : "Cache block invalidate instruction enable" }, + "FIOM" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fence of I/O implies Memory" }, + }, 0 ], + + # Supervisor Trap Handling + 0x140: ["sscratch", "Scratch register for supervisor trap handlers.", {}, 0], + 0x141: ["sepc", "Supervisor exception program counter.", {}, 0], + 0x142: ["scause", "Supervisor trap cause.", { + "Interrupt" : { "high_bit" : 63, "low_bit" : 63, "readonly" : False, "desc" : "Bit to set a trap" }, + "Code" : { "high_bit" : 62, "low_bit" : 0, "readonly" : False, "desc" : "The exception code" } + }, 0], + 0x143: ["stval", "Supervisor bad address or instruction.", {}, 0], + 0x144: ["sip", "Supervisor interrupt pending.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "SEIP" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupt pending" }, + "UEIP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "User-mode external interrupts pending" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : True, "desc" : "undocumented" }, + "STIP" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupt pending" }, + "UTIP" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "User-mode Machine timer interrupt pending" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : True, "desc" : "undocumented" }, + "SSIP" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupt pending" }, + "USIP" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "User-mode software interrupt pending" } + }, 0], + + # Supervisor Protection and Translation + 0x180: ["satp", "Supervisor address translation and protection.", { + "MODE" : { "high_bit" : 63, "low_bit" : 60, "readonly" : False, "desc" : "Type of translation" }, + "ASID" : { "high_bit" : 59, "low_bit" : 44, "readonly" : False, "desc" : "Address space identifier" }, + "PPN" : { "high_bit" : 43, "low_bit" : 0, "readonly" : False, "desc" : "Physical page number" } + }, 0], + + # Machine Information Registers + 0xf11: ["mvendorid", "Vendor ID.", { + "Bank" : { "high_bit" : 31, "low_bit" : 7, "readonly" : False, "desc" : "The number of one-byte continuation codes" }, + "Offset" : { "high_bit" : 6, "low_bit" : 0, "readonly" : True, "desc" : "Encodes the final byte" }, + }, 0], + 0xf12: ["marchid", "Architecture ID.", {}, 0], + 0xf13: ["mimpid", "Implementation ID.", {}, 0], + 0xf14: ["mhartid", "Hardware thread ID.", {}, 0], + 0xf15: ["mconfigptr", "Pointer to configuration data structure", {}, 0], + + # Machine Trap Setup + 0x300: ["mstatus", "Machine status register.", { + "SD" : { "high_bit" : 63, "low_bit" : 63, "readonly" : False, "desc" : "Fast-check bit: summarizes either FS/XS/VS set" }, + "WPRI" : { "high_bit" : 62, "low_bit" : 40, "readonly" : True, "desc" : "reserved" }, + "MPV" : { "high_bit" : 39, "low_bit" : 39, "readonly" : False, "desc" : "Machine Previous Virtualization Mode" }, + "GVA" : { "high_bit" : 38, "low_bit" : 38, "readonly" : False, "desc" : "Guest Virtual Address" }, + "MBE" : { "high_bit" : 37, "low_bit" : 37, "readonly" : True, "desc" : "Controls endianness of explicit memory accesses made from M-mode" }, + "SBE" : { "high_bit" : 36, "low_bit" : 36, "readonly" : True, "desc" : "Controls endianness of explicit memory accesses made from S-mode" }, + "SXL" : { "high_bit" : 35, "low_bit" : 34, "readonly" : True, "desc" : "Controls XLEN value for S-mode" }, + "UXL" : { "high_bit" : 33, "low_bit" : 32, "readonly" : True, "desc" : "Controls XLEN value for U-mode" }, + "WPRI" : { "high_bit" : 31, "low_bit" : 23, "readonly" : True, "desc" : "undocumented" }, + "TSR" : { "high_bit" : 22, "low_bit" : 22, "readonly" : False, "desc" : "Trap SRET" }, + "TW" : { "high_bit" : 21, "low_bit" : 21, "readonly" : False, "desc" : "Timeout Wait" }, + "TVM" : { "high_bit" : 20, "low_bit" : 20, "readonly" : False, "desc" : "Trap Virtual Memory" }, + "MXR" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "Make executable readable" }, + "SUM" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "Permit supervisor user memory access" }, + "MPRV" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "Modify Privilege" }, + "XS" : { "high_bit" : 16, "low_bit" : 15, "readonly" : False, "desc" : "Extension status" }, + "FS" : { "high_bit" : 14, "low_bit" : 13, "readonly" : False, "desc" : "Floating-point status" }, + "MPP" : { "high_bit" : 12, "low_bit" : 11, "readonly" : False, "desc" : "Machine previous privilege mode" }, + "VS" : { "high_bit" : 10, "low_bit" : 9, "readonly" : False, "desc" : "Vector status" }, + "SPP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor previous privilege mode" }, + "MPIE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Indicates whether M-mode interrupts were enabled prior to trapping into M-mode" }, + "UBE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from U-mode" }, + "SPIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Indicates whether S-mode interrupts were enabled prior to trapping into S-mode" }, + "UPIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "indicates whether U-mode interrupts were enabled prior to trapping into U-mode" }, + "MIE" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Enable/Disable interrupts in M-mode" }, + "WPRI" : { "high_bit" : 2, "low_bit" : 2, "readonly" : True, "desc" : "reserved" }, + "SIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable/Disable interrupts in S-mode" }, + "UIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable/disable interrupts in U-mode" } + }, 0], + 0x301: ["misa", "ISA and extension.", { + "MXL" : { 'high_bit' : 63, 'low_bit' : 62, 'readonly' : False, "desc" : "Machine XLEN" }, + "WLRL" : { 'high_bit' : 61, 'low_bit' : 26, 'readonly' : False, "desc" : "Unknown" }, + "Extensions" : { 'high_bit' : 25, 'low_bit' : 0, 'readonly' : False, "desc" : "Encodes the native base integer ISA" }, + "A" : { 'high_bit' : 0 , 'low_bit' : 0 , 'readonly' : False, "desc" : "Atomic extension" }, + "B" : { 'high_bit' : 1 , 'low_bit' : 1 , 'readonly' : True, "desc" : "Bit Manipulation extension" }, + "C" : { 'high_bit' : 2 , 'low_bit' : 2 , 'readonly' : False, "desc" : "Compressed extension" }, + "D" : { 'high_bit' : 3 , 'low_bit' : 3 , 'readonly' : False, "desc" : "Double-precision extension" }, + "E" : { 'high_bit' : 4 , 'low_bit' : 4 , 'readonly' : True, "desc" : "RV32E extension" }, + "F" : { 'high_bit' : 5 , 'low_bit' : 5 , 'readonly' : False, "desc" : "Single-precision extension" }, + "G" : { 'high_bit' : 6 , 'low_bit' : 6 , 'readonly' : True, "desc" : "Additional standards extension" }, + "H" : { 'high_bit' : 7 , 'low_bit' : 7 , 'readonly' : True, "desc" : "Hypervisor extension" }, + "I" : { 'high_bit' : 8 , 'low_bit' : 8 , 'readonly' : True, "desc" : "RV32I/64I/128I base ISA extension" }, + "J" : { 'high_bit' : 9 , 'low_bit' : 9 , 'readonly' : True, "desc" : "Reserved" }, + "K" : { 'high_bit' : 10, 'low_bit' : 10, 'readonly' : True, "desc" : "Reserved" }, + "L" : { 'high_bit' : 11, 'low_bit' : 11, 'readonly' : True, "desc" : "Reserved" }, + "M" : { 'high_bit' : 12, 'low_bit' : 12, 'readonly' : False, "desc" : "Integer Multiply/Divide extension" }, + "N" : { 'high_bit' : 13, 'low_bit' : 13, 'readonly' : True, "desc" : "User-level interrupts extension" }, + "O" : { 'high_bit' : 14, 'low_bit' : 14, 'readonly' : True, "desc" : "Reserved" }, + "P" : { 'high_bit' : 15, 'low_bit' : 15, 'readonly' : True, "desc" : "Reserved" }, + "Q" : { 'high_bit' : 16, 'low_bit' : 16, 'readonly' : True, "desc" : "Quad-precision floating-point extension" }, + "R" : { 'high_bit' : 17, 'low_bit' : 17, 'readonly' : True, "desc" : "Reserved" }, + "S" : { 'high_bit' : 18, 'low_bit' : 18, 'readonly' : True, "desc" : "Supervisor mode implemented extension" }, + "T" : { 'high_bit' : 19, 'low_bit' : 19, 'readonly' : True, "desc" : "Reserved" }, + "U" : { 'high_bit' : 20, 'low_bit' : 20, 'readonly' : True, "desc" : "User mode implemented extension" }, + "V" : { 'high_bit' : 21, 'low_bit' : 21, 'readonly' : True, "desc" : "Vector extension" }, + "W" : { 'high_bit' : 22, 'low_bit' : 22, 'readonly' : True, "desc" : "Reserved" }, + "X" : { 'high_bit' : 23, 'low_bit' : 23, 'readonly' : True, "desc" : "Non-standard extensions" }, + "Y" : { 'high_bit' : 24, 'low_bit' : 24, 'readonly' : True, "desc" : "Reserved" }, + "Z" : { 'high_bit' : 25, 'low_bit' : 25, 'readonly' : True, "desc" : "Reserved" }, + }, 0], + 0x302: ["medeleg", "Machine exception delegation register.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 24, "readonly" : True, "desc" : "reserved" }, + "MECALL" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode environment call" }, + }, 0], + 0x303: ["mideleg", "Machine interrupt delegation register.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEI" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Supervisor guest external interrupts" }, + "MEI" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode external interrupts" }, + "VSEI" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtuall supervisor-mode external interrupts" }, + "SEI" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupts" }, + "UEI" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "User-mode external interrupts" }, + "MTI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "Machine-mode timer interrupts" }, + "VSTI" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtuall supervisor-mode timer interrupts" }, + "STI" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupts" }, + "UTI" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "User-mode timer interrupts" }, + "MSI" : { "high_bit" : 3, "low_bit" : 3, "readonly" : True, "desc" : "Machine-mode software interrupts" }, + "VSSI" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupts" }, + "SSI" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupts" }, + "USI" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "User-mode software interrupts" } + }, 0], + 0x304: ["mie", "Machine interrupt-enable register.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEIE" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Enable supervisor guest external interrupts" }, + "MEIE" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "Enable machine-mode external interrupts" }, + "VSEIE" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Enable virtuall supervisor-mode external interrupts" }, + "SEIE" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enable supervisor-mode external interrupts" }, + "UEIE" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Enable user-mode external interrupts" }, + "MTIE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Enable machine-mode timer interrupts" }, + "VSTIE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enable virtuall supervisor-mode timer interrupts" }, + "STIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Enable supervisor-mode timer interrupts" }, + "UTIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Enable user-mode timer interrupts" }, + "MSIE" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Enable machine-mode software interrupts" }, + "VSSIE" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Enable virtual supervisor-mode software interrupts" }, + "SSIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable supervisor-mode software interrupts" }, + "USIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Enable user-mode software interrupts" } + }, 0], + 0x305: ["mtvec", "Machine trap-handler base address.", { + "BASE" : { "high_bit" : 63, "low_bit" : 2, "readonly" : False, "desc" : "Vector base address" }, + "MODE" : { "high_bit" : 1, "low_bit" : 0, "readonly" : False, "desc" : "0 - Direct, 1 - Vectored" } + }, 0], + 0x306: ["mcounteren", "Machine counter enable.", { + "HPM31" : { "high_bit" : 31 , "low_bit" : 31, "readonly" : False, "desc" : "undocumented" }, + "HPM30" : { "high_bit" : 30 , "low_bit" : 30, "readonly" : False, "desc" : "undocumented" }, + "HPM29" : { "high_bit" : 29 , "low_bit" : 29, "readonly" : False, "desc" : "undocumented" }, + "HPM28" : { "high_bit" : 28 , "low_bit" : 28, "readonly" : False, "desc" : "undocumented" }, + "HPM27" : { "high_bit" : 27 , "low_bit" : 27, "readonly" : False, "desc" : "undocumented" }, + "HPM26" : { "high_bit" : 26 , "low_bit" : 26, "readonly" : False, "desc" : "undocumented" }, + "HPM25" : { "high_bit" : 25 , "low_bit" : 25, "readonly" : False, "desc" : "undocumented" }, + "HPM24" : { "high_bit" : 24 , "low_bit" : 24, "readonly" : False, "desc" : "undocumented" }, + "HPM23" : { "high_bit" : 23 , "low_bit" : 23, "readonly" : False, "desc" : "undocumented" }, + "HPM22" : { "high_bit" : 22 , "low_bit" : 22, "readonly" : False, "desc" : "undocumented" }, + "HPM21" : { "high_bit" : 21 , "low_bit" : 21, "readonly" : False, "desc" : "undocumented" }, + "HPM20" : { "high_bit" : 20 , "low_bit" : 20, "readonly" : False, "desc" : "undocumented" }, + "HPM19" : { "high_bit" : 19 , "low_bit" : 19, "readonly" : False, "desc" : "undocumented" }, + "HPM18" : { "high_bit" : 18 , "low_bit" : 18, "readonly" : False, "desc" : "undocumented" }, + "HPM17" : { "high_bit" : 17 , "low_bit" : 17, "readonly" : False, "desc" : "undocumented" }, + "HPM16" : { "high_bit" : 16 , "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "HPM15" : { "high_bit" : 15 , "low_bit" : 15, "readonly" : False, "desc" : "undocumented" }, + "HPM14" : { "high_bit" : 14 , "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "HPM13" : { "high_bit" : 13 , "low_bit" : 13, "readonly" : False, "desc" : "undocumented" }, + "HPM12" : { "high_bit" : 12 , "low_bit" : 12, "readonly" : False, "desc" : "undocumented" }, + "HPM11" : { "high_bit" : 11 , "low_bit" : 11, "readonly" : False, "desc" : "undocumented" }, + "HPM10" : { "high_bit" : 10 , "low_bit" : 10, "readonly" : False, "desc" : "undocumented" }, + "HPM9" : { "high_bit" : 9 , "low_bit" : 9, "readonly" : False, "desc" : "undocumented" }, + "HPM8" : { "high_bit" : 8 , "low_bit" : 8, "readonly" : False, "desc" : "undocumented" }, + "HPM7" : { "high_bit" : 7 , "low_bit" : 7, "readonly" : False, "desc" : "undocumented" }, + "HPM6" : { "high_bit" : 6 , "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "HPM5" : { "high_bit" : 5 , "low_bit" : 5, "readonly" : False, "desc" : "undocumented" }, + "HPM4" : { "high_bit" : 4 , "low_bit" : 4, "readonly" : False, "desc" : "undocumented" }, + "HPM3" : { "high_bit" : 3 , "low_bit" : 3, "readonly" : False, "desc" : "undocumented" }, + "IR" : { "high_bit" : 2 , "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "TM" : { "high_bit" : 1 , "low_bit" : 1, "readonly" : False, "desc" : "undocumented" }, + "CY" : { "high_bit" : 0 , "low_bit" : 0, "readonly" : False, "desc" : "undocumented" } + }, 0], + + # Machine Trap Handling + 0x340: ["mscratch", "Scratch register for machine trap handlers.", {}, 0], + 0x341: ["mepc", "Machine exception program counter.", {}, 0], + 0x342: ["mcause", "Machine trap cause.", { + "Interrupt" : { "high_bit" : 63, "low_bit" : 63, "readonly" : False, "desc" : "Bit to set a trap" }, + "Code" : { "high_bit" : 62, "low_bit" : 0, "readonly" : False, "desc" : "The exception code" } + }, 0], + 0x343: ["mtval", "Machine bad address or instruction.", {}, 0], + 0x344: ["mip", "Machine interrupt pending.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 13, "readonly" : True, "desc" : "undocumented" }, + "SGEIP" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Supervisor guest external interrupt pending" }, + "MEIP" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "Machine-mode external interrupt pending" }, + "VSEIP" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtual supervisor-mode external interrupt pending" }, + "SEIP" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupt pending" }, + "UEIP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "User-mode external interrupts pending" }, + "MTIP" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Machine-mode timer interrupt pending" }, + "VSTIP" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtual supervisor-mode timer interrupt pending" }, + "STIP" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupt pending" }, + "UTIP" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "User-mode Machine timer interrupt pending" }, + "MSIP" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Machine-mode software interrupt pending" }, + "VSSIP" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupt pending" }, + "SSIP" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupt pending" }, + "USIP" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "User-mode software interrupt pending" } + }, 0], + 0x34a: ["mtinst", "Machine trap instruction (transformed).", {}, 0], + 0x34b: ["mtval2", "Machine bad guest physical address.", {}, 0], + + # Machine Configuration + 0x30a: ["menvcfg", "Machine environment configuration register.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 8, "readonly" : False, "desc" : "reserved" }, + "CBZE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Cache block zero instruction enable" }, + "CBCFE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Cache block clean and flush instruction enable" }, + "CBIE" : { "high_bit" : 5, "low_bit" : 4, "readonly" : False, "desc" : "Cache block invalidate instruction enable" }, + "FIOM" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fence of I/O implies Memory" }, + }, 0], + 0x747: ["mseccfg", "Machine security configuration register.", { + "WPRI" : { "high_bit" : 63, "low_bit" : 0, "readonly" : False, "desc" : "reserved" }, + }, 0], + + # Machine Memory Protection + 0x3a0: ["pmpcfg0", "Physical memory protection configuration.", {}, 0], + 0x3a2: ["pmpcfg2", "Physical memory protection configuration.", {}, 0], + 0x3a4: ["pmpcfg4", "Physical memory protection configuration.", {}, 0], + 0x3a6: ["pmpcfg6", "Physical memory protection configuration.", {}, 0], + 0x3a8: ["pmpcfg8", "Physical memory protection configuration.", {}, 0], + 0x3aa: ["pmpcfg10", "Physical memory protection configuration.", {}, 0], + 0x3ac: ["pmpcfg12", "Physical memory protection configuration.", {}, 0], + 0x3ae: ["pmpcfg14", "Physical memory protection configuration.", {}, 0], + 0x3b0: ["pmpaddr0", "Physical memory protection address register.", {}, 0], + 0x3b1: ["pmpaddr1", "Physical memory protection address register.", {}, 0], + 0x3b2: ["pmpaddr2", "Physical memory protection address register.", {}, 0], + 0x3b3: ["pmpaddr3", "Physical memory protection address register.", {}, 0], + 0x3b4: ["pmpaddr4", "Physical memory protection address register.", {}, 0], + 0x3b5: ["pmpaddr5", "Physical memory protection address register.", {}, 0], + 0x3b6: ["pmpaddr6", "Physical memory protection address register.", {}, 0], + 0x3b7: ["pmpaddr7", "Physical memory protection address register.", {}, 0], + 0x3b8: ["pmpaddr8", "Physical memory protection address register.", {}, 0], + 0x3b9: ["pmpaddr9", "Physical memory protection address register.", {}, 0], + 0x3ba: ["pmpaddr10", "Physical memory protection address register.", {}, 0], + 0x3bb: ["pmpaddr11", "Physical memory protection address register.", {}, 0], + 0x3bc: ["pmpaddr12", "Physical memory protection address register.", {}, 0], + 0x3bd: ["pmpaddr13", "Physical memory protection address register.", {}, 0], + 0x3be: ["pmpaddr14", "Physical memory protection address register.", {}, 0], + 0x3bf: ["pmpaddr15", "Physical memory protection address register.", {}, 0], + 0x3c0: ["pmpaddr16", "Physical memory protection address register.", {}, 0], + 0x3c1: ["pmpaddr17", "Physical memory protection address register.", {}, 0], + 0x3c2: ["pmpaddr18", "Physical memory protection address register.", {}, 0], + 0x3c3: ["pmpaddr19", "Physical memory protection address register.", {}, 0], + 0x3c4: ["pmpaddr20", "Physical memory protection address register.", {}, 0], + 0x3c5: ["pmpaddr21", "Physical memory protection address register.", {}, 0], + 0x3c6: ["pmpaddr22", "Physical memory protection address register.", {}, 0], + 0x3c7: ["pmpaddr23", "Physical memory protection address register.", {}, 0], + 0x3c8: ["pmpaddr24", "Physical memory protection address register.", {}, 0], + 0x3c9: ["pmpaddr25", "Physical memory protection address register.", {}, 0], + 0x3ca: ["pmpaddr26", "Physical memory protection address register.", {}, 0], + 0x3cb: ["pmpaddr27", "Physical memory protection address register.", {}, 0], + 0x3cc: ["pmpaddr28", "Physical memory protection address register.", {}, 0], + 0x3cd: ["pmpaddr29", "Physical memory protection address register.", {}, 0], + 0x3ce: ["pmpaddr30", "Physical memory protection address register.", {}, 0], + 0x3cf: ["pmpaddr31", "Physical memory protection address register.", {}, 0], + 0x3d0: ["pmpaddr32", "Physical memory protection address register.", {}, 0], + 0x3d1: ["pmpaddr33", "Physical memory protection address register.", {}, 0], + 0x3d2: ["pmpaddr34", "Physical memory protection address register.", {}, 0], + 0x3d3: ["pmpaddr35", "Physical memory protection address register.", {}, 0], + 0x3d4: ["pmpaddr36", "Physical memory protection address register.", {}, 0], + 0x3d5: ["pmpaddr37", "Physical memory protection address register.", {}, 0], + 0x3d6: ["pmpaddr38", "Physical memory protection address register.", {}, 0], + 0x3d7: ["pmpaddr39", "Physical memory protection address register.", {}, 0], + 0x3d8: ["pmpaddr40", "Physical memory protection address register.", {}, 0], + 0x3d9: ["pmpaddr41", "Physical memory protection address register.", {}, 0], + 0x3da: ["pmpaddr42", "Physical memory protection address register.", {}, 0], + 0x3db: ["pmpaddr43", "Physical memory protection address register.", {}, 0], + 0x3dc: ["pmpaddr44", "Physical memory protection address register.", {}, 0], + 0x3dd: ["pmpaddr45", "Physical memory protection address register.", {}, 0], + 0x3de: ["pmpaddr46", "Physical memory protection address register.", {}, 0], + 0x3df: ["pmpaddr47", "Physical memory protection address register.", {}, 0], + 0x3e0: ["pmpaddr48", "Physical memory protection address register.", {}, 0], + 0x3e1: ["pmpaddr49", "Physical memory protection address register.", {}, 0], + 0x3e2: ["pmpaddr50", "Physical memory protection address register.", {}, 0], + 0x3e3: ["pmpaddr51", "Physical memory protection address register.", {}, 0], + 0x3e4: ["pmpaddr52", "Physical memory protection address register.", {}, 0], + 0x3e5: ["pmpaddr53", "Physical memory protection address register.", {}, 0], + 0x3e6: ["pmpaddr54", "Physical memory protection address register.", {}, 0], + 0x3e7: ["pmpaddr55", "Physical memory protection address register.", {}, 0], + 0x3e8: ["pmpaddr56", "Physical memory protection address register.", {}, 0], + 0x3e9: ["pmpaddr57", "Physical memory protection address register.", {}, 0], + 0x3ea: ["pmpaddr58", "Physical memory protection address register.", {}, 0], + 0x3eb: ["pmpaddr59", "Physical memory protection address register.", {}, 0], + 0x3ec: ["pmpaddr60", "Physical memory protection address register.", {}, 0], + 0x3ed: ["pmpaddr61", "Physical memory protection address register.", {}, 0], + 0x3ee: ["pmpaddr62", "Physical memory protection address register.", {}, 0], + 0x3ef: ["pmpaddr63", "Physical memory protection address register.", {}, 0], + + # Machine Counter/Timers + 0xB00: ["mcycle", "Machine cycle counter.", {}, 0], + 0xB02: ["minstret", "Machine instructions-retired counter.", {}, 0], + 0xB03: ["mhpmcounter3", "Machine performance-monitoring counter.", {}, 0], + 0xB04: ["mhpmcounter4", "Machine performance-monitoring counter.", {}, 0], + 0xB05: ["mhpmcounter5", "Machine performance-monitoring counter.", {}, 0], + 0xB06: ["mhpmcounter6", "Machine performance-monitoring counter.", {}, 0], + 0xB07: ["mhpmcounter7", "Machine performance-monitoring counter.", {}, 0], + 0xB08: ["mhpmcounter8", "Machine performance-monitoring counter.", {}, 0], + 0xB09: ["mhpmcounter9", "Machine performance-monitoring counter.", {}, 0], + 0xB0A: ["mhpmcounter10", "Machine performance-monitoring counter.", {}, 0], + 0xB0B: ["mhpmcounter11", "Machine performance-monitoring counter.", {}, 0], + 0xB0C: ["mhpmcounter12", "Machine performance-monitoring counter.", {}, 0], + 0xB0D: ["mhpmcounter13", "Machine performance-monitoring counter.", {}, 0], + 0xB0E: ["mhpmcounter14", "Machine performance-monitoring counter.", {}, 0], + 0xB0F: ["mhpmcounter15", "Machine performance-monitoring counter.", {}, 0], + 0xB10: ["mhpmcounter16", "Machine performance-monitoring counter.", {}, 0], + 0xB11: ["mhpmcounter17", "Machine performance-monitoring counter.", {}, 0], + 0xB12: ["mhpmcounter18", "Machine performance-monitoring counter.", {}, 0], + 0xB13: ["mhpmcounter19", "Machine performance-monitoring counter.", {}, 0], + 0xB14: ["mhpmcounter20", "Machine performance-monitoring counter.", {}, 0], + 0xB15: ["mhpmcounter21", "Machine performance-monitoring counter.", {}, 0], + 0xB16: ["mhpmcounter22", "Machine performance-monitoring counter.", {}, 0], + 0xB17: ["mhpmcounter23", "Machine performance-monitoring counter.", {}, 0], + 0xB18: ["mhpmcounter24", "Machine performance-monitoring counter.", {}, 0], + 0xB19: ["mhpmcounter25", "Machine performance-monitoring counter.", {}, 0], + 0xB1A: ["mhpmcounter26", "Machine performance-monitoring counter.", {}, 0], + 0xB1B: ["mhpmcounter27", "Machine performance-monitoring counter.", {}, 0], + 0xB1C: ["mhpmcounter28", "Machine performance-monitoring counter.", {}, 0], + 0xB1D: ["mhpmcounter29", "Machine performance-monitoring counter.", {}, 0], + 0xB1E: ["mhpmcounter30", "Machine performance-monitoring counter.", {}, 0], + 0xB1F: ["mhpmcounter31", "Machine performance-monitoring counter.", {}, 0], + + # Machine Counter Setup + 0x320: ["mcountinhibit", "Machine counter-inhibit register.", { + "HPM31" : { "high_bit" : 31 , "low_bit" : 31, "readonly" : False, "desc" : "undocumented" }, + "HPM30" : { "high_bit" : 30 , "low_bit" : 30, "readonly" : False, "desc" : "undocumented" }, + "HPM29" : { "high_bit" : 29 , "low_bit" : 29, "readonly" : False, "desc" : "undocumented" }, + "HPM28" : { "high_bit" : 28 , "low_bit" : 28, "readonly" : False, "desc" : "undocumented" }, + "HPM27" : { "high_bit" : 27 , "low_bit" : 27, "readonly" : False, "desc" : "undocumented" }, + "HPM26" : { "high_bit" : 26 , "low_bit" : 26, "readonly" : False, "desc" : "undocumented" }, + "HPM25" : { "high_bit" : 25 , "low_bit" : 25, "readonly" : False, "desc" : "undocumented" }, + "HPM24" : { "high_bit" : 24 , "low_bit" : 24, "readonly" : False, "desc" : "undocumented" }, + "HPM23" : { "high_bit" : 23 , "low_bit" : 23, "readonly" : False, "desc" : "undocumented" }, + "HPM22" : { "high_bit" : 22 , "low_bit" : 22, "readonly" : False, "desc" : "undocumented" }, + "HPM21" : { "high_bit" : 21 , "low_bit" : 21, "readonly" : False, "desc" : "undocumented" }, + "HPM20" : { "high_bit" : 20 , "low_bit" : 20, "readonly" : False, "desc" : "undocumented" }, + "HPM19" : { "high_bit" : 19 , "low_bit" : 19, "readonly" : False, "desc" : "undocumented" }, + "HPM18" : { "high_bit" : 18 , "low_bit" : 18, "readonly" : False, "desc" : "undocumented" }, + "HPM17" : { "high_bit" : 17 , "low_bit" : 17, "readonly" : False, "desc" : "undocumented" }, + "HPM16" : { "high_bit" : 16 , "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "HPM15" : { "high_bit" : 15 , "low_bit" : 15, "readonly" : False, "desc" : "undocumented" }, + "HPM14" : { "high_bit" : 14 , "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "HPM13" : { "high_bit" : 13 , "low_bit" : 13, "readonly" : False, "desc" : "undocumented" }, + "HPM12" : { "high_bit" : 12 , "low_bit" : 12, "readonly" : False, "desc" : "undocumented" }, + "HPM11" : { "high_bit" : 11 , "low_bit" : 11, "readonly" : False, "desc" : "undocumented" }, + "HPM10" : { "high_bit" : 10 , "low_bit" : 10, "readonly" : False, "desc" : "undocumented" }, + "HPM9" : { "high_bit" : 9 , "low_bit" : 9, "readonly" : False, "desc" : "undocumented" }, + "HPM8" : { "high_bit" : 8 , "low_bit" : 8, "readonly" : False, "desc" : "undocumented" }, + "HPM7" : { "high_bit" : 7 , "low_bit" : 7, "readonly" : False, "desc" : "undocumented" }, + "HPM6" : { "high_bit" : 6 , "low_bit" : 6, "readonly" : False, "desc" : "undocumented" }, + "HPM5" : { "high_bit" : 5 , "low_bit" : 5, "readonly" : False, "desc" : "undocumented" }, + "HPM4" : { "high_bit" : 4 , "low_bit" : 4, "readonly" : False, "desc" : "undocumented" }, + "HPM3" : { "high_bit" : 3 , "low_bit" : 3, "readonly" : False, "desc" : "undocumented" }, + "IR" : { "high_bit" : 2 , "low_bit" : 2, "readonly" : False, "desc" : "undocumented" }, + "RESV" : { "high_bit" : 1 , "low_bit" : 1, "readonly" : True, "desc" : "undocumented" }, + "CY" : { "high_bit" : 0 , "low_bit" : 0, "readonly" : False, "desc" : "undocumented" } + }, 0], + 0x323: ["mhpmevent3", "Machine performance-monitoring event selector.", {}, 0], + 0x324: ["mhpmevent4", "Machine performance-monitoring event selector.", {}, 0], + 0x325: ["mhpmevent5", "Machine performance-monitoring event selector.", {}, 0], + 0x326: ["mhpmevent6", "Machine performance-monitoring event selector.", {}, 0], + 0x327: ["mhpmevent7", "Machine performance-monitoring event selector.", {}, 0], + 0x328: ["mhpmevent8", "Machine performance-monitoring event selector.", {}, 0], + 0x329: ["mhpmevent9", "Machine performance-monitoring event selector.", {}, 0], + 0x32A: ["mhpmevent10", "Machine performance-monitoring event selector.", {}, 0], + 0x32B: ["mhpmevent11", "Machine performance-monitoring event selector.", {}, 0], + 0x32C: ["mhpmevent12", "Machine performance-monitoring event selector.", {}, 0], + 0x32D: ["mhpmevent13", "Machine performance-monitoring event selector.", {}, 0], + 0x32E: ["mhpmevent14", "Machine performance-monitoring event selector.", {}, 0], + 0x32F: ["mhpmevent15", "Machine performance-monitoring event selector.", {}, 0], + 0x330: ["mhpmevent16", "Machine performance-monitoring event selector.", {}, 0], + 0x331: ["mhpmevent17", "Machine performance-monitoring event selector.", {}, 0], + 0x332: ["mhpmevent18", "Machine performance-monitoring event selector.", {}, 0], + 0x333: ["mhpmevent19", "Machine performance-monitoring event selector.", {}, 0], + 0x334: ["mhpmevent20", "Machine performance-monitoring event selector.", {}, 0], + 0x335: ["mhpmevent21", "Machine performance-monitoring event selector.", {}, 0], + 0x336: ["mhpmevent22", "Machine performance-monitoring event selector.", {}, 0], + 0x337: ["mhpmevent23", "Machine performance-monitoring event selector.", {}, 0], + 0x338: ["mhpmevent24", "Machine performance-monitoring event selector.", {}, 0], + 0x339: ["mhpmevent25", "Machine performance-monitoring event selector.", {}, 0], + 0x33A: ["mhpmevent26", "Machine performance-monitoring event selector.", {}, 0], + 0x33B: ["mhpmevent27", "Machine performance-monitoring event selector.", {}, 0], + 0x33C: ["mhpmevent28", "Machine performance-monitoring event selector.", {}, 0], + 0x33D: ["mhpmevent29", "Machine performance-monitoring event selector.", {}, 0], + 0x33E: ["mhpmevent30", "Machine performance-monitoring event selector.", {}, 0], + 0x33F: ["mhpmevent31", "Machine performance-monitoring event selector.", {}, 0], + + # Hypervisor Registers + 0x200: ["vsstatus", "Virtual superviosr status register", { + "SD" : { "high_bit" : 63, "low_bit" : 63, "readonly" : False, "desc" : "Fast-check bit: summarizes either FS/XS/VS set" }, + "WPRI" : { "high_bit" : 62, "low_bit" : 34, "readonly" : True, "desc" : "resv" }, + "UXL" : { "high_bit" : 33, "low_bit" : 32, "readonly" : True, "desc" : "Controls XLEN value for U-mode" }, + "WPRI" : { "high_bit" : 31, "low_bit" : 20, "readonly" : True, "desc" : "resv" }, + "MXR" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "Make executable readable" }, + "SUM" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "Permit supervisor user memory access" }, + "WPRI" : { "high_bit" : 17, "low_bit" : 17, "readonly" : False, "desc" : "resv" }, + "XS" : { "high_bit" : 16, "low_bit" : 15, "readonly" : False, "desc" : "Extension status" }, + "FS" : { "high_bit" : 14, "low_bit" : 13, "readonly" : False, "desc" : "Floating-point status" }, + "WPRI" : { "high_bit" : 12, "low_bit" : 11, "readonly" : True, "desc" : "resv" }, + "VS" : { "high_bit" : 10, "low_bit" : 9, "readonly" : False, "desc" : "Vector status" }, + "SPP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor previous privilege mode" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "resv" }, + "UBE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Controls endianness of explicit memory accesses made from U-mode" }, + "SPIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Indicates whether S-mode interrupts were enabled prior to trapping into S-mode" }, + "WPRI" : { "high_bit" : 4, "low_bit" : 2, "readonly" : True, "desc" : "resv" }, + "SIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable/Disable interrupts in S-mode" }, + "WPRI" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "resv" }, + }, 0], + 0x204: ["vsie", "Virtual supervisor interrupt-enable register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "SEIE" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enable supervisor-mode external interrupts" }, + "UEIE" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "Enable user-mode external interrupts" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : True, "desc" : "undocumented" }, + "STIE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Enable supervisor-mode timer interrupts" }, + "UTIE" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "Enable user-mode timer interrupts" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : True, "desc" : "undocumented" }, + "SSIE" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Enable supervisor-mode software interrupts" }, + "USIE" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "Enable user-mode software interrupts" } + }, 0], + 0x205: ["vstvec", "Virtual supervisor trap vector base address register", { + "BASE" : { "high_bit" : 63, "low_bit" : 2, "readonly" : False, "desc" : "Vector base address" }, + "MODE" : { "high_bit" : 1 , "low_bit" : 0, "readonly" : False, "desc" : "0 - Direct, 1 - Vectored" } + }, 0], + 0x240: ["vsscratch", "Virtual supervisor scratch register", {}, 0], + 0x241: ["vsepc", "Virtual supervisor exception program counter", {}, 0], + 0x242: ["vscause", "Virtual supervisor cause register", { + "Interrupt" : { "high_bit" : 63, "low_bit" : 63, "readonly" : False, "desc" : "Bit to set a trap" }, + "Code" : { "high_bit" : 62, "low_bit" : 0 , "readonly" : False, "desc" : "The exception code" } + }, 0], + 0x243: ["vstval", "Virtual supervisor trap value register", {}, 0], + 0x244: ["vsip", "Virtual supervisor interrupt-pending register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "SEIP" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Supervisor-mode external interrupt pending" }, + "UEIP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "User-mode external interrupts pending" }, + "WPRI" : { "high_bit" : 7, "low_bit" : 6, "readonly" : True, "desc" : "undocumented" }, + "STIP" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "Supervisor-mode timer interrupt pending" }, + "UTIP" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "User-mode Machine timer interrupt pending" }, + "WPRI" : { "high_bit" : 3, "low_bit" : 2, "readonly" : True, "desc" : "undocumented" }, + "SSIP" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "Supervisor-mode software interrupt pending" }, + "USIP" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "User-mode software interrupt pending" } + }, 0], + 0x280: ["vsatp", "Virtual interrupt-pending register", { + "MODE" : { "high_bit" : 63, "low_bit" : 60, "readonly" : False, "desc" : "Type of translation" }, + "ASID" : { "high_bit" : 59, "low_bit" : 44, "readonly" : False, "desc" : "Address space identifier" }, + "PPN" : { "high_bit" : 43, "low_bit" : 0, "readonly" : False, "desc" : "Physical page number" } + }, 0], + + 0x600: ["hstatus", "Hypervisor status register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 34, "readonly" : True, "desc" : "reserved" }, + "VSXL" : { "high_bit" : 33, "low_bit" : 32, "readonly" : True, "desc" : "Controls XLEN value for VS-mode" }, + "WPRI" : { "high_bit" : 31, "low_bit" : 23, "readonly" : True, "desc" : "reserved" }, + "VTSR" : { "high_bit" : 22, "low_bit" : 22, "readonly" : False, "desc" : "Virtual Trap SRET" }, + "VTW" : { "high_bit" : 21, "low_bit" : 21, "readonly" : False, "desc" : "Virtual Timeout Wait" }, + "VTVM" : { "high_bit" : 20, "low_bit" : 20, "readonly" : False, "desc" : "Virtual Trap Virtual Memory" }, + "WPRI" : { "high_bit" : 19, "low_bit" : 18, "readonly" : True, "desc" : "reserved" }, + "VGEIN" : { "high_bit" : 17, "low_bit" : 12, "readonly" : False, "desc" : "Virtual Guest External Interrupt Number" }, + "WPRI" : { "high_bit" : 11, "low_bit" : 10, "readonly" : True, "desc" : "reserved" }, + "HU" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Hypervisor in U-mode" }, + "SPVP" : { "high_bit" : 8, "low_bit" : 8, "readonly" : False, "desc" : "Supervisor Previous Virtual Privilege" }, + "SPV" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Supervisor Previous Virtualization mode" }, + "GVA" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Guest Virtual Address" }, + "VSBE" : { "high_bit" : 5, "low_bit" : 5, "readonly" : True, "desc" : "Controls endianness of explicit memory accesses made from VS-mode" }, + "WPRI" : { "high_bit" : 4, "low_bit" : 0, "readonly" : True, "desc" : "reserved" }, + }, 0], + 0x602: ["hedeleg", "Hypervisor exception delegation register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 24, "readonly" : True, "desc" : "reserved" }, + "SGPF" : { "high_bit" : 23, "low_bit" : 23, "readonly" : True, "desc" : "Store/AMO guest-page fault" }, + "VIRTINST" : { "high_bit" : 22, "low_bit" : 22, "readonly" : True, "desc" : "Virtual instruction" }, + "LGPF" : { "high_bit" : 21, "low_bit" : 21, "readonly" : True, "desc" : "Load guest-page fault" }, + "IGPF" : { "high_bit" : 20, "low_bit" : 20, "readonly" : True, "desc" : "Instruction guest-page fault" }, + "WPRI" : { "high_bit" : 19, "low_bit" : 16, "readonly" : True, "desc" : "reserved" }, + "WPRI" : { "high_bit" : 14, "low_bit" : 14, "readonly" : True, "desc" : "reserved" }, + "MECALL" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode environment call" }, + "VSECALL" : { "high_bit" : 10, "low_bit" : 10, "readonly" : True, "desc" : "Virtual supervisor-mode environment call" }, + "HSECALL" : { "high_bit" : 9, "low_bit" : 9, "readonly" : True, "desc" : "Supervisor-mode environment call" }, + }, 0], + 0x603: ["hideleg", "Hypervisor interrupt delegation register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEI" : { "high_bit" : 12, "low_bit" : 12, "readonly" : True, "desc" : "Supervisor guest external interrupts" }, + "MEI" : { "high_bit" : 11, "low_bit" : 11, "readonly" : True, "desc" : "Machine-mode external interrupts" }, + "VSEI" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtuall supervisor-mode external interrupts" }, + "SEI" : { "high_bit" : 9, "low_bit" : 9, "readonly" : True, "desc" : "Supervisor-mode external interrupts" }, + "UEI" : { "high_bit" : 8, "low_bit" : 8, "readonly" : True, "desc" : "User-mode external interrupts" }, + "MTI" : { "high_bit" : 7, "low_bit" : 7, "readonly" : True, "desc" : "Machine-mode timer interrupts" }, + "VSTI" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtuall supervisor-mode timer interrupts" }, + "STI" : { "high_bit" : 5, "low_bit" : 5, "readonly" : True, "desc" : "Supervisor-mode timer interrupts" }, + "UTI" : { "high_bit" : 4, "low_bit" : 4, "readonly" : True, "desc" : "User-mode timer interrupts" }, + "MSI" : { "high_bit" : 3, "low_bit" : 3, "readonly" : True, "desc" : "Machine-mode software interrupts" }, + "VSSI" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupts" }, + "SSI" : { "high_bit" : 1, "low_bit" : 1, "readonly" : True, "desc" : "Supervisor-mode software interrupts" }, + "USI" : { "high_bit" : 0, "low_bit" : 0, "readonly" : True, "desc" : "User-mode software interrupts" } + }, 0], + 0x604: ["hie", "Hypervisor interrupt-enable register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEIE" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Enable supervisor guest external interrupts" }, + "VSEIE" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Enable virtuall supervisor-mode external interrupts" }, + "VSTIE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enable virtuall supervisor-mode timer interrupts" }, + "VSSIE" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Enable virtual supervisor-mode software interrupts" }, + }, 0], + 0x606: ["hcounteren", "Hypervisor counter-enable register", {}, 0], + 0x607: ["hgeie", "Hypervisor guest external interrupt-enable register", {}, 0], + 0x643: ["htval", "Hypervisor trap value register", {}, 0], + 0x644: ["hip", "Hypervisor interrupt-pending register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 13, "readonly" : True, "desc" : "reserved" }, + "SGEIP" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "Supervisor guest external interrupt pending" }, + "VSEIP" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtual supervisor-mode external interrupt pending" }, + "VSTIP" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtual supervisor-mode timer interrupt pending" }, + "VSSIP" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupt pending" }, + }, 0], + 0x645: ["hvip", "Hypervisor virtual-interrupt-pending register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 11, "readonly" : True, "desc" : "reserved" }, + "VSEIP" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "Virtual supervisor-mode external interrupt pending" }, + "VSTIP" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Virtual supervisor-mode timer interrupt pending" }, + "VSSIP" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "Virtual supervisor-mode software interrupt pending" }, + }, 0], + 0x64a: ["htinst", "Hypervisor trap instruction register", {}, 0], + 0xe12: ["hgeip", "Hypervisor guest external interrupt pending", {}, 0], + 0x680: ["hgatp", "Hypervisor guest address translation and protection register", { + "MODE" : { "high_bit" : 63, "low_bit" : 60, "readonly" : False, "desc" : "Type of translation" }, + "WPRI" : { "high_bit" : 59, "low_bit" : 58, "readonly" : True, "desc" : "reserved" }, + "VMID" : { "high_bit" : 57, "low_bit" : 44, "readonly" : False, "desc" : "Virtual machine identifier" }, + "PPN" : { "high_bit" : 43, "low_bit" : 0 , "readonly" : False, "desc" : "Physical page number" } + }, 0], + 0x60a: ["henvcfg", "Hypervisor environment configuration register", { + "WPRI" : { "high_bit" : 63, "low_bit" : 8, "readonly" : False, "desc" : "reserved" }, + "CBZE" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Cache block zero instruction enable" }, + "CBCFE" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Cache block clean and flush instruction enable" }, + "CBIE" : { "high_bit" : 5, "low_bit" : 4, "readonly" : False, "desc" : "Cache block invalidate instruction enable" }, + "FIOM" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "Fence of I/O implies Memory" }, + }, 0], + 0x605: ["htimedelta", "Hypervisor time delta register", {}, 0], + 0x6a8: ["hcontext", "Hypervisor mode context register", {}, 0], + + # Debug/Trace Registers (shared with Debug Mode) + 0x7a0: ["tselect", "Debug/Trace trigger register select.", {}, 0], + 0x7a1: ["tdata1", "First Debug/Trace trigger data register.", { + "type" : { "high_bit" : 63, "low_bit" : 60, "readonly" : False, "desc" : "Type of trigger" }, + "dmode" : { "high_bit" : 59, "low_bit" : 59, "readonly" : False, "desc" : "If bit is set, only Debug Mode can write to the tdata registers. Other writes are ignored." }, + "data" : { "high_bit" : 58, "low_bit" : 0, "readonly" : False, "desc" : "Trigger-specific data" }, + "mcontrol_maskmax" : { "high_bit" : 58, "low_bit" : 53, "readonly" : False, "desc" : "TODO" }, + "mcontrol_sizehi" : { "high_bit" : 22, "low_bit" : 21, "readonly" : False, "desc" : "TODO" }, + "mcontrol_hit" : { "high_bit" : 20, "low_bit" : 20, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "mcontrol_select" : { "high_bit" : 19, "low_bit" : 19, "readonly" : False, "desc" : "TODO" }, + "mcontrol_timing" : { "high_bit" : 18, "low_bit" : 18, "readonly" : False, "desc" : "TODO" }, + "mcontrol_sizelo" : { "high_bit" : 17, "low_bit" : 16, "readonly" : False, "desc" : "TODO" }, + "mcontrol_action" : { "high_bit" : 15, "low_bit" : 12, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + "mcontrol_chain" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "TODO" }, + "mcontrol_match" : { "high_bit" : 10, "low_bit" : 7, "readonly" : False, "desc" : "TODO" }, + "mcontrol_m" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enables this trigger in M-mode" }, + "mcontrol_s" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "Enables this trigger in S-mode" }, + "mcontrol_u" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "Enables this trigger in U-mode" }, + "mcontrol_execute" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "When set, trigger fires on VA or opcode of instructions" }, + "mcontrol_store" : { "high_bit" : 1, "low_bit" : 1, "readonly" : False, "desc" : "When set, trigger fires on VA or data of stores" }, + "mcontrol_load" : { "high_bit" : 0, "low_bit" : 0, "readonly" : False, "desc" : "When set, trigger fires on VA or data of loads" }, + "icount_hit" : { "high_bit" : 24, "low_bit" : 24, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "icount_count" : { "high_bit" : 23, "low_bit" : 10, "readonly" : False, "desc" : "When count is decremented to 0, this trigger fires" }, + "icount_m" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Decrement count in M-mode" }, + "icount_s" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Decrement count in S-mode" }, + "icount_u" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Decrement count in U-mode" }, + "icount_action" : { "high_bit" : 5, "low_bit" : 0, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + "etrigger_hit" : { "high_bit" : 58, "low_bit" : 58, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "etrigger_m" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enables this trigger in M-mode" }, + "etrigger_s" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Enables this trigger in S-mode" }, + "etrigger_u" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enables this trigger in U-mode" }, + "etrigger_action" : { "high_bit" : 5, "low_bit" : 0, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + "itrigger_hit" : { "high_bit" : 58, "low_bit" : 58, "readonly" : False, "desc" : "Set when this trigger matches (optional)" }, + "itrigger_m" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "Enables this trigger in M-mode" }, + "itrigger_s" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "Enables this trigger in S-mode" }, + "itrigger_u" : { "high_bit" : 6, "low_bit" : 6, "readonly" : False, "desc" : "Enables this trigger in U-mode" }, + "itrigger_action" : { "high_bit" : 5, "low_bit" : 0, "readonly" : False, "desc" : "Action to take when trigger is fired" }, + }, 0], + 0x7a2: ["tdata2", "Second Debug/Trace trigger data register.", {}, 0], + 0x7a3: ["tdata3", "Third Debug/Trace trigger data register.", {}, 0], + 0x7a4: ["tinfo", "Trigger info", {}, 0], + 0x7a5: ["tcontrol", "Trigger control", { + "Resv" : { "high_bit" : 63, "low_bit" : 8, "readonly" : True, "desc" : "Tied to zero" }, + "mpte" : { "high_bit" : 7, "low_bit" : 7, "readonly" : False, "desc" : "M-mode previous trigger enable field" }, + "Resv" : { "high_bit" : 6, "low_bit" : 4, "readonly" : True, "desc" : "Tied to zero" }, + "mte" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "M-mode trigger enable field" }, + "Resv" : { "high_bit" : 2, "low_bit" : 0, "readonly" : True, "desc" : "Tied to zero" }, + }, 0], + 0x7a8: ["mcontext", "Machine context", {}, 0], + 0x7aa: ["scontext", "Supervisor context", {}, 0], + + #Debug Mode Registers + 0x7b0: ["dcsr", "Debug control and status register.", { + "RESV" : { "high_bit" : 63, "low_bit" : 32, "readonly" : True, "desc" : "undocumented" }, + "xdebugver" : { "high_bit" : 31, "low_bit" : 28, "readonly" : True, "desc" : "External debug support available" }, + "RESV" : { "high_bit" : 27, "low_bit" : 16, "readonly" : False, "desc" : "undocumented" }, + "ebreakm" : { "high_bit" : 15, "low_bit" : 15, "readonly" : False, "desc" : "If set, M-mode ebreak instructions will enter debug mode" }, + "RESV" : { "high_bit" : 14, "low_bit" : 14, "readonly" : False, "desc" : "undocumented" }, + "ebreaks" : { "high_bit" : 13, "low_bit" : 13, "readonly" : False, "desc" : "If set, S-mode ebreak instructions will enter debug mode" }, + "ebreaku" : { "high_bit" : 12, "low_bit" : 12, "readonly" : False, "desc" : "If set, U-mode ebreak instructions will enter debug mode" }, + "stepie" : { "high_bit" : 11, "low_bit" : 11, "readonly" : False, "desc" : "Enables interrupts during single-stepping" }, + "stopcount" : { "high_bit" : 10, "low_bit" : 10, "readonly" : False, "desc" : "If set, don't increment any counters while in debug mode" }, + "stoptime" : { "high_bit" : 9, "low_bit" : 9, "readonly" : False, "desc" : "If set, don't increment any timers while in debug mode" }, + "cause" : { "high_bit" : 8, "low_bit" : 6, "readonly" : False, "desc" : "Explains why debug mode was entered" }, + "RESV" : { "high_bit" : 5, "low_bit" : 5, "readonly" : False, "desc" : "undocumented" }, + "mprven" : { "high_bit" : 4, "low_bit" : 4, "readonly" : False, "desc" : "If not set, ignore mstatus.mprv when in debug mode" }, + "nmip" : { "high_bit" : 3, "low_bit" : 3, "readonly" : False, "desc" : "When set, there is a non-maskable interrupt pending" }, + "step" : { "high_bit" : 2, "low_bit" : 2, "readonly" : False, "desc" : "When set and not in debug mode, execute a single execute then enter debug mode" }, + "prv" : { "high_bit" : 1, "low_bit" : 0, "readonly" : True, "desc" : "Previous privilege mode when entering debug mode" } + }, 4026531843], + 0x7b1: ["dpc", "Debug PC", {}, 0], + 0x7b2: ["dscratch0", "Debug scratch register 0.", {}, 0], + 0x7b3: ["dscratch1", "Debug scratch register 1.", {}, 0], +} diff --git a/sparta/sparta/functional/RegisterDefnsJSON.hpp b/sparta/sparta/functional/RegisterDefnsJSON.hpp new file mode 100644 index 0000000000..a478b3e13b --- /dev/null +++ b/sparta/sparta/functional/RegisterDefnsJSON.hpp @@ -0,0 +1,235 @@ +#pragma once + +#include +#include +#include +#include + +namespace sparta +{ + +class RegisterDefnsFromJSON +{ +public: + RegisterDefnsFromJSON(const std::vector& register_defns_json_filenames) + { + for (const auto& filename : register_defns_json_filenames) { + parse_(filename); + } + + // Add a definition that indicates the end of the array + register_defns_.push_back(RegisterBase::DEFINITION_END); + } + + RegisterDefnsFromJSON(const std::string& register_defns_json_filename) + { + parse_(register_defns_json_filename); + + // Add a definition that indicates the end of the array + register_defns_.push_back(RegisterBase::DEFINITION_END); + } + + RegisterBase::Definition* getAllDefns() { + return register_defns_.data(); + } + +private: + void parse_(const std::string& register_defns_json_filename) + { + // Read the file into a string + std::ifstream ifs(register_defns_json_filename); + std::stringstream ss; + ss << ifs.rdbuf(); + std::string json_str = ss.str(); + + // Parse the JSON string + rapidjson::Document document; + document.Parse(json_str.c_str()); + + for (auto& item : document.GetArray()) { + if (item.HasMember("enabled") && !item["enabled"].GetBool()) { + continue; + } + + const RegisterBase::ident_type id = item["num"].GetInt(); + + cached_strings_.emplace_back(item["name"].GetString()); + const char *name = cached_strings_.back().raw(); + + const RegisterBase::group_num_type group_num = item["group_num"].GetInt(); + auto iter = group_idx_map_.find(group_num); + if (iter == group_idx_map_.end()) { + group_idx_map_[group_num] = 0; + } + + RegisterBase::group_idx_type group_idx = group_idx_map_[group_num]++; + cached_strings_.emplace_back(item["group_name"].GetString()); + const char* group = cached_strings_.back().raw(); + + if (std::string(group).empty()) { + group_idx = RegisterBase::GROUP_IDX_NONE; + } + + cached_strings_.emplace_back(item["desc"].GetString()); + const char* desc = cached_strings_.back().raw(); + + const RegisterBase::size_type bytes = item["size"].GetInt(); + + std::vector field_defns; + if (item.HasMember("fields")) { + for (auto it = item["fields"].MemberBegin(); it != item["fields"].MemberEnd(); ++it) { + const char* field_name = it->name.GetString(); + const rapidjson::Value& field_info = it->value; + cached_field_defns_.emplace_back(field_name, field_info); + field_defns.push_back(cached_field_defns_.back().getDefn()); + } + } + + static const std::vector bank_membership; + + std::vector alias_strings; + for (auto& alias : item["aliases"].GetArray()) { + alias_strings.push_back(alias.GetString()); + } + cached_aliases_.emplace_back(alias_strings); + const char** aliases = cached_aliases_.back().raw(); + + constexpr RegisterBase::ident_type subset_of = RegisterBase::INVALID_ID; + constexpr RegisterBase::size_type subset_offset = 0; + + const unsigned char *initial_value = nullptr; + if (item.HasMember("initial_value")) { + cached_initial_values_.emplace_back(item["initial_value"].GetString()); + initial_value = cached_initial_values_.back().raw(); + } + + constexpr RegisterBase::Definition::HintsT hints = 0; + constexpr RegisterBase::Definition::RegDomainT regdomain = 0; + + RegisterBase::Definition defn = { + id, + name, + group_num, + group, + group_idx, + desc, + bytes, + field_defns, + bank_membership, + aliases, + subset_of, + subset_offset, + initial_value, + hints, + regdomain + }; + + register_defns_.push_back(defn); + } + } + + // Converts a string to a const char* pointer + class StringRef + { + public: + StringRef(const std::string& str) : storage_(str) {} + const char* raw() const { return storage_.c_str(); } + private: + std::string storage_; + }; + + // Converts a vector of strings to an array of const char* pointers + class AliasRef + { + public: + AliasRef(const std::vector& aliases) + : storage_(aliases) + { + for (const auto& str : storage_) { + pointers_.push_back(str.c_str()); + } + } + + const char** raw() { + return pointers_.data(); + } + + private: + std::vector storage_; + std::vector pointers_; + }; + + // Converts any hex ("0xdeafbeef") to a const unsigned char* pointer + class InitialValueRef + { + public: + InitialValueRef(const std::string& hex_str) + { + // Remove the "0x" prefix if present + std::string hex = hex_str; + if (hex.substr(0, 2) == "0x") { + hex = hex.substr(2); + } + + // Ensure the hex string has an even length + sparta_assert(hex.length() % 2 == 0, "Hex string must have an even length"); + + // Create a vector to hold the bytes + hex_bytes_.resize(hex.length() / 2); + + // Convert hex string to bytes + for (size_t i = 0; i < hex.length(); i += 2) { + const auto byte_string = hex.substr(i, 2); + std::istringstream iss(byte_string); + int byte; + iss >> std::hex >> byte; + hex_bytes_[i / 2] = static_cast(byte); + } + } + + const unsigned char* raw() const { + return hex_bytes_.data(); + } + + private: + std::vector hex_bytes_; + }; + + // Converts a rapidjson::Value that represents a field to a Field::Definition + class FieldDefnConverter + { + public: + FieldDefnConverter(const std::string& field_name, const rapidjson::Value& field_info) + : field_name_(field_name) + , desc_(field_info["desc"].GetString()) + , field_defn_(field_name_.c_str(), + desc_.c_str(), + field_info["low_bit"].GetInt(), + field_info["high_bit"].GetInt(), + field_info["readonly"].GetBool()) + { + } + + const RegisterBase::Field::Definition& getDefn() const + { + return field_defn_; + } + + private: + std::string field_name_; + std::string desc_; + RegisterBase::Field::Definition field_defn_; + }; + + std::deque cached_strings_; + std::deque cached_aliases_; + std::deque cached_initial_values_; + std::deque cached_field_defns_; + std::vector register_defns_; + + // TODO: Find the official way to handle group_idx. For now we will just use + // a map of auto-incrementing group_idx values for each group_num + std::map group_idx_map_; +}; + +} // namespace sparta diff --git a/sparta/sparta/functional/RegisterSet.hpp b/sparta/sparta/functional/RegisterSet.hpp index 7e8044b8bf..659c2c8551 100644 --- a/sparta/sparta/functional/RegisterSet.hpp +++ b/sparta/sparta/functional/RegisterSet.hpp @@ -14,6 +14,7 @@ #include "sparta/functional/Register.hpp" #include "sparta/functional/RegisterBankTable.hpp" +#include "sparta/functional/RegisterDefnsJSON.hpp" #include "sparta/simulation/TreeNode.hpp" #include "sparta/utils/SpartaException.hpp" #include "sparta/utils/SpartaAssert.hpp" @@ -536,6 +537,26 @@ class RegisterSet : public TreeNode // Handled in delegated consturctor } + template + RegisterSet(TreeNode *parent, + std::unique_ptr defns, + const RegisterProxyBase::Definition *proxy_defs, + CurrentBankFunction cbfxn, + RegisterTypeTag tag) + : RegisterSet(parent, defns->getAllDefns(), proxy_defs, cbfxn, tag) + { + defs_from_json_ = std::move(defns); + } + + template + RegisterSet(TreeNode *parent, + std::unique_ptr defns, + RegisterTypeTag tag) + : RegisterSet(parent, defns->getAllDefns(), nullptr, nullptr, tag) + { + defs_from_json_ = std::move(defns); + } + template static std::unique_ptr create(TreeNode *parent, @@ -555,6 +576,52 @@ class RegisterSet : public TreeNode parent, defs, RegisterTypeTag())); } + template + static std::unique_ptr + create(TreeNode *parent, + const std::string& register_defns_json, + const RegisterProxyBase::Definition *proxy_defs, + CurrentBankFunction cbfxn) + { + auto defns = std::make_unique(register_defns_json); + + return std::unique_ptr(new RegisterSet( + parent, std::move(defns), proxy_defs, cbfxn, RegisterTypeTag())); + } + + template + static std::unique_ptr + create(TreeNode *parent, const std::string& register_defns_json) + { + auto defns = std::make_unique(register_defns_json); + + return std::unique_ptr(new RegisterSet( + parent, std::move(defns), RegisterTypeTag())); + } + + template + static std::unique_ptr + create(TreeNode *parent, + const std::vector& register_defns_jsons, + const RegisterProxyBase::Definition *proxy_defs, + CurrentBankFunction cbfxn) + { + auto defns = std::make_unique(register_defns_jsons); + + return std::unique_ptr(new RegisterSet( + parent, std::move(defns), proxy_defs, cbfxn, RegisterTypeTag())); + } + + template + static std::unique_ptr + create(TreeNode *parent, const std::vector& register_defns_jsons) + { + auto defns = std::make_unique(register_defns_jsons); + + return std::unique_ptr(new RegisterSet( + parent, std::move(defns), RegisterTypeTag())); + } + /*! * \brief Destructor * @@ -1032,6 +1099,14 @@ class RegisterSet : public TreeNode */ CurrentBankFunction cur_bank_fxn_; + /*! + * \brief Register definitions parsed from JSON file(s). We have to hold onto + * this to keep the definitions alive, specifically the various strings that + * are held by the register/field definitions as a const char* (e.g. group + * name, field name, etc.) + */ + std::unique_ptr defs_from_json_; + }; // class RegisterSet /*! diff --git a/sparta/test/Register/Register_test.cpp b/sparta/test/Register/Register_test.cpp index 276cd13533..c23ac5fc8a 100644 --- a/sparta/test/Register/Register_test.cpp +++ b/sparta/test/Register/Register_test.cpp @@ -254,8 +254,66 @@ class CallbackDummy } }; +void dumpRegisterDefnsToJSON(const std::string& filename, Register::Definition* defs) +{ + std::ofstream json_file(filename); + if (!json_file.is_open()) { + throw SpartaException("Failed to open file for writing: ") << filename; + } + + json_file << "[\n"; + for (RegisterBase::Definition* def = defs; def->name != nullptr; ++def) { + json_file << " {\n"; + json_file << " \"name\": \"" << def->name << "\",\n"; + json_file << " \"num\": " << def->id << ",\n"; + json_file << " \"desc\": \"" << def->desc << "\",\n"; + json_file << " \"size\": " << def->bytes << ",\n"; + + json_file << " \"aliases\": ["; + if (def->aliases == nullptr) { + json_file << "],\n"; + } else { + json_file << "\n"; + for (auto alias = def->aliases; alias != nullptr; ++alias) { + json_file << " \"" << *alias << "\""; + if (*(alias + 1) != nullptr) { + json_file << ","; + } + json_file << "\n"; + } + json_file << " ],\n"; + } + + json_file << " \"fields\": {\n"; + for (const auto& field : def->fields) { + json_file << " \"" << field.name << "\": {\n"; + json_file << " \"desc\": \"" << field.desc << "\",\n"; + json_file << " \"low_bit\": " << field.low_bit << ",\n"; + json_file << " \"high_bit\": " << field.high_bit << ",\n"; + json_file << " \"readonly\": " << std::boolalpha << field.read_only << "\n"; + json_file << " }"; + if (&field != &def->fields.back()) { + json_file << ","; + } + json_file << "\n"; + } + json_file << " },\n"; + + json_file << " \"group_name\": \"" << def->group << "\",\n"; + json_file << " \"group_num\": " << def->group_num << "\n"; + + json_file << " }"; + if ((def + 1)->name != nullptr) { + json_file << ","; + } + json_file << "\n"; + } + + json_file << "]\n"; +} + //! Issue 89, test field register writes to large fields -void testFieldRegisterWrite() +void testFieldRegisterWrite(bool use_json = false) { Register::ident_type new_regid = 1000; // Start counting at some unique ID @@ -267,7 +325,13 @@ void testFieldRegisterWrite() }; RootTreeNode root; DummyDevice good_dummy(&root); - std::unique_ptr regs(RegisterSet::create(&good_dummy, good_reg_defs)); + std::unique_ptr regs; + if (!use_json) { + regs = RegisterSet::create(&good_dummy, good_reg_defs); + } else { + dumpRegisterDefnsToJSON("reg_defs.json", good_reg_defs); + regs = RegisterSet::create(&good_dummy, "reg_defs.json"); + } regs->getRegister("fp_reg")->getField("sp")->write(1); regs->getRegister("fp_reg")->getField("dp")->write(1); @@ -285,7 +349,7 @@ void testFieldRegisterWrite() //! Load up some good regs from a table -void testGoodRegs() +void testGoodRegs(bool use_json = false) { Register::ident_type new_regid = 1000; // Start counting at some unique ID @@ -304,7 +368,13 @@ void testGoodRegs() RootTreeNode root; DummyDevice good_dummy(&root); - std::unique_ptr good_regs(RegisterSet::create(&good_dummy, good_reg_defs)); + std::unique_ptr good_regs; + if (!use_json) { + good_regs = RegisterSet::create(&good_dummy, good_reg_defs); + } else { + dumpRegisterDefnsToJSON("reg_defs.json", good_reg_defs); + good_regs = RegisterSet::create(&good_dummy, "reg_defs.json"); + } #ifndef REGISTER_SET_GET_ARCH_DATA_REMOVED EXPECT_TRUE(good_regs->getArchData().isLaidOut()); std::cout << "Layout of good dummy regs:" << std::endl; @@ -759,8 +829,10 @@ int main() root.bindTreeLate(); // Construct some good and bad regs to test out size constraints - testFieldRegisterWrite(); - testGoodRegs(); + testFieldRegisterWrite(); // Create registers directly + testFieldRegisterWrite(true); // Create registers from JSON + testGoodRegs(); // Create registers directly + testGoodRegs(true); // Create registers from JSON testBadRegs();