Compare commits
5 Commits
toooba-reg
...
bypass-tlb
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f7aa79b99 | |||
| f2cc45d169 | |||
| b9b318b4f5 | |||
| bf7bd16c53 | |||
| c1cf362c70 |
BIN
Tests/isa/CheriPage
Executable file
BIN
Tests/isa/CheriPage
Executable file
Binary file not shown.
129
Tests/isa/CheriPage.S
Normal file
129
Tests/isa/CheriPage.S
Normal file
@@ -0,0 +1,129 @@
|
||||
.option norvc
|
||||
.option norelax
|
||||
|
||||
# ==================================================
|
||||
# Text section
|
||||
# ==================================================
|
||||
.section .text
|
||||
.globl _start
|
||||
_start:
|
||||
|
||||
vm_boot:
|
||||
# Only hart 0 runs
|
||||
csrr a0, mhartid
|
||||
bnez a0, hang
|
||||
|
||||
# --------------------------------------------------
|
||||
# root_pt[0] -> l1_pt
|
||||
# --------------------------------------------------
|
||||
cllc c0, l1_pt
|
||||
li t2, 4096
|
||||
csetbounds c0, c0, t2
|
||||
|
||||
cgetaddr t0, c0
|
||||
srli t0, t0, 12
|
||||
slli t0, t0, 10
|
||||
ori t0, t0, 0x1 # V bit
|
||||
|
||||
cllc c1, root_pt
|
||||
li t2, 4096
|
||||
csetbounds c1, c1, t2
|
||||
sd t0, 0(c1)
|
||||
|
||||
# --------------------------------------------------
|
||||
# l1_pt[0] -> l0_pt
|
||||
# --------------------------------------------------
|
||||
cllc c0, l0_pt
|
||||
li t2, 4096
|
||||
csetbounds c0, c0, t2
|
||||
|
||||
cgetaddr t0, c0
|
||||
srli t0, t0, 12
|
||||
slli t0, t0, 10
|
||||
ori t0, t0, 0x1 # V bit
|
||||
|
||||
cllc c1, l1_pt
|
||||
li t2, 4096
|
||||
csetbounds c1, c1, t2
|
||||
sd t0, 0(c1)
|
||||
|
||||
# --------------------------------------------------
|
||||
# l0_pt[0] -> leaf (RWX)
|
||||
# --------------------------------------------------
|
||||
li t0, (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<6) # V R W X A
|
||||
|
||||
cllc c1, l0_pt
|
||||
li t2, 4096
|
||||
csetbounds c1, c1, t2
|
||||
sd t0, 0(c1)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Enable Sv39 paging
|
||||
# --------------------------------------------------
|
||||
cllc c0, root_pt
|
||||
li t2, 4096
|
||||
csetbounds c0, c0, t2
|
||||
|
||||
cgetaddr t0, c0
|
||||
srli t0, t0, 12
|
||||
li t1, (8 << 60) # MODE = Sv39
|
||||
or t0, t0, t1
|
||||
csrw satp, t0
|
||||
sfence.vma zero, zero
|
||||
|
||||
# --------------------------------------------------
|
||||
# Safe data access
|
||||
# --------------------------------------------------
|
||||
cllc c2, test_buf
|
||||
li t2, 16
|
||||
csetbounds c2, c2, t2
|
||||
|
||||
li t3, 0x1122334455667788
|
||||
sd t3, 0(c2)
|
||||
ld t4, 0(c2)
|
||||
bne t3, t4, hang
|
||||
|
||||
# --------------------------------------------------
|
||||
# Signal success
|
||||
# --------------------------------------------------
|
||||
cllc c0, tohost
|
||||
li t2, 8
|
||||
csetbounds c0, c0, t2
|
||||
li t1, 1
|
||||
sd t1, 0(c0)
|
||||
|
||||
hang:
|
||||
wfi
|
||||
j hang
|
||||
|
||||
# ==================================================
|
||||
# Data section (aligned, contiguous, no .org)
|
||||
# ==================================================
|
||||
.section .data
|
||||
.align 12
|
||||
.globl root_pt
|
||||
root_pt:
|
||||
.zero 4096 # Root page table
|
||||
|
||||
.align 12
|
||||
.globl l1_pt
|
||||
l1_pt:
|
||||
.zero 4096 # Level 1 page table
|
||||
|
||||
.align 12
|
||||
.globl l0_pt
|
||||
l0_pt:
|
||||
.zero 4096 # Level 0 page table
|
||||
|
||||
.align 3
|
||||
.globl test_buf
|
||||
test_buf:
|
||||
.zero 16 # Test buffer
|
||||
|
||||
.globl tohost
|
||||
tohost:
|
||||
.dword 0
|
||||
|
||||
.globl fromhost
|
||||
fromhost:
|
||||
.dword 0
|
||||
230
Tests/isa/PageRead.S
Normal file
230
Tests/isa/PageRead.S
Normal file
@@ -0,0 +1,230 @@
|
||||
.option norvc
|
||||
.option norelax
|
||||
|
||||
# ==================================================
|
||||
# Text section
|
||||
# ==================================================
|
||||
.section .text
|
||||
.globl _start
|
||||
.globl vm_boot
|
||||
|
||||
_start:
|
||||
vm_boot:
|
||||
# --------------------------------------------------
|
||||
# Only hart 0 runs
|
||||
# --------------------------------------------------
|
||||
csrr a0, mhartid
|
||||
bnez a0, hang
|
||||
|
||||
# --------------------------------------------------
|
||||
# Build page tables
|
||||
# --------------------------------------------------
|
||||
|
||||
#
|
||||
# Page table setup (Sv39) — binary + hex example
|
||||
#
|
||||
# Purpose:
|
||||
# Build a VALID page table entry (PTE) in the root page table
|
||||
# that points to the next-level page table (l1_pt).
|
||||
#
|
||||
# Assume:
|
||||
# l1_pt physical address =
|
||||
# binary: 00000000 10000000 01000000 00110000 00000000
|
||||
# hex: 0x0000000080403000
|
||||
# (page aligned, lower 12 bits = 0)
|
||||
#
|
||||
# Step-by-step instruction meaning:
|
||||
#
|
||||
# la t0, l1_pt
|
||||
# Load physical address of l1_pt.
|
||||
#
|
||||
# t0 =
|
||||
# binary: 00000000 10000000 01000000 00110000 00000000
|
||||
# hex: 0x0000000080403000
|
||||
#
|
||||
# srli t0, t0, 12
|
||||
# Drop 12-bit page offset → extract Physical Page Number (PPN).
|
||||
#
|
||||
# t0 (PPN) =
|
||||
# binary: 00000000 00000000 10000000 01000000 0011
|
||||
# hex: 0x0000000000080403
|
||||
#
|
||||
# slli t0, t0, 10
|
||||
# Shift PPN into PTE bit positions [63:10].
|
||||
# Bits [9:0] are flags.
|
||||
#
|
||||
# t0 =
|
||||
# binary: 00000000 00000000 10000000 01000000 0011 0000000000
|
||||
# hex: 0x0000000020100C00
|
||||
#
|
||||
# ori t0, t0, 1
|
||||
# Set bit 0 (V = Valid).
|
||||
#
|
||||
# t0 (final PTE) =
|
||||
# binary: 00000000 00000000 10000000 01000000 0011 0000000001
|
||||
# hex: 0x0000000020100C01
|
||||
#
|
||||
# Memory effect:
|
||||
#
|
||||
# root_pt[0] =
|
||||
# bit index:
|
||||
# 63 10 9 0
|
||||
# +----------------------------------+----------+
|
||||
# | PPN = 0x0000000000080403 | V = 1 |
|
||||
# +----------------------------------+----------+
|
||||
#
|
||||
# binary: 00000000 00000000 10000000 01000000 0011 0000000001
|
||||
# hex: 0x0000000020100C01
|
||||
#
|
||||
# Result:
|
||||
# Root page table entry 0 is VALID and points to l1_pt.
|
||||
# The MMU uses this entry to continue the Sv39 page-table walk.
|
||||
#
|
||||
|
||||
|
||||
# root_pt[0] -> l1_pt
|
||||
la t0, l1_pt
|
||||
srli t0, t0, 12 # PPN
|
||||
slli t0, t0, 10 # PTE format
|
||||
ori t0, t0, 0x1 # V
|
||||
la t1, root_pt
|
||||
sd t0, 0(t1)
|
||||
|
||||
# l1_pt[0] -> l0_pt
|
||||
la t0, l0_pt
|
||||
srli t0, t0, 12
|
||||
slli t0, t0, 10
|
||||
ori t0, t0, 0x1 # V
|
||||
la t1, l1_pt
|
||||
sd t0, 0(t1)
|
||||
|
||||
# l0_pt[0] -> identity mapping (RWX)
|
||||
li t0, (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<6) # V R W X A
|
||||
la t1, l0_pt
|
||||
sd t0, 0(t1)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Enable Sv39 paging
|
||||
# --------------------------------------------------
|
||||
|
||||
# Enable virtual memory (Sv39) — SATP setup diagram (binary)
|
||||
#
|
||||
# Assume:
|
||||
# root_pt physical address =
|
||||
# 00000000 10000000 01000000 00010000 00000000
|
||||
# (4 KB aligned, lower 12 bits = 0)
|
||||
#
|
||||
# Instruction flow:
|
||||
#
|
||||
# la t0, root_pt
|
||||
# t0 =
|
||||
# 00000000 10000000 01000000 00010000 00000000
|
||||
#
|
||||
# srli t0, t0, 12 ; extract PPN
|
||||
# t0 (PPN) =
|
||||
# 00000000 00000000 10000000 01000000 0001
|
||||
#
|
||||
# li t1, (8 << 60) ; MODE = Sv39
|
||||
# t1 =
|
||||
# 1000 0000000000000000000000000000000000000000000000000000
|
||||
# ^^^^
|
||||
# MODE[63:60] = 1000 (Sv39)
|
||||
#
|
||||
# or t0, t0, t1
|
||||
# satp value =
|
||||
# 1000 0000000000000000000000000000000010000000010000000001
|
||||
# |<-- MODE -->|<----------- ASID ---------->|<---- PPN ---->|
|
||||
#
|
||||
# csrw satp, t0
|
||||
# satp register loaded:
|
||||
#
|
||||
# 63 60 59 44 43 0
|
||||
# +------+----------------------------------+----------------+
|
||||
# |1000 |0000000000000000 |0000000010000000010000000001|
|
||||
# +------+----------------------------------+----------------+
|
||||
# MODE=Sv39 ASID=0 root_pt PPN
|
||||
#
|
||||
# sfence.vma zero, zero
|
||||
# Flush all TLB entries so new page tables are used
|
||||
#
|
||||
# Meaning:
|
||||
# - Virtual memory enabled in Sv39 mode
|
||||
# - Root page table base = root_pt
|
||||
# - ASID = 0
|
||||
# - MMU now performs 3-level page table walks
|
||||
#
|
||||
|
||||
la t0, root_pt
|
||||
srli t0, t0, 12
|
||||
li t1, (8 << 60) # MODE=Sv39
|
||||
or t0, t0, t1
|
||||
csrw satp, t0
|
||||
sfence.vma zero, zero
|
||||
|
||||
# --------------------------------------------------
|
||||
# Write data to memory (safe area)
|
||||
# --------------------------------------------------
|
||||
la t2, test_buf
|
||||
li t3, 0x1122334455667788
|
||||
sd t3, 0(t2)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Read data back
|
||||
# --------------------------------------------------
|
||||
ld t4, 0(t2)
|
||||
|
||||
# Optional check (simple)
|
||||
bne t3, t4, hang
|
||||
|
||||
# --------------------------------------------------
|
||||
# Signal success
|
||||
# --------------------------------------------------
|
||||
la t0, tohost
|
||||
li t1, 1
|
||||
sd t1, 0(t0)
|
||||
|
||||
hang:
|
||||
wfi
|
||||
j hang
|
||||
|
||||
# ==================================================
|
||||
# Required test symbol
|
||||
# ==================================================
|
||||
.globl exit
|
||||
exit:
|
||||
j exit
|
||||
|
||||
# ==================================================
|
||||
# Data section
|
||||
# ==================================================
|
||||
.section .data
|
||||
.align 3
|
||||
|
||||
.globl tohost
|
||||
.globl fromhost
|
||||
tohost:
|
||||
.dword 0
|
||||
fromhost:
|
||||
.dword 0
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test buffer (safe data memory)
|
||||
# --------------------------------------------------
|
||||
.align 3
|
||||
test_buf:
|
||||
.zero 16
|
||||
|
||||
# --------------------------------------------------
|
||||
# Page tables (must be 4 KiB each)
|
||||
# --------------------------------------------------
|
||||
.align 12
|
||||
root_pt:
|
||||
.zero 4096
|
||||
|
||||
.align 12
|
||||
l1_pt:
|
||||
.zero 4096
|
||||
|
||||
.align 12
|
||||
l0_pt:
|
||||
.zero 4096
|
||||
@@ -12,7 +12,7 @@ _start:
|
||||
vm_boot:
|
||||
# Only hart 0
|
||||
csrr a0, mhartid
|
||||
bnez a0, hang
|
||||
bnez a0, hang.
|
||||
|
||||
# --------------------------------------------------
|
||||
# Build page table entries
|
||||
|
||||
@@ -8,10 +8,11 @@ ARCH ?= RV64ACDFIMSUxCHERI
|
||||
BSC_COMPILATION_FLAGS += -verbose
|
||||
# Default ISA test
|
||||
|
||||
# TEST ?= rv64ui-p-add
|
||||
TEST ?= rv64ui-p-add
|
||||
# TEST ?= rv64um-v-mulw
|
||||
# TEST ?= Page
|
||||
TEST ?= PageReadWrite
|
||||
# TEST ?= PageReadWrite
|
||||
# TEST ?= CheriPage
|
||||
|
||||
#================================================================
|
||||
# Parameter settings for MIT RISCY, setup paths etc. for Include_Common
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,8 +56,6 @@ BSC_COMPILATION_FLAGS += \
|
||||
-D FABRIC64 \
|
||||
-D BLUESIM \
|
||||
-D PERFORMANCE_MONITORING \
|
||||
-D PERF_COUNT \
|
||||
-D STATCOUNTERS \
|
||||
-keep-fires -aggressive-conditions -no-warn-action-shadowing -check-assert \
|
||||
-suppress-warnings G0020 -steps-max-intervals 10000000 \
|
||||
-steps-warn-interval 1000000 \
|
||||
|
||||
@@ -112,7 +112,6 @@ BSC_COMPILATION_FLAGS += \
|
||||
-D RISCV \
|
||||
-D TSO_MM \
|
||||
-D RV64 \
|
||||
-D PERF_COUNT \
|
||||
-D ISA_PRIV_M -D ISA_PRIV_S -D ISA_PRIV_U \
|
||||
-D SV39 \
|
||||
-D ISA_I -D ISA_M -D ISA_A -D ISA_F -D ISA_D -D ISA_FD_DIV -D ISA_C \
|
||||
|
||||
@@ -366,11 +366,6 @@ module mkCore#(CoreId coreId)(Core);
|
||||
// whether perf data is collected
|
||||
Reg#(Bool) doStatsReg <- mkConfigReg(True);
|
||||
|
||||
// Hack to get set stat reg to true
|
||||
// rule forceSetStatRegToTrue;
|
||||
// doStatsReg <= True;
|
||||
// endrule
|
||||
|
||||
// write aggressive elements + wakupe reservation stations
|
||||
function Action writeAggr(Integer wrAggrPort, PhyRIndx dst);
|
||||
action
|
||||
|
||||
@@ -330,8 +330,7 @@ interface StatsCsr;
|
||||
endinterface
|
||||
|
||||
module mkStatsCsr(StatsCsr);
|
||||
// Seeting CSR stat to true
|
||||
Reg#(Bool) doStats <- mkConfigReg(True);
|
||||
Reg#(Bool) doStats <- mkConfigReg(False);
|
||||
|
||||
FIFO#(Bool) writeQ <- mkFIFO1;
|
||||
|
||||
|
||||
@@ -320,6 +320,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
// pipeline fifos
|
||||
let dispToRegQ <- mkMemDispToRegFifo;
|
||||
let regToExeQ <- mkMemRegToExeFifo;
|
||||
let trollToExeQ <- mkMemRegToExeFifo;
|
||||
|
||||
// wire to recv bypass
|
||||
Vector#(TMul#(2, AluExeNum), RWire#(Tuple2#(PhyRIndx, CapPipe))) bypassWire <- replicateM(mkRWire);
|
||||
@@ -600,73 +601,156 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
regToExeQ.deq;
|
||||
let regToExe = regToExeQ.first;
|
||||
let x = regToExe.data;
|
||||
if(verbose) $display("%t : [doExeMem] ", $time, fshow(regToExe));
|
||||
// trollToExeQ.enq(regToExe);
|
||||
// ==============================
|
||||
// if(verbose) $display("%t : [doExeMem] ", $time, fshow(regToExe));
|
||||
|
||||
let shiftBE = DataMemAccess(x.shiftBEData);
|
||||
if (x.origBE == TagMemAccess) begin
|
||||
// // Moved to the next stage
|
||||
// // let shiftBE = DataMemAccess(x.shiftBEData);
|
||||
// // if (x.origBE == TagMemAccess) begin
|
||||
// // shiftBE = TagMemAccess;
|
||||
// // end
|
||||
|
||||
// CapPipe ddc = cast(inIfc.scaprf_rd(scrAddrDDC));
|
||||
|
||||
// // get size of the access
|
||||
// Bit#(TAdd#(CacheUtils::LogCLineNumMemDataBytes,1)) accessByteCount = zeroExtend(pack(countOnes(pack(x.origBE.DataMemAccess))));
|
||||
// if (x.origBE == TagMemAccess) begin
|
||||
// accessByteCount = fromInteger(valueOf(CacheUtils::CLineNumMemDataBytes));
|
||||
// end
|
||||
|
||||
// `ifdef KONATA
|
||||
// $display("KONATAE\t%0d\t%0d\t0\tMem2", cur_cycle, x.u_id);
|
||||
// $display("KONATAS\t%0d\t%0d\t0\tMem3", cur_cycle, x.u_id);
|
||||
// $fflush;
|
||||
// `endif
|
||||
// Make our own versions where this is passed as a queue to
|
||||
// the next stage and processed there:
|
||||
// We only need
|
||||
// - x.mem_func(Maybe to see if it's a load ?)
|
||||
// - x (We can get the hardware permissions, cap_mem permission, prepareBoundsCheck)
|
||||
// - We will assume a one on one mapping with offset with a delta value of 1 (Hardcoded
|
||||
// for just testing)
|
||||
trollToExeQ.enq(regToExe);
|
||||
|
||||
// go to next stage by sending to TLB
|
||||
// dTlb.procReq(DTlbReq {
|
||||
// inst: MemExeToFinish {
|
||||
// mem_func: x.mem_func,
|
||||
// tag: x.tag,
|
||||
// ldstq_tag: x.ldstq_tag,
|
||||
// shiftedBE: shiftBE,
|
||||
// vaddr: x.vaddr,
|
||||
// `ifdef INCLUDE_TANDEM_VERIF
|
||||
// store_data: x.rVal2,
|
||||
// store_data_BE: origBE,
|
||||
// `endif
|
||||
// misaligned: memAddrMisaligned(getAddr(x.vaddr), x.origBE),
|
||||
// capStore: isValidCap(x.rVal2) && x.origBE == DataMemAccess(unpack(~0)),
|
||||
// allowCapLoad: getHardPerms(x.rVal1).permitLoadCap && x.origBE == DataMemAccess(unpack(~0)),
|
||||
// capException: capChecksMem(x.rVal1, x.rVal2, x.cap_checks, x.mem_func, x.origBE),
|
||||
// check: prepareBoundsCheck(x.rVal1, x.rVal2, almightyCap/*ToDo: pcc*/,
|
||||
// ddc, getAddr(x.vaddr), accessByteCount, x.cap_checks)
|
||||
// `ifdef KONATA
|
||||
// , u_id: x.u_id
|
||||
// `endif
|
||||
// },
|
||||
// specBits: regToExe.spec_bits
|
||||
// });
|
||||
|
||||
// When the DTLB proq request is called
|
||||
// Could be only 1 at a time but let's assume there are plenty
|
||||
// We assume there is queue of requests (|,|,|,|), We assume these run while other instructions
|
||||
// are getting executed (When Proq response is called one by one from the queue responses with
|
||||
// physical addresses are being executed to be stored or read from memory).
|
||||
|
||||
endrule
|
||||
|
||||
rule doFinishMem;
|
||||
// Over here we are reducing the tracing surface area to ensure
|
||||
// It's easier to write a TLB bypasser.
|
||||
let regToExe = trollToExeQ.first;
|
||||
// Let's check if lol access data can be found in the
|
||||
// the previous stage.
|
||||
let lol = regToExe.data;
|
||||
// =============================
|
||||
// dTlb.deqProcResp;
|
||||
// let dTlbResp = dTlb.procResp;
|
||||
// Assumtion instruction related can be passed on
|
||||
// from the previous stage.
|
||||
// let tlbresp = dTlbResp.inst;
|
||||
// let {paddr, expCause, allowCapPTE} = dTlbResp.resp;
|
||||
// Assuming physcial address is virtual address just for testing
|
||||
let paddr = getAddr(lol.vaddr);
|
||||
// These are just assumtions for testing
|
||||
// let expCause = dTlb.Invalid;
|
||||
let allowCapPTE = True;
|
||||
|
||||
if(verbose) $display("%t : [doFinishMem] ", $time, fshow(regToExe));
|
||||
|
||||
// Moved to the next stage
|
||||
let shiftBE = DataMemAccess(lol.shiftBEData);
|
||||
if (lol.origBE == TagMemAccess) begin
|
||||
shiftBE = TagMemAccess;
|
||||
end
|
||||
|
||||
CapPipe ddc = cast(inIfc.scaprf_rd(scrAddrDDC));
|
||||
|
||||
// get size of the access
|
||||
Bit#(TAdd#(CacheUtils::LogCLineNumMemDataBytes,1)) accessByteCount = zeroExtend(pack(countOnes(pack(x.origBE.DataMemAccess))));
|
||||
if (x.origBE == TagMemAccess) begin
|
||||
accessByteCount = fromInteger(valueOf(CacheUtils::CLineNumMemDataBytes));
|
||||
end
|
||||
// Bit#(TAdd#(CacheUtils::LogCLineNumMemDataBytes,1)) accessByteCount = zeroExtend(pack(countOnes(pack(x.origBE.DataMemAccess))));
|
||||
// if (x.origBE == TagMemAccess) begin
|
||||
// accessByteCount = fromInteger(valueOf(CacheUtils::CLineNumMemDataBytes));
|
||||
// end
|
||||
|
||||
`ifdef KONATA
|
||||
$display("KONATAE\t%0d\t%0d\t0\tMem2", cur_cycle, x.u_id);
|
||||
$display("KONATAS\t%0d\t%0d\t0\tMem3", cur_cycle, x.u_id);
|
||||
$fflush;
|
||||
`endif
|
||||
// go to next stage by sending to TLB
|
||||
dTlb.procReq(DTlbReq {
|
||||
inst: MemExeToFinish {
|
||||
mem_func: x.mem_func,
|
||||
tag: x.tag,
|
||||
ldstq_tag: x.ldstq_tag,
|
||||
shiftedBE: shiftBE,
|
||||
vaddr: x.vaddr,
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data: x.rVal2,
|
||||
store_data_BE: origBE,
|
||||
`endif
|
||||
misaligned: memAddrMisaligned(getAddr(x.vaddr), x.origBE),
|
||||
capStore: isValidCap(x.rVal2) && x.origBE == DataMemAccess(unpack(~0)),
|
||||
allowCapLoad: getHardPerms(x.rVal1).permitLoadCap && x.origBE == DataMemAccess(unpack(~0)),
|
||||
capException: capChecksMem(x.rVal1, x.rVal2, x.cap_checks, x.mem_func, x.origBE),
|
||||
check: prepareBoundsCheck(x.rVal1, x.rVal2, almightyCap/*ToDo: pcc*/,
|
||||
ddc, getAddr(x.vaddr), accessByteCount, x.cap_checks)
|
||||
`ifdef KONATA
|
||||
, u_id: x.u_id
|
||||
`endif
|
||||
},
|
||||
specBits: regToExe.spec_bits
|
||||
});
|
||||
endrule
|
||||
|
||||
rule doFinishMem;
|
||||
dTlb.deqProcResp;
|
||||
let dTlbResp = dTlb.procResp;
|
||||
let x = dTlbResp.inst;
|
||||
let {paddr, expCause, allowCapPTE} = dTlbResp.resp;
|
||||
// Capability checks computed early over instead of the previous stage
|
||||
// This will resolve:
|
||||
// - .check
|
||||
// - .capException
|
||||
// - .allowCapLoad
|
||||
// - .capStore
|
||||
|
||||
// get access byte count
|
||||
// get size of the access
|
||||
Bit#(TAdd#(CacheUtils::LogCLineNumMemDataBytes,1)) accessByteCount = zeroExtend(pack(countOnes(pack(lol.origBE.DataMemAccess))));
|
||||
if (lol.origBE == TagMemAccess) begin
|
||||
accessByteCount = fromInteger(valueOf(CacheUtils::CLineNumMemDataBytes));
|
||||
end
|
||||
let check = prepareBoundsCheck(lol.rVal1, lol.rVal2, almightyCap/*ToDo: pcc*/,ddc, getAddr(lol.vaddr), accessByteCount, lol.cap_checks);
|
||||
|
||||
let capException = capChecksMem(lol.rVal1, lol.rVal2, lol.cap_checks, lol.mem_func, lol.origBE);
|
||||
|
||||
let allowCapLoad = getHardPerms(lol.rVal1).permitLoadCap && lol.origBE == DataMemAccess(unpack(~0));
|
||||
|
||||
// (TODO) Still need to pass the:
|
||||
// (done) tag
|
||||
// (done) ldstq_tag
|
||||
// (done) shiftedBE
|
||||
|
||||
Maybe#(Trap) cause = Invalid;
|
||||
if (expCause matches tagged Valid .c) cause = Valid(Exception(c));
|
||||
// if (expCause matches tagged Valid .c) cause = Valid(Exception(c));
|
||||
|
||||
if(verbose) $display("%t : [doFinishMem] ", $time, fshow(dTlbResp));
|
||||
if(isValid(cause) && verbose) $display(" [doFinishMem - dTlb response] PAGEFAULT!");
|
||||
|
||||
// if(verbose) $display("%t : [doFinishMem] ", $time, fshow(dTlbResp));
|
||||
$display("Bypassing TLB");
|
||||
// if(isValid(cause) && verbose) $display(" [doFinishMem - dTlb response] PAGEFAULT!");
|
||||
|
||||
Data store_data = ?;
|
||||
ByteEn store_data_BE = ?;
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data = x.store_data;
|
||||
store_data_BE = x.store_data_BE;
|
||||
`endif
|
||||
// `ifdef INCLUDE_TANDEM_VERIF
|
||||
// store_data = tlbresp.store_data;
|
||||
// store_data_BE = tlbresp.store_data_BE;
|
||||
// `endif
|
||||
let misaligned = memAddrMisaligned(getAddr(lol.vaddr), lol.origBE);
|
||||
|
||||
// check misalignment
|
||||
if(!isValid(cause) && x.misaligned) begin
|
||||
case(x.mem_func)
|
||||
if(!isValid(cause) && misaligned) begin
|
||||
case(lol.mem_func)
|
||||
Ld, Lr: begin
|
||||
cause = Valid(Exception(excLoadAddrMisaligned));
|
||||
end
|
||||
@@ -676,25 +760,25 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef RVFI_DII
|
||||
// TestRIG expects us throw an access fault for any memory access outside of a 8 MiB memory at 0x8000000.
|
||||
if (!isValid(cause) && (paddr < 'h80000000 || paddr >= 'h80800000)) begin
|
||||
case(x.mem_func)
|
||||
Ld, Lr: begin
|
||||
cause = Valid(Exception(excLoadAccessFault));
|
||||
end
|
||||
default: begin
|
||||
cause = Valid(Exception(excStoreAccessFault));
|
||||
end
|
||||
endcase
|
||||
end
|
||||
`endif
|
||||
// `ifdef RVFI_DII
|
||||
// // TestRIG expects us throw an access fault for any memory access outside of a 8 MiB memory at 0x8000000.
|
||||
// if (!isValid(cause) && (paddr < 'h80000000 || paddr >= 'h80800000)) begin
|
||||
// case(tlbresp.mem_func)
|
||||
// Ld, Lr: begin
|
||||
// cause = Valid(Exception(excLoadAccessFault));
|
||||
// end
|
||||
// default: begin
|
||||
// cause = Valid(Exception(excStoreAccessFault));
|
||||
// end
|
||||
// endcase
|
||||
// end
|
||||
// `endif
|
||||
|
||||
// check if addr is MMIO (only valid in case of no page fault)
|
||||
Bool isMMIO = inIfc.isMMIOAddr(paddr);
|
||||
// raise access fault in case of MMIO Lr/Sc
|
||||
if(!isValid(cause) && isMMIO) begin
|
||||
case(x.mem_func)
|
||||
case(lol.mem_func)
|
||||
Lr: begin
|
||||
cause = Valid(Exception(excLoadAccessFault));
|
||||
end
|
||||
@@ -706,40 +790,42 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
|
||||
// update ROB (access at commit and non-mmio st done can only be true
|
||||
// when there is no exceptio)
|
||||
Bool isLrScAmo = (case(x.mem_func)
|
||||
Bool isLrScAmo = (case(lol.mem_func)
|
||||
Lr, Sc, Amo: True;
|
||||
default: False;
|
||||
endcase);
|
||||
if (x.check matches tagged Valid .check &&& x.capException matches tagged Invalid) begin
|
||||
if (check matches tagged Valid .check &&& capException matches tagged Invalid) begin
|
||||
if (!( (check.check_low >= check.authority_base) &&
|
||||
(check.check_inclusive ? (check.check_high <= check.authority_top )
|
||||
: (check.check_high < check.authority_top ))))
|
||||
x.capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: cheriExcLengthViolation});
|
||||
capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: cheriExcLengthViolation});
|
||||
end
|
||||
if (x.capException matches tagged Valid .c) cause = Valid(CapException(c));
|
||||
if (capException matches tagged Valid .c) cause = Valid(CapException(c));
|
||||
Bool access_at_commit = !isValid(cause) && (isMMIO || isLrScAmo);
|
||||
Bool non_mmio_st_done = !isValid(cause) && !isMMIO && x.mem_func == St;
|
||||
inIfc.rob_setExecuted_doFinishMem(x.tag, getAddr(x.vaddr),
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data, store_data_BE,
|
||||
`endif
|
||||
// Bool access_at_commit = True;
|
||||
Bool non_mmio_st_done = !isValid(cause) && !isMMIO && lol.mem_func == St;
|
||||
// Bool non_mmio_st_done = !isMMIO && lol.mem_func == St;
|
||||
inIfc.rob_setExecuted_doFinishMem(lol.tag, getAddr(lol.vaddr),
|
||||
// `ifdef INCLUDE_TANDEM_VERIF
|
||||
// store_data, store_data_BE,
|
||||
// `endif
|
||||
access_at_commit, non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle{
|
||||
regWriteData: memData[pack(x.ldstq_tag)],
|
||||
memByteEn: unpack(truncate(pack(x.shiftedBE.DataMemAccess) >> getAddr(x.vaddr)[3:0]))
|
||||
}
|
||||
`endif
|
||||
// , ExtraTraceBundle{
|
||||
// regWriteData: memData[pack(tlbresp.ldstq_tag)],
|
||||
// memByteEn: unpack(truncate(pack(tlbresp.shiftedBE.DataMemAccess) >> getAddr(tlbresp.vaddr)[3:0]))
|
||||
// }
|
||||
// `endif
|
||||
);
|
||||
|
||||
let pc = inIfc.rob_getPC(x.tag);
|
||||
let pc = inIfc.rob_getPC(lol.tag);
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
`ifdef CONTRACTS_VERIFY
|
||||
function Bool is_16b_inst (Bit #(n) inst);
|
||||
return (inst [1:0] != 2'b11);
|
||||
endfunction
|
||||
let ppc = inIfc.rob_getPredPC(x.tag);
|
||||
let inst = inIfc.rob_getOrig_Inst(x.tag);
|
||||
let ppc = inIfc.rob_getPredPC(lol.tag);
|
||||
let inst = inIfc.rob_getOrig_Inst(lol.tag);
|
||||
let validPc = is_16b_inst(inst) ? addPc(pc,2) : addPc(pc,4);
|
||||
if(cause matches tagged Valid .c &&& (ppc != validPc)) begin
|
||||
EventsTransExe events_trans = unpack(0);
|
||||
@@ -749,23 +835,33 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
`endif
|
||||
`endif
|
||||
|
||||
`ifdef KONATA
|
||||
$display("KONATAE\t%0d\t%0d\t0\tMem3", cur_cycle, x.u_id);
|
||||
$display("KONATAS\t%0d\t%0d\t0\tMem4", cur_cycle, x.u_id);
|
||||
$fflush;
|
||||
`endif
|
||||
// `ifdef KONATA
|
||||
// $display("KONATAE\t%0d\t%0d\t0\tMem3", cur_cycle, tlbresp.u_id);
|
||||
// $display("KONATAS\t%0d\t%0d\t0\tMem4", cur_cycle, tlbresp.u_id);
|
||||
// $fflush;
|
||||
// `endif
|
||||
// Try me!
|
||||
// if (x.mem_func == St) begin
|
||||
// paddr = 256;
|
||||
// end
|
||||
|
||||
// update LSQ
|
||||
// Important bit that updates memory ?
|
||||
// LSQUpdateAddrResult updRes <- lsq.updateAddr(
|
||||
// lol.ldstq_tag, cause, allowCapLoad && allowCapPTE, paddr, isMMIO, shiftBE
|
||||
// );
|
||||
LSQUpdateAddrResult updRes <- lsq.updateAddr(
|
||||
x.ldstq_tag, cause, x.allowCapLoad && allowCapPTE, paddr, isMMIO, x.shiftedBE
|
||||
lol.ldstq_tag, cause, allowCapLoad && allowCapPTE, paddr, isMMIO, shiftBE
|
||||
);
|
||||
|
||||
|
||||
// issue non-MMIO Ld which has no exception and is not waiting for
|
||||
// wrong path resp
|
||||
if (x.mem_func == Ld && !isMMIO &&
|
||||
if (lol.mem_func == Ld && !isMMIO &&
|
||||
!isValid(cause) && !updRes.waitWPResp
|
||||
&& !updRes.delayIssue) begin
|
||||
LdQTag ldTag = ?;
|
||||
if(x.ldstq_tag matches tagged Ld .t) begin
|
||||
if(lol.ldstq_tag matches tagged Ld .t) begin
|
||||
ldTag = t;
|
||||
end
|
||||
else begin
|
||||
@@ -774,7 +870,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
issueLd.wset(LSQIssueLdInfo {
|
||||
tag: ldTag,
|
||||
paddr: paddr,
|
||||
shiftedBE: x.shiftedBE,
|
||||
shiftedBE: shiftBE,
|
||||
pcHash: hash(getAddr(pc))
|
||||
});
|
||||
end
|
||||
@@ -1467,7 +1563,6 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
// MMIO may cause exception, must have spec tag, and only can be St/Amo
|
||||
doAssert(lsqDeqSt.memFunc == St || lsqDeqSt.memFunc == Amo, "must be St/Amo");
|
||||
`ifdef PERF_COUNT
|
||||
$display(inIfc.doStats);
|
||||
if(inIfc.doStats) begin
|
||||
if(lsqDeqSt.acq) begin
|
||||
exeLrScAmoAcqCnt.incr(1);
|
||||
|
||||
@@ -144,7 +144,7 @@ typedef union tagged {
|
||||
module mkDTlb#(
|
||||
function TlbReq getTlbReq(instT inst)
|
||||
)(DTlb::DTlb#(instT)) provisos(Bits#(instT, a__));
|
||||
Bool verbose = False;
|
||||
Bool verbose = True;
|
||||
|
||||
// TLB array
|
||||
DTlbArray tlb <- mkDTlbArray;
|
||||
|
||||
Reference in New Issue
Block a user