Skip to content

Commit

Permalink
[racl] Add RACL support for mbx
Browse files Browse the repository at this point in the history
Signed-off-by: David Schrammel <[email protected]>
  • Loading branch information
davidschrammel committed Jan 24, 2025
1 parent 9361fb9 commit 09155b6
Show file tree
Hide file tree
Showing 8 changed files with 1,117 additions and 130 deletions.
32 changes: 31 additions & 1 deletion hw/ip/mbx/data/mbx.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
bus_interfaces: [
{ protocol: "tlul", direction: "device", name: "core" }
{ protocol: "tlul", direction: "host", name: "sram" }
{ protocol: "tlul", direction: "device", name: "soc" }
{ protocol: "tlul", direction: "device", name: "soc", racl_support: true }
]
inter_signal_list: [
{ struct: "logic",
Expand Down Expand Up @@ -52,6 +52,36 @@
package: "",
default: "1'b0"
}
{ struct: "racl_policy_vec",
type: "uni",
name: "racl_policies",
act: "rcv",
package: "top_racl_pkg",
desc: '''
Incoming RACL policy vector from a racl_ctrl instance.
The policy selection vector (parameter) selects the policy for each register.
'''
}
{ struct: "logic",
type: "uni",
name: "racl_error",
act: "req",
width : "1",
desc: '''
RACL error indication signal.
If 1, the error log contains valid information.
'''
}
{ struct: "racl_error_log",
type: "uni",
name: "racl_error_log",
act: "req",
width: "1"
package: "top_racl_pkg",
desc: '''
RACL error log information of this module.
'''
}
]
interrupt_list: [
{ name: "mbx_ready"
Expand Down
1 change: 1 addition & 0 deletions hw/ip/mbx/mbx.core
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ filesets:
- lowrisc:prim:all
- lowrisc:tlul:headers
- lowrisc:ip:tlul
- lowrisc:systems:top_racl_pkg
files:
- rtl/mbx_reg_pkg.sv
- rtl/mbx.sv
Expand Down
43 changes: 31 additions & 12 deletions hw/ip/mbx/rtl/mbx.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ module mbx
import tlul_pkg::*;
import mbx_reg_pkg::*;
#(
parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}},
parameter int unsigned CfgSramAddrWidth = 32,
parameter int unsigned CfgSramDataWidth = 32,
parameter int unsigned CfgObjectSizeWidth = 11,
parameter bit DoeIrqSupport = 1'b1,
parameter bit DoeAsyncMsgSupport = 1'b1
parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}},
parameter int unsigned CfgSramAddrWidth = 32,
parameter int unsigned CfgSramDataWidth = 32,
parameter int unsigned CfgObjectSizeWidth = 11,
parameter bit DoeIrqSupport = 1'b1,
parameter bit DoeAsyncMsgSupport = 1'b1,
parameter bit EnableRacl = 1'b0,
parameter bit RaclErrorRsp = 1'b1,
parameter int unsigned RaclPolicySelVecSoc[4] = '{4{0}},
parameter int unsigned RaclPolicySelWinSocWDATA = 0,
parameter int unsigned RaclPolicySelWinSocRDATA = 0
) (
input logic clk_i,
input logic rst_ni,
Expand All @@ -29,6 +34,10 @@ module mbx
// Alerts
input prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i,
output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o,
// RACL interface
input top_racl_pkg::racl_policy_vec_t racl_policies_i,
output logic racl_error_o,
output top_racl_pkg::racl_error_log_t racl_error_log_o,
// Device port facing OpenTitan
input tlul_pkg::tl_h2d_t core_tl_d_i,
output tlul_pkg::tl_d2h_t core_tl_d_o,
Expand Down Expand Up @@ -184,10 +193,15 @@ module mbx
assign mbx_error_set = hostif_control_error_set | imbx_overflow_error_set;

mbx_sysif #(
.CfgSramAddrWidth ( CfgSramAddrWidth ),
.CfgSramDataWidth ( CfgSramDataWidth ),
.DoeIrqSupport ( DoeIrqSupport ),
.DoeAsyncMsgSupport ( DoeAsyncMsgSupport )
.CfgSramAddrWidth ( CfgSramAddrWidth ),
.CfgSramDataWidth ( CfgSramDataWidth ),
.DoeIrqSupport ( DoeIrqSupport ),
.DoeAsyncMsgSupport ( DoeAsyncMsgSupport ),
.EnableRacl ( EnableRacl ),
.RaclErrorRsp ( RaclErrorRsp ),
.RaclPolicySelVecSoc ( RaclPolicySelVecSoc ),
.RaclPolicySelWinSocWDATA ( RaclPolicySelWinSocWDATA ),
.RaclPolicySelWinSocRDATA ( RaclPolicySelWinSocRDATA )
) u_sysif (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
Expand Down Expand Up @@ -229,7 +243,11 @@ module mbx
.write_data_o ( sysif_write_data ),
.read_data_read_valid_o ( sysif_read_data_read_valid ),
.read_data_write_valid_o ( sysif_read_data_write_valid ),
.read_data_i ( sysif_read_data )
.read_data_i ( sysif_read_data ),
// RACL interface
.racl_policies_i ( racl_policies_i ),
.racl_error_o ( racl_error_o ),
.racl_error_log_o ( racl_error_o )
);


