@@ -526,6 +526,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
526526`endif
527527 Reg # ( WordXL) rg_addr < - mkRegU; // VA or PA
528528 Reg # ( Tuple2# ( Bool , Bit # ( 128 ))) rg_st_amo_val < - mkRegU; // Store-value for ST, SC, AMO
529+ Reg # ( Bool ) rg_allow_cap < - mkRegU; // Whether load result is allowed to be tagged by VM page bits
529530
530531 // The following are needed for VM
531532`ifdef ISA_PRIV_S
@@ -583,9 +584,9 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
583584 Reg # ( Bool ) dw_exc < - mkDWire ( False ) ;
584585 Reg # ( Exc_Code) rg_exc_code < - mkRegU;
585586 Reg # ( Exc_Code) dw_exc_code < - mkDWire ( ? ) ;
586- Reg # ( Tuple2# ( Bool , Bit # ( 128 ))) rg_ld_val < - mkRegU ; // Load-value for LOAD/LR/AMO, success/fail for SC
587- Reg # ( Tuple2# ( Bool , Bit # ( 128 ))) dw_output_ld_val < - mkDWire ( ? ) ;
588- Reg # ( Tuple2# ( Bool , Bit # ( 128 ))) dw_output_st_amo_val < - mkDWire ( ? ) ; // stored value for ST, SC, AMO (for verification only)
587+ Reg # ( Tuple2# ( Bool , Bit # ( 128 ))) rg_ld_val < - mkReg ( tuple2 ( False , ? )) ; // Load-value for LOAD/LR/AMO, success/fail for SC
588+ Reg # ( Tuple2# ( Bool , Bit # ( 128 ))) dw_output_ld_val < - mkDWire ( tuple2 ( False , ? ) );
589+ Reg # ( Tuple2# ( Bool , Bit # ( 128 ))) dw_output_st_amo_val < - mkDWire ( tuple2 ( False , ? ) ); // stored value for ST, SC, AMO (for verification only)
589590
590591 // This reg is used during PTWs
591592 Reg # ( PA) rg_pte_pa < - mkRegU;
@@ -685,11 +686,13 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
685686 // Functions to drive read-responses (outputs)
686687
687688 // Memory-read responses
688- function Action fa_drive_mem_rsp ( Bit # ( 3 ) width_code, Bool is_unsigned, Addr addr, Cache_Entry ld_val, Cache_Entry st_amo_val, Bool commit) ;
689+ function Action fa_drive_mem_rsp ( Bit # ( 3 ) width_code, Bool is_unsigned, Addr addr, Cache_Entry ld_val, Cache_Entry st_amo_val, Bool allow_cap , Bool commit) ;
689690 action
690691 dw_valid <= commit;
691692 // Value loaded into rd (LOAD, LR, AMO, SC success/fail result)
692- dw_output_ld_val <= fn_extract_and_extend_bytes ( width_code, is_unsigned, addr, ld_val) ;
693+ let extracted = fn_extract_and_extend_bytes ( width_code, is_unsigned, addr, ld_val) ;
694+ if ( ! allow_cap) extracted = tuple2( False , tpl_2( extracted)) ;
695+ dw_output_ld_val <= extracted;
693696 // Value stored into mem (STORE, SC, AMO final value stored)
694697 dw_output_st_amo_val <= tuple2( tpl_1( st_amo_val) [ ( valueOf( CLEN) == 64 && addr[ 4 : 0 ] == 0 ) ? 1 : 0 ] == 1'b1 , tpl_2( st_amo_val)) ;
695698 if ( cfg_verbosity > 1 )
@@ -699,10 +702,11 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
699702 endfunction
700703
701704 // IO-read responses
702- function Action fa_drive_IO_read_rsp ( Bit # ( 3 ) width_code, Bool is_unsigned, Addr addr, Tuple2# ( Bool , Bit # ( 128 )) ld_val) ;
705+ function Action fa_drive_IO_read_rsp ( Bit # ( 3 ) width_code, Bool is_unsigned, Addr addr, Tuple2# ( Bool , Bit # ( 128 )) ld_val, Bool allow_cap ) ;
703706 action
704707 dw_valid <= True ;
705708 // Value loaded into rd (LOAD, LR, AMO, SC success/fail result)
709+ if ( ! allow_cap) ld_val = tuple2( False , tpl_2( ld_val)) ;
706710 dw_output_ld_val <= ld_val;
707711 if ( cfg_verbosity > 1 )
708712 $display ( " %0d: %s.drive_IO_read_rsp: addr 0x%0h ld_val 0x%0h" , cur_cycle, d_or_i, addr, ld_val) ;
@@ -936,6 +940,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
936940 tlb_result,
937941 dmem_not_imem,
938942 (( rg_op == CACHE_LD) || is_AMO_LR) ,
943+ tpl_1( rg_st_amo_val) ,
939944 rg_priv,
940945 rg_sstatus_SUM,
941946 rg_mstatus_MXR) ;
@@ -967,6 +972,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
967972`endif
968973
969974 rg_pa <= vm_xlate_result.pa;
975+ rg_allow_cap <= vm_xlate_result.allow_cap;
970976 let is_mem_addr = soc_map.m_is_mem_addr ( fn_PA_to_Fabric_Addr ( vm_xlate_result.pa)) ;
971977
972978 // Access to non-memory
@@ -989,7 +995,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
989995 if (( rg_op == CACHE_LD) || is_AMO_LR || ( ! dmem_not_imem)) begin
990996 if ( hit) begin
991997 // Cache hit; drive response
992- fa_drive_mem_rsp ( rg_width_code, rg_is_unsigned, rg_addr, word128, unpack( 0 ) , dw_commit) ;
998+ fa_drive_mem_rsp ( rg_width_code, rg_is_unsigned, rg_addr, word128, unpack( 0 ) , vm_xlate_result.allow_cap , dw_commit) ;
993999
9941000`ifdef ISA_A
9951001 if ( is_AMO_LR) begin
@@ -1091,7 +1097,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
10911097 else begin // do_write == False
10921098 // SC fail
10931099 // Hard-code address to 0 to ensure fn_extract_and_extend_bytes takes the LSBs of our 1 value.
1094- fa_drive_mem_rsp ( rg_width_code, rg_is_unsigned, 0 , tuple2( 0 , 1 ) , unpack( 0 ) , dw_commit) ;
1100+ fa_drive_mem_rsp ( rg_width_code, rg_is_unsigned, 0 , tuple2( 0 , 1 ) , unpack( 0 ) , False , dw_commit) ;
10951101 if ( cfg_verbosity > 1 )
10961102 $display ( " AMO SC: Fail response for addr 0x%0h" , rg_addr) ;
10971103 end
@@ -1635,7 +1641,9 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
16351641
16361642 rule rl_ST_AMO_response ( rg_state == CACHE_ST_AMO_RSP && dmem_not_imem) ;
16371643 dw_valid <= True ;
1638- dw_output_ld_val <= rg_ld_val; // Irrelevant for ST; relevant for SC, AMO
1644+ let ld_val = rg_ld_val;
1645+ if ( ! rg_allow_cap) ld_val = tuple2( False , tpl_2( ld_val)) ;
1646+ dw_output_ld_val <= ld_val; // Irrelevant for ST; relevant for SC, AMO
16391647 dw_output_st_amo_val <= rg_st_amo_val;
16401648 endrule
16411649
@@ -1687,7 +1695,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
16871695
16881696 // Successful read
16891697 if ( rd_data.rresp == OKAY) begin
1690- fa_drive_IO_read_rsp ( rg_width_code, rg_is_unsigned, rg_addr, ld_val) ;
1698+ fa_drive_IO_read_rsp ( rg_width_code, rg_is_unsigned, rg_addr, ld_val, rg_allow_cap ) ;
16911699 rg_state <= IO_READ_RSP;
16921700 end
16931701
@@ -1705,7 +1713,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
17051713 rg_lower_word64 <= rd_data.rdata;
17061714 end else begin // rg_lower_word64_full && rd_data.rlast
17071715 if ( rd_data.rresp == OKAY) begin
1708- fa_drive_IO_read_rsp( rg_width_code, rg_is_unsigned, rg_addr, tuple2( False , { rd_data.rdata, rg_lower_word64} )) ; // No tags from IO mem
1716+ fa_drive_IO_read_rsp( rg_width_code, rg_is_unsigned, rg_addr, tuple2( False , { rd_data.rdata, rg_lower_word64} ) , rg_allow_cap ) ; // No tags from IO mem
17091717 rg_ld_val <= tuple2( False , { rd_data.rdata, rg_lower_word64} ) ;
17101718 rg_lower_word64_full <= False ;
17111719 end else begin
@@ -1724,7 +1732,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
17241732 // Stays in this state until CPU's next request puts it back into RUNNING state
17251733
17261734 rule rl_maintain_io_read_rsp ( ! resetting && rg_state == IO_READ_RSP && dmem_not_imem) ;
1727- fa_drive_IO_read_rsp ( rg_width_code, rg_is_unsigned, rg_addr, rg_ld_val) ;
1735+ fa_drive_IO_read_rsp ( rg_width_code, rg_is_unsigned, rg_addr, rg_ld_val, rg_allow_cap ) ;
17281736 endrule
17291737
17301738 // ----------------------------------------------------------------
@@ -1838,7 +1846,7 @@ module mkMMU_Cache #(parameter Bool dmem_not_imem,
18381846 // Write back new st_val to fabric
18391847 fa_fabric_send_write_req ( rg_width_code, rg_pa, new_st_val) ;
18401848
1841- fa_drive_IO_read_rsp ( rg_width_code, rg_is_unsigned, rg_addr, new_ld_val) ;
1849+ fa_drive_IO_read_rsp ( rg_width_code, rg_is_unsigned, rg_addr, new_ld_val, rg_allow_cap ) ;
18421850 rg_ld_val <= new_ld_val;
18431851 rg_state <= IO_READ_RSP;
18441852
0 commit comments