O3: Implement memory mapped IPRs for O3.
This commit is contained in:
parent
6308ca27ff
commit
206c2e9a0e
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "arch/faults.hh"
|
#include "arch/faults.hh"
|
||||||
#include "arch/locked_mem.hh"
|
#include "arch/locked_mem.hh"
|
||||||
|
#include "arch/mmapped_ipr.hh"
|
||||||
#include "base/fast_alloc.hh"
|
#include "base/fast_alloc.hh"
|
||||||
#include "base/hashmap.hh"
|
#include "base/hashmap.hh"
|
||||||
#include "config/full_system.hh"
|
#include "config/full_system.hh"
|
||||||
|
@ -578,6 +579,43 @@ LSQUnit<Impl>::read(Request *req, Request *sreqLow, Request *sreqHigh,
|
||||||
load_inst->recordResult = true;
|
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) {
|
while (store_idx != -1) {
|
||||||
// End once we've reached the top of the LSQ
|
// End once we've reached the top of the LSQ
|
||||||
if (store_idx == storeWBIdx) {
|
if (store_idx == storeWBIdx) {
|
||||||
|
|
|
@ -716,6 +716,9 @@ LSQUnit<Impl>::writebackStores()
|
||||||
DynInstPtr inst = storeQueue[storeWBIdx].inst;
|
DynInstPtr inst = storeQueue[storeWBIdx].inst;
|
||||||
|
|
||||||
Request *req = storeQueue[storeWBIdx].req;
|
Request *req = storeQueue[storeWBIdx].req;
|
||||||
|
RequestPtr sreqLow = storeQueue[storeWBIdx].sreqLow;
|
||||||
|
RequestPtr sreqHigh = storeQueue[storeWBIdx].sreqHigh;
|
||||||
|
|
||||||
storeQueue[storeWBIdx].committed = true;
|
storeQueue[storeWBIdx].committed = true;
|
||||||
|
|
||||||
assert(!inst->memData);
|
assert(!inst->memData);
|
||||||
|
@ -741,9 +744,6 @@ LSQUnit<Impl>::writebackStores()
|
||||||
data_pkt->dataStatic(inst->memData);
|
data_pkt->dataStatic(inst->memData);
|
||||||
data_pkt->senderState = state;
|
data_pkt->senderState = state;
|
||||||
} else {
|
} else {
|
||||||
RequestPtr sreqLow = storeQueue[storeWBIdx].sreqLow;
|
|
||||||
RequestPtr sreqHigh = storeQueue[storeWBIdx].sreqHigh;
|
|
||||||
|
|
||||||
// Create two packets if the store is split in two.
|
// Create two packets if the store is split in two.
|
||||||
data_pkt = new Packet(sreqLow, command, Packet::Broadcast);
|
data_pkt = new Packet(sreqLow, command, Packet::Broadcast);
|
||||||
snd_data_pkt = new Packet(sreqHigh, command, Packet::Broadcast);
|
snd_data_pkt = new Packet(sreqHigh, command, Packet::Broadcast);
|
||||||
|
@ -794,20 +794,40 @@ LSQUnit<Impl>::writebackStores()
|
||||||
state->noWB = true;
|
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"
|
DPRINTF(IEW, "D-Cache became blocked when writing [sn:%lli], will"
|
||||||
"retry later\n",
|
"retry later\n",
|
||||||
inst->seqNum);
|
inst->seqNum);
|
||||||
|
|
||||||
// Need to store the second packet, if split.
|
// Need to store the second packet, if split.
|
||||||
if (TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit) {
|
if (split) {
|
||||||
state->pktToSend = true;
|
state->pktToSend = true;
|
||||||
state->pendingPacket = snd_data_pkt;
|
state->pendingPacket = snd_data_pkt;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// If split, try to send the second packet too
|
// If split, try to send the second packet too
|
||||||
if (TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit) {
|
if (split) {
|
||||||
assert(snd_data_pkt);
|
assert(snd_data_pkt);
|
||||||
|
|
||||||
// Ensure there are enough ports to use.
|
// Ensure there are enough ports to use.
|
||||||
|
|
Loading…
Reference in a new issue