Expand Down Expand Up @@ -355,5 +373,6 @@ module mbx
`ASSERT_KNOWN(CoreTlAReadyKnownO_A, core_tl_d_o.a_ready)
`ASSERT_KNOWN(SocTlDValidKnownO_A, soc_tl_d_o.d_valid)
`ASSERT_KNOWN(SocTlAReadyKnownO_A, soc_tl_d_o.a_ready)

`ASSERT_KNOWN(RaclErrorKnown_A, racl_error_o)
`ASSERT_KNOWN(RaclErrorLogKnown_A, racl_error_log_o)
endmodule
93 changes: 78 additions & 15 deletions hw/ip/mbx/rtl/mbx_soc_reg_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@

`include "prim_assert.sv"

module mbx_soc_reg_top (
module mbx_soc_reg_top
# (
parameter bit EnableRacl = 1'b0,
parameter bit RaclErrorRsp = 1'b1,
parameter int unsigned RaclPolicySelVec[4] = '{4{0}}
) (
input clk_i,
input rst_ni,
input tlul_pkg::tl_h2d_t tl_i,
Expand All @@ -20,6 +25,11 @@ module mbx_soc_reg_top (
output mbx_reg_pkg::mbx_soc_reg2hw_t reg2hw, // Write
input mbx_reg_pkg::mbx_soc_hw2reg_t hw2reg, // Read

// RACL interface
input top_racl_pkg::racl_policy_vec_t racl_policies_i,
output logic racl_error_o,
output top_racl_pkg::racl_error_log_t racl_error_log_o,

// Integrity check errors
output logic intg_err_o
);
Expand Down Expand Up @@ -162,7 +172,8 @@ module mbx_soc_reg_top (
.be_o (reg_be),
.busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
// Translate RACL error to TLUL error if enabled
.error_i (reg_error | (RaclErrorRsp & racl_error_o))
);

// cdc oversampling signals
Expand Down Expand Up @@ -460,28 +471,78 @@ module mbx_soc_reg_top (


logic [3:0] addr_hit;
top_racl_pkg::racl_role_vec_t racl_role_vec;
top_racl_pkg::racl_role_t racl_role;

logic [3:0] racl_addr_hit_read;
logic [3:0] racl_addr_hit_write;

if (EnableRacl) begin : gen_racl_role_logic
// Retrieve RACL role from user bits and one-hot encode that for the comparison bitmap
assign racl_role = top_racl_pkg::tlul_extract_racl_role_bits(tl_i.a_user.rsvd);

prim_onehot_enc #(
.OneHotWidth( $bits(top_racl_pkg::racl_role_vec_t) )
) u_racl_role_encode (
.in_i ( racl_role ),
.en_i ( 1'b1 ),
.out_o( racl_role_vec )
);
end else begin : gen_no_racl_role_logic
assign racl_role = '0;
assign racl_role_vec = '0;
end

always_comb begin
addr_hit = '0;
racl_addr_hit_read = '0;
racl_addr_hit_write = '0;
addr_hit[0] = (reg_addr == MBX_SOC_CONTROL_OFFSET);
addr_hit[1] = (reg_addr == MBX_SOC_STATUS_OFFSET);
addr_hit[2] = (reg_addr == MBX_SOC_DOE_INTR_MSG_ADDR_OFFSET);
addr_hit[3] = (reg_addr == MBX_SOC_DOE_INTR_MSG_DATA_OFFSET);

if (EnableRacl) begin : gen_racl_hit
for (int unsigned slice_idx = 0; slice_idx < 4; slice_idx++) begin
racl_addr_hit_read[slice_idx] =
addr_hit[slice_idx] & (|(racl_policies_i[RaclPolicySelVec[slice_idx]].read_perm
& racl_role_vec));
racl_addr_hit_write[slice_idx] =
addr_hit[slice_idx] & (|(racl_policies_i[RaclPolicySelVec[slice_idx]].write_perm
& racl_role_vec));
end
end else begin : gen_no_racl
racl_addr_hit_read = addr_hit;
racl_addr_hit_write = addr_hit;
end
end

assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
// A valid address hit but failed the RACL check
assign racl_error_o = tl_i.a_valid &
(|addr_hit) & ~(|(addr_hit & (racl_addr_hit_read | racl_addr_hit_write)));
assign racl_error_log_o.racl_role = racl_role;

if (EnableRacl) begin : gen_racl_log
assign racl_error_log_o.ctn_uid = top_racl_pkg::tlul_extract_ctn_uid_bits(tl_i.a_user.rsvd);
assign racl_error_log_o.read_access = tl_i.a_opcode == tlul_pkg::Get;
end else begin : gen_no_racl_log
assign racl_error_log_o.ctn_uid = '0;
assign racl_error_log_o.read_access = 1'b0;
end

// Check sub-word write is permitted
always_comb begin
wr_err = (reg_we &
((addr_hit[0] & (|(MBX_SOC_PERMIT[0] & ~reg_be))) |
(addr_hit[1] & (|(MBX_SOC_PERMIT[1] & ~reg_be))) |
(addr_hit[2] & (|(MBX_SOC_PERMIT[2] & ~reg_be))) |
(addr_hit[3] & (|(MBX_SOC_PERMIT[3] & ~reg_be)))));
((racl_addr_hit_write[0] & (|(MBX_SOC_PERMIT[0] & ~reg_be))) |
(racl_addr_hit_write[1] & (|(MBX_SOC_PERMIT[1] & ~reg_be))) |
(racl_addr_hit_write[2] & (|(MBX_SOC_PERMIT[2] & ~reg_be))) |
(racl_addr_hit_write[3] & (|(MBX_SOC_PERMIT[3] & ~reg_be)))));
end

// Generate write-enables
assign soc_control_re = addr_hit[0] & reg_re & !reg_error;
assign soc_control_we = addr_hit[0] & reg_we & !reg_error;
assign soc_control_re = racl_addr_hit_write[0] & reg_re & !reg_error;
assign soc_control_we = racl_addr_hit_write[0] & reg_we & !reg_error;

assign soc_control_abort_wd = reg_wdata[0];

Expand All @@ -490,13 +551,13 @@ module mbx_soc_reg_top (
assign soc_control_doe_async_msg_en_wd = reg_wdata[3];

assign soc_control_go_wd = reg_wdata[31];
assign soc_status_we = addr_hit[1] & reg_we & !reg_error;
assign soc_status_we = racl_addr_hit_write[1] & reg_we & !reg_error;

assign soc_status_doe_intr_status_wd = reg_wdata[1];
assign soc_doe_intr_msg_addr_we = addr_hit[2] & reg_we & !reg_error;
assign soc_doe_intr_msg_addr_we = racl_addr_hit_write[2] & reg_we & !reg_error;

assign soc_doe_intr_msg_addr_wd = reg_wdata[31:0];
assign soc_doe_intr_msg_data_we = addr_hit[3] & reg_we & !reg_error;
assign soc_doe_intr_msg_data_we = racl_addr_hit_write[3] & reg_we & !reg_error;

assign soc_doe_intr_msg_data_wd = reg_wdata[31:0];

Expand All @@ -513,26 +574,26 @@ module mbx_soc_reg_top (
always_comb begin
reg_rdata_next = '0;
unique case (1'b1)
addr_hit[0]: begin
racl_addr_hit_read[0]: begin
reg_rdata_next[0] = '0;
reg_rdata_next[1] = soc_control_doe_intr_en_qs;
reg_rdata_next[3] = soc_control_doe_async_msg_en_qs;
reg_rdata_next[31] = '0;
end

addr_hit[1]: begin
racl_addr_hit_read[1]: begin
reg_rdata_next[0] = soc_status_busy_qs;
reg_rdata_next[1] = soc_status_doe_intr_status_qs;
reg_rdata_next[2] = soc_status_error_qs;
reg_rdata_next[3] = soc_status_doe_async_msg_status_qs;
reg_rdata_next[31] = soc_status_ready_qs;
end

addr_hit[2]: begin
racl_addr_hit_read[2]: begin
reg_rdata_next[31:0] = soc_doe_intr_msg_addr_qs;
end

addr_hit[3]: begin
racl_addr_hit_read[3]: begin
reg_rdata_next[31:0] = soc_doe_intr_msg_data_qs;
end

Expand All @@ -557,6 +618,8 @@ module mbx_soc_reg_top (
logic unused_be;
assign unused_wdata = ^reg_wdata;
assign unused_be = ^reg_be;
logic unused_policy_sel;
assign unused_policy_sel = ^racl_policies_i;

// Assertions for Register Interface
`ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
Expand Down
Loading

0 comments on commit 09155b6

Please sign in to comment.