summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/alpha/mmapped_ipr.hh22
-rw-r--r--src/arch/arm/mmapped_ipr.hh18
-rw-r--r--src/arch/generic/SConscript1
-rw-r--r--src/arch/generic/mmapped_ipr.cc84
-rw-r--r--src/arch/generic/mmapped_ipr.hh181
-rw-r--r--src/arch/mips/mmapped_ipr.hh18
-rw-r--r--src/arch/power/mmapped_ipr.hh18
-rw-r--r--src/arch/sparc/mmapped_ipr.hh11
-rw-r--r--src/arch/x86/mmapped_ipr.hh43
9 files changed, 314 insertions, 82 deletions
diff --git a/src/arch/alpha/mmapped_ipr.hh b/src/arch/alpha/mmapped_ipr.hh
index 24f7ce335..46ed6bd49 100644
--- a/src/arch/alpha/mmapped_ipr.hh
+++ b/src/arch/alpha/mmapped_ipr.hh
@@ -37,27 +37,11 @@
* ISA-specific helper functions for memory mapped IPR accesses.
*/
-#include "base/types.hh"
-#include "mem/packet.hh"
-
-class ThreadContext;
+#include "arch/generic/mmapped_ipr.hh"
namespace AlphaISA {
-
-inline Cycles
-handleIprRead(ThreadContext *xc, Packet *pkt)
-{
- panic("No handleIprRead implementation in Alpha\n");
-}
-
-
-inline Cycles
-handleIprWrite(ThreadContext *xc, Packet *pkt)
-{
- panic("No handleIprWrite implementation in Alpha\n");
-}
-
-
+ using GenericISA::handleIprRead;
+ using GenericISA::handleIprWrite;
} // namespace AlphaISA
#endif // __ARCH_ALPHA_MMAPPED_IPR_HH__
diff --git a/src/arch/arm/mmapped_ipr.hh b/src/arch/arm/mmapped_ipr.hh
index 474aacbcf..d515b8371 100644
--- a/src/arch/arm/mmapped_ipr.hh
+++ b/src/arch/arm/mmapped_ipr.hh
@@ -39,26 +39,14 @@
* ISA-specific helper functions for memory mapped IPR accesses.
*/
-#include "base/misc.hh"
-#include "mem/packet.hh"
+#include "arch/generic/mmapped_ipr.hh"
class ThreadContext;
namespace ArmISA
{
-inline Cycles
-handleIprRead(ThreadContext *xc, Packet *pkt)
-{
- panic("No implementation for handleIprRead in ARM\n");
-}
-
-inline Cycles
-handleIprWrite(ThreadContext *xc, Packet *pkt)
-{
- panic("No implementation for handleIprWrite in ARM\n");
-}
-
-
+ using GenericISA::handleIprRead;
+ using GenericISA::handleIprWrite;
} // namespace ArmISA
#endif
diff --git a/src/arch/generic/SConscript b/src/arch/generic/SConscript
index 3dfc509a4..bac70fa32 100644
--- a/src/arch/generic/SConscript
+++ b/src/arch/generic/SConscript
@@ -32,3 +32,4 @@ if env['TARGET_ISA'] == 'null':
Return()
Source('decode_cache.cc')
+Source('mmapped_ipr.cc')
diff --git a/src/arch/generic/mmapped_ipr.cc b/src/arch/generic/mmapped_ipr.cc
new file mode 100644
index 000000000..3d85eea9f
--- /dev/null
+++ b/src/arch/generic/mmapped_ipr.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013 Andreas Sandberg
+ * 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.
+ *
+ * Authors: Andreas Sandberg
+ */
+
+#include "arch/generic/mmapped_ipr.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "sim/pseudo_inst.hh"
+
+using namespace GenericISA;
+
+static void
+handlePseudoInst(ThreadContext *xc, Packet *pkt)
+{
+ const Addr offset(pkt->getAddr() & IPR_IN_CLASS_MASK);
+ const uint8_t func((offset >> 8) & 0xFF);
+ const uint8_t subfunc(offset & 0xFF);
+ uint64_t ret;
+
+ assert((offset >> 16) == 0);
+ ret = PseudoInst::pseudoInst(xc, func, subfunc);
+ if (pkt->isRead())
+ pkt->set(ret);
+}
+
+Cycles
+GenericISA::handleGenericIprRead(ThreadContext *xc, Packet *pkt)
+{
+ Addr va(pkt->getAddr());
+ Addr cls((va & IPR_CLASS_MASK) >> IPR_CLASS_SHIFT);
+
+ switch (cls) {
+ case IPR_CLASS_PSEUDO_INST:
+ handlePseudoInst(xc, pkt);
+ break;
+ default:
+ panic("Unhandled generic IPR read: 0x%x\n", va);
+ }
+
+ return Cycles(1);
+}
+
+Cycles
+GenericISA::handleGenericIprWrite(ThreadContext *xc, Packet *pkt)
+{
+ Addr va(pkt->getAddr());
+ Addr cls((va & IPR_CLASS_MASK) >> IPR_CLASS_SHIFT);
+
+ switch (cls) {
+ case IPR_CLASS_PSEUDO_INST:
+ handlePseudoInst(xc, pkt);
+ break;
+ default:
+ panic("Unhandled generic IPR write: 0x%x\n", va);
+ }
+
+ return Cycles(1);
+}
diff --git a/src/arch/generic/mmapped_ipr.hh b/src/arch/generic/mmapped_ipr.hh
new file mode 100644
index 000000000..55ce6e4d5
--- /dev/null
+++ b/src/arch/generic/mmapped_ipr.hh
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2013 Andreas Sandberg
+ * 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.
+ *
+ * Authors: Andreas Sandberg
+ */
+
+#ifndef __ARCH_GENERIC_MMAPPED_IPR_HH__
+#define __ARCH_GENERIC_MMAPPED_IPR_HH__
+
+#include "base/types.hh"
+#include "mem/packet.hh"
+
+class ThreadContext;
+
+/**
+ * @file
+ *
+ * ISA-generic helper functions for memory mapped IPR accesses.
+ */
+
+namespace GenericISA
+{
+ /** @{ */
+ /**
+ * Memory requests with the MMAPPED_IPR flag are generally mapped
+ * to registers. There is a class of these registers that are
+ * internal to gem5, for example gem5 pseudo-ops in virtualized
+ * mode.
+ *
+ * In order to make the IPR space manageable we always set bit 63
+ * (IPR_GENERIC) for accesses that should be handled by the
+ * generic ISA code. Architectures may use the rest of the IPR
+ * space internally.
+ */
+
+ /** Is this a generic IPR access? */
+ const Addr IPR_GENERIC = ULL(0x8000000000000000);
+
+ /** @{ */
+ /** Mask when extracting the class of a generic IPR */
+ const Addr IPR_CLASS_MASK = ULL(0x7FFF000000000000);
+ /** Shift amount when extracting the class of a generic IPR */
+ const int IPR_CLASS_SHIFT = 48;
+ /** @} */
+
+ /** Mask to extract the offset in within a generic IPR class */
+ const Addr IPR_IN_CLASS_MASK = ULL(0x0000FFFFFFFFFFFF);
+
+ /** gem5 pseudo-inst emulation.
+ *
+ * Read and writes to this class execute gem5
+ * pseudo-instructions. A write discards the return value of the
+ * instruction, while a read returns it.
+ *
+ * @see pseudoInst()
+ */
+ const Addr IPR_CLASS_PSEUDO_INST = 0x0;
+
+ /** @} */
+
+ /**
+ * Generate a generic IPR address that emulates a pseudo inst
+ *
+ * @see PseudoInst::pseudoInst()
+ *
+ * @param func Function ID to call.
+ * @param subfunc Sub-function, usually 0.
+ * @return Address in the IPR space corresponding to the call.
+ */
+ inline Addr
+ iprAddressPseudoInst(uint8_t func, uint8_t subfunc)
+ {
+ return IPR_GENERIC | (IPR_CLASS_PSEUDO_INST << IPR_CLASS_SHIFT) |
+ (func << 8) | subfunc;
+ }
+
+ /**
+ * Check if this is an platform independent IPR access
+ *
+ * Accesses to internal platform independent gem5 registers are
+ * handled by handleGenericIprRead() and
+ * handleGenericIprWrite(). This method determines if a packet
+ * should be routed to those functions instead of the platform
+ * specific code.
+ *
+ * @see handleGenericIprRead
+ * @see handleGenericIprWrite
+ */
+ inline bool
+ isGenericIprAccess(const Packet *pkt)
+ {
+ return pkt->getAddr() & IPR_GENERIC;
+ }
+
+ /**
+ * Handle generic IPR reads
+ *
+ * @param xc Thread context of the current thread.
+ * @param pkt Packet from the CPU
+ * @return Latency in CPU cycles
+ */
+ Cycles handleGenericIprRead(ThreadContext *xc, Packet *pkt);
+ /**
+ * Handle generic IPR writes
+ *
+ * @param xc Thread context of the current thread.
+ * @param pkt Packet from the CPU
+ * @return Latency in CPU cycles
+ */
+ Cycles handleGenericIprWrite(ThreadContext *xc, Packet *pkt);
+
+ /**
+ * Helper function to handle IPRs when the target architecture doesn't
+ * need its own IPR handling.
+ *
+ * This function calls handleGenericIprRead if the accessing a
+ * generic IPR and panics otherwise.
+ *
+ * @param xc Thread context of the current thread.
+ * @param pkt Packet from the CPU
+ * @return Latency in CPU cycles
+ */
+ inline Cycles
+ handleIprRead(ThreadContext *xc, Packet *pkt)
+ {
+ if (!isGenericIprAccess(pkt))
+ panic("Unhandled IPR access\n");
+
+ return handleGenericIprRead(xc, pkt);
+ }
+
+
+ /**
+ * Helper function to handle IPRs when the target architecture
+ * doesn't need its own IPR handling.
+ *
+ * This function calls handleGenericIprWrite if the accessing a
+ * generic IPR and panics otherwise.
+ *
+ * @param xc Thread context of the current thread.
+ * @param pkt Packet from the CPU
+ * @return Latency in CPU cycles
+ */
+ inline Cycles
+ handleIprWrite(ThreadContext *xc, Packet *pkt)
+ {
+ if (!isGenericIprAccess(pkt))
+ panic("Unhandled IPR access\n");
+
+ return handleGenericIprWrite(xc, pkt);
+ }
+
+} // namespace GenericISA
+
+
+
+#endif
diff --git a/src/arch/mips/mmapped_ipr.hh b/src/arch/mips/mmapped_ipr.hh
index 4c84d05f2..032fa28b2 100644
--- a/src/arch/mips/mmapped_ipr.hh
+++ b/src/arch/mips/mmapped_ipr.hh
@@ -37,26 +37,14 @@
* ISA-specific helper functions for memory mapped IPR accesses.
*/
-#include "base/misc.hh"
-#include "mem/packet.hh"
+#include "arch/generic/mmapped_ipr.hh"
class ThreadContext;
namespace MipsISA
{
-
-inline Cycles
-handleIprRead(ThreadContext *xc, Packet *pkt)
-{
- panic("No implementation for handleIprRead in MIPS\n");
-}
-
-inline Cycles
-handleIprWrite(ThreadContext *xc, Packet *pkt)
-{
- panic("No implementation for handleIprWrite in MIPS\n");
-}
-
+ using GenericISA::handleIprRead;
+ using GenericISA::handleIprWrite;
} // namespace MipsISA
#endif
diff --git a/src/arch/power/mmapped_ipr.hh b/src/arch/power/mmapped_ipr.hh
index 142253462..28e3b613c 100644
--- a/src/arch/power/mmapped_ipr.hh
+++ b/src/arch/power/mmapped_ipr.hh
@@ -41,26 +41,14 @@
* ISA-specific helper functions for memory mapped IPR accesses.
*/
-#include "base/misc.hh"
-#include "mem/packet.hh"
+#include "arch/generic/mmapped_ipr.hh"
class ThreadContext;
namespace PowerISA
{
-
-inline Cycles
-handleIprRead(ThreadContext *xc, Packet *pkt)
-{
- panic("No implementation for handleIprRead in POWER\n");
-}
-
-inline Cycles
-handleIprWrite(ThreadContext *xc, Packet *pkt)
-{
- panic("No implementation for handleIprWrite in POWER\n");
-}
-
+ using GenericISA::handleIprRead;
+ using GenericISA::handleIprWrite;
} // namespace PowerISA
#endif // __ARCH_POWER_MMAPPED_IPR_HH__
diff --git a/src/arch/sparc/mmapped_ipr.hh b/src/arch/sparc/mmapped_ipr.hh
index 153944e9d..e7d27eed5 100644
--- a/src/arch/sparc/mmapped_ipr.hh
+++ b/src/arch/sparc/mmapped_ipr.hh
@@ -37,6 +37,7 @@
* ISA-specific helper functions for memory mapped IPR accesses.
*/
+#include "arch/generic/mmapped_ipr.hh"
#include "arch/sparc/tlb.hh"
#include "cpu/thread_context.hh"
#include "mem/packet.hh"
@@ -47,13 +48,19 @@ namespace SparcISA
inline Cycles
handleIprRead(ThreadContext *xc, Packet *pkt)
{
- return xc->getDTBPtr()->doMmuRegRead(xc, pkt);
+ if (GenericISA::isGenericIprAccess(pkt))
+ return GenericISA::handleGenericIprRead(xc, pkt);
+ else
+ return xc->getDTBPtr()->doMmuRegRead(xc, pkt);
}
inline Cycles
handleIprWrite(ThreadContext *xc, Packet *pkt)
{
- return xc->getDTBPtr()->doMmuRegWrite(xc, pkt);
+ if (GenericISA::isGenericIprAccess(pkt))
+ return GenericISA::handleGenericIprWrite(xc, pkt);
+ else
+ return xc->getDTBPtr()->doMmuRegWrite(xc, pkt);
}
diff --git a/src/arch/x86/mmapped_ipr.hh b/src/arch/x86/mmapped_ipr.hh
index 02c125171..bd24d33da 100644
--- a/src/arch/x86/mmapped_ipr.hh
+++ b/src/arch/x86/mmapped_ipr.hh
@@ -46,6 +46,7 @@
* ISA-specific helper functions for memory mapped IPR accesses.
*/
+#include "arch/generic/mmapped_ipr.hh"
#include "arch/x86/regs/misc.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
@@ -56,27 +57,37 @@ namespace X86ISA
inline Cycles
handleIprRead(ThreadContext *xc, Packet *pkt)
{
- Addr offset = pkt->getAddr() & mask(3);
- MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
- MiscReg data = htog(xc->readMiscReg(index));
- // Make sure we don't trot off the end of data.
- assert(offset + pkt->getSize() <= sizeof(MiscReg));
- pkt->setData(((uint8_t *)&data) + offset);
- return Cycles(1);
+ if (GenericISA::isGenericIprAccess(pkt)) {
+ return GenericISA::handleGenericIprRead(xc, pkt);
+ } else {
+ Addr offset = pkt->getAddr() & mask(3);
+ MiscRegIndex index = (MiscRegIndex)(
+ pkt->getAddr() / sizeof(MiscReg));
+ MiscReg data = htog(xc->readMiscReg(index));
+ // Make sure we don't trot off the end of data.
+ assert(offset + pkt->getSize() <= sizeof(MiscReg));
+ pkt->setData(((uint8_t *)&data) + offset);
+ return Cycles(1);
+ }
}
inline Cycles
handleIprWrite(ThreadContext *xc, Packet *pkt)
{
- Addr offset = pkt->getAddr() & mask(3);
- MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
- MiscReg data;
- data = htog(xc->readMiscRegNoEffect(index));
- // Make sure we don't trot off the end of data.
- assert(offset + pkt->getSize() <= sizeof(MiscReg));
- pkt->writeData(((uint8_t *)&data) + offset);
- xc->setMiscReg(index, gtoh(data));
- return Cycles(1);
+ if (GenericISA::isGenericIprAccess(pkt)) {
+ return GenericISA::handleGenericIprWrite(xc, pkt);
+ } else {
+ Addr offset = pkt->getAddr() & mask(3);
+ MiscRegIndex index = (MiscRegIndex)(
+ pkt->getAddr() / sizeof(MiscReg));
+ MiscReg data;
+ data = htog(xc->readMiscRegNoEffect(index));
+ // Make sure we don't trot off the end of data.
+ assert(offset + pkt->getSize() <= sizeof(MiscReg));
+ pkt->writeData(((uint8_t *)&data) + offset);
+ xc->setMiscReg(index, gtoh(data));
+ return Cycles(1);
+ }
}
}