diff options
Diffstat (limited to 'mips')
| -rw-r--r-- | mips/mips_insts.sail | 16 | ||||
| -rw-r--r-- | mips/mips_prelude.sail | 77 |
2 files changed, 55 insertions, 38 deletions
diff --git a/mips/mips_insts.sail b/mips/mips_insts.sail index d4459fb1..5827369e 100644 --- a/mips/mips_insts.sail +++ b/mips/mips_insts.sail @@ -1325,8 +1325,8 @@ function clause execute (MFC0(rt, rd, sel, double)) = { { case (0b00000,0b000) -> (0x00000000 : [TLBProbe] : 0x0000000 : TLBIndex) (* 0, TLB Index *) case (0b00001,0b000) -> EXTZ(TLBRandom) (* 1, TLB Random *) - case (0b00010,0b000) -> EXTZ(TLBEntryLo0)(* 2, TLB EntryLo0 *) - case (0b00011,0b000) -> EXTZ(TLBEntryLo1)(* 3, TLB EntryLo1 *) + case (0b00010,0b000) -> TLBEntryLo0 (* 2, TLB EntryLo0 *) + case (0b00011,0b000) -> TLBEntryLo1 (* 3, TLB EntryLo1 *) case (0b00100,0b000) -> TLBContext (* 4, TLB Context *) case (0b00101,0b000) -> EXTZ(TLBPageMask : 0x000) (* 5, TLB PageMask *) case (0b00110,0b000) -> EXTZ(TLBWired) (* 6, TLB Wired *) @@ -1400,8 +1400,8 @@ function clause execute (MTC0(rt, rd, sel, double)) = { { case (0b00000,0b000) -> TLBIndex := mask(reg_val) (* NB no write to TLBProbe *) case (0b00001,0b000) -> () (* TLBRandom is read only *) - case (0b00010,0b000) -> TLBEntryLo0 := mask(reg_val) - case (0b00011,0b000) -> TLBEntryLo1 := mask(reg_val) + case (0b00010,0b000) -> TLBEntryLo0 := reg_val + case (0b00011,0b000) -> TLBEntryLo1 := reg_val case (0b00100,0b000) -> (TLBContext.PTEBase) := (reg_val[63..23]) case (0b00100,0b010) -> CP0UserLocal := reg_val case (0b00101,0b000) -> TLBPageMask := (reg_val[28..13]) @@ -1464,10 +1464,14 @@ function unit TLBWriteEntry((TLBIndexT) idx) = { ((TLBEntries[idx]).asid ) := TLBEntryHi.ASID; ((TLBEntries[idx]).g ) := ((TLBEntryLo0.G) & (TLBEntryLo1.G)); ((TLBEntries[idx]).valid ) := bitone; + ((TLBEntries[idx]).caps0 ) := TLBEntryLo0.CapS; + ((TLBEntries[idx]).capl0 ) := TLBEntryLo0.CapL; ((TLBEntries[idx]).pfn0 ) := TLBEntryLo0.PFN; ((TLBEntries[idx]).c0 ) := TLBEntryLo0.C; ((TLBEntries[idx]).d0 ) := TLBEntryLo0.D; ((TLBEntries[idx]).v0 ) := TLBEntryLo0.V; + ((TLBEntries[idx]).caps1 ) := TLBEntryLo1.CapS; + ((TLBEntries[idx]).capl1 ) := TLBEntryLo1.CapL; ((TLBEntries[idx]).pfn1 ) := TLBEntryLo1.PFN; ((TLBEntries[idx]).c1 ) := TLBEntryLo1.C; ((TLBEntries[idx]).d1 ) := TLBEntryLo1.D; @@ -1497,11 +1501,15 @@ function clause execute (TLBR) = { TLBEntryHi.R := entry.r; TLBEntryHi.VPN2 := entry.vpn2; TLBEntryHi.ASID := entry.asid; + TLBEntryLo0.CapS:= entry.caps0; + TLBEntryLo0.CapL:= entry.capl0; TLBEntryLo0.PFN := entry.pfn0; TLBEntryLo0.C := entry.c0; TLBEntryLo0.D := entry.d0; TLBEntryLo0.V := entry.v0; TLBEntryLo0.G := entry.g; + TLBEntryLo1.CapS:= entry.caps1; + TLBEntryLo1.CapL:= entry.capl1; TLBEntryLo1.PFN := entry.pfn1; TLBEntryLo1.C := entry.c1; TLBEntryLo1.D := entry.d1; diff --git a/mips/mips_prelude.sail b/mips/mips_prelude.sail index e1ae31fb..04574115 100644 --- a/mips/mips_prelude.sail +++ b/mips/mips_prelude.sail @@ -24,7 +24,9 @@ typedef CauseReg = register bits [ 31 : 0 ] { (*1 .. 0 : Z4;*) } -typedef TLBEntryLoReg = register bits [29 : 0] { +typedef TLBEntryLoReg = register bits [63 : 0] { + 63 : CapS; + 62 : CapL; 29 .. 6 : PFN; 5 .. 3 : C; 2 : D; @@ -57,21 +59,25 @@ let (TLBIndexT) TLBIndexMax = 0b111 let MAX_VA = unsigned(0xffffffffff) let MAX_PA = unsigned(0xfffffffff) -typedef TLBEntry = register bits [112 : 0] { - 112 .. 97: pagemask; (* 16 bits *) - 96 .. 95: r; (* 2 bits *) - 94 .. 68: vpn2; (* 27 bits *) - 67 .. 60: asid; (* 8 bits *) - 59 : g; - 58 : valid; - 57 .. 34: pfn0; (* 24 bits *) - 33 .. 31: c0; (* 3 bits *) - 30 : d0; - 29 : v0; - 28 .. 5 : pfn1; - 4 .. 2 : c1; - 1 : d1; - 0 : v1; +typedef TLBEntry = register bits [116 : 0] { + 116 .. 101: pagemask; + 100 .. 99 : r ; + 98 .. 72 : vpn2 ; + 71 .. 64 : asid ; + 63 : g ; + 62 : valid ; + 61 : caps1 ; + 60 : capl1 ; + 59 .. 36 : pfn1 ; + 35 .. 33 : c1 ; + 32 : d1 ; + 31 : v1 ; + 30 : caps0 ; + 29 : capl0 ; + 28 .. 5 : pfn0 ; + 4 .. 2 : c0 ; + 1 : d0 ; + 0 : v0 ; } register (bit[1]) TLBProbe @@ -338,13 +344,13 @@ function unit incrementCP0Count() = { } function bool tlbEntryMatch(r, vpn2, asid, (TLBEntry) entry) = - let entryVal = (bit[113]) entry in - let entryValid = (entryVal[58]) in - let entryR = (entryVal[96..95]) in - let entryMask = (entryVal[112..97]) in - let entryVPN = (entryVal[94..68]) in - let entryASID = (entryVal[67..60]) in - let entryG = (entryVal[59]) in + let entryVal = (bit[117]) entry in + let entryValid = (entryVal[62]) in + let entryR = (entryVal[100..99]) in + let entryMask = (entryVal[116..101]) in + let entryVPN = (entryVal[98..72]) in + let entryASID = (entryVal[71..64]) in + let entryG = (entryVal[63]) in ((entryValid) & (r == (entryR)) & ((vpn2 & ~(EXTZ(entryMask))) == ((entryVPN) & ~(EXTZ(entryMask)))) & @@ -373,12 +379,12 @@ function option<TLBIndexT> tlbSearch((bit[64]) VAddr) = else None -function (bit[64]) TLBTranslate2 ((bit[64]) vAddr, (MemAccessType) accessType) = { +function (bit[64], bool) TLBTranslate2 ((bit[64]) vAddr, (MemAccessType) accessType) = { let idx = tlbSearch(vAddr) in switch(idx) { case (Some(idx)) -> - let entry = ((bit[113])(TLBEntries[idx])) in - let entryMask = (entry[112..97]) in + let entry = ((bit[117])(TLBEntries[idx])) in + let entryMask = (entry[116..101]) in let evenOddBit = switch(entryMask) { case 0x0000 -> 12 @@ -393,21 +399,21 @@ function (bit[64]) TLBTranslate2 ((bit[64]) vAddr, (MemAccessType) accessType) = case _ -> undefined } in let isOdd = (vAddr[evenOddBit]) in - let (pfn, v, c, d) = if (isOdd) then - (entry[28..5], entry[0], entry[4..2], entry[1]) + let (caps, capl, pfn, d, v) = if (isOdd) then + (entry[61], entry[60], entry[59..36], entry[32], entry[31]) else - (entry[57..34], entry[29], entry[33..31], entry[30]) in + (entry[30], entry[29], entry[28..5], entry[1], entry[0]) in if (~(v)) then exit (SignalExceptionTLB(if (accessType == StoreData) then XTLBInvS else XTLBInvL, vAddr)) else if ((accessType == StoreData) & ~(d)) then exit (SignalExceptionTLB(TLBMod, vAddr)) else - EXTZ(pfn[23..((evenOddBit)-(12))] : vAddr[((evenOddBit)-(1)) .. 0]) + (EXTZ(pfn[23..((evenOddBit)-(12))] : vAddr[((evenOddBit)-(1)) .. 0]), if (accessType == StoreData) then caps else capl) case None -> exit (SignalExceptionTLB(if (accessType == StoreData) then XTLBRefillS else XTLBRefillL, vAddr)) } } -function (bit[64]) TLBTranslate ((bit[64]) vAddr, (MemAccessType) accessType) = +function (bit[64], bool) TLBTranslateC ((bit[64]) vAddr, (MemAccessType) accessType) = { let currentAccessLevel = getAccessLevel() in let compat32 = (vAddr[61..31] == 0b1111111111111111111111111111111) in @@ -426,8 +432,8 @@ function (bit[64]) TLBTranslate ((bit[64]) vAddr, (MemAccessType) accessType) = if (((nat)currentAccessLevel) < ((nat)requiredLevel)) then exit (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr)) else - let pa = switch(addr) { - case (Some(a)) -> a + let (pa, c) = switch(addr) { + case (Some(a)) -> (a, false) case None -> if ((~(compat32)) & (unsigned(vAddr[61..0]) > MAX_VA)) then exit (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr)) else @@ -436,9 +442,12 @@ function (bit[64]) TLBTranslate ((bit[64]) vAddr, (MemAccessType) accessType) = in if (unsigned(pa) > MAX_PA) then exit (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr)) else - pa + (pa, c) } +function (bit[64]) TLBTranslate ((bit[64]) vAddr, (MemAccessType) accessType) = + let (addr, c) = TLBTranslateC(vAddr, accessType) in addr + typedef regno = bit[5] (* a register number *) typedef imm16 = bit[16] (* 16-bit immediate *) typedef regregreg = (regno, regno, regno) (* a commonly used instruction format with three register operands *) |
