kernel_stats.hh
locked_mem.hh
microcode_rom.hh
- mmapped_ipr.hh
process.hh
pseudo_inst.hh
registers.hh
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * Copyright (c) 2007-2008 The Florida State University
- * 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.
- */
-
-#ifndef __ARCH_ARM_MMAPPED_IPR_HH__
-#define __ARCH_ARM_MMAPPED_IPR_HH__
-
-/**
- * @file
- *
- * ISA-specific helper functions for memory mapped IPR accesses.
- */
-
-#include "base/types.hh"
-#include "mem/packet.hh"
-#include "mem/packet_access.hh"
-#include "sim/pseudo_inst.hh"
-#include "sim/system.hh"
-
-class ThreadContext;
-
-namespace ArmISA
-{
-
-inline Cycles
-handleIprRead(ThreadContext *tc, Packet *pkt)
-{
- Addr addr = pkt->getAddr();
- auto m5opRange = tc->getSystemPtr()->m5opRange();
- if (m5opRange.contains(addr)) {
- uint8_t func;
- PseudoInst::decodeAddrOffset(addr - m5opRange.start(), func);
- uint64_t ret = PseudoInst::pseudoInst<PseudoInstABI>(tc, func);
- pkt->setLE(ret);
- }
- return Cycles(1);
-}
-
-inline Cycles
-handleIprWrite(ThreadContext *tc, Packet *pkt)
-{
- Addr addr = pkt->getAddr();
- auto m5opRange = tc->getSystemPtr()->m5opRange();
- if (m5opRange.contains(addr)) {
- uint8_t func;
- PseudoInst::decodeAddrOffset(addr - m5opRange.start(), func);
- PseudoInst::pseudoInst<PseudoInstABI>(tc, func);
- }
- return Cycles(1);
-}
-
-} // namespace ArmISA
-
-#endif
#include "debug/Checkpoint.hh"
#include "debug/TLB.hh"
#include "debug/TLBVerbose.hh"
+#include "mem/packet_access.hh"
#include "mem/page_table.hh"
#include "mem/request.hh"
#include "params/ArmTLB.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
+#include "sim/pseudo_inst.hh"
using namespace std;
using namespace ArmISA;
{
const Addr paddr = req->getPaddr();
- if (m5opRange.contains(paddr))
- req->setFlags(Request::MMAPPED_IPR);
+ if (m5opRange.contains(paddr)) {
+ uint8_t func;
+ PseudoInst::decodeAddrOffset(paddr - m5opRange.start(), func);
+ req->setLocalAccessor(
+ [func, mode](ThreadContext *tc, PacketPtr pkt) -> Cycles
+ {
+ uint64_t ret = PseudoInst::pseudoInst<PseudoInstABI>(tc, func);
+ if (mode == Read)
+ pkt->setLE(ret);
+ return Cycles(1);
+ }
+ );
+ }
return NoFault;
}
// Now do the access
if (fault == NoFault &&
!req->getFlags().isSet(Request::NO_ACCESS)) {
- if (req->isLLSC() || req->isMmappedIpr())
- // LLSCs and mem. mapped IPRs are ignored
+ if (req->isLLSC() || req->isLocalAccess())
+ // LLSCs and local accesses are ignored
return false;
// the translating proxy will perform the virtual to physical
// translation again
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * 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.
- */
-
-#ifndef __ARCH_MIPS_MMAPPED_IPR_HH__
-#define __ARCH_MIPS_MMAPPED_IPR_HH__
-
-/**
- * @file
- *
- * ISA-specific helper functions for memory mapped IPR accesses.
- */
-
-#include "base/types.hh"
-
-class Packet;
-class ThreadContext;
-
-namespace MipsISA
-{
-
-inline Cycles handleIprRead(ThreadContext *, Packet *) { return Cycles(1); }
-inline Cycles handleIprWrite(ThreadContext *, Packet *) { return Cycles(1); }
-
-} // namespace MipsISA
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * Copyright (c) 2007-2008 The Florida State University
- * Copyright (c) 2009 The University of Edinburgh
- * 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.
- */
-
-#ifndef __ARCH_POWER_MMAPPED_IPR_HH__
-#define __ARCH_POWER_MMAPPED_IPR_HH__
-
-/**
- * @file
- *
- * ISA-specific helper functions for memory mapped IPR accesses.
- */
-
-#include "base/types.hh"
-
-class Packet;
-class ThreadContext;
-
-namespace PowerISA
-{
-
-inline Cycles handleIprRead(ThreadContext *, Packet *) { return Cycles(1); }
-inline Cycles handleIprWrite(ThreadContext *, Packet *) { return Cycles(1); }
-
-} // namespace PowerISA
-
-#endif // __ARCH_POWER_MMAPPED_IPR_HH__
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * 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.
- */
-
-#ifndef __ARCH_RISCV_MMAPPED_IPR_HH__
-#define __ARCH_RISCV_MMAPPED_IPR_HH__
-
-/**
- * @file
- *
- * ISA-specific helper functions for memory mapped IPR accesses.
- */
-
-#include "base/types.hh"
-
-class Packet;
-class ThreadContext;
-
-namespace RiscvISA
-{
-
-inline Cycles handleIprRead(ThreadContext *, Packet *) { return Cycles(1); }
-inline Cycles handleIprWrite(ThreadContext *, Packet *) { return Cycles(1); }
-
-} // namespace RiscvISA
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * 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.
- */
-
-#ifndef __ARCH_SPARC_MMAPPED_IPR_HH__
-#define __ARCH_SPARC_MMAPPED_IPR_HH__
-
-/**
- * @file
- *
- * ISA-specific helper functions for memory mapped IPR accesses.
- */
-
-#include "arch/sparc/tlb.hh"
-#include "cpu/thread_context.hh"
-#include "mem/packet.hh"
-
-namespace SparcISA
-{
-
-inline Cycles
-handleIprRead(ThreadContext *xc, Packet *pkt)
-{
- return dynamic_cast<TLB *>(xc->getDTBPtr())->doMmuRegRead(xc, pkt);
-}
-
-inline Cycles
-handleIprWrite(ThreadContext *xc, Packet *pkt)
-{
- return dynamic_cast<TLB *>(xc->getDTBPtr())->doMmuRegWrite(xc, pkt);
-}
-
-
-} // namespace SparcISA
-
-#endif
regAccessOk:
handleMmuRegAccess:
- DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n");
- req->setFlags(Request::MMAPPED_IPR);
+ DPRINTF(TLB, "TLB: DTB Translating local access\n");
+ req->setLocalAccessor(
+ [this,write](ThreadContext *tc, PacketPtr pkt) -> Cycles
+ {
+ return write ? doMmuRegWrite(tc, pkt) : doMmuRegRead(tc, pkt);
+ }
+ );
req->setPaddr(req->getVaddr());
return NoFault;
};
+++ /dev/null
-/*
- * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
- * 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_X86_MMAPPEDIPR_HH__
-#define __ARCH_X86_MMAPPEDIPR_HH__
-
-/**
- * @file
- *
- * ISA-specific helper functions for memory mapped IPR accesses.
- */
-
-#include "arch/x86/pseudo_inst_abi.hh"
-#include "arch/x86/regs/misc.hh"
-#include "cpu/base.hh"
-#include "cpu/thread_context.hh"
-#include "mem/packet.hh"
-#include "mem/packet_access.hh"
-#include "sim/pseudo_inst.hh"
-
-namespace X86ISA
-{
- inline Cycles
- handleIprRead(ThreadContext *tc, Packet *pkt)
- {
- Addr addr = pkt->getAddr();
- auto m5opRange = tc->getSystemPtr()->m5opRange();
- if (m5opRange.contains(addr)) {
- uint8_t func;
- PseudoInst::decodeAddrOffset(addr - m5opRange.start(), func);
- uint64_t ret = PseudoInst::pseudoInst<X86PseudoInstABI>(tc, func);
- pkt->setLE(ret);
- } else {
- Addr offset = addr & mask(3);
- MiscRegIndex index = (MiscRegIndex)(addr / sizeof(RegVal));
- RegVal data = htole(tc->readMiscReg(index));
- // Make sure we don't trot off the end of data.
- assert(offset + pkt->getSize() <= sizeof(RegVal));
- pkt->setData(((uint8_t *)&data) + offset);
- }
- return Cycles(1);
- }
-
- inline Cycles
- handleIprWrite(ThreadContext *tc, Packet *pkt)
- {
- Addr addr = pkt->getAddr();
- auto m5opRange = tc->getSystemPtr()->m5opRange();
- if (m5opRange.contains(addr)) {
- uint8_t func;
- PseudoInst::decodeAddrOffset(addr - m5opRange.start(), func);
- PseudoInst::pseudoInst<X86PseudoInstABI>(tc, func);
- } else {
- Addr offset = addr & mask(3);
- MiscRegIndex index = (MiscRegIndex)(addr / sizeof(RegVal));
- RegVal data = htole(tc->readMiscRegNoEffect(index));
- // Make sure we don't trot off the end of data.
- assert(offset + pkt->getSize() <= sizeof(RegVal));
- pkt->writeData(((uint8_t *)&data) + offset);
- tc->setMiscReg(index, letoh(data));
- }
- return Cycles(1);
- }
-}
-
-#endif // __ARCH_X86_MMAPPEDIPR_HH__
#include "arch/x86/faults.hh"
#include "arch/x86/insts/microldstop.hh"
#include "arch/x86/pagetable_walker.hh"
+#include "arch/x86/pseudo_inst_abi.hh"
#include "arch/x86/regs/misc.hh"
#include "arch/x86/regs/msr.hh"
#include "arch/x86/x86_traits.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/TLB.hh"
+#include "mem/packet_access.hh"
#include "mem/page_table.hh"
#include "mem/request.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
+#include "sim/pseudo_inst.hh"
namespace X86ISA {
}
}
+namespace
+{
+
+Cycles
+localMiscRegAccess(bool read, MiscRegIndex regNum,
+ ThreadContext *tc, PacketPtr pkt)
+{
+ if (read) {
+ RegVal data = htole(tc->readMiscReg(regNum));
+ assert(pkt->getSize() <= sizeof(RegVal));
+ pkt->setData((uint8_t *)&data);
+ } else {
+ RegVal data = htole(tc->readMiscRegNoEffect(regNum));
+ assert(pkt->getSize() <= sizeof(RegVal));
+ pkt->writeData((uint8_t *)&data);
+ tc->setMiscReg(regNum, letoh(data));
+ }
+ return Cycles(1);
+}
+
+} // anonymous namespace
+
Fault
-TLB::translateInt(const RequestPtr &req, ThreadContext *tc)
+TLB::translateInt(bool read, RequestPtr req, ThreadContext *tc)
{
DPRINTF(TLB, "Addresses references internal memory.\n");
Addr vaddr = req->getVaddr();
panic("CPUID memory space not yet implemented!\n");
} else if (prefix == IntAddrPrefixMSR) {
vaddr = (vaddr >> 3) & ~IntAddrPrefixMask;
- req->setFlags(Request::MMAPPED_IPR);
MiscRegIndex regNum;
if (!msrAddrToIndex(regNum, vaddr))
return std::make_shared<GeneralProtection>(0);
- //The index is multiplied by the size of a RegVal so that
- //any memory dependence calculations will not see these as
- //overlapping.
- req->setPaddr((Addr)regNum * sizeof(RegVal));
+ req->setLocalAccessor(
+ [read,regNum](ThreadContext *tc, PacketPtr pkt)
+ {
+ return localMiscRegAccess(read, regNum, tc, pkt);
+ }
+ );
+
return NoFault;
} else if (prefix == IntAddrPrefixIO) {
// TODO If CPL > IOPL or in virtual mode, check the I/O permission
// space.
assert(!(IOPort & ~0xFFFF));
if (IOPort == 0xCF8 && req->getSize() == 4) {
- req->setFlags(Request::MMAPPED_IPR);
- req->setPaddr(MISCREG_PCI_CONFIG_ADDRESS * sizeof(RegVal));
+ req->setLocalAccessor(
+ [read](ThreadContext *tc, PacketPtr pkt)
+ {
+ return localMiscRegAccess(
+ read, MISCREG_PCI_CONFIG_ADDRESS, tc, pkt);
+ }
+ );
} else if ((IOPort & ~mask(2)) == 0xCFC) {
req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
Addr configAddress =
Addr paddr = req->getPaddr();
if (m5opRange.contains(paddr)) {
- req->setFlags(Request::MMAPPED_IPR | Request::STRICT_ORDER);
+ req->setFlags(Request::STRICT_ORDER);
+ uint8_t func;
+ PseudoInst::decodeAddrOffset(paddr - m5opRange.start(), func);
+ req->setLocalAccessor(
+ [func, mode](ThreadContext *tc, PacketPtr pkt) -> Cycles
+ {
+ uint64_t ret =
+ PseudoInst::pseudoInst<X86PseudoInstABI>(tc, func);
+ if (mode == Read)
+ pkt->setLE(ret);
+ return Cycles(1);
+ }
+ );
} else if (FullSystem) {
// Check for an access to the local APIC
LocalApicBase localApicBase =
// If this is true, we're dealing with a request to a non-memory address
// space.
if (seg == SEGMENT_REG_MS) {
- return translateInt(req, tc);
+ return translateInt(mode == Read, req, tc);
}
Addr vaddr = req->getVaddr();
Stats::Scalar rdMisses;
Stats::Scalar wrMisses;
- Fault translateInt(const RequestPtr &req, ThreadContext *tc);
+ Fault translateInt(bool read, RequestPtr req, ThreadContext *tc);
Fault translate(const RequestPtr &req, ThreadContext *tc,
Translation *translation, Mode mode,
pkt->dataStatic(data);
- if (!(mem_req->isUncacheable() || mem_req->isMmappedIpr())) {
+ if (!(mem_req->isUncacheable() || mem_req->isLocalAccess())) {
// Access memory to see if we have the same data
dcachePort->sendFunctional(pkt);
} else {
#include <csignal>
#include <ostream>
-#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "debug/Checkpoint.hh"
#include "debug/Drain.hh"
PacketPtr pkt = new Packet(mmio_req, cmd);
pkt->dataStatic(data);
- if (mmio_req->isMmappedIpr()) {
+ if (mmio_req->isLocalAccess()) {
// We currently assume that there is no need to migrate to a
- // different event queue when doing IPRs. Currently, IPRs are
- // only used for m5ops, so it should be a valid assumption.
- const Cycles ipr_delay(write ?
- TheISA::handleIprWrite(tc, pkt) :
- TheISA::handleIprRead(tc, pkt));
+ // different event queue when doing local accesses. Currently, they
+ // are only used for m5ops, so it should be a valid assumption.
+ const Cycles ipr_delay = mmio_req->localAccessor(tc, pkt);
threadContextDirty = true;
delete pkt;
return clockPeriod() * ipr_delay;
#include <sstream>
#include "arch/locked_mem.hh"
-#include "arch/mmapped_ipr.hh"
#include "base/logging.hh"
#include "cpu/minor/cpu.hh"
#include "cpu/minor/exec_context.hh"
}
} else {
/* Store. Can it be sent to the store buffer? */
- if (bufferable && !request->request->isMmappedIpr()) {
+ if (bufferable && !request->request->isLocalAccess()) {
request->setState(LSQRequest::StoreToStoreBuffer);
moveFromRequestsToTransfers(request);
DPRINTF(MinorMem, "Moving store into transfers queue\n");
* so the response can be correctly handled */
assert(packet->findNextSenderState<LSQRequest>());
- if (request->request->isMmappedIpr()) {
+ if (request->request->isLocalAccess()) {
ThreadContext *thread =
cpu.getContext(cpu.contextToThread(
request->request->contextId()));
- if (request->isLoad) {
+ if (request->isLoad)
DPRINTF(MinorMem, "IPR read inst: %s\n", *(request->inst));
- TheISA::handleIprRead(thread, packet);
- } else {
+ else
DPRINTF(MinorMem, "IPR write inst: %s\n", *(request->inst));
- TheISA::handleIprWrite(thread, packet);
- }
+
+ request->request->localAccessor(thread, packet);
request->stepToNextPacket();
ret = request->sentAllPackets();
/**
* Memory mapped IPR accesses
*/
- virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt) = 0;
- virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt) = 0;
+ virtual Cycles handleLocalAccess(
+ ThreadContext *thread, PacketPtr pkt) = 0;
/**
* Test if the request accesses a particular cache line.
virtual bool recvTimingResp(PacketPtr pkt);
virtual void sendPacketToCache();
virtual void buildPackets();
- virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt);
- virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt);
+ virtual Cycles handleLocalAccess(ThreadContext *thread, PacketPtr pkt);
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask);
};
virtual void sendPacketToCache();
virtual void buildPackets();
- virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt);
- virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt);
+ virtual Cycles handleLocalAccess(ThreadContext *thread, PacketPtr pkt);
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask);
virtual RequestPtr mainRequest();
}
}
-template<class Impl>
-void
-LSQ<Impl>::SingleDataRequest::handleIprWrite(ThreadContext *thread,
- PacketPtr pkt)
-{
- TheISA::handleIprWrite(thread, pkt);
-}
-
-template<class Impl>
-void
-LSQ<Impl>::SplitDataRequest::handleIprWrite(ThreadContext *thread,
- PacketPtr mainPkt)
-{
- unsigned offset = 0;
- for (auto r: _requests) {
- PacketPtr pkt = new Packet(r, MemCmd::WriteReq);
- pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset);
- TheISA::handleIprWrite(thread, pkt);
- offset += r->getSize();
- delete pkt;
- }
-}
-
template<class Impl>
Cycles
-LSQ<Impl>::SingleDataRequest::handleIprRead(ThreadContext *thread,
- PacketPtr pkt)
+LSQ<Impl>::SingleDataRequest::handleLocalAccess(
+ ThreadContext *thread, PacketPtr pkt)
{
- return TheISA::handleIprRead(thread, pkt);
+ return pkt->req->localAccessor(thread, pkt);
}
template<class Impl>
Cycles
-LSQ<Impl>::SplitDataRequest::handleIprRead(ThreadContext *thread,
- PacketPtr mainPkt)
+LSQ<Impl>::SplitDataRequest::handleLocalAccess(
+ ThreadContext *thread, PacketPtr mainPkt)
{
Cycles delay(0);
unsigned offset = 0;
for (auto r: _requests) {
- PacketPtr pkt = new Packet(r, MemCmd::ReadReq);
+ PacketPtr pkt =
+ new Packet(r, isLoad() ? MemCmd::ReadReq : MemCmd::WriteReq);
pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset);
- Cycles d = TheISA::handleIprRead(thread, pkt);
+ Cycles d = r->localAccessor(thread, pkt);
if (d > delay)
delay = d;
offset += r->getSize();
#include "arch/generic/vec_reg.hh"
#include "arch/isa_traits.hh"
#include "arch/locked_mem.hh"
-#include "arch/mmapped_ipr.hh"
#include "config/the_isa.hh"
#include "cpu/inst_seq.hh"
#include "cpu/timebuf.hh"
load_inst->recordResult(true);
}
- if (req->mainRequest()->isMmappedIpr()) {
+ if (req->mainRequest()->isLocalAccess()) {
assert(!load_inst->memData);
load_inst->memData = new uint8_t[MaxDataBytes];
main_pkt->dataStatic(load_inst->memData);
- Cycles delay = req->handleIprRead(thread, main_pkt);
+ Cycles delay = req->mainRequest()->localAccessor(thread, main_pkt);
WritebackEvent *wb = new WritebackEvent(load_inst, main_pkt, this);
cpu->schedule(wb, cpu->clockEdge(delay));
}
}
- if (req->request()->isMmappedIpr()) {
+ if (req->request()->isLocalAccess()) {
assert(!inst->isStoreConditional());
ThreadContext *thread = cpu->tcBase(lsqID);
PacketPtr main_pkt = new Packet(req->mainRequest(),
MemCmd::WriteReq);
main_pkt->dataStatic(inst->memData);
- req->handleIprWrite(thread, main_pkt);
+ req->request()->localAccessor(thread, main_pkt);
delete main_pkt;
completeStore(storeWBIt);
storeWBIt++;
#include "cpu/simple/atomic.hh"
#include "arch/locked_mem.hh"
-#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "base/output.hh"
#include "config/the_isa.hh"
Packet pkt(req, Packet::makeReadCmd(req));
pkt.dataStatic(data);
- if (req->isMmappedIpr()) {
- dcache_latency += TheISA::handleIprRead(thread->getTC(), &pkt);
+ if (req->isLocalAccess()) {
+ dcache_latency += req->localAccessor(thread->getTC(), &pkt);
} else {
dcache_latency += sendPacket(dcachePort, &pkt);
}
Packet pkt(req, Packet::makeWriteCmd(req));
pkt.dataStatic(data);
- if (req->isMmappedIpr()) {
+ if (req->isLocalAccess()) {
dcache_latency +=
- TheISA::handleIprWrite(thread->getTC(), &pkt);
+ req->localAccessor(thread->getTC(), &pkt);
} else {
dcache_latency += sendPacket(dcachePort, &pkt);
Packet pkt(req, Packet::makeWriteCmd(req));
pkt.dataStatic(data);
- if (req->isMmappedIpr())
- dcache_latency += TheISA::handleIprRead(thread->getTC(), &pkt);
+ if (req->isLocalAccess())
+ dcache_latency += req->localAccessor(thread->getTC(), &pkt);
else {
dcache_latency += sendPacket(dcachePort, &pkt);
}
#include "cpu/simple/timing.hh"
#include "arch/locked_mem.hh"
-#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
if (pkt->isRead() && pkt->req->isLLSC()) {
TheISA::handleLockedRead(thread, pkt->req);
}
- if (req->isMmappedIpr()) {
- Cycles delay = TheISA::handleIprRead(thread->getTC(), pkt);
+ if (req->isLocalAccess()) {
+ Cycles delay = req->localAccessor(thread->getTC(), pkt);
new IprEvent(pkt, this, clockEdge(delay));
_status = DcacheWaitResponse;
dcache_pkt = NULL;
{
pkt1 = pkt2 = NULL;
- assert(!req1->isMmappedIpr() && !req2->isMmappedIpr());
+ assert(!req1->isLocalAccess() && !req2->isLocalAccess());
if (req->getFlags().isSet(Request::NO_ACCESS)) {
pkt1 = buildPacket(req, read);
SimpleThread* thread = t_info.thread;
const RequestPtr &req = dcache_pkt->req;
- if (req->isMmappedIpr()) {
- Cycles delay = TheISA::handleIprWrite(thread->getTC(), dcache_pkt);
+ if (req->isLocalAccess()) {
+ Cycles delay = req->localAccessor(thread->getTC(), dcache_pkt);
new IprEvent(dcache_pkt, this, clockEdge(delay));
_status = DcacheWaitResponse;
dcache_pkt = NULL;
#include "mem/page_table.hh"
#include "mem/request.hh"
#include "sim/process.hh"
+#include "sim/pseudo_inst.hh"
namespace X86ISA
{
}
}
+
+
+ namespace
+ {
+
+ Cycles
+ localMiscRegAccess(bool read, MiscRegIndex regNum,
+ ThreadContext *tc, PacketPtr pkt)
+ {
+ if (read) {
+ RegVal data = htole(tc->readMiscReg(regNum));
+ // Make sure we don't trot off the end of data.
+ pkt->setData((uint8_t *)&data);
+ } else {
+ RegVal data = htole(tc->readMiscRegNoEffect(regNum));
+ tc->setMiscReg(regNum, letoh(data));
+ }
+ return Cycles(1);
+ }
+
+ } // anonymous namespace
+
Fault
- GpuTLB::translateInt(const RequestPtr &req, ThreadContext *tc)
+ GpuTLB::translateInt(bool read, const RequestPtr &req, ThreadContext *tc)
{
DPRINTF(GPUTLB, "Addresses references internal memory.\n");
Addr vaddr = req->getVaddr();
if (prefix == IntAddrPrefixCPUID) {
panic("CPUID memory space not yet implemented!\n");
} else if (prefix == IntAddrPrefixMSR) {
- vaddr = vaddr >> 3;
- req->setFlags(Request::MMAPPED_IPR);
- Addr regNum = 0;
+ vaddr = (vaddr >> 3) & ~IntAddrPrefixMask;
- switch (vaddr & ~IntAddrPrefixMask) {
- case 0x10:
- regNum = MISCREG_TSC;
- break;
- case 0x1B:
- regNum = MISCREG_APIC_BASE;
- break;
- case 0xFE:
- regNum = MISCREG_MTRRCAP;
- break;
- case 0x174:
- regNum = MISCREG_SYSENTER_CS;
- break;
- case 0x175:
- regNum = MISCREG_SYSENTER_ESP;
- break;
- case 0x176:
- regNum = MISCREG_SYSENTER_EIP;
- break;
- case 0x179:
- regNum = MISCREG_MCG_CAP;
- break;
- case 0x17A:
- regNum = MISCREG_MCG_STATUS;
- break;
- case 0x17B:
- regNum = MISCREG_MCG_CTL;
- break;
- case 0x1D9:
- regNum = MISCREG_DEBUG_CTL_MSR;
- break;
- case 0x1DB:
- regNum = MISCREG_LAST_BRANCH_FROM_IP;
- break;
- case 0x1DC:
- regNum = MISCREG_LAST_BRANCH_TO_IP;
- break;
- case 0x1DD:
- regNum = MISCREG_LAST_EXCEPTION_FROM_IP;
- break;
- case 0x1DE:
- regNum = MISCREG_LAST_EXCEPTION_TO_IP;
- break;
- case 0x200:
- regNum = MISCREG_MTRR_PHYS_BASE_0;
- break;
- case 0x201:
- regNum = MISCREG_MTRR_PHYS_MASK_0;
- break;
- case 0x202:
- regNum = MISCREG_MTRR_PHYS_BASE_1;
- break;
- case 0x203:
- regNum = MISCREG_MTRR_PHYS_MASK_1;
- break;
- case 0x204:
- regNum = MISCREG_MTRR_PHYS_BASE_2;
- break;
- case 0x205:
- regNum = MISCREG_MTRR_PHYS_MASK_2;
- break;
- case 0x206:
- regNum = MISCREG_MTRR_PHYS_BASE_3;
- break;
- case 0x207:
- regNum = MISCREG_MTRR_PHYS_MASK_3;
- break;
- case 0x208:
- regNum = MISCREG_MTRR_PHYS_BASE_4;
- break;
- case 0x209:
- regNum = MISCREG_MTRR_PHYS_MASK_4;
- break;
- case 0x20A:
- regNum = MISCREG_MTRR_PHYS_BASE_5;
- break;
- case 0x20B:
- regNum = MISCREG_MTRR_PHYS_MASK_5;
- break;
- case 0x20C:
- regNum = MISCREG_MTRR_PHYS_BASE_6;
- break;
- case 0x20D:
- regNum = MISCREG_MTRR_PHYS_MASK_6;
- break;
- case 0x20E:
- regNum = MISCREG_MTRR_PHYS_BASE_7;
- break;
- case 0x20F:
- regNum = MISCREG_MTRR_PHYS_MASK_7;
- break;
- case 0x250:
- regNum = MISCREG_MTRR_FIX_64K_00000;
- break;
- case 0x258:
- regNum = MISCREG_MTRR_FIX_16K_80000;
- break;
- case 0x259:
- regNum = MISCREG_MTRR_FIX_16K_A0000;
- break;
- case 0x268:
- regNum = MISCREG_MTRR_FIX_4K_C0000;
- break;
- case 0x269:
- regNum = MISCREG_MTRR_FIX_4K_C8000;
- break;
- case 0x26A:
- regNum = MISCREG_MTRR_FIX_4K_D0000;
- break;
- case 0x26B:
- regNum = MISCREG_MTRR_FIX_4K_D8000;
- break;
- case 0x26C:
- regNum = MISCREG_MTRR_FIX_4K_E0000;
- break;
- case 0x26D:
- regNum = MISCREG_MTRR_FIX_4K_E8000;
- break;
- case 0x26E:
- regNum = MISCREG_MTRR_FIX_4K_F0000;
- break;
- case 0x26F:
- regNum = MISCREG_MTRR_FIX_4K_F8000;
- break;
- case 0x277:
- regNum = MISCREG_PAT;
- break;
- case 0x2FF:
- regNum = MISCREG_DEF_TYPE;
- break;
- case 0x400:
- regNum = MISCREG_MC0_CTL;
- break;
- case 0x404:
- regNum = MISCREG_MC1_CTL;
- break;
- case 0x408:
- regNum = MISCREG_MC2_CTL;
- break;
- case 0x40C:
- regNum = MISCREG_MC3_CTL;
- break;
- case 0x410:
- regNum = MISCREG_MC4_CTL;
- break;
- case 0x414:
- regNum = MISCREG_MC5_CTL;
- break;
- case 0x418:
- regNum = MISCREG_MC6_CTL;
- break;
- case 0x41C:
- regNum = MISCREG_MC7_CTL;
- break;
- case 0x401:
- regNum = MISCREG_MC0_STATUS;
- break;
- case 0x405:
- regNum = MISCREG_MC1_STATUS;
- break;
- case 0x409:
- regNum = MISCREG_MC2_STATUS;
- break;
- case 0x40D:
- regNum = MISCREG_MC3_STATUS;
- break;
- case 0x411:
- regNum = MISCREG_MC4_STATUS;
- break;
- case 0x415:
- regNum = MISCREG_MC5_STATUS;
- break;
- case 0x419:
- regNum = MISCREG_MC6_STATUS;
- break;
- case 0x41D:
- regNum = MISCREG_MC7_STATUS;
- break;
- case 0x402:
- regNum = MISCREG_MC0_ADDR;
- break;
- case 0x406:
- regNum = MISCREG_MC1_ADDR;
- break;
- case 0x40A:
- regNum = MISCREG_MC2_ADDR;
- break;
- case 0x40E:
- regNum = MISCREG_MC3_ADDR;
- break;
- case 0x412:
- regNum = MISCREG_MC4_ADDR;
- break;
- case 0x416:
- regNum = MISCREG_MC5_ADDR;
- break;
- case 0x41A:
- regNum = MISCREG_MC6_ADDR;
- break;
- case 0x41E:
- regNum = MISCREG_MC7_ADDR;
- break;
- case 0x403:
- regNum = MISCREG_MC0_MISC;
- break;
- case 0x407:
- regNum = MISCREG_MC1_MISC;
- break;
- case 0x40B:
- regNum = MISCREG_MC2_MISC;
- break;
- case 0x40F:
- regNum = MISCREG_MC3_MISC;
- break;
- case 0x413:
- regNum = MISCREG_MC4_MISC;
- break;
- case 0x417:
- regNum = MISCREG_MC5_MISC;
- break;
- case 0x41B:
- regNum = MISCREG_MC6_MISC;
- break;
- case 0x41F:
- regNum = MISCREG_MC7_MISC;
- break;
- case 0xC0000080:
- regNum = MISCREG_EFER;
- break;
- case 0xC0000081:
- regNum = MISCREG_STAR;
- break;
- case 0xC0000082:
- regNum = MISCREG_LSTAR;
- break;
- case 0xC0000083:
- regNum = MISCREG_CSTAR;
- break;
- case 0xC0000084:
- regNum = MISCREG_SF_MASK;
- break;
- case 0xC0000100:
- regNum = MISCREG_FS_BASE;
- break;
- case 0xC0000101:
- regNum = MISCREG_GS_BASE;
- break;
- case 0xC0000102:
- regNum = MISCREG_KERNEL_GS_BASE;
- break;
- case 0xC0000103:
- regNum = MISCREG_TSC_AUX;
- break;
- case 0xC0010000:
- regNum = MISCREG_PERF_EVT_SEL0;
- break;
- case 0xC0010001:
- regNum = MISCREG_PERF_EVT_SEL1;
- break;
- case 0xC0010002:
- regNum = MISCREG_PERF_EVT_SEL2;
- break;
- case 0xC0010003:
- regNum = MISCREG_PERF_EVT_SEL3;
- break;
- case 0xC0010004:
- regNum = MISCREG_PERF_EVT_CTR0;
- break;
- case 0xC0010005:
- regNum = MISCREG_PERF_EVT_CTR1;
- break;
- case 0xC0010006:
- regNum = MISCREG_PERF_EVT_CTR2;
- break;
- case 0xC0010007:
- regNum = MISCREG_PERF_EVT_CTR3;
- break;
- case 0xC0010010:
- regNum = MISCREG_SYSCFG;
- break;
- case 0xC0010016:
- regNum = MISCREG_IORR_BASE0;
- break;
- case 0xC0010017:
- regNum = MISCREG_IORR_BASE1;
- break;
- case 0xC0010018:
- regNum = MISCREG_IORR_MASK0;
- break;
- case 0xC0010019:
- regNum = MISCREG_IORR_MASK1;
- break;
- case 0xC001001A:
- regNum = MISCREG_TOP_MEM;
- break;
- case 0xC001001D:
- regNum = MISCREG_TOP_MEM2;
- break;
- case 0xC0010114:
- regNum = MISCREG_VM_CR;
- break;
- case 0xC0010115:
- regNum = MISCREG_IGNNE;
- break;
- case 0xC0010116:
- regNum = MISCREG_SMM_CTL;
- break;
- case 0xC0010117:
- regNum = MISCREG_VM_HSAVE_PA;
- break;
- default:
+ MiscRegIndex regNum;
+ if (!msrAddrToIndex(regNum, vaddr))
return std::make_shared<GeneralProtection>(0);
- }
- //The index is multiplied by the size of a MiscReg so that
- //any memory dependence calculations will not see these as
- //overlapping.
- req->setPaddr(regNum * sizeof(RegVal));
+
+ req->setLocalAccessor(
+ [read,regNum,vaddr](ThreadContext *tc, PacketPtr pkt)
+ {
+ return localMiscRegAccess(read, regNum, tc, pkt);
+ }
+ );
+
return NoFault;
} else if (prefix == IntAddrPrefixIO) {
// TODO If CPL > IOPL or in virtual mode, check the I/O permission
// Make sure the address fits in the expected 16 bit IO address
// space.
assert(!(IOPort & ~0xFFFF));
-
if (IOPort == 0xCF8 && req->getSize() == 4) {
- req->setFlags(Request::MMAPPED_IPR);
- req->setPaddr(MISCREG_PCI_CONFIG_ADDRESS * sizeof(RegVal));
+ req->setLocalAccessor(
+ [read](ThreadContext *tc, PacketPtr pkt)
+ {
+ return localMiscRegAccess(
+ read, MISCREG_PCI_CONFIG_ADDRESS, tc, pkt);
+ }
+ );
} else if ((IOPort & ~mask(2)) == 0xCFC) {
- req->setFlags(Request::UNCACHEABLE);
-
+ req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
Addr configAddress =
tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS);
-
if (bits(configAddress, 31, 31)) {
req->setPaddr(PhysAddrPrefixPciConfig |
- mbits(configAddress, 30, 2) |
- (IOPort & mask(2)));
+ mbits(configAddress, 30, 2) |
+ (IOPort & mask(2)));
} else {
req->setPaddr(PhysAddrPrefixIO | IOPort);
}
} else {
- req->setFlags(Request::UNCACHEABLE);
+ req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
req->setPaddr(PhysAddrPrefixIO | IOPort);
}
return NoFault;
// If this is true, we're dealing with a request
// to a non-memory address space.
if (seg == SEGMENT_REG_MS) {
- return translateInt(req, tc);
+ return translateInt(mode == Read, req, tc);
}
delayedResponse = false;
// strictly ordered)
const Request::FlagsType no_merge_flags =
Request::UNCACHEABLE | Request::STRICT_ORDER |
- Request::MMAPPED_IPR | Request::PRIVILEGED |
- Request::LLSC | Request::MEM_SWAP |
+ Request::PRIVILEGED | Request::LLSC | Request::MEM_SWAP |
Request::MEM_SWAP_COND | Request::SECURE;
const auto &req_flags = pkt->req->getFlags();
bool compat_write = !req_flags.isSet(no_merge_flags);
};
}
+class Packet;
class Request;
+class ThreadContext;
typedef std::shared_ptr<Request> RequestPtr;
typedef uint16_t MasterID;
* the UNCACHEABLE flag is set as well.
*/
STRICT_ORDER = 0x00000800,
- /** This request is to a memory mapped register. */
- MMAPPED_IPR = 0x00002000,
/** This request is made in privileged mode. */
PRIVILEGED = 0x00008000,
ARG_SEGMENT = 0x00000800,
};
+ using LocalAccessor =
+ std::function<Cycles(ThreadContext *tc, Packet *pkt)>;
+
private:
typedef uint16_t PrivateFlagsType;
typedef ::Flags<PrivateFlagsType> PrivateFlags;
/** A pointer to an atomic operation */
AtomicOpFunctorPtr atomicOpFunctor;
+ LocalAccessor _localAccessor;
+
public:
/**
_taskId(other._taskId), _asid(other._asid), _vaddr(other._vaddr),
_extraData(other._extraData), _contextId(other._contextId),
_pc(other._pc), _reqInstSeqNum(other._reqInstSeqNum),
+ _localAccessor(other._localAccessor),
translateDelta(other.translateDelta),
accessDelta(other.accessDelta), depth(other.depth)
{
-
atomicOpFunctor.reset(other.atomicOpFunctor ?
other.atomicOpFunctor->clone() : nullptr);
}
accessDelta = 0;
translateDelta = 0;
atomicOpFunctor = std::move(amo_op);
+ _localAccessor = nullptr;
}
/**
return _time;
}
+ /** Is this request for a local memory mapped resource/register? */
+ bool isLocalAccess() { return (bool)_localAccessor; }
+ /** Set the function which will enact that access. */
+ void setLocalAccessor(LocalAccessor acc) { _localAccessor = acc; }
+ /** Perform the installed local access. */
+ Cycles
+ localAccessor(ThreadContext *tc, Packet *pkt)
+ {
+ return _localAccessor(tc, pkt);
+ }
+
/**
* Accessor for atomic-op functor.
*/
bool isLockedRMW() const { return _flags.isSet(LOCKED_RMW); }
bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
- bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
bool isSecure() const { return _flags.isSet(SECURE); }
bool isPTWalk() const { return _flags.isSet(PT_WALK); }
bool isAcquire() const { return _flags.isSet(ACQUIRE); }