mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Fixed a very complex interaction between interrupts, the icache, dcache, and hptw.
If an interrupt occurred at the start of an ITLB miss or DTLB miss the page table walk should be aborted before starting.
This commit is contained in:
parent
0bf1836a3a
commit
705572f0ac
@ -24,7 +24,7 @@ in the memory stage. This is the core reason for the complexity.
|
||||
The above table classifies the operations into 8 categories.
|
||||
2 of the 8 are not possible because a DTLB miss implies a memory operation.
|
||||
Each (I/D)TLB miss results in either a write to the corresponding TLB or a TLB fault.
|
||||
To complicate things it is possilbe to have current ITLB and DTLB misses, which
|
||||
To complicate things it is possilbe to have concurrent ITLB and DTLB misses, which
|
||||
both can result in either a write or a fault. The table belows shows the possible
|
||||
scenarios and the sequence of operations.
|
||||
|
||||
@ -72,3 +72,19 @@ to normal mode.
|
||||
|
||||
Type 5a is a Type 4a with a current memory operation. The Dcache first switches to walker mode
|
||||
|
||||
Other traps.
|
||||
A new problem has emerged. What happens when an interrupt occurs during a page table walk?
|
||||
The dcache has an output called CommittedM which tells the CPU if the memory operation is
|
||||
committed into the memory system. It would be wrong to pin the interrupt to a memory operation
|
||||
when it is already or partially committed to the memory system. Instead the next instruction
|
||||
has to be pinned to the interrupt. The complexity occurs with the ITLB miss; types 4, 5 and 7.
|
||||
|
||||
Type 4: The ITLB misses and starts using the dcache to fetch the page table. There is no memory
|
||||
operation. Depending on where in the walk the operations could be aborted. If the tlb is not yet
|
||||
updated then the walk could be aborted. However if the TLB is updated then the interrupt must be
|
||||
delayed until the next instruction.
|
||||
|
||||
What is the meaning of CommittedM?
|
||||
This signal informs the CPU if a memory operation is not started or if it is between started
|
||||
and done. Once a memory op is started it should not be interrupted. This is used to prevent the
|
||||
CPU from generating an interrupt after the operation is partially or completely done.
|
||||
|
21
wally-pipelined/src/cache/dcachefsm.sv
vendored
21
wally-pipelined/src/cache/dcachefsm.sv
vendored
@ -192,16 +192,9 @@ module dcachefsm
|
||||
LRUWriteEn = 1'b0;
|
||||
CommittedM = 1'b0;
|
||||
|
||||
if(FlushDCacheM) begin
|
||||
NextState = STATE_FLUSH;
|
||||
DCacheStall = 1'b1;
|
||||
SelAdrM = 2'b11;
|
||||
FlushAdrCntRst = 1'b1;
|
||||
FlushWayCntRst = 1'b1;
|
||||
end
|
||||
|
||||
// TLB Miss
|
||||
else if((AnyCPUReqM & DTLBMissM) | ITLBMissF) begin
|
||||
if(((AnyCPUReqM & DTLBMissM) | ITLBMissF) & ~(ExceptionM | PendingInterruptM)) begin
|
||||
// the LSU arbiter has not yet selected the PTW.
|
||||
// The CPU needs to be stalled until that happens.
|
||||
// If we set DCacheStall for 1 cycle before going to
|
||||
@ -212,6 +205,16 @@ module dcachefsm
|
||||
DCacheStall = 1'b1;
|
||||
NextState = STATE_PTW_READY;
|
||||
end
|
||||
|
||||
// Flush dcache to next level of memory
|
||||
else if(FlushDCacheM & ~(ExceptionM | PendingInterruptM)) begin
|
||||
NextState = STATE_FLUSH;
|
||||
DCacheStall = 1'b1;
|
||||
SelAdrM = 2'b11;
|
||||
FlushAdrCntRst = 1'b1;
|
||||
FlushWayCntRst = 1'b1;
|
||||
end
|
||||
|
||||
// amo hit
|
||||
else if(AtomicM[1] & (&MemRWM) & CacheableM & ~(ExceptionM | PendingInterruptM) & CacheHit & ~DTLBMissM) begin
|
||||
SelAdrM = 2'b10;
|
||||
@ -623,7 +626,7 @@ module dcachefsm
|
||||
CntReset = 1'b0;
|
||||
AHBWrite = 1'b0;
|
||||
AHBRead = 1'b0;
|
||||
CommittedM = 1'b0;
|
||||
CommittedM = 1'b1;
|
||||
NextState = STATE_READY;
|
||||
|
||||
|
||||
|
5
wally-pipelined/src/cache/icache.sv
vendored
5
wally-pipelined/src/cache/icache.sv
vendored
@ -32,6 +32,9 @@ module icache
|
||||
input logic StallF,
|
||||
input logic [`PA_BITS-1:0] PCNextF,
|
||||
input logic [`PA_BITS-1:0] PCPF,
|
||||
|
||||
input logic ExceptionM, PendingInterruptM,
|
||||
|
||||
// Data read in from the ebu unit
|
||||
input logic [`XLEN-1:0] InstrInF,
|
||||
input logic InstrAckF,
|
||||
@ -286,6 +289,8 @@ module icache
|
||||
.ITLBMissF,
|
||||
.ITLBWriteF,
|
||||
.WalkerInstrPageFaultF,
|
||||
.ExceptionM,
|
||||
.PendingInterruptM,
|
||||
.InstrAckF,
|
||||
.InstrReadF,
|
||||
.hit,
|
||||
|
4
wally-pipelined/src/cache/icachefsm.sv
vendored
4
wally-pipelined/src/cache/icachefsm.sv
vendored
@ -36,6 +36,8 @@ module icachefsm
|
||||
input logic ITLBWriteF,
|
||||
input logic WalkerInstrPageFaultF,
|
||||
|
||||
input logic ExceptionM, PendingInterruptM,
|
||||
|
||||
// BUS interface
|
||||
input logic InstrAckF,
|
||||
|
||||
@ -135,7 +137,7 @@ module icachefsm
|
||||
STATE_READY: begin
|
||||
SelAdr = 2'b00;
|
||||
ICacheReadEn = 1'b1;
|
||||
if (ITLBMissF) begin
|
||||
if (ITLBMissF & ~(ExceptionM | PendingInterruptM)) begin
|
||||
NextState = STATE_TLB_MISS;
|
||||
end else if (hit & ~spill) begin
|
||||
ICacheStallF = 1'b0;
|
||||
|
@ -62,6 +62,8 @@ module ifu (
|
||||
output logic IllegalIEUInstrFaultD,
|
||||
output logic InstrMisalignedFaultM,
|
||||
output logic [`XLEN-1:0] InstrMisalignedAdrM,
|
||||
input logic ExceptionM, PendingInterruptM,
|
||||
|
||||
|
||||
|
||||
// mmu management
|
||||
|
@ -134,8 +134,8 @@ module lsu
|
||||
.SATP_REGW(SATP_REGW),
|
||||
.PCF(PCF),
|
||||
.MemAdrM(MemAdrM),
|
||||
.ITLBMissF(ITLBMissF),
|
||||
.DTLBMissM(DTLBMissM),
|
||||
.ITLBMissF(ITLBMissF & ~PendingInterruptM),
|
||||
.DTLBMissM(DTLBMissM & ~PendingInterruptM),
|
||||
.MemRWM(MemRWM),
|
||||
.PTE(PTE),
|
||||
.PageType,
|
||||
|
@ -159,6 +159,7 @@ module wallypipelinedhart (
|
||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
|
||||
.ExceptionM, .PendingInterruptM,
|
||||
// Fetch
|
||||
.InstrInF(InstrRData), .InstrAckF, .PCF, .InstrPAdrF,
|
||||
.InstrReadF, .ICacheStallF,
|
||||
|
Loading…
Reference in New Issue
Block a user