From e141d9e4d0bf4d9845cf1ce8a5d955363219bb87 Mon Sep 17 00:00:00 2001 From: Minje Jun Date: Sun, 21 Jan 2024 16:14:53 +0900 Subject: [PATCH 01/11] mem-ruby: Writeback CHI UD_RU line at local evict In Ruby CHI protocol UD_RU state means the line is in UD state in the local cache and the upstream may have it in UD or UC state. In the previous implementation UD_RU line was just dropped without WriteBack which can cause loss of dirty data when the upstream has it in UC state. This commit fixes it by performing WriteBack when evciting UD_RU line. Change-Id: I1db9b4f95cc576e71dcef38b01de24775df514ba --- src/mem/ruby/protocol/chi/CHI-cache-funcs.sm | 8 ++++---- src/mem/ruby/protocol/chi/CHI-cache-transitions.sm | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm b/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm index fbafda61cd..ccef1d8deb 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm @@ -892,10 +892,10 @@ void copyCacheAndDir(CacheEntry cache_entry, DirEntry dir_entry, if (is_valid(cache_entry) && ((initialState == State:UD) || (initialState == State:SD) || (initialState == State:UC) || (initialState == State:SC) || - (initialState == State:UD_RSC) || (initialState == State:SD_RSC) || - (initialState == State:UC_RSC) || (initialState == State:SC_RSC) || - (initialState == State:UD_RSD) || (initialState == State:SD_RSD) || - (initialState == State:UD_T))) { + (initialState == State:UD_RU) || (initialState == State:UD_RSC) || + (initialState == State:SD_RSC) || (initialState == State:UC_RSC) || + (initialState == State:SC_RSC) || (initialState == State:UD_RSD) || + (initialState == State:SD_RSD) || (initialState == State:UD_T))) { tbe.dataBlk := cache_entry.DataBlk; tbe.dataBlkValid.fillMask(); tbe.dataValid := true; diff --git a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm index 31b5b0914a..b2cb419833 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm @@ -710,10 +710,10 @@ transition({UD_RSC, UC_RSC, SC_RSC, SD_RSC, UD, RU, RSD, RUSD, RUSC, UD_RSD, SD_ // Cache Replacement -// When in UD_RU,UC_RU,UD_RSD,SD_RSD we also just drop the line since an upstream +// When in UC_RU,UD_RSD,SD_RSD we also just drop the line since an upstream // cache has an up-to-data line that it will either WriteBack or WriteEvict transition({SC,UC,SC_RSC,UC_RSC, - UD_RU,UC_RU,UD_RSD,SD_RSD}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { + UC_RU,UD_RSD,SD_RSD}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_JustDrop; Profile_Eviction; @@ -722,7 +722,7 @@ transition({SC,UC,SC_RSC,UC_RSC, ProcessNextState; } -transition({UD,SD,UD_RSC,SD_RSC}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UD,SD,UD_RU,UD_RSC,SD_RSC}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_WB; Profile_Eviction; @@ -749,7 +749,7 @@ transition({UD,SD,UC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { ProcessNextState; } -transition({UD_RU,UC_RU,UD_RSD,SD_RSD,SC_RSC,UC_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UC_RU,UD_RSD,SD_RSD,SC_RSC,UC_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_JustDrop; Profile_Eviction; @@ -758,7 +758,7 @@ transition({UD_RU,UC_RU,UD_RSD,SD_RSD,SC_RSC,UC_RSC}, Local_Eviction, BUSY_BLKD) ProcessNextState; } -transition({UD_RSC,SD_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UD_RU,UD_RSC,SD_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_WB; Profile_Eviction; From 1b5d92ee9c00ed4efd4e3d098b316bc1aa30d4b2 Mon Sep 17 00:00:00 2001 From: Minje Jun Date: Wed, 31 Jan 2024 13:42:32 +0900 Subject: [PATCH 02/11] mem-ruby: Revert Writeback CHI UD_RU line at local evict This reverts commit d613d814a431525e122552a667eed653a057f2be. Change-Id: I50e218b7debf3a2836ce12515d8fcb6c0b38df53 --- src/mem/ruby/protocol/chi/CHI-cache-funcs.sm | 8 ++++---- src/mem/ruby/protocol/chi/CHI-cache-transitions.sm | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm b/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm index ccef1d8deb..fbafda61cd 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-funcs.sm @@ -892,10 +892,10 @@ void copyCacheAndDir(CacheEntry cache_entry, DirEntry dir_entry, if (is_valid(cache_entry) && ((initialState == State:UD) || (initialState == State:SD) || (initialState == State:UC) || (initialState == State:SC) || - (initialState == State:UD_RU) || (initialState == State:UD_RSC) || - (initialState == State:SD_RSC) || (initialState == State:UC_RSC) || - (initialState == State:SC_RSC) || (initialState == State:UD_RSD) || - (initialState == State:SD_RSD) || (initialState == State:UD_T))) { + (initialState == State:UD_RSC) || (initialState == State:SD_RSC) || + (initialState == State:UC_RSC) || (initialState == State:SC_RSC) || + (initialState == State:UD_RSD) || (initialState == State:SD_RSD) || + (initialState == State:UD_T))) { tbe.dataBlk := cache_entry.DataBlk; tbe.dataBlkValid.fillMask(); tbe.dataValid := true; diff --git a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm index b2cb419833..31b5b0914a 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-transitions.sm @@ -710,10 +710,10 @@ transition({UD_RSC, UC_RSC, SC_RSC, SD_RSC, UD, RU, RSD, RUSD, RUSC, UD_RSD, SD_ // Cache Replacement -// When in UC_RU,UD_RSD,SD_RSD we also just drop the line since an upstream +// When in UD_RU,UC_RU,UD_RSD,SD_RSD we also just drop the line since an upstream // cache has an up-to-data line that it will either WriteBack or WriteEvict transition({SC,UC,SC_RSC,UC_RSC, - UC_RU,UD_RSD,SD_RSD}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { + UD_RU,UC_RU,UD_RSD,SD_RSD}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_JustDrop; Profile_Eviction; @@ -722,7 +722,7 @@ transition({SC,UC,SC_RSC,UC_RSC, ProcessNextState; } -transition({UD,SD,UD_RU,UD_RSC,SD_RSC}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UD,SD,UD_RSC,SD_RSC}, LocalHN_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_WB; Profile_Eviction; @@ -749,7 +749,7 @@ transition({UD,SD,UC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { ProcessNextState; } -transition({UC_RU,UD_RSD,SD_RSD,SC_RSC,UC_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UD_RU,UC_RU,UD_RSD,SD_RSD,SC_RSC,UC_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_JustDrop; Profile_Eviction; @@ -758,7 +758,7 @@ transition({UC_RU,UD_RSD,SD_RSD,SC_RSC,UC_RSC}, Local_Eviction, BUSY_BLKD) {Repl ProcessNextState; } -transition({UD_RU,UD_RSC,SD_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { +transition({UD_RSC,SD_RSC}, Local_Eviction, BUSY_BLKD) {ReplTBEAvailable} { Initiate_Replacement; Initiate_Replacement_WB; Profile_Eviction; From 628be390a0c52efbae3d8a3cc1c84be6184c6d44 Mon Sep 17 00:00:00 2001 From: Minje Jun Date: Wed, 31 Jan 2024 17:48:29 +0900 Subject: [PATCH 03/11] mem-ruby: Fix ReadShared hit handling on UD line In case ReadShared hit on a UD line and there's no sharers, this chage makes the downstream respond with Unique even though it doesn't deallocate the line. This will make the requestor to UD and the downstream to UD_RU. In the previous implementation, loosely exclusive intermediate cache can cause loss of dirty data. Example sequence is as below. Configurations L2 cache: Roughly inclusive to L1 without back-invalidation - dealloc_on_* = false - dealloc_backinv_* = false L3 cache: Roughly exclusive to L2 without back-invalidation - alloc_on_readshared = tue - alloc_on_readunique = false - dealloc_on_shared = false - dealloc_on_unique = true - dealloc_backinv_* = false - is_HN = false LLC: Same clusivity as L3 except is_HN = true For all caches, allow_SD = true and fwd_unique_on_readshared = false Example problem sequence: 1. L1 sends ReadUnique then becomes UD. L2 is UC_RU. L3 and LLC are RU. 2. L1 evicts the line to L2 by WriteBackFull (UD_PD). L2 becomes UD. 3. L2 evicts the line to L3 using WriteBackFull (UD_PD). L3 becomes UD. 4. L1 reads the line with ReadShared which misses on L2. 5. L2 reads the line with ReadShared which hits on L3. L3 becomes UD_RSC because it doesn't deallocate the line (dataToBeInvalid=false) 6. L3 evicts the line to LLC by WriteCleanFull (UD_PD) because L3 doesn't back-invalidate and still has sharer. The local cache line is invalidated by Deallocate_CacheBlock. L3 becomes RUSC and LLC becomes UD_RU. 7. When UD_RU is evicted at LLC, the UD_RU line is dropped expecting the upstream to writeback, causing loss of dirty data. Change-Id: Ic9bee27f2ec8906dd5df8bd3be60e5a9a76c782f --- src/mem/ruby/protocol/chi/CHI-cache-actions.sm | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm index 34358050cf..eb54d01053 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) + // if the request type allows SD + bool snd_dirty_on_rs := is_rd_shared && !is_rd_nsd; + + // 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 + bool snd_unique_on_rs := (fwd_unique_on_readshared || + tbe.dataToBeInvalid || + snd_dirty_on_rs) && 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; if (is_rd_once) { tbe.snd_msgType := CHIDataType:CompData_I; From db5c71a919a67ff97c996a5b398828a407550bf2 Mon Sep 17 00:00:00 2001 From: Minje Jun Date: Tue, 6 Feb 2024 16:03:11 +0900 Subject: [PATCH 04/11] mem-ruby: Pass UD on ReadShared hit only if SD is not allowed This commit allows CompData_SD be sent when ReadShared hits on UD line and the local cache keeps the line, unless the request doesn't allow SD. Change-Id: I337f24c871cc4c19c5b5fb11f9b35c0a8eb7911c --- src/mem/ruby/protocol/chi/CHI-cache-actions.sm | 10 +++++----- src/mem/ruby/protocol/chi/CHI-cache-transitions.sm | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm index eb54d01053..6123a6c70d 100644 --- a/src/mem/ruby/protocol/chi/CHI-cache-actions.sm +++ b/src/mem/ruby/protocol/chi/CHI-cache-actions.sm @@ -2600,18 +2600,18 @@ action(Send_CompData, desc="") { bool is_rd_nsd := tbe.reqType == CHIRequestType:ReadNotSharedDirty; bool is_rd_unique := tbe.reqType == CHIRequestType:ReadUnique; - // if the request type allows SD - bool snd_dirty_on_rs := is_rd_shared && !is_rd_nsd; - // 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 + // 3) Dirty will be passed but the request doesn't allow SD bool snd_unique_on_rs := (fwd_unique_on_readshared || tbe.dataToBeInvalid || - snd_dirty_on_rs) + (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.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; From 816ef46c78a9a4b345eab77ff52710f9036de0a1 Mon Sep 17 00:00:00 2001 From: Yu-Cheng Chang Date: Fri, 23 Feb 2024 00:33:34 +0800 Subject: [PATCH 05/11] arch-riscv: Fix fflags behavior of float inst. in O3 CPU (#868) According to the RISC-V spec [1]. Any float-point instructions accumulate FFLAGS register rather than write it to reflect the CSR behavior. In the previous implementation. We read the FFLAGS, set the exception flags, and write the result back to the FFLAGS. This works in the gem5 simple and minor CPU model as they are actually written to `regFile` after executing the instructions. However, in the gem5 O3 CPU model, it will record in the `destMiscReg` buffer until the commit stage when writing to the `miscReg` in the execution stage. The next instruction will get the old FFLAGS and cause the incorrect result. The CL introduced the `MISCREG_FFLAGS_EXE` and used the same size of `miscRegFile` because the `MISCREG_FFLAGS_EXE` and `MISCREG_FFLAGS` shared the same space. When executing the float-pointing instruction, any exception flags should be updated via `MISCREG_FFLAGS_EXE` to accumulate the FFLAGS in `setMiscReg` method. For the MISCREG_FFLAGS, it should only be called in the CSROp. [1] Syntactic Dependencies: Appendix A https://github.com/riscv/riscv-isa-manual/blob/c80ecada1ccc3120e2c8003bd7ca8e91c2e91bf9/src/mm-eplan.adoc#syntactic-dependencies-rules-9-11 gem5 issue: https://github.com/gem5/gem5/issues/755 Change-Id: Ib7f13d95b8a921c37766a54a217a5a4b1ef17c6f --- src/arch/riscv/isa.cc | 21 +++++++++++++++++---- src/arch/riscv/isa/formats/fp.isa | 5 +---- src/arch/riscv/isa/formats/vector_arith.isa | 4 +--- src/arch/riscv/regs/misc.hh | 5 +++++ 4 files changed, 24 insertions(+), 11 deletions(-) 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 }; From 47f3ad45d370359648654b5d8955376b3415c42d Mon Sep 17 00:00:00 2001 From: Yu-Cheng Chang Date: Sat, 24 Feb 2024 01:09:28 +0800 Subject: [PATCH 06/11] stdlib: Add get_last_exit_event_code to get m5 exit status code (#890) Change-Id: I7319437dff24e31f343e71b6b8993f833b62147c --- src/python/gem5/simulate/simulator.py | 6 ++++++ 1 file changed, 6 insertions(+) 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. From 00ed1d30cfde05b921de1e61e7be1b5396a30e5e Mon Sep 17 00:00:00 2001 From: wmin0 Date: Mon, 26 Feb 2024 22:42:27 +0800 Subject: [PATCH 07/11] python,util: Fix SimObjectParams default constructor and destructor (#880) The empty constructor prevent zero-initialization working correctly. In this change we fix the issue by removing the unwanted empty constructor. We also change the default destructor specification with c++11 style. Change-Id: I869a93ca5283f811c2aa58406f1478459e0d7022 --- build_tools/sim_object_param_struct_hh.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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; """ From 521a7c1de02f736361bc88621028ee7e6ae6cf16 Mon Sep 17 00:00:00 2001 From: Yu-Cheng Chang Date: Tue, 27 Feb 2024 02:31:18 +0800 Subject: [PATCH 08/11] tests: Exit riscv_asmtest script with simulator status code (#891) It will be helpful to check if the instruction simulate well Change-Id: I5faa435fad79601682126ee7978d8444093df900 --- tests/gem5/asmtest/configs/riscv_asmtest.py | 3 +++ 1 file changed, 3 insertions(+) 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()) From bcf455755e7abf2fde3dddcb8a1c1917aa8a91ca Mon Sep 17 00:00:00 2001 From: Yu-Cheng Chang Date: Tue, 27 Feb 2024 02:32:53 +0800 Subject: [PATCH 09/11] arch-riscv,dev: Update the PLIC implementation (#886) Update the PLIC based on the [riscv-plic-spec](https://github.com/riscv/riscv-plic-spec) in the PR: - Support customized PLIC hardID and privilege mode configuration - Backward compatable with the n_contexts parameter, will generate the config like {0,M}, {0,S}, {1,M} ... Change-Id: Ibff736827edb7c97921e01fa27f503574a27a562 --- src/dev/riscv/HiFive.py | 6 +- src/dev/riscv/Plic.py | 45 +++++++--- src/dev/riscv/plic.cc | 83 ++++++++++++++----- src/dev/riscv/plic.hh | 22 ++--- .../boards/experimental/lupv_board.py | 19 +++-- .../gem5/components/boards/riscv_board.py | 23 +++-- .../riscvmatched/riscvmatched_board.py | 23 +++-- 7 files changed, 155 insertions(+), 66 deletions(-) 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/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")) From 19901861708d99184539a665edac132d8e003b23 Mon Sep 17 00:00:00 2001 From: Nicholas Mosier Date: Mon, 26 Feb 2024 10:33:48 -0800 Subject: [PATCH 10/11] configs: Ensure m5ops base doesn't overlap physical mem in KVM (#875) Fix #874, in which running se.py with 4GB or more memory (via option --mem-size=4GB) causes all KVM programs to crash or hang. This occurred because the m5ops address range (set to 0xFFFF0000-0x100000000) overlapped with physical memory under such a configuration. This patch fixes the bug by moving the m5ops address range if phyiscal memory is >=4GB. Change-Id: Ic8a004517bc2be2c27860ed314460be749a11dc1 --- configs/deprecated/example/se.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 920497c19fd4616561fc4e702292111ea3caaf42 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 26 Feb 2024 15:03:14 -0800 Subject: [PATCH 11/11] tests: Add compiler test for gcc 13 (#858) Change-Id: I41bdf3ab7ffff21c4148ef17fc5229b5597ec953 --- .github/workflows/compiler-tests.yaml | 6 +-- util/dockerfiles/docker-compose.yaml | 5 ++ .../ubuntu-22.04_gcc_13-version/Dockerfile | 53 +++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 util/dockerfiles/ubuntu-22.04_gcc_13-version/Dockerfile 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/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