From 8b72ccfab178c5cf61a84898f7c2206047a98122 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 16 Jan 2025 15:00:28 +0100 Subject: [PATCH] [hw,ac_range_check,rtl] Add RACL checks to the AC Range Checks Signed-off-by: Robert Schilling --- .../ac_range_check/ac_range_check.core.tpl | 1 + .../data/ac_range_check.hjson.tpl | 17 ++++++++- .../data/ac_range_check.tpldesc.hjson | 12 ++++++ .../ac_range_check/rtl/ac_range_check.sv.tpl | 38 +++++++++++++++---- util/topgen.py | 2 + 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/hw/ip_templates/ac_range_check/ac_range_check.core.tpl b/hw/ip_templates/ac_range_check/ac_range_check.core.tpl index d4f7d3bab0d3a..4f175cb1a48a5 100644 --- a/hw/ip_templates/ac_range_check/ac_range_check.core.tpl +++ b/hw/ip_templates/ac_range_check/ac_range_check.core.tpl @@ -13,6 +13,7 @@ filesets: - lowrisc:ip:tlul - lowrisc:prim:mubi - lowrisc:prim:all + - lowrisc:systems:top_racl_pkg files: - rtl/${module_instance_name}_reg_pkg.sv - rtl/${module_instance_name}_reg_top.sv diff --git a/hw/ip_templates/ac_range_check/data/ac_range_check.hjson.tpl b/hw/ip_templates/ac_range_check/data/ac_range_check.hjson.tpl index 9ecc01eb29641..2ad71d9c45132 100644 --- a/hw/ip_templates/ac_range_check/data/ac_range_check.hjson.tpl +++ b/hw/ip_templates/ac_range_check/data/ac_range_check.hjson.tpl @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 // +<% +import math +%>\ # AC Range Check register template { name: "ac_range_check" @@ -122,12 +125,22 @@ swaccess: "ro" hwaccess: "hwo" fields: [ - { bits: "22:18" +<% + denied_ctn_uid_lsb = 14 + nr_role_bits + deny_range_index_lsb = denied_ctn_uid_lsb + nr_ctn_uid_bits + deny_range_index_size = math.ceil(math.log(num_ranges, 2)) +%>\ + { bits: "${deny_range_index_lsb+deny_range_index_size-1}:${deny_range_index_lsb}" name: "deny_range_index" resval: 0x0 desc: "Index of the range that caused the denied access." } - { bits: "17:14" + { bits: "${deny_range_index_lsb-1}:${denied_ctn_uid_lsb}" + name: "denied_ctn_uid" + resval: 0x0 + desc: "Source CTN UID that was denied access." + } + { bits: "${denied_ctn_uid_lsb-1}:14" name: "denied_source_role" resval: 0x0 desc: "Source RACL role that was denied access." diff --git a/hw/ip_templates/ac_range_check/data/ac_range_check.tpldesc.hjson b/hw/ip_templates/ac_range_check/data/ac_range_check.tpldesc.hjson index fb65ec872a80b..efbf4b09ec175 100644 --- a/hw/ip_templates/ac_range_check/data/ac_range_check.tpldesc.hjson +++ b/hw/ip_templates/ac_range_check/data/ac_range_check.tpldesc.hjson @@ -21,5 +21,17 @@ type: "int", default: "32", } + { + name: "nr_role_bits", + desc: "Number of RACL bits", + type: "int", + default: "4", + } + { + name: "nr_ctn_uid_bits", + desc: "Number of CTN UID bits", + type: "int", + default: "5", + } ] } diff --git a/hw/ip_templates/ac_range_check/rtl/ac_range_check.sv.tpl b/hw/ip_templates/ac_range_check/rtl/ac_range_check.sv.tpl index 16cd4af6eeb97..890a47bd00551 100644 --- a/hw/ip_templates/ac_range_check/rtl/ac_range_check.sv.tpl +++ b/hw/ip_templates/ac_range_check/rtl/ac_range_check.sv.tpl @@ -84,8 +84,20 @@ module ${module_instance_name} ////////////////////////////////////////////////////////////////////////////// logic [NumRanges-1:0] addr_hit, deny_mask, read_mask, write_mask, execute_mask, log_enable_mask; + logic [NumRanges-1:0] racl_read_hit, racl_write_hit; + + // Retrieve RACL role from user bits and one-hot encode that for the comparison bitmap + top_racl_pkg::racl_role_vec_t racl_role_vec; + assign racl_role = top_racl_pkg::tlul_extract_racl_role_bits(ctn_tl_h2d_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 ) + ); - // TODO(#25454): RACL checks get implemented once RACL is in for (int i = 0; i < NumRanges; i++) begin : gen_range_checks // Extend base, limit, and mask to 32-bit logic [31:0] base_ext, limit_ext; @@ -101,14 +113,21 @@ module ${module_instance_name} assign addr_hit[i] = prim_mubi_pkg::mubi4_test_true_loose(reg2hw.range_perm[i].enable.q) & tor_hit; + // Perform RACL checks - check if the incoming role matches with the configured policy + assign racl_read_hit [i] = |(racl_role_vec & reg2hw.range_racl_policy_shadowed[i].read_perm.q) + assign racl_write_hit[i] = |(racl_role_vec & reg2hw.range_racl_policy_shadowed[i].write_perm.q) + // Decode the multi-bit access fields for convinient access logic perm_read_access, perm_write_access, perm_execute_access; assign perm_read_access = - prim_mubi_pkg::mubi4_test_true_strict(reg2hw.range_perm[i].read_access.q); + prim_mubi_pkg::mubi4_test_true_strict(reg2hw.range_perm[i].read_access.q) & + racl_read_hit[i]; assign perm_write_access = - prim_mubi_pkg::mubi4_test_true_strict(reg2hw.range_perm[i].write_access.q); + prim_mubi_pkg::mubi4_test_true_strict(reg2hw.range_perm[i].write_access.q) & + racl_write_hit[i]; assign perm_execute_access = - prim_mubi_pkg::mubi4_test_true_strict(reg2hw.range_perm[i].execute_access.q); + prim_mubi_pkg::mubi4_test_true_strict(reg2hw.range_perm[i].execute_access.q) & + racl_read_hit[i]; // Access is denied if no read_, write_, or execute access is set in the permission mask // The permission masks need to be reversed to allow for the right priority order. @@ -117,8 +136,8 @@ module ${module_instance_name} addr_hit[i] & ~(perm_read_access | perm_write_access | perm_execute_access); // Determine the read, write, and execute mask. Store a hit in their index - assign read_mask[NumRanges - 1 - i] = addr_hit[i] & perm_read_access; - assign write_mask[NumRanges - 1 - i] = addr_hit[i] & perm_write_access; + assign read_mask [NumRanges - 1 - i] = addr_hit[i] & perm_read_access; + assign write_mask [NumRanges - 1 - i] = addr_hit[i] & perm_write_access; assign execute_mask[NumRanges - 1 - i] = addr_hit[i] & perm_execute_access; end @@ -224,9 +243,12 @@ module ${module_instance_name} assign hw2reg.log_status.denied_racl_write.de = log_first_deny | clear_log; assign hw2reg.log_status.denied_racl_write.d = '0; - // TODO(#25454): RACL status gets implemented once RACL is in assign hw2reg.log_status.denied_source_role.de = log_first_deny | clear_log; - assign hw2reg.log_status.denied_source_role.d = '0; + assign hw2reg.log_status.denied_source_role.d = racl_role; + + assign hw2reg.log_status.denied_ctn_uid.de = log_first_deny | clear_log; + assign hw2reg.log_status.denied_ctn_uid.d = + top_racl_pkg::tlul_extract_ctn_uid_bits(ctn_tl_h2d_i.a_user.rsvd); // TODO(#25456): Need to determine the index that caused the denial assign hw2reg.log_status.deny_range_index.de = log_first_deny | clear_log; diff --git a/util/topgen.py b/util/topgen.py index 47aa0486d2c0f..8b3cebbb94625 100755 --- a/util/topgen.py +++ b/util/topgen.py @@ -572,6 +572,8 @@ def generate_ac_range_check(topcfg: Dict[str, object], out_path: Path) -> None: # Get the AC Range Check instance ac_ranges = lib.find_module(topcfg['module'], 'ac_range_check') params = { + "nr_role_bits": 4, + "nr_ctn_uid_bits": 5, "num_ranges": topcfg['ac_range_check']['num_ranges'], "module_instance_name": ac_ranges['type'] }