-
Notifications
You must be signed in to change notification settings - Fork 790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RACL] Implement config parsing, racl_ctrl, and reggen checks #25664
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// | ||
// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: | ||
// | ||
// util/topgen.py -t hw/top_darjeeling/data/top_darjeeling.hjson \ | ||
// -o hw/top_darjeeling/ \ | ||
// --rnd_cnst_seed \ | ||
// 1017106219537032642877583828875051302543807092889754935647094601236425074047 | ||
|
||
|
||
package top_racl_pkg; | ||
// Number of RACL policies used | ||
parameter int unsigned NrRaclPolicies = 1; | ||
|
||
// Number of RACL bits transferred | ||
parameter int unsigned NrRaclBits = 4; | ||
|
||
// Number of CTN UID bits transferred | ||
parameter int unsigned NrCtnUidBits = 8; | ||
|
||
// RACL role type binary encoded | ||
typedef logic [NrRaclBits-1:0] racl_role_t; | ||
|
||
// CTN UID assigned the bus originator | ||
typedef logic [NrCtnUidBits-1:0] ctn_uid_t; | ||
|
||
// RACL permission: A one-hot encoded role vector | ||
typedef logic [(2**NrRaclBits)-1:0] racl_role_vec_t; | ||
|
||
// RACL policy containing a read and write permission | ||
typedef struct packed { | ||
racl_role_vec_t read_perm; | ||
racl_role_vec_t write_perm; | ||
} racl_policy_t; | ||
|
||
// RACL policy vector for distributing RACL policies from the RACL widget to the subscribing IP | ||
typedef racl_policy_t [NrRaclPolicies-1:0] racl_policy_vec_t; | ||
|
||
// RACL information logged in case of a denial | ||
typedef struct packed { | ||
racl_role_t racl_role; | ||
ctn_uid_t ctn_uid; | ||
// 0: Write access, 1: Read access | ||
logic read_not_write; | ||
} racl_error_log_t; | ||
|
||
// Extract RACL role bits from the TLUL reserved user bits | ||
function automatic racl_role_t tlul_extract_racl_role_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); | ||
// Waive unused bits | ||
logic unused_rsvd_bits; | ||
unused_rsvd_bits = ^{rsvd}; | ||
|
||
return racl_role_t'(rsvd[11:8]); | ||
endfunction | ||
|
||
// Extract CTN UID bits from the TLUL reserved user bits | ||
function automatic ctn_uid_t tlul_extract_ctn_uid_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); | ||
// Waive unused bits | ||
logic unused_rsvd_bits; | ||
unused_rsvd_bits = ^{rsvd}; | ||
|
||
return ctn_uid_t'(rsvd[7:0]); | ||
endfunction | ||
|
||
|
||
endpackage |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
CAPI=2: | ||
# Copyright lowRISC contributors (OpenTitan project). | ||
# Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
name: "lowrisc:systems:top_darjeeling_racl_pkg:0.1" | ||
description: "Autogenerated top_darjeeling_racl_pkg used in RTL and DV." | ||
virtual: | ||
- lowrisc:systems:top_racl_pkg | ||
|
||
filesets: | ||
files_rtl: | ||
depend: | ||
- lowrisc:tlul:headers | ||
files: | ||
- rtl/autogen/top_racl_pkg.sv | ||
file_type: systemVerilogSource | ||
|
||
targets: | ||
default: &default_target | ||
filesets: | ||
- files_rtl |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// | ||
// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: | ||
// | ||
// util/topgen.py -t hw/top_earlgrey/data/top_earlgrey.hjson \ | ||
// -o hw/top_earlgrey/ \ | ||
// --rnd_cnst_seed \ | ||
// 1017106219537032642877583828875051302543807092889754935647094601236425074047 | ||
|
||
|
||
package top_racl_pkg; | ||
// Number of RACL policies used | ||
parameter int unsigned NrRaclPolicies = 1; | ||
|
||
// Number of RACL bits transferred | ||
parameter int unsigned NrRaclBits = 4; | ||
|
||
// Number of CTN UID bits transferred | ||
parameter int unsigned NrCtnUidBits = 8; | ||
|
||
// RACL role type binary encoded | ||
typedef logic [NrRaclBits-1:0] racl_role_t; | ||
|
||
// CTN UID assigned the bus originator | ||
typedef logic [NrCtnUidBits-1:0] ctn_uid_t; | ||
|
||
// RACL permission: A one-hot encoded role vector | ||
typedef logic [(2**NrRaclBits)-1:0] racl_role_vec_t; | ||
|
||
// RACL policy containing a read and write permission | ||
typedef struct packed { | ||
racl_role_vec_t read_perm; | ||
racl_role_vec_t write_perm; | ||
} racl_policy_t; | ||
|
||
// RACL policy vector for distributing RACL policies from the RACL widget to the subscribing IP | ||
typedef racl_policy_t [NrRaclPolicies-1:0] racl_policy_vec_t; | ||
|
||
// RACL information logged in case of a denial | ||
typedef struct packed { | ||
racl_role_t racl_role; | ||
ctn_uid_t ctn_uid; | ||
// 0: Write access, 1: Read access | ||
logic read_not_write; | ||
} racl_error_log_t; | ||
|
||
// Extract RACL role bits from the TLUL reserved user bits | ||
function automatic racl_role_t tlul_extract_racl_role_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); | ||
// Waive unused bits | ||
logic unused_rsvd_bits; | ||
unused_rsvd_bits = ^{rsvd}; | ||
|
||
return racl_role_t'(rsvd[11:8]); | ||
endfunction | ||
|
||
// Extract CTN UID bits from the TLUL reserved user bits | ||
function automatic ctn_uid_t tlul_extract_ctn_uid_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); | ||
// Waive unused bits | ||
logic unused_rsvd_bits; | ||
unused_rsvd_bits = ^{rsvd}; | ||
|
||
return ctn_uid_t'(rsvd[7:0]); | ||
endfunction | ||
|
||
|
||
endpackage |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
CAPI=2: | ||
# Copyright lowRISC contributors (OpenTitan project). | ||
# Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
name: "lowrisc:systems:top_earlgrey_racl_pkg:0.1" | ||
description: "Autogenerated top_earlgrey_racl_pkg used in RTL and DV." | ||
virtual: | ||
- lowrisc:systems:top_racl_pkg | ||
|
||
filesets: | ||
files_rtl: | ||
depend: | ||
- lowrisc:tlul:headers | ||
files: | ||
- rtl/autogen/top_racl_pkg.sv | ||
file_type: systemVerilogSource | ||
|
||
targets: | ||
default: &default_target | ||
filesets: | ||
- files_rtl |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Copyright lowRISC contributors (OpenTitan project). | ||
# Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
# SPDX-License-Identifier: Apache-2.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Copyright lowRISC contributors (OpenTitan project). | ||
# Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import hjson | ||
import sys | ||
from reggen.validate import check_keys | ||
|
||
# Required fields for the RACL hjson | ||
racl_required = { | ||
'roles': ['l', 'List, specifying all RACL roles'], | ||
'policies': ['g', 'Dict, specifying the policies of all RACL groups'] | ||
} | ||
|
||
|
||
# Default configuration to render the RACL package for systems that don't use RACL but need the | ||
# type definitions | ||
DEFAULT_RACL_CONFIG = { | ||
'nr_policies': 1, | ||
'policies': {}, | ||
} | ||
|
||
|
||
def parse_racl_config(config_path: str): | ||
try: | ||
with open(config_path, 'r') as f_racl_config: | ||
racl_config = hjson.load(f_racl_config) | ||
except OSError: | ||
raise SystemExit(sys.exc_info()[1]) | ||
|
||
# TODO further error handling | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some hint about the missing checks? |
||
error = check_keys(racl_config, racl_required, [], [], 'RACL Config') | ||
if error: | ||
raise SystemExit(f"Error occurred while validating {config_path}") | ||
|
||
# Determine the maximum number of policies over all RACL groups for RTL | ||
# RTL needs to create the vectors based on the largest group | ||
racl_config['nr_policies'] = max(len(policies) for policies in racl_config['policies'].values()) | ||
|
||
for racl_group, policies in racl_config['policies'].items(): | ||
for policy in policies: | ||
def compute_policy_value(permission: str): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like the return value type delaration could be |
||
permission_value = 0 | ||
for role in policy[permission]: | ||
role_id = racl_config['roles'][role]['role_id'] | ||
permission_value += 2**role_id | ||
return permission_value | ||
|
||
policy['rd_default'] = compute_policy_value('allowed_rd') | ||
policy['wr_default'] = compute_policy_value('allowed_wr') | ||
return racl_config |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
IpTemplate, TemplateRenderError) | ||
from mako import exceptions | ||
from mako.template import Template | ||
from raclgen.lib import DEFAULT_RACL_CONFIG, parse_racl_config | ||
from reggen import access, gen_rtl, gen_sec_cm_testplan, window | ||
from reggen.countermeasure import CounterMeasure | ||
from reggen.inter_signal import InterSignal | ||
|
@@ -526,6 +527,15 @@ def generate_ac_range_check(topcfg: Dict[str, object], out_path: Path) -> None: | |
ipgen_render("ac_range_check", topname, params, out_path) | ||
|
||
|
||
# Generate RACL collateral | ||
def generate_racl(topcfg: Dict[str, object], out_path: Path) -> None: | ||
# Not all tops use RACL | ||
if 'racl_config' not in topcfg: | ||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it make sense to set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason this was not added is to make it easier to detect if no RACL is used, i.e., down below: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Detection of no RACL could be as simple as |
||
|
||
topcfg['racl'] = parse_racl_config(topcfg['racl_config']) | ||
|
||
|
||
def generate_top_only(top_only_dict: Dict[str, bool], out_path: Path, | ||
top_name: str, alt_hjson_path: str) -> None: | ||
log.info("Generating top only modules") | ||
|
@@ -866,6 +876,9 @@ def _process_top( | |
# Generate ac_range_check | ||
generate_ac_range_check(completecfg, out_path) | ||
|
||
# Generate RACL collateral | ||
generate_racl(completecfg, out_path) | ||
|
||
# Generate top only modules | ||
# These modules are not ipgen, but are not in hw/ip | ||
generate_top_only(top_only_dict, cfg_path, top_name, args.hjson_path) | ||
|
@@ -1249,6 +1262,12 @@ def render_template(template_path: str, rendered_path: Path, | |
out_path / f"rtl/autogen/{top_name}_rnd_cnst_pkg.sv", | ||
gencmd=gencmd) | ||
|
||
racl_config = completecfg.get('racl', DEFAULT_RACL_CONFIG) | ||
render_template(TOPGEN_TEMPLATE_PATH / 'toplevel_racl_pkg.sv.tpl', | ||
out_path / 'rtl' / 'autogen' / 'top_racl_pkg.sv', | ||
gencmd=gencmd, | ||
racl_config=racl_config) | ||
|
||
# Since SW does not use FuseSoC and instead expects those files always | ||
# to be in hw/top_{topname}/sw/autogen, we currently create these files | ||
# twice: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright lowRISC contributors (OpenTitan project). | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
${gencmd} | ||
|
||
package top_racl_pkg; | ||
// Number of RACL policies used | ||
parameter int unsigned NrRaclPolicies = ${racl_config['nr_policies']}; | ||
|
||
// Number of RACL bits transferred | ||
parameter int unsigned NrRaclBits = 4; | ||
|
||
// Number of CTN UID bits transferred | ||
parameter int unsigned NrCtnUidBits = 8; | ||
|
||
// RACL role type binary encoded | ||
typedef logic [NrRaclBits-1:0] racl_role_t; | ||
|
||
// CTN UID assigned the bus originator | ||
typedef logic [NrCtnUidBits-1:0] ctn_uid_t; | ||
|
||
// RACL permission: A one-hot encoded role vector | ||
typedef logic [(2**NrRaclBits)-1:0] racl_role_vec_t; | ||
|
||
// RACL policy containing a read and write permission | ||
typedef struct packed { | ||
racl_role_vec_t read_perm; | ||
racl_role_vec_t write_perm; | ||
} racl_policy_t; | ||
|
||
// RACL policy vector for distributing RACL policies from the RACL widget to the subscribing IP | ||
typedef racl_policy_t [NrRaclPolicies-1:0] racl_policy_vec_t; | ||
|
||
// RACL information logged in case of a denial | ||
typedef struct packed { | ||
racl_role_t racl_role; | ||
ctn_uid_t ctn_uid; | ||
// 0: Write access, 1: Read access | ||
logic read_not_write; | ||
} racl_error_log_t; | ||
|
||
// Extract RACL role bits from the TLUL reserved user bits | ||
function automatic racl_role_t tlul_extract_racl_role_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); | ||
// Waive unused bits | ||
logic unused_rsvd_bits; | ||
unused_rsvd_bits = ^{rsvd}; | ||
|
||
return racl_role_t'(rsvd[11:8]); | ||
endfunction | ||
|
||
// Extract CTN UID bits from the TLUL reserved user bits | ||
function automatic ctn_uid_t tlul_extract_ctn_uid_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); | ||
// Waive unused bits | ||
logic unused_rsvd_bits; | ||
unused_rsvd_bits = ^{rsvd}; | ||
|
||
return ctn_uid_t'(rsvd[7:0]); | ||
endfunction | ||
|
||
% for racl_group, policies in racl_config['policies'].items(): | ||
<% prefix = "" if len(racl_config['policies'].keys()) == 1 else f"{racl_group.upper()}_" %>\ | ||
/** | ||
* Policies for group ${racl_group} | ||
*/ | ||
|
||
% for policy in policies: | ||
/* | ||
* Policy ${policy['name']} allowed READ roles: | ||
* ${', '.join(policy['allowed_wr'])} | ||
*/ | ||
parameter racl_policy_t RACL_POLICY_${prefix}${policy['name'].upper()}_RD_DEFAULT = 16'h${f"{policy['rd_default']:x}"}; | ||
|
||
/** | ||
* Policy ${policy['name']} allowed WRITE roles: | ||
* ${', '.join(policy['allowed_wr'])} | ||
*/ | ||
parameter racl_policy_t RACL_POLICY_${prefix}${policy['name'].upper()}_WR_DEFAULT = 16'h${f"{policy['wr_default']:x}"}; | ||
|
||
% endfor | ||
% endfor | ||
|
||
endpackage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coud you add a return type, probably
...str) -> Dict[str, object]:
or some more specific type for the value in the Dict?