diff --git a/.github/workflows/compiler-tests.yaml b/.github/workflows/compiler-tests.yaml index 3ae6faead1..fde8f3cd44 100644 --- a/.github/workflows/compiler-tests.yaml +++ b/.github/workflows/compiler-tests.yaml @@ -16,8 +16,8 @@ jobs: strategy: fail-fast: false matrix: - image: [gcc-version-12, gcc-version-11, gcc-version-10, gcc-version-8, clang-version-16, clang-version-15, clang-version-14, clang-version-13, - clang-version-12, clang-version-11, clang-version-10, clang-version-9, clang-version-8, clang-version-7, ubuntu-20.04_all-dependencies, + image: [gcc-version-13, gcc-version-12, gcc-version-11, gcc-version-10, gcc-version-8, clang-version-16, clang-version-15, clang-version-14, + clang-version-13, clang-version-12, clang-version-11, clang-version-10, clang-version-9, clang-version-8, clang-version-7, ubuntu-20.04_all-dependencies, ubuntu-22.04_all-dependencies, ubuntu-22.04_min-dependencies] opts: [.opt, .fast] runs-on: [self-hosted, linux, x64] @@ -40,7 +40,7 @@ jobs: matrix: gem5-compilation: [ARM, ARM_MESI_Three_Level, ARM_MESI_Three_Level_HTM, ARM_MOESI_hammer, Garnet_standalone, MIPS, 'NULL', NULL_MESI_Two_Level, NULL_MOESI_CMP_directory, NULL_MOESI_CMP_token, NULL_MOESI_hammer, POWER, RISCV, SPARC, X86, X86_MI_example, X86_MOESI_AMD_Base, VEGA_X86] - image: [gcc-version-12, clang-version-16] + image: [gcc-version-13, clang-version-16] opts: [.opt] runs-on: [self-hosted, linux, x64] timeout-minutes: 2880 # 48 hours diff --git a/build_tools/sim_object_param_struct_hh.py b/build_tools/sim_object_param_struct_hh.py index c82c25921c..23e10a9bfa 100644 --- a/build_tools/sim_object_param_struct_hh.py +++ b/build_tools/sim_object_param_struct_hh.py @@ -211,8 +211,7 @@ code.indent() if sim_object == SimObject: code( """ -SimObjectParams() {} -virtual ~SimObjectParams() {} +virtual ~SimObjectParams() = default; std::string name; """ diff --git a/configs/deprecated/example/se.py b/configs/deprecated/example/se.py index afdb82489d..6ad4b02b32 100644 --- a/configs/deprecated/example/se.py +++ b/configs/deprecated/example/se.py @@ -224,7 +224,7 @@ for cpu in system.cpu: if ObjectList.is_kvm_cpu(CPUClass) or ObjectList.is_kvm_cpu(FutureClass): if buildEnv["USE_X86_ISA"]: system.kvm_vm = KvmVM() - system.m5ops_base = 0xFFFF0000 + system.m5ops_base = max(0xFFFF0000, Addr(args.mem_size).getValue()) for process in multiprocesses: process.useArchPT = True process.kvmInSE = True diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 18e9b5fce2..da5e5fc8f1 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -240,6 +240,8 @@ namespace RiscvISA [MISCREG_HPMCOUNTER29H] = "HPMCOUNTER29H", [MISCREG_HPMCOUNTER30H] = "HPMCOUNTER30H", [MISCREG_HPMCOUNTER31H] = "HPMCOUNTER31H", + + [MISCREG_FFLAGS_EXE] = "FFLAGS_EXE", }}; namespace @@ -276,7 +278,7 @@ ISA::ISA(const Params &p) : BaseISA(p), p.vlen, p.elen); - miscRegFile.resize(NUM_MISCREGS); + miscRegFile.resize(NUM_PHYS_MISCREGS); clear(); } @@ -304,7 +306,7 @@ ISA::copyRegsFrom(ThreadContext *src) } // Copying Misc Regs - for (int i = 0; i < NUM_MISCREGS; i++) + for (int i = 0; i < NUM_PHYS_MISCREGS; i++) tc->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); // Lastly copy PC/NPC @@ -409,7 +411,7 @@ RegVal ISA::readMiscRegNoEffect(RegIndex idx) const { // Illegal CSR - panic_if(idx > NUM_MISCREGS, "Illegal CSR index %#x\n", idx); + panic_if(idx > NUM_PHYS_MISCREGS, "Illegal CSR index %#x\n", idx); DPRINTF(RiscvMisc, "Reading MiscReg %s (%d): %#x.\n", MiscRegNames[idx], idx, miscRegFile[idx]); return miscRegFile[idx]; @@ -571,6 +573,10 @@ ISA::readMiscReg(RegIndex idx) (readMiscRegNoEffect(MISCREG_VXRM) << 1); } break; + case MISCREG_FFLAGS_EXE: + { + return readMiscRegNoEffect(MISCREG_FFLAGS) & FFLAGS_MASK; + } default: // Try reading HPM counters // As a placeholder, all HPM counters are just cycle counters @@ -603,7 +609,7 @@ void ISA::setMiscRegNoEffect(RegIndex idx, RegVal val) { // Illegal CSR - panic_if(idx > NUM_MISCREGS, "Illegal CSR index %#x\n", idx); + panic_if(idx > NUM_PHYS_MISCREGS, "Illegal CSR index %#x\n", idx); DPRINTF(RiscvMisc, "Setting MiscReg %s (%d) to %#x.\n", MiscRegNames[idx], idx, val); miscRegFile[idx] = val; @@ -770,6 +776,13 @@ ISA::setMiscReg(RegIndex idx, RegVal val) setMiscRegNoEffect(MISCREG_VXRM, (val & 0x6) >> 1); } break; + case MISCREG_FFLAGS_EXE: + { + RegVal new_val = readMiscRegNoEffect(MISCREG_FFLAGS); + new_val |= (val & FFLAGS_MASK); + setMiscRegNoEffect(MISCREG_FFLAGS, new_val); + } + break; default: setMiscRegNoEffect(idx, val); } diff --git a/src/arch/riscv/isa/formats/fp.isa b/src/arch/riscv/isa/formats/fp.isa index d0bd245ae4..d459a59a50 100644 --- a/src/arch/riscv/isa/formats/fp.isa +++ b/src/arch/riscv/isa/formats/fp.isa @@ -46,13 +46,10 @@ def template FloatExecute {{ %(op_decl)s; %(op_rd)s; - RegVal FFLAGS = xc->readMiscReg(MISCREG_FFLAGS); std::feclearexcept(FE_ALL_EXCEPT); %(code)s; - - FFLAGS |= softfloat_exceptionFlags; + xc->setMiscReg(MISCREG_FFLAGS_EXE, softfloat_exceptionFlags); softfloat_exceptionFlags = 0; - xc->setMiscReg(MISCREG_FFLAGS, FFLAGS); %(op_wb)s; diff --git a/src/arch/riscv/isa/formats/vector_arith.isa b/src/arch/riscv/isa/formats/vector_arith.isa index 7f87f1e163..0a4acd3db9 100644 --- a/src/arch/riscv/isa/formats/vector_arith.isa +++ b/src/arch/riscv/isa/formats/vector_arith.isa @@ -114,12 +114,10 @@ let {{ def fflags_wrapper(code): return ''' - RegVal FFLAGS = xc->readMiscReg(MISCREG_FFLAGS); std::feclearexcept(FE_ALL_EXCEPT); ''' + code + ''' - FFLAGS |= softfloat_exceptionFlags; + xc->setMiscReg(MISCREG_FFLAGS_EXE, softfloat_exceptionFlags); softfloat_exceptionFlags = 0; - xc->setMiscReg(MISCREG_FFLAGS, FFLAGS); ''' def declareVArithTemplate( diff --git a/src/arch/riscv/regs/misc.hh b/src/arch/riscv/regs/misc.hh index 837cbfacbd..cc4fe6fe55 100644 --- a/src/arch/riscv/regs/misc.hh +++ b/src/arch/riscv/regs/misc.hh @@ -246,6 +246,11 @@ enum MiscRegIndex MISCREG_HPMCOUNTER30H, MISCREG_HPMCOUNTER31H, + NUM_PHYS_MISCREGS, + + // This CSR shared the same space with MISCREG_FFLAGS + MISCREG_FFLAGS_EXE = NUM_PHYS_MISCREGS, + NUM_MISCREGS }; diff --git a/src/dev/riscv/HiFive.py b/src/dev/riscv/HiFive.py index 04b2672ea8..17c4b35a29 100755 --- a/src/dev/riscv/HiFive.py +++ b/src/dev/riscv/HiFive.py @@ -221,10 +221,10 @@ class HiFive(HiFiveBase): self.plic.n_src = max(plic_srcs) + 1 def setNumCores(self, num_cpu): - """Sets the PLIC and CLINT to have the right number of threads and - contexts. Assumes that the cores have a single hardware thread. + """Sets the CLINT to number of threads and the PLIC hartID/pmode for + each contexts. Assumes that the cores have a single hardware thread. """ - self.plic.n_contexts = num_cpu * 2 + self.plic.hart_config = ",".join(["MS" for _ in range(num_cpu)]) self.clint.num_threads = num_cpu def generateDeviceTree(self, state): diff --git a/src/dev/riscv/Plic.py b/src/dev/riscv/Plic.py index b4486b9350..ff80323d48 100644 --- a/src/dev/riscv/Plic.py +++ b/src/dev/riscv/Plic.py @@ -58,10 +58,8 @@ class PlicBase(BasicPioDevice): class Plic(PlicBase): """ This implementation of PLIC is based on - the SiFive U54MC datasheet: - https://sifive.cdn.prismic.io/sifive/fab000f6- - 0e07-48d0-9602-e437d5367806_sifive_U54MC_rtl_ - full_20G1.03.00_manual.pdf + the riscv-plic-spec repository: + https://github.com/riscv/riscv-plic-spec/releases/tag/1.0.0 """ type = "Plic" @@ -69,9 +67,20 @@ class Plic(PlicBase): cxx_class = "gem5::Plic" pio_size = 0x4000000 n_src = Param.Int("Number of interrupt sources") + # Ref: https://github.com/qemu/qemu/blob/760b4dc/hw/intc/sifive_plic.c#L285 + hart_config = Param.String( + "", + "String represent for PLIC hart/pmode config like QEMU plic" + "Ex." + "'M' 1 hart with M mode" + "'MS,MS' 2 harts, 0-1 with M and S mode" + "'M,MS,MS,MS,MS' 5 harts, 0 with M mode, 1-5 with M and S mode", + ) n_contexts = Param.Int( + 0, + "Deprecated, use `hart_config` instead. " "Number of interrupt contexts. Usually the number " - "of threads * 2. One for M mode, one for S mode" + "of threads * 2. One for M mode, one for S mode", ) def generateDeviceTree(self, state): @@ -89,12 +98,26 @@ class Plic(PlicBase): cpus = self.system.unproxy(self).cpu int_extended = list() - for cpu in cpus: - phandle = int_state.phandle(cpu) - int_extended.append(phandle) - int_extended.append(0xB) - int_extended.append(phandle) - int_extended.append(0x9) + if self.n_contexts != 0: + for cpu in cpus: + phandle = int_state.phandle(cpu) + int_extended.append(phandle) + int_extended.append(0xB) + int_extended.append(phandle) + int_extended.append(0x9) + elif self.hart_config != "": + cpu_id = 0 + phandle = int_state.phandle(cpus[cpu_id]) + for c in self.hart_config: + if c == ",": + cpu_id += 1 + phandle = int_state.phandle(cpus[cpu_id]) + elif c == "S": + int_extended.append(phandle) + int_extended.append(0x9) + elif c == "M": + int_extended.append(phandle) + int_extended.append(0xB) node.append(FdtPropertyWords("interrupts-extended", int_extended)) node.append(FdtProperty("interrupt-controller")) diff --git a/src/dev/riscv/plic.cc b/src/dev/riscv/plic.cc index fd42920dc5..ca5acbd27b 100644 --- a/src/dev/riscv/plic.cc +++ b/src/dev/riscv/plic.cc @@ -57,10 +57,18 @@ Plic::Plic(const Params ¶ms) : PlicBase(params), system(params.system), nSrc(params.n_src), - nContext(params.n_contexts), registers(params.name, pioAddr, this), update([this]{updateOutput();}, name() + ".update") { + fatal_if(params.hart_config != "" && params.n_contexts != 0, + "the hart_config and n_contexts can't be set simultaneously"); + + if (params.n_contexts != 0) { + initContextFromNContexts(params.n_contexts); + } + if (params.hart_config != "") { + initContextFromHartConfig(params.hart_config); + } } void @@ -80,7 +88,7 @@ Plic::post(int src_id) // Update states pendingPriority[src_id] = registers.priority[src_id].get(); - for (int i = 0; i < nContext; i++) { + for (int i = 0; i < contextConfigs.size(); i++) { bool enabled = bits(registers.enable[i][src_index].get(), src_offset); effPriority[i][src_id] = enabled ? pendingPriority[src_id] : 0; } @@ -109,7 +117,7 @@ Plic::clear(int src_id) // Update states pendingPriority[src_id] = 0; - for (int i = 0; i < nContext; i++) { + for (int i = 0; i < contextConfigs.size(); i++) { effPriority[i][src_id] = 0; } DPRINTF(Plic, @@ -174,20 +182,20 @@ Plic::init() // Setup internal states pendingPriority.resize(nSrc, 0x0); - for (int i = 0; i < nContext; i++) { + for (int i = 0; i < contextConfigs.size(); i++) { std::vector context_priority(nSrc, 0x0); effPriority.push_back(context_priority); } - lastID.resize(nContext, 0x0); + lastID.resize(contextConfigs.size(), 0x0); // Setup outputs output = PlicOutput{ - std::vector(nContext, 0x0), - std::vector(nContext, 0x0)}; + std::vector(contextConfigs.size(), 0x0), + std::vector(contextConfigs.size(), 0x0)}; DPRINTF(Plic, "Device init - %d contexts, %d sources, %d pending registers\n", - nContext, nSrc, nSrc32); + contextConfigs.size(), nSrc, nSrc32); BasicPioDevice::init(); } @@ -204,15 +212,15 @@ Plic::PlicRegisters::init() - plic->nSrc32 * 4; reserved.emplace_back("reserved1", reserve1_size); const size_t reserve2_size = thresholdStart - enableStart - - plic->nContext * enablePadding; + - plic->contextConfigs.size() * enablePadding; reserved.emplace_back("reserved2", reserve2_size); const size_t reserve3_size = plic->pioSize - thresholdStart - - plic->nContext * thresholdPadding; + - plic->contextConfigs.size() * thresholdPadding; reserved.emplace_back("reserved3", reserve3_size); // Sanity check assert(plic->pioSize >= thresholdStart - + plic->nContext * thresholdPadding); + + plic->contextConfigs.size() * thresholdPadding); assert((int) plic->pioSize <= maxBankSize); // Calculate hole sizes @@ -228,7 +236,7 @@ Plic::PlicRegisters::init() pending.emplace_back( std::string("pending") + std::to_string(i), 0); } - for (int i = 0; i < plic->nContext; i++) { + for (int i = 0; i < plic->contextConfigs.size(); i++) { enable.push_back(std::vector()); for (int j = 0; j < plic->nSrc32; j++) { @@ -264,7 +272,7 @@ Plic::PlicRegisters::init() addRegister(reserved[1]); // Enable - for (int i = 0; i < plic->nContext; i++) { + for (int i = 0; i < plic->contextConfigs.size(); i++) { for (int j = 0; j < plic->nSrc32; j++) { auto write_cb = std::bind(&Plic::writeEnable, plic, _1, _2, j, i); enable[i][j].writer(write_cb); @@ -275,7 +283,7 @@ Plic::PlicRegisters::init() addRegister(reserved[2]); // Threshold and claim - for (int i = 0; i < plic->nContext; i++) { + for (int i = 0; i < plic->contextConfigs.size(); i++) { auto threshold_cb = std::bind(&Plic::writeThreshold, plic, _1, _2, i); threshold[i].writer(threshold_cb); auto read_cb = std::bind(&Plic::readClaim, plic, _1, i); @@ -301,7 +309,7 @@ Plic::writePriority(Register32& reg, const uint32_t& data, const int src_id) // Update states bool pending = bits(registers.pending[src_index].get(), src_offset); pendingPriority[src_id] = pending ? reg.get() : 0; - for (int i = 0; i < nContext; i++) { + for (int i = 0; i < contextConfigs.size(); i++) { bool enabled = bits( registers.enable[i][src_index].get(), src_offset); effPriority[i][src_id] = enabled ? pendingPriority[src_id] : 0; @@ -394,11 +402,11 @@ Plic::propagateOutput() { // Calculate new output PlicOutput new_output{ - std::vector(nContext, 0x0), - std::vector(nContext, 0x0)}; + std::vector(contextConfigs.size(), 0x0), + std::vector(contextConfigs.size(), 0x0)}; uint32_t max_id; uint32_t max_priority; - for (int i = 0; i < nContext; i++) { + for (int i = 0; i < contextConfigs.size(); i++) { max_id = max_element(effPriority[i].begin(), effPriority[i].end()) - effPriority[i].begin(); max_priority = effPriority[i][max_id]; @@ -421,6 +429,39 @@ Plic::propagateOutput() } } +void +Plic::initContextFromNContexts(int n_contexts) +{ + contextConfigs.reserve(n_contexts); + for (uint32_t i = 0; i < (uint32_t)n_contexts; i += 2) { + contextConfigs.emplace_back((i >> 1), ExceptionCode::INT_EXT_MACHINE); + contextConfigs.emplace_back((i >> 1), ExceptionCode::INT_EXT_SUPER); + } +} + +void +Plic::initContextFromHartConfig(const std::string& hart_config) +{ + contextConfigs.reserve(hart_config.size()); + uint32_t hart_id = 0; + for (char c: hart_config) { + switch (c) { + case ',': + hart_id++; + break; + case 'M': + contextConfigs.emplace_back(hart_id, ExceptionCode::INT_EXT_MACHINE); + break; + case 'S': + contextConfigs.emplace_back(hart_id, ExceptionCode::INT_EXT_SUPER); + break; + default: + fatal("hart_config should not contains the value: %c", c); + break; + } + } +} + void Plic::updateOutput() { @@ -443,10 +484,8 @@ void Plic::updateInt() { // Update xEIP lines - for (int i = 0; i < nContext; i++) { - int thread_id = i >> 1; - int int_id = (i & 1) ? - ExceptionCode::INT_EXT_SUPER : ExceptionCode::INT_EXT_MACHINE; + for (int i = 0; i < contextConfigs.size(); i++) { + auto [thread_id, int_id] = contextConfigs[i]; auto tc = system->threads[thread_id]; uint32_t max_id = output.maxID[i]; diff --git a/src/dev/riscv/plic.hh b/src/dev/riscv/plic.hh index 00128ee56c..ef5eee8df8 100644 --- a/src/dev/riscv/plic.hh +++ b/src/dev/riscv/plic.hh @@ -57,11 +57,9 @@ namespace gem5 using namespace RiscvISA; /** * NOTE: - * This implementation of CLINT is based on - * the SiFive U54MC datasheet: - * https://sifive.cdn.prismic.io/sifive/fab000f6- - * 0e07-48d0-9602-e437d5367806_sifive_U54MC_rtl_ - * full_20G1.03.00_manual.pdf + * This implementation of PLIC is based on + * he riscv-plic-spec repository: + * https://github.com/riscv/riscv-plic-spec/releases/tag/1.0.0 */ /** @@ -124,13 +122,9 @@ class Plic : public PlicBase */ int nSrc32; /** - * Number of interrupt contexts - * = nThread * 2 - * e.g. context 0 => thread 0 M mode - * context 1 => thread 0 S mode - * This is based on SiFive U54MC datasheet + * PLIC hart/pmode address configs, stored in the format {hartID, pmode} */ - int nContext; + std::vector> contextConfigs; public: typedef PlicParams Params; @@ -261,6 +255,12 @@ class Plic : public PlicBase std::vector lastID; PlicOutput output; + /** + * The function for handling context config from params + */ + void initContextFromNContexts(int n_contexts); + void initContextFromHartConfig(const std::string& hart_config); + /** * Trigger: * - Plic::post diff --git a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm index 34358050cf..6123a6c70d 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm @@ -2600,11 +2600,18 @@ action(Send_CompData, desc="") { bool is_rd_nsd := tbe.reqType == CHIRequestType:ReadNotSharedDirty; bool is_rd_unique := tbe.reqType == CHIRequestType:ReadUnique; - // if the config allows (or not caching the data) and line has no sharers - bool snd_unique_on_rs := (fwd_unique_on_readshared || tbe.dataToBeInvalid) + // Send UC/UD on ReadShared or ReadNotSharedDirty if the line has no sharers + // and one of the followings are met + // 1) the config allows or + // 2) local cache won't have the line or + // 3) Dirty will be passed but the request doesn't allow SD + bool snd_unique_on_rs := (fwd_unique_on_readshared || + tbe.dataToBeInvalid || + (tbe.dataDirty && is_rd_nsd)) && tbe.dataUnique && tbe.dir_sharers.isEmpty(); // if the request type allows and we won't be caching the data - bool snd_dirty_on_rs := is_rd_shared && !is_rd_nsd && tbe.dataToBeInvalid; + bool snd_dirty_on_rs := (is_rd_shared && !is_rd_nsd) && + !tbe.dir_ownerExists; if (is_rd_once) { tbe.snd_msgType := CHIDataType:CompData_I; diff --git a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm index 31b5b0914a..9aaee236ac 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm @@ -767,7 +767,7 @@ transition({UD_RSC,SD_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { ProcessNextState; } -transition({UD_RSC,SD_RSC,UC_RSC,UD_RU,UC_RU,UD_RSD}, Global_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UD_RSC,SD_RSC,UC_RSC,UD_RU,UC_RU,UD_RSD,SD_RSD}, Global_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_WB_BackInvalidate; Profile_Eviction; diff --git a/src/python/gem5/components/boards/experimental/lupv_board.py b/src/python/gem5/components/boards/experimental/lupv_board.py index 2448ede45e..62ecfd59e4 100644 --- a/src/python/gem5/components/boards/experimental/lupv_board.py +++ b/src/python/gem5/components/boards/experimental/lupv_board.py @@ -185,7 +185,7 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload): # point for our bbl to use upon startup, and will # remain unused during the simulation self.pic.n_src = 0 - self.pic.n_contexts = 0 + self.pic.hart_config = "" self.lupio_pic.n_src = max(pic_srcs) + 1 self.lupio_pic.num_threads = self.processor.get_num_cores() @@ -403,10 +403,19 @@ class LupvBoard(AbstractSystemBoard, KernelDiskWorkload): plic_node.append(FdtPropertyWords("riscv,ndev", 0)) int_extended = list() - for i, core in enumerate(self.get_processor().get_cores()): - phandle = state.phandle(f"cpu@{i}.int_state") - int_extended.append(phandle) - int_extended.append(self._excep_code["INT_EXT_MACHINE"]) + cpu_id = 0 + phandle = int_state.phandle(f"cpu@{cpu_id}.int_state") + for c in plic.hart_config: + if c == ",": + cpu_id += 1 + assert cpu_id < self.get_processor().get_num_cores() + phandle = int_state.phandle(f"cpu@{cpu_id}.int_state") + elif c == "S": + int_extended.append(phandle) + int_extended.append(self._excep_code["INT_SOFT_SUPER"]) + elif c == "M": + int_extended.append(phandle) + int_extended.append(self._excep_code["INT_EXT_MACHINE"]) plic_node.append(FdtPropertyWords("interrupts-extended", int_extended)) plic_node.append(FdtProperty("interrupt-controller")) diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index dcb6fab7c5..555f723df1 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -102,7 +102,9 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): # Contains a CLINT, PLIC, UART, and some functions for the dtb, etc. self.platform = HiFive() # Note: This only works with single threaded cores. - self.platform.plic.n_contexts = self.processor.get_num_cores() * 2 + self.platform.plic.hart_config = ",".join( + ["MS" for _ in range(self.processor.get_num_cores())] + ) self.platform.attachPlic() self.platform.clint.num_threads = self.processor.get_num_cores() @@ -353,12 +355,19 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): plic_node.append(FdtPropertyWords("riscv,ndev", [plic.n_src - 1])) int_extended = list() - for i, core in enumerate(self.get_processor().get_cores()): - phandle = state.phandle(f"cpu@{i}.int_state") - int_extended.append(phandle) - int_extended.append(0xB) - int_extended.append(phandle) - int_extended.append(0x9) + cpu_id = 0 + phandle = int_state.phandle(f"cpu@{cpu_id}.int_state") + for c in plic.hart_config: + if c == ",": + cpu_id += 1 + assert cpu_id < self.get_processor().get_num_cores() + phandle = int_state.phandle(f"cpu@{cpu_id}.int_state") + elif c == "S": + int_extended.append(phandle) + int_extended.append(0x9) + elif c == "M": + int_extended.append(phandle) + int_extended.append(0xB) plic_node.append(FdtPropertyWords("interrupts-extended", int_extended)) plic_node.append(FdtProperty("interrupt-controller")) diff --git a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py index 0de69a40f2..570effaec7 100644 --- a/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py +++ b/src/python/gem5/prebuilt/riscvmatched/riscvmatched_board.py @@ -149,7 +149,9 @@ class RISCVMatchedBoard( # Contains a CLINT, PLIC, UART, and some functions for the dtb, etc. self.platform = HiFive() # Note: This only works with single threaded cores. - self.platform.plic.n_contexts = self.processor.get_num_cores() * 2 + self.platform.plic.hart_config = ",".join( + ["MS" for _ in range(self.processor.get_num_cores())] + ) self.platform.attachPlic() self.platform.clint.num_threads = self.processor.get_num_cores() @@ -433,12 +435,19 @@ class RISCVMatchedBoard( plic_node.append(FdtPropertyWords("riscv,ndev", [plic.n_src - 1])) int_extended = list() - for i, core in enumerate(self.get_processor().get_cores()): - phandle = state.phandle(f"cpu@{i}.int_state") - int_extended.append(phandle) - int_extended.append(0xB) - int_extended.append(phandle) - int_extended.append(0x9) + cpu_id = 0 + phandle = int_state.phandle(f"cpu@{cpu_id}.int_state") + for c in plic.hart_config: + if c == ",": + cpu_id += 1 + assert cpu_id < self.get_processor().get_num_cores() + phandle = int_state.phandle(f"cpu@{cpu_id}.int_state") + elif c == "S": + int_extended.append(phandle) + int_extended.append(0x9) + elif c == "M": + int_extended.append(phandle) + int_extended.append(0xB) plic_node.append(FdtPropertyWords("interrupts-extended", int_extended)) plic_node.append(FdtProperty("interrupt-controller")) diff --git a/src/python/gem5/simulate/simulator.py b/src/python/gem5/simulate/simulator.py index 708a484ead..9aadee0169 100644 --- a/src/python/gem5/simulate/simulator.py +++ b/src/python/gem5/simulate/simulator.py @@ -470,6 +470,12 @@ class Simulator: """ return self._last_exit_event.getCause() + def get_last_exit_event_code(self) -> int: + """ + Returns the last exit event status code + """ + return self._last_exit_event.getCode() + def get_current_tick(self) -> int: """ Returns the current tick. diff --git a/tests/gem5/asmtest/configs/riscv_asmtest.py b/tests/gem5/asmtest/configs/riscv_asmtest.py index d6582e4698..578dfaa976 100644 --- a/tests/gem5/asmtest/configs/riscv_asmtest.py +++ b/tests/gem5/asmtest/configs/riscv_asmtest.py @@ -32,6 +32,7 @@ gem5 while still being functinal. """ import argparse +import sys from gem5.components.boards.simple_board import SimpleBoard from gem5.components.cachehierarchies.classic.no_cache import NoCache @@ -119,3 +120,5 @@ print( simulator.get_current_tick(), simulator.get_last_exit_event_cause() ) ) + +sys.exit(simulator.get_last_exit_event_code()) diff --git a/util/dockerfiles/docker-compose.yaml b/util/dockerfiles/docker-compose.yaml index 5c63e101ba..69a9c2a1f5 100644 --- a/util/dockerfiles/docker-compose.yaml +++ b/util/dockerfiles/docker-compose.yaml @@ -65,6 +65,11 @@ services: args: - version=12 image: gcr.io/gem5-test/gcc-version-12:latest + gcc-13: + build: + context: ubuntu-22.04_gcc_13-version + dockerfile: Dockerfile + image: gcr.io/gem5-test/gcc-version-13:latest clang-7: build: context: ubuntu-20.04_clang-version diff --git a/util/dockerfiles/ubuntu-22.04_gcc_13-version/Dockerfile b/util/dockerfiles/ubuntu-22.04_gcc_13-version/Dockerfile new file mode 100644 index 0000000000..157cf4f9ba --- /dev/null +++ b/util/dockerfiles/ubuntu-22.04_gcc_13-version/Dockerfile @@ -0,0 +1,53 @@ +# Copyright (c) 2024 The Regents of the University of California +# All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +FROM --platform=${BUILDPLATFORM} ubuntu:22.04 + +# Valid version values: +# 13 + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt -y update && \ + # software-properties-common is necessary to install + # to add PPA to the system + apt -y install software-properties-common && \ + # Installing PPA is necessary to install gcc-13 + # because it is not available in the default repositories + # for Ubuntu 22.04 + add-apt-repository ppa:ubuntu-toolchain-r/test -y && \ + apt -y update && \ + apt -y install git m4 scons zlib1g zlib1g-dev libprotobuf-dev \ + protobuf-compiler libprotoc-dev libgoogle-perftools-dev python3-dev \ + doxygen libboost-all-dev libhdf5-serial-dev python3-pydot libpng-dev \ + gcc-13 g++-13 make + +RUN update-alternatives --install \ + /usr/bin/g++ g++ /usr/bin/g++- 100 +RUN update-alternatives --install \ + /usr/bin/gcc gcc /usr/bin/gcc-13 100 +RUN update-alternatives --install \ + /usr/bin/c++ c++ /usr/bin/g++-13 100 +RUN update-alternatives --install \ + /usr/bin/cc cc /usr/bin/gcc-13 100