Jordi Vaquero has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/36835 )
Change subject: arch-arm: Implementing Arm8 LOR feature
......................................................................
arch-arm: Implementing Arm8 LOR feature
This patch implementents Limited ordering feature for Armv8.
This consist in addiung memory barrier regions to block ld/st
depending on the region their PA falls in.
This required some minor modification in the path for timing and o3
cpu types. In this case on completeDataAccess we refer to the LOR_helper
functions to free the barrier for the operation that has been waiting.
Change-Id: I2e0d4962f8672856185054917482204d2f220cbe
---
M src/arch/arm/ArmISA.py
M src/arch/arm/SConscript
M src/arch/arm/isa.cc
M src/arch/arm/isa.hh
M src/arch/arm/isa/formats/aarch64.isa
M src/arch/arm/isa/includes.isa
M src/arch/arm/isa/insts/ldr64.isa
M src/arch/arm/isa/insts/str64.isa
M src/arch/arm/isa/templates/mem64.isa
A src/arch/arm/lor_helper.cc
A src/arch/arm/lor_helper.hh
M src/arch/arm/miscregs.cc
M src/arch/arm/miscregs.hh
M src/arch/arm/tlb.cc
M src/arch/arm/tlb.hh
M src/arch/arm/utility.cc
M src/arch/arm/utility.hh
M src/arch/generic/tlb.hh
M src/cpu/o3/lsq_impl.hh
M src/cpu/simple/timing.cc
M src/mem/request.hh
21 files changed, 477 insertions(+), 14 deletions(-)
diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py
index 02f24d3..1e645d3 100644
--- a/src/arch/arm/ArmISA.py
+++ b/src/arch/arm/ArmISA.py
@@ -109,13 +109,17 @@
# 4K | 64K | !16K | !BigEndEL0 | !SNSMem | !BigEnd | 8b ASID | 40b PA
id_aa64mmfr0_el1 = Param.UInt64(0x0000000000f00002,
"AArch64 Memory Model Feature Register 0")
- # PAN | HPDS | VHE
- id_aa64mmfr1_el1 = Param.UInt64(0x0000000000101100,
- "AArch64 Memory Model Feature Register 1")
+ # PAN | LO | HPDS | VHE
+ id_aa64mmfr1_el1 = Param.UInt64(0x0000000000111100,
+ "AArch64 Memory Model Feature Register 1")
# |VARANGE
id_aa64mmfr2_el1 = Param.UInt64(0x0000000000010000,
"AArch64 Memory Model Feature Register 2")
+ # Select number of regions and region descriptors
+ lorid_el1 = Param.UInt64(0x0000000000FF00FF,
+ "LORegion ID Register")
+
# Any access (read/write) to an unimplemented
# Implementation Defined registers is not causing an Undefined
Instruction.
# It is rather executed as a NOP.
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index 31e83a7..3faff7d 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -77,6 +77,7 @@
Source('linux/process.cc')
Source('linux/se_workload.cc')
Source('linux/fs_workload.cc')
+ Source('lor_helper.cc')
Source('freebsd/freebsd.cc')
Source('freebsd/fs_workload.cc')
Source('freebsd/se_workload.cc')
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 3607c29..4292b70 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -112,6 +112,7 @@
highestELIs64 ? Enums::Full : Enums::Elem;
selfDebug = new SelfDebug();
+ lorHelper = new LORHelper();
initializeMiscRegMetadata();
preUnflattenMiscReg();
@@ -372,6 +373,8 @@
miscRegs[MISCREG_ID_AA64MMFR1_EL1] = p.id_aa64mmfr1_el1;
miscRegs[MISCREG_ID_AA64MMFR2_EL1] = p.id_aa64mmfr2_el1;
+ miscRegs[MISCREG_LORID_EL1] = p.lorid_el1;
+
miscRegs[MISCREG_ID_DFR0_EL1] =
(p.pmu ? 0x03000000ULL : 0); // Enable PMUv3
@@ -460,6 +463,7 @@
return;
selfDebug->init(tc);
+ lorHelper->init(tc);
Gicv3 *gicv3 = dynamic_cast<Gicv3 *>(system->getGIC());
if (!gicv3)
@@ -1336,6 +1340,10 @@
case MISCREG_DBGWCR15_EL1:
selfDebug->updateDBGWCR(15, val);
break;
+ case MISCREG_LORC_EL1:
+ if (val & 0x1)
+ lorHelper->updateDescriptor(tc, val);
+ break;
case MISCREG_IFSR:
{
// ARM ARM (ARM DDI 0406C.b) B4.1.96
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 4a824ed..92ced40 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -110,6 +110,7 @@
bool afterStartup;
SelfDebug * selfDebug;
+ LORHelper * lorHelper;
/** MiscReg metadata **/
struct MiscRegLUTEntry {
@@ -485,6 +486,19 @@
return arm_isa->getSelfDebug();
}
+ LORHelper*
+ getLorHelper() const
+ {
+ return lorHelper;
+ }
+
+ static LORHelper*
+ getLorHelper(ThreadContext *tc)
+ {
+ auto *arm_isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
+ return arm_isa->getLorHelper();
+ }
+
RegVal readMiscRegNoEffect(int misc_reg) const;
RegVal readMiscReg(int misc_reg);
void setMiscRegNoEffect(int misc_reg, RegVal val);
diff --git a/src/arch/arm/isa/formats/aarch64.isa
b/src/arch/arm/isa/formats/aarch64.isa
index f1a0cdb..44f6333 100644
--- a/src/arch/arm/isa/formats/aarch64.isa
+++ b/src/arch/arm/isa/formats/aarch64.isa
@@ -1285,6 +1285,19 @@
default:
M5_UNREACHABLE;
}
+ case 0x8:
+ switch (size) {
+ case 0x0:
+ return new STLLRB(machInst, rt, rnsp);
+ case 0x1:
+ return new STLLRH(machInst, rt, rnsp);
+ case 0x2:
+ return new STLLR32(machInst, rt, rnsp);
+ case 0x3:
+ return new STLLR64(machInst, rt, rnsp);
+ default:
+ M5_UNREACHABLE;
+ }
case 0x9:
switch (size) {
case 0x0:
@@ -1324,6 +1337,19 @@
default:
M5_UNREACHABLE;
}
+ case 0xc:
+ switch (size) {
+ case 0x0:
+ return new LDLARB(machInst, rt, rnsp);
+ case 0x1:
+ return new LDLARH(machInst, rt, rnsp);
+ case 0x2:
+ return new LDLAR32(machInst, rt, rnsp);
+ case 0x3:
+ return new LDLAR64(machInst, rt, rnsp);
+ default:
+ M5_UNREACHABLE;
+ }
case 0xd:
switch (size) {
case 0x0:
diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa
index 13b47c8..2324d56 100644
--- a/src/arch/arm/isa/includes.isa
+++ b/src/arch/arm/isa/includes.isa
@@ -104,6 +104,7 @@
#include "arch/arm/isa.hh"
#include "arch/arm/htm.hh"
#include "arch/arm/isa_traits.hh"
+#include "arch/arm/lor_helper.hh"
#include "arch/arm/pauth_helpers.hh"
#include "arch/arm/semihosting.hh"
#include "arch/arm/utility.hh"
diff --git a/src/arch/arm/isa/insts/ldr64.isa
b/src/arch/arm/isa/insts/ldr64.isa
index 76b0cae..957c46b 100644
--- a/src/arch/arm/isa/insts/ldr64.isa
+++ b/src/arch/arm/isa/insts/ldr64.isa
@@ -61,6 +61,7 @@
self.memFlags = []
self.instFlags = []
self.codeBlobs = {"postacc_code" : ""}
+ self.codeBlobs["lor_inst"] = "false";
# Add memory request flags where necessary
if self.user:
@@ -86,7 +87,7 @@
# Only the first microop should perform alignment checking.
self.memFlags.append("%d" % int(math.log(self.size, 2)))
- if self.flavor not in ("acquire", "acex", "exclusive",
+ if self.flavor not in ("lor", "acquire", "acex", "exclusive",
"acexp", "exp"):
self.memFlags.append("ArmISA::TLB::AllowUnaligned")
@@ -94,6 +95,9 @@
self.instFlags.extend(["IsWriteBarrier", "IsReadBarrier"])
self.memFlags.append("Request::ACQUIRE")
+ if self.flavor == "lor":
+ self.memFlags.append("ArmISA::TLB::LORInst")
+
if self.flavor in ("acex", "exclusive", "exp", "acexp"):
self.memFlags.append("Request::LLSC")
@@ -149,7 +153,8 @@
assert not wbDecl
fa_code = None
- if not self.micro and self.flavor in
("normal", "widen", "acquire"):
+ if not self.micro and self.flavor in ("normal", "widen", "lor",
+ "acquire"):
fa_code = '''
fault->annotate(ArmISA::ArmFault::SAS, %s);
fault->annotate(ArmISA::ArmFault::SSE, %s);
@@ -162,8 +167,8 @@
"true" if self.sign else "false",
"true" if (self.size == 8 or
self.flavor == "widen") else "false",
- "true" if self.flavor == "acquire" else "false")
-
+ "true" if self.flavor in ("lor", "acquire")
+ else "false")
(newHeader, newDecoder, newExec) = \
self.fillTemplates(self.name, self.Name, self.codeBlobs,
self.memFlags, self.instFlags,
@@ -475,6 +480,11 @@
LoadRaw64("ldarh", "LDARH64", size=2, flavor="acquire").emit()
LoadRaw64("ldarb", "LDARB64", size=1, flavor="acquire").emit()
+ LoadRaw64("ldlar", "LDLAR64", size=8, flavor="lor").emit()
+ LoadRaw64("ldlar", "LDLAR32", size=4, flavor="lor").emit()
+ LoadRaw64("ldlarh", "LDLARH", size=2, flavor="lor").emit()
+ LoadRaw64("ldlarb", "LDLARB", size=1, flavor="lor").emit()
+
LoadEx64("ldaxr", "LDAXRX64", size=8, flavor="acex").emit()
LoadEx64("ldaxr", "LDAXRW64", size=4, flavor="acex").emit()
LoadEx64("ldaxrh", "LDAXRH64", size=2, flavor="acex").emit()
diff --git a/src/arch/arm/isa/insts/str64.isa
b/src/arch/arm/isa/insts/str64.isa
index ed99064..22dcf3d 100644
--- a/src/arch/arm/isa/insts/str64.isa
+++ b/src/arch/arm/isa/insts/str64.isa
@@ -59,6 +59,7 @@
self.memFlags = []
self.instFlags = []
self.codeBlobs = { "postacc_code" : "" }
+ self.codeBlobs["lor_inst"] = "false";
# Add memory request flags where necessary
if self.user:
@@ -71,10 +72,13 @@
# Only the first microop should perform alignment checking.
self.memFlags.append("%d" % int(math.log(self.size, 2)))
- if self.flavor not in ("release", "relex", "exclusive",
+ if self.flavor not in ("lor", "release", "relex", "exclusive",
"relexp", "exp"):
self.memFlags.append("ArmISA::TLB::AllowUnaligned")
+ if self.flavor == "lor":
+ self.memFlags.append("ArmISA::TLB::LORInst")
+
if self.micro:
self.instFlags.append("IsMicroop")
@@ -96,7 +100,7 @@
assert not wbDecl
fa_code = None
- if not self.micro and self.flavor in ("normal", "release"):
+ if not self.micro and self.flavor in
("lor", "normal", "release"):
fa_code = '''
fault->annotate(ArmISA::ArmFault::SAS, %s);
fault->annotate(ArmISA::ArmFault::SSE, false);
@@ -107,7 +111,8 @@
"1" if self.size == 2 else
"2" if self.size == 4 else "3",
"true" if self.size == 8 else "false",
- "true" if self.flavor == "release" else "false")
+ "true" if self.flavor in ("lor", "release")
+ else "false")
(newHeader, newDecoder, newExec) = \
self.fillTemplates(self.name, self.Name, self.codeBlobs,
@@ -321,6 +326,11 @@
StoreRaw64("stlrh", "STLRH64", size=2, flavor="release").emit()
StoreRaw64("stlrb", "STLRB64", size=1, flavor="release").emit()
+ StoreRaw64("stllr", "STLLR64", size=8, flavor="lor").emit()
+ StoreRaw64("stllr", "STLLR32", size=4, flavor="lor").emit()
+ StoreRaw64("stllrh", "STLLRH", size=2, flavor="lor").emit()
+ StoreRaw64("stllrb", "STLLRB", size=1, flavor="lor").emit()
+
StoreEx64("stlxr", "STLXRX64", size=8, flavor="relex").emit()
StoreEx64("stlxr", "STLXRW64", size=4, flavor="relex").emit()
StoreEx64("stlxrh", "STLXRH64", size=2, flavor="relex").emit()
diff --git a/src/arch/arm/isa/templates/mem64.isa
b/src/arch/arm/isa/templates/mem64.isa
index 3b90f8c..2a7e878 100644
--- a/src/arch/arm/isa/templates/mem64.isa
+++ b/src/arch/arm/isa/templates/mem64.isa
@@ -56,6 +56,9 @@
%(ea_code)s;
if (fault == NoFault) {
+ if (%(lor_inst)s && !EnabledLOR(xc->tcBase())) {
+ memAccessFlags |= Request::ACQUIRE;
+ }
fault = readMemAtomicLE(xc, traceData, EA, Mem,
memAccessFlags);
%(memacc_code)s;
}
@@ -108,6 +111,9 @@
}
if (fault == NoFault) {
+ if (%(lor_inst)s && !EnabledLOR(xc->tcBase())) {
+ memAccessFlags |= Request::RELEASE;
+ }
fault = writeMemAtomicLE(xc, traceData, Mem, EA,
memAccessFlags, NULL);
}
@@ -136,6 +142,9 @@
}
if (fault == NoFault) {
+ if (%(lor_inst)s && !EnabledLOR(xc->tcBase())) {
+ memAccessFlags |= Request::RELEASE;
+ }
fault = writeMemTimingLE(xc, traceData, Mem, EA,
memAccessFlags,
NULL);
}
@@ -213,6 +222,9 @@
%(ea_code)s;
if (fault == NoFault) {
+ if (%(lor_inst)s && !EnabledLOR(xc->tcBase())) {
+ memAccessFlags |= Request::ACQUIRE;
+ }
fault = initiateMemRead(xc, traceData, EA, Mem,
memAccessFlags);
}
diff --git a/src/arch/arm/lor_helper.cc b/src/arch/arm/lor_helper.cc
new file mode 100644
index 0000000..7035ab0
--- /dev/null
+++ b/src/arch/arm/lor_helper.cc
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2010-2020 Metempsy Technologies
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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.
+ */
+
+#include "arch/arm/lor_helper.hh"
+
+namespace ArmISA
+{
+bool
+LORDescriptor::isEnabled(LORRequest *req)
+{
+ int qsize = queue.size();
+ if (!valid)
+ return false;
+ if (qsize > 0) {
+ queue.push_back(req);
+ return true;
+ } else {
+ if (req->lorInst) {
+ queue.push_back(req);
+ }
+ return false;
+ }
+
+}
+
+void
+LORDescriptor::completeInst()
+{
+ if (queue.empty())
+ return;
+ LORRequest* req = queue.front();
+ queue.pop_front();
+ bool lor_inst = req->lorInst;
+ Fault fault = NoFault;
+ while (fault != NoFault && queue.size() > 0 && !lor_inst) {
+ req->finishTranslation();
+ req = queue.front();
+ queue.pop_front();
+ lor_inst = req->lorInst;
+ }
+}
+
+int
+LORHelper::findDescriptor(Addr address)
+{
+ int index = -1;
+ for (auto &p: regionVec) {
+ if (p->start <= address && p->end >= address) {
+ index = p->dId;
+ break;
+ }
+ }
+ return index;
+}
+
+bool
+LORHelper::isLOREnabled(Addr addr, LORRequest* req)
+{
+ int index = findDescriptor(addr);
+ bool enabled = !(nRegions == 0 || nRegDesc == 0 || index == -1);
+
+ if (!enabled) {
+ return false;
+ } else {
+ enabled = regionVec[index]->isEnabled(req);
+ if (enabled && req->lorInst)
+ req->setDescriptor(index);
+ return enabled;
+ }
+}
+
+void
+LORHelper::completeInst(RequestPtr & req)
+{
+ regionVec[req->getOrderingIndex()]->completeInst();
+}
+
+}
diff --git a/src/arch/arm/lor_helper.hh b/src/arch/arm/lor_helper.hh
new file mode 100644
index 0000000..346df1d
--- /dev/null
+++ b/src/arch/arm/lor_helper.hh
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2010-2020 Metempsy Technologies
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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.
+ */
+#ifndef __ARCH_ARM_LOR_HELPER_HH__
+#define __ARCH_ARM_LOR_HELPER_HH__
+
+#include <deque>
+
+#include "arch/arm/faults.hh"
+#include "arch/generic/tlb.hh"
+#include "cpu/o3/lsq.hh"
+#include "cpu/thread_context.hh"
+#include "mem/request.hh"
+
+namespace ArmISA
+{
+class LORDescriptor;
+
+struct LORRequest {
+ BaseTLB::Translation* trans;
+ const RequestPtr &req;
+ ThreadContext *tc;
+ BaseTLB::Mode mode;
+ bool lorInst;
+
+ LORRequest(BaseTLB::Translation * _trans, const RequestPtr &_req,
+ ThreadContext *_tc, BaseTLB::Mode _mode, bool _lorInst):
+ trans(_trans), req(_req), tc(_tc), lorInst(_lorInst)
+ {}
+
+ void setDescriptor(int desc_idx)
+ {
+ req->setOrderingIndex(desc_idx);
+ }
+
+ void finishTranslation()
+ {
+ trans->finish(NoFault, req, tc, mode);
+ }
+};
+
+class LORDescriptor
+{
+ public:
+ int dId;
+ Addr start;
+ Addr end;
+ bool valid;
+ int regionId;
+
+ std::deque<LORRequest*> queue;
+ LORDescriptor(int _dId): dId(_dId), valid(false)
+ {
+ queue = std::deque<LORRequest*>();
+ }
+
+ ~LORDescriptor()
+ {
+ queue.clear();
+ }
+ bool isEnabled(LORRequest* req);
+ void completeInst();
+};
+
+class LORHelper
+{
+
+ std::vector<LORDescriptor *> regionVec;
+ uint8_t nRegions;
+ uint8_t nRegDesc;
+
+
+ public:
+ LORHelper()
+ {
+ regionVec = std::vector<LORDescriptor*>();
+ nRegions = 0;
+ nRegDesc = 0;
+ }
+
+ ~LORHelper()
+ {
+ for (auto &r: regionVec) {
+ delete r;
+ }
+ }
+
+ void
+ updateDescriptor(ThreadContext *tc, uint64_t lorc)
+ {
+ uint64_t lorsa = tc->readMiscReg(MISCREG_LORSA_EL1);
+ uint64_t lorea = tc->readMiscReg(MISCREG_LOREA_EL1);
+ uint64_t lorn = tc->readMiscReg(MISCREG_LORN_EL1);
+
+ Addr start = bits(lorsa, 51, 16);
+ Addr end = bits(lorea, 51, 16);
+ int r_id = bits(lorc, 9, 2);
+
+ regionVec[r_id]->start = start;
+ regionVec[r_id]->end = end;
+ regionVec[r_id]->valid = lorsa & 0x1;
+ regionVec[r_id]->regionId = lorn & 0xff;
+ }
+
+ void
+ init(ThreadContext *tc)
+ {
+ uint64_t lorid = tc->readMiscReg(MISCREG_LORID_EL1);
+ nRegions = bits(lorid, 7, 0);
+ nRegDesc = bits(lorid, 23, 16);
+
+ for (int i=0; i < nRegions; i++) {
+ regionVec.push_back(new LORDescriptor(i));
+ }
+
+ }
+
+ int findDescriptor(Addr address);
+ bool isLOREnabled(Addr addr, LORRequest* req);
+ void completeInst(RequestPtr &req);
+
+};
+
+}
+#endif
diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc
index 932abc3..e626e68 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -2787,6 +2787,20 @@
return MISCREG_AMAIR_EL1;
}
break;
+ case 4:
+ switch (op2) {
+ case 0:
+ return MISCREG_LORSA_EL1;
+ case 1:
+ return MISCREG_LOREA_EL1;
+ case 2:
+ return MISCREG_LORN_EL1;
+ case 3:
+ return MISCREG_LORC_EL1;
+ case 7:
+ return MISCREG_LORID_EL1;
+ }
+ break;
}
break;
case 4:
@@ -5210,6 +5224,16 @@
.allPrivileges().exceptUserMode().writes(0);
InitReg(MISCREG_ISR_EL1)
.allPrivileges().exceptUserMode().writes(0);
+ InitReg(MISCREG_LORC_EL1)
+ .allPrivileges().exceptUserMode();
+ InitReg(MISCREG_LOREA_EL1)
+ .allPrivileges().exceptUserMode();
+ InitReg(MISCREG_LORID_EL1)
+ .allPrivileges().exceptUserMode().writes(0);
+ InitReg(MISCREG_LORN_EL1)
+ .allPrivileges().exceptUserMode();
+ InitReg(MISCREG_LORSA_EL1)
+ .allPrivileges().exceptUserMode();
InitReg(MISCREG_VBAR_EL2)
.hyp().mon()
.res0(0x7ff)
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index f683297..1db15ca 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -729,6 +729,11 @@
MISCREG_VBAR_EL12,
MISCREG_RVBAR_EL1,
MISCREG_ISR_EL1,
+ MISCREG_LORC_EL1,
+ MISCREG_LOREA_EL1,
+ MISCREG_LORID_EL1,
+ MISCREG_LORN_EL1,
+ MISCREG_LORSA_EL1,
MISCREG_VBAR_EL2,
MISCREG_RVBAR_EL2,
MISCREG_VBAR_EL3,
@@ -1830,6 +1835,11 @@
"vbar_el12",
"rvbar_el1",
"isr_el1",
+ "lorc_el1",
+ "lorea_el1",
+ "lorid_el1",
+ "lorn_el1",
+ "lorsa_el1",
"vbar_el2",
"rvbar_el2",
"vbar_el3",
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 0e61186..3bd4685 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1295,14 +1295,36 @@
if (translation && (callFromS2 || !stage2Req || req->hasPaddr() ||
fault != NoFault)) {
- if (!delay)
- translation->finish(fault, req, tc, mode);
- else
+ if (!delay) {
+ bool lor_block = false;
+ if (fault == NoFault && HaveLORExt(tc)) {
+ Request::Flags flags = req->getFlags();
+ LORRequest * lor_req = new LORRequest(translation, req,
+ tc, mode, flags & LORInst);
+ LORHelper *lor = ArmISA::ISA::getLorHelper(tc);
+ lor_block = lor->isLOREnabled(req->getPaddr(), lor_req);
+ if (!lor_block) {
+ if (mode == Write) {
+ req->setFlags(Request::RELEASE);
+ } else {
+ req->setFlags(Request::ACQUIRE);
+ }
+ }
+ }
+ if (!lor_block)
+ translation->finish(fault, req, tc, mode);
+ } else
translation->markDelayed();
}
return fault;
}
+void
+TLB::handleOrdering(ThreadContext *tc, RequestPtr &req) {
+ LORHelper *lor = ArmISA::ISA::getLorHelper(tc);
+ lor->completeInst(req);
+}
+
Port *
TLB::getTableWalkerPort()
{
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index b05c9ba..16200f9 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -44,6 +44,7 @@
#include "arch/arm/faults.hh"
#include "arch/arm/isa_traits.hh"
+#include "arch/arm/lor_helper.hh"
#include "arch/arm/pagetable.hh"
#include "arch/arm/utility.hh"
#include "arch/generic/tlb.hh"
@@ -120,7 +121,9 @@
AllowUnaligned = 0x8,
// Priv code operating as if it wasn't
- UserMode = 0x10
+ UserMode = 0x10,
+ // Indicates that the request is made from a LOR instruction
+ LORInst = 0x20
};
enum ArmTranslationType {
@@ -254,6 +257,8 @@
bool checkPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req,
Mode mode);
+ void handleOrdering(ThreadContext *tc, RequestPtr &req);
+
/** Reset the entire TLB. Used for CPU switching to prevent stale
* translations after multiple switches
*/
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 5cfb3fe..06ed979 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -319,6 +319,13 @@
}
bool
+HaveLORExt(ThreadContext *tc)
+{
+ AA64MMFR1 id_aa64mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
+ return id_aa64mmfr1.lo;
+}
+
+bool
HaveVirtHostExt(ThreadContext *tc)
{
AA64MMFR1 id_aa64mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
@@ -377,6 +384,17 @@
}
bool
+EnabledLOR(ThreadContext *tc)
+{
+ uint64_t lorid = tc->readMiscReg(MISCREG_LORID_EL1);
+ int nRegions = bits(lorid, 7, 0);
+ int nRegDesc = bits(lorid, 23, 16);
+ bool enabled = !(nRegions == 0 || nRegDesc == 0);
+ return enabled && HaveLORExt(tc);
+
+}
+
+bool
ELIs64(ThreadContext *tc, ExceptionLevel el)
{
return !ELIs32(tc, el);
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index 6ec6403..e86ec81 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -152,12 +152,15 @@
}
bool HavePACExt(ThreadContext *tc);
+bool HaveLORExt(ThreadContext *tc);
bool HaveVirtHostExt(ThreadContext *tc);
bool HaveLVA(ThreadContext *tc);
bool HaveSecureEL2Ext(ThreadContext *tc);
bool IsSecureEL2Enabled(ThreadContext *tc);
bool EL2Enabled(ThreadContext *tc);
+bool EnabledLOR(ThreadContext *tc);
+
/**
* This function checks whether selected EL provided as an argument
* is using the AArch32 ISA. This information might be unavailable
diff --git a/src/arch/generic/tlb.hh b/src/arch/generic/tlb.hh
index 59b3a01..21d80c1 100644
--- a/src/arch/generic/tlb.hh
+++ b/src/arch/generic/tlb.hh
@@ -98,6 +98,8 @@
panic("Not implemented.\n");
}
+ virtual void handleOrdering(ThreadContext *tc, RequestPtr &req) = 0;
+
/**
* Do post-translation physical address finalization.
*
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index b67edc4..cf45f4a 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -970,6 +970,8 @@
state->outstanding--;
assert(pkt == _packets.front());
_port.completeDataAccess(pkt);
+ //LOR handle
+ _port.getMMUPtr()->dtb->handleOrdering(_inst->thread->getTC(),
pkt->req);
return true;
}
@@ -996,6 +998,8 @@
resp->dataStatic(_data);
resp->senderState = _senderState;
_port.completeDataAccess(resp);
+ _port.getMMUPtr()->dtb->handleOrdering(_inst->thread->getTC(),
+ pkt->req);
delete resp;
}
return true;
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 9c529b4..d59d31b 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -1046,6 +1046,10 @@
panic("HTM - unhandled rc %s", htmFailureToStr(htm_rc));
}
} else {
+ SimpleThread* thread = t_info->thread;
+ thread->mmu->dtb->handleOrdering(thread->getTC(), pkt->req);
+ curStaticInst->completeAcc(pkt, threadInfo[curThread],
+ traceData);
fault = curStaticInst->completeAcc(pkt, t_info,
traceData);
}
diff --git a/src/mem/request.hh b/src/mem/request.hh
index 73c823b..2898a33 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -407,6 +407,9 @@
LocalAccessor _localAccessor;
+ /** Extra data used for ARM LOR subsistem to identify memory region **/
+ int orderIndex = 0;
+
/** The instruction count at the time this request is created */
Counter _instCount = 0;
@@ -860,6 +863,18 @@
void setAccessLatency() { accessDelta = curTick() - _time -
translateDelta; }
Tick getAccessLatency() const { return accessDelta; }
+ void
+ setOrderingIndex(int idx)
+ {
+ orderIndex = idx;
+ }
+
+ int
+ getOrderingIndex()
+ {
+ return orderIndex;
+ }
+
/**
* Accessor for the sequence number of instruction that creates the
* request.
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/36835
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I2e0d4962f8672856185054917482204d2f220cbe
Gerrit-Change-Number: 36835
Gerrit-PatchSet: 1
Gerrit-Owner: Jordi Vaquero <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s