arch-riscv: Fixed CPU switching and PLIC issue with MinorCPU
Added takeover methods for PMA Checker and RiscvTLB to ensure that checkpoint restoration works. Also added logic in PLIC to prevent posting interrupts to a CPU that has yet to complete the current interrupt. PLIC's behaviour when a CPU claims another interrupt before completion is also changed. Now PLIC will return the uncompleted interrupt ID instead of return 0. This behaviour is not documented in the specs but is designed this way to avoid issues from CPU side (especially MinorCPU). Change-Id: I68eaaf56d2c4d76cc1e0a1e2160f5abe184c2cd5 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41933 Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Ayaz Akram <yazakram@ucdavis.edu>
This commit is contained in:
committed by
Andrea Mondelli
parent
7bb690c1ee
commit
975fcf1355
@@ -354,17 +354,18 @@ Plic::readClaim(Register32& reg, const int context_id)
|
||||
context_id, max_int_id);
|
||||
clear(max_int_id);
|
||||
reg.update(max_int_id);
|
||||
return reg.get();
|
||||
} else {
|
||||
DPRINTF(Plic,
|
||||
"Claim already cleared - context: %d, interrupt ID: %d\n",
|
||||
context_id, max_int_id);
|
||||
reg.update(0);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
warn("PLIC claim failed (not completed) - context: %d", context_id);
|
||||
reg.update(0);
|
||||
warn("PLIC claim repeated (not completed) - context: %d, last: %d",
|
||||
context_id, lastID[context_id]);
|
||||
return lastID[context_id];
|
||||
}
|
||||
return reg.get();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -381,6 +382,7 @@ Plic::writeClaim(Register32& reg, const uint32_t& data, const int context_id)
|
||||
DPRINTF(Plic,
|
||||
"Complete - context: %d, interrupt ID: %d\n",
|
||||
context_id, reg.get());
|
||||
updateInt();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -445,11 +447,11 @@ Plic::updateInt()
|
||||
uint32_t max_id = output.maxID[i];
|
||||
uint32_t priority = output.maxPriority[i];
|
||||
uint32_t threshold = registers.threshold[i].get();
|
||||
if (priority > threshold && max_id > 0) {
|
||||
if (priority > threshold && max_id > 0 && lastID[i] == 0) {
|
||||
DPRINTF(Plic,
|
||||
"Int posted - thread: %d, int id: %d, ",
|
||||
thread_id, int_id);
|
||||
DPRINTF(Plic,
|
||||
DPRINTFR(Plic,
|
||||
"pri: %d, thres: %d\n", priority, threshold);
|
||||
intrctrl->post(thread_id, int_id, 0);
|
||||
} else {
|
||||
@@ -457,7 +459,7 @@ Plic::updateInt()
|
||||
DPRINTF(Plic,
|
||||
"Int filtered - thread: %d, int id: %d, ",
|
||||
thread_id, int_id);
|
||||
DPRINTF(Plic,
|
||||
DPRINTFR(Plic,
|
||||
"pri: %d, thres: %d\n", priority, threshold);
|
||||
}
|
||||
intrctrl->clear(thread_id, int_id, 0);
|
||||
@@ -499,6 +501,12 @@ Plic::serialize(CheckpointOut &cp) const
|
||||
SERIALIZE_SCALAR(n_outputs);
|
||||
SERIALIZE_CONTAINER(output.maxID);
|
||||
SERIALIZE_CONTAINER(output.maxPriority);
|
||||
SERIALIZE_CONTAINER(pendingPriority);
|
||||
for (int i=0; i < effPriority.size(); i++) {
|
||||
arrayParamOut(cp, std::string("effPriority") +
|
||||
std::to_string(i), effPriority[i]);
|
||||
}
|
||||
SERIALIZE_CONTAINER(lastID);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -541,4 +549,11 @@ Plic::unserialize(CheckpointIn &cp)
|
||||
}
|
||||
UNSERIALIZE_CONTAINER(output.maxID);
|
||||
UNSERIALIZE_CONTAINER(output.maxPriority);
|
||||
UNSERIALIZE_CONTAINER(pendingPriority);
|
||||
for (int i=0; i < effPriority.size(); i++) {
|
||||
arrayParamIn(cp, std::string("effPriority") +
|
||||
std::to_string(i), effPriority[i]);
|
||||
}
|
||||
UNSERIALIZE_CONTAINER(lastID);
|
||||
updateInt();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user