From c6db5cf57c204198b872b47cc9d80a672b1ede0c Mon Sep 17 00:00:00 2001 From: KotorinMinami Date: Mon, 30 Dec 2024 08:43:17 +0800 Subject: [PATCH] add disable tlb option --- c_emulator/riscv_platform.c | 5 +++ c_emulator/riscv_platform.h | 1 + c_emulator/riscv_platform_impl.c | 1 + c_emulator/riscv_platform_impl.h | 1 + c_emulator/riscv_sim.c | 6 +++ model/riscv_platform.sail | 2 + model/riscv_vmem.sail | 63 +++++++++++++++++--------------- model/riscv_vmem_tlb.sail | 11 ++++-- 8 files changed, 57 insertions(+), 33 deletions(-) diff --git a/c_emulator/riscv_platform.c b/c_emulator/riscv_platform.c index e19008c51..520b6ceea 100644 --- a/c_emulator/riscv_platform.c +++ b/c_emulator/riscv_platform.c @@ -117,6 +117,11 @@ bool plat_enable_misaligned_access(unit u) return rv_enable_misaligned; } +bool plat_enable_tlb(unit u) +{ + return rv_enable_tlb; +} + bool plat_mtval_has_illegal_inst_bits(unit u) { return rv_mtval_has_illegal_inst_bits; diff --git a/c_emulator/riscv_platform.h b/c_emulator/riscv_platform.h index 8d8d8aaef..db86da0bc 100644 --- a/c_emulator/riscv_platform.h +++ b/c_emulator/riscv_platform.h @@ -24,6 +24,7 @@ uint64_t sys_vector_elen_exp(unit); bool plat_enable_dirty_update(unit); bool plat_enable_misaligned_access(unit); bool plat_mtval_has_illegal_inst_bits(unit); +bool plat_enable_tlb(unit); mach_bits sys_writable_hpm_counters(unit u); mach_bits plat_ram_base(unit); diff --git a/c_emulator/riscv_platform_impl.c b/c_emulator/riscv_platform_impl.c index fd7cbdc2c..60db2cf15 100644 --- a/c_emulator/riscv_platform_impl.c +++ b/c_emulator/riscv_platform_impl.c @@ -25,6 +25,7 @@ bool rv_enable_dirty_update = false; bool rv_enable_misaligned = false; bool rv_mtval_has_illegal_inst_bits = false; bool rv_enable_writable_fiom = true; +bool rv_enable_tlb = true; uint64_t rv_writable_hpm_counters = 0xFFFFFFFF; uint64_t rv_ram_base = UINT64_C(0x80000000); diff --git a/c_emulator/riscv_platform_impl.h b/c_emulator/riscv_platform_impl.h index dc472623a..c69ca27ec 100644 --- a/c_emulator/riscv_platform_impl.h +++ b/c_emulator/riscv_platform_impl.h @@ -29,6 +29,7 @@ extern bool rv_enable_dirty_update; extern bool rv_enable_misaligned; extern bool rv_mtval_has_illegal_inst_bits; extern bool rv_enable_writable_fiom; +extern bool rv_enable_tlb; extern uint64_t rv_writable_hpm_counters; extern uint64_t rv_ram_base; diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c index f394588e8..10564d789 100644 --- a/c_emulator/riscv_sim.c +++ b/c_emulator/riscv_sim.c @@ -60,6 +60,7 @@ enum { OPT_ENABLE_ZICBOZ, OPT_ENABLE_SSTC, OPT_CACHE_BLOCK_SIZE, + OPT_DISABLE_TLB, }; static bool do_dump_dts = false; @@ -160,6 +161,7 @@ static struct option options[] = { {"enable-zicbom", no_argument, 0, OPT_ENABLE_ZICBOM }, {"enable-zicboz", no_argument, 0, OPT_ENABLE_ZICBOZ }, {"cache-block-size", required_argument, 0, OPT_CACHE_BLOCK_SIZE }, + {"disable-tlb", no_argument, 0, OPT_DISABLE_TLB }, #ifdef SAILCOV {"sailcov-file", required_argument, 0, 'c' }, #endif @@ -450,6 +452,10 @@ static int process_args(int argc, char **argv) rv_enable_zfinx = true; rv_enable_fdext = false; break; + case OPT_DISABLE_TLB: + fprintf(stderr, "disabling TLB support.\n"); + rv_enable_tlb = false; + break; #ifdef SAILCOV case 'c': sailcov_file = strdup(optarg); diff --git a/model/riscv_platform.sail b/model/riscv_platform.sail index cde93f6e7..209442ff2 100644 --- a/model/riscv_platform.sail +++ b/model/riscv_platform.sail @@ -63,6 +63,8 @@ val plat_htif_tohost = pure {c: "plat_htif_tohost", lem: "plat_htif_tohost"} : u function plat_htif_tohost () = to_bits(physaddrbits_len, elf_tohost ()) // todo: fromhost +val plat_enable_tlb = pure "plat_enable_tlb" : unit -> bool + val phys_mem_segments : unit -> list((physaddrbits, physaddrbits)) function phys_mem_segments() = (plat_rom_base (), plat_rom_size ()) :: diff --git a/model/riscv_vmem.sail b/model/riscv_vmem.sail index 91155e23b..1fd8491f5 100644 --- a/model/riscv_vmem.sail +++ b/model/riscv_vmem.sail @@ -345,39 +345,44 @@ function translate_TLB_miss(sv_params : SV_Params, match ptw_result { PTW_Failure(f, ext_ptw) => TR_Failure(f, ext_ptw), PTW_Success(pAddr, pte, pteAddr, level, global, ext_ptw) => { - let ext_pte = msbs_of_PTE(sv_params, pte); - // Without TLBs, this 'match' expression can be replaced simply - // by: 'TR_Address(pAddr, ext_ptw)' (see TLB_NOTE above) - match update_PTE_Bits(sv_params, pte, ac) { - None() => { - add_to_TLB(asid, vAddr, pAddr, pte, pteAddr, level, global, - sv_params.vpn_size_bits, - pagesize_bits); - TR_Address(pAddr, ext_ptw) - }, - Some(pte') => - // See riscv_platform.sail - if not(plat_enable_dirty_update()) then - // pte needs dirty/accessed update but that is not enabled - TR_Failure(PTW_PTE_Update(), ext_ptw) - else { - // Writeback the PTE (which has new A/D bits) - let pte_phys_addr = physaddr(pteAddr[(physaddrbits_len - 1) .. 0]); - - match write_pte(pte_phys_addr, 2 ^ sv_params.log_pte_size_bytes, pte') { - MemValue(_) => { - add_to_TLB(asid, vAddr, pAddr, pte', pteAddr, level, global, - sv_params.vpn_size_bits, - pagesize_bits); - TR_Address(pAddr, ext_ptw) - }, - MemException(e) => - TR_Failure(PTW_Access(), ext_ptw) + if not(plat_enable_tlb()) then + // Without TLBs, this 'match' expression can be replaced simply + // by: 'TR_Address(pAddr, ext_ptw)' (see TLB_NOTE above) + TR_Address(pAddr, ext_ptw) + else { + // Add the new PTE to the TLB + let ext_pte = msbs_of_PTE(sv_params, pte); + match update_PTE_Bits(sv_params, pte, ac) { + None() => { + add_to_TLB(asid, vAddr, pAddr, pte, pteAddr, level, global, + sv_params.vpn_size_bits, + pagesize_bits); + TR_Address(pAddr, ext_ptw) + }, + Some(pte') => + // See riscv_platform.sail + if not(plat_enable_dirty_update()) then + // pte needs dirty/accessed update but that is not enabled + TR_Failure(PTW_PTE_Update(), ext_ptw) + else { + // Writeback the PTE (which has new A/D bits) + let pte_phys_addr = physaddr(pteAddr[(physaddrbits_len - 1) .. 0]); + + match write_pte(pte_phys_addr, 2 ^ sv_params.log_pte_size_bytes, pte') { + MemValue(_) => { + add_to_TLB(asid, vAddr, pAddr, pte', pteAddr, level, global, + sv_params.vpn_size_bits, + pagesize_bits); + TR_Address(pAddr, ext_ptw) + }, + MemException(e) => + TR_Failure(PTW_Access(), ext_ptw) + } } - } } } } + } } // PRIVATE diff --git a/model/riscv_vmem_tlb.sail b/model/riscv_vmem_tlb.sail index d066f1356..af19a9333 100644 --- a/model/riscv_vmem_tlb.sail +++ b/model/riscv_vmem_tlb.sail @@ -81,10 +81,13 @@ function flush_TLB_Entry(e : TLB_Entry, // PUBLIC: invoked in translate() [riscv_vmem.sail] function lookup_TLB (asid : asidbits, vaddr : bits(64)) -> option((tlb_index_range, TLB_Entry)) = { - let index = tlb_hash(vaddr); - match tlb[index] { - None() => None(), - Some(entry) => if match_TLB_Entry(entry, asid, vaddr) then Some((index, entry)) else None(), + if not (plat_enable_tlb()) then None() + else { + let index = tlb_hash(vaddr); + match tlb[index] { + None() => None(), + Some(entry) => if match_TLB_Entry(entry, asid, vaddr) then Some((index, entry)) else None(), + } } }