#include "arch/faults.hh"
#include "arch/locked_mem.hh"
+#include "arch/mmapped_ipr.hh"
#include "base/fast_alloc.hh"
#include "base/hashmap.hh"
#include "config/full_system.hh"
load_inst->recordResult = true;
}
+ if (req->isMmappedIpr()) {
+ assert(!load_inst->memData);
+ load_inst->memData = new uint8_t[64];
+
+ ThreadContext *thread = cpu->tcBase(lsqID);
+ Tick delay;
+ PacketPtr data_pkt =
+ new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
+
+ if (!TheISA::HasUnalignedMemAcc || !sreqLow) {
+ data_pkt->dataStatic(load_inst->memData);
+ delay = TheISA::handleIprRead(thread, data_pkt);
+ } else {
+ assert(sreqLow->isMmappedIpr() && sreqHigh->isMmappedIpr());
+ PacketPtr fst_data_pkt =
+ new Packet(sreqLow, MemCmd::ReadReq, Packet::Broadcast);
+ PacketPtr snd_data_pkt =
+ new Packet(sreqHigh, MemCmd::ReadReq, Packet::Broadcast);
+
+ fst_data_pkt->dataStatic(load_inst->memData);
+ snd_data_pkt->dataStatic(load_inst->memData + sreqLow->getSize());
+
+ delay = TheISA::handleIprRead(thread, fst_data_pkt);
+ unsigned delay2 = TheISA::handleIprRead(thread, snd_data_pkt);
+ if (delay2 > delay)
+ delay = delay2;
+
+ delete sreqLow;
+ delete sreqHigh;
+ delete fst_data_pkt;
+ delete snd_data_pkt;
+ }
+ WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this);
+ cpu->schedule(wb, curTick() + delay);
+ return NoFault;
+ }
+
while (store_idx != -1) {
// End once we've reached the top of the LSQ
if (store_idx == storeWBIdx) {
DynInstPtr inst = storeQueue[storeWBIdx].inst;
Request *req = storeQueue[storeWBIdx].req;
+ RequestPtr sreqLow = storeQueue[storeWBIdx].sreqLow;
+ RequestPtr sreqHigh = storeQueue[storeWBIdx].sreqHigh;
+
storeQueue[storeWBIdx].committed = true;
assert(!inst->memData);
data_pkt->dataStatic(inst->memData);
data_pkt->senderState = state;
} else {
- RequestPtr sreqLow = storeQueue[storeWBIdx].sreqLow;
- RequestPtr sreqHigh = storeQueue[storeWBIdx].sreqHigh;
-
// Create two packets if the store is split in two.
data_pkt = new Packet(sreqLow, command, Packet::Broadcast);
snd_data_pkt = new Packet(sreqHigh, command, Packet::Broadcast);
state->noWB = true;
}
- if (!sendStore(data_pkt)) {
+ bool split =
+ TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit;
+
+ ThreadContext *thread = cpu->tcBase(lsqID);
+
+ if (req->isMmappedIpr()) {
+ assert(!inst->isStoreConditional());
+ TheISA::handleIprWrite(thread, data_pkt);
+ delete data_pkt;
+ if (split) {
+ assert(snd_data_pkt->req->isMmappedIpr());
+ TheISA::handleIprWrite(thread, snd_data_pkt);
+ delete snd_data_pkt;
+ delete sreqLow;
+ delete sreqHigh;
+ }
+ delete state;
+ delete req;
+ completeStore(storeWBIdx);
+ incrStIdx(storeWBIdx);
+ } else if (!sendStore(data_pkt)) {
DPRINTF(IEW, "D-Cache became blocked when writing [sn:%lli], will"
"retry later\n",
inst->seqNum);
// Need to store the second packet, if split.
- if (TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit) {
+ if (split) {
state->pktToSend = true;
state->pendingPacket = snd_data_pkt;
}
} else {
// If split, try to send the second packet too
- if (TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit) {
+ if (split) {
assert(snd_data_pkt);
// Ensure there are enough ports to use.