diff --git a/module/atu/include/mod_atu.h b/module/atu/include/mod_atu.h index 5234a98aa9cd6300b2c274187c9ec5a6a40b8df9..c554b5377a9607f2ab3b4232ff5b010a99b2efd3 100644 --- a/module/atu/include/mod_atu.h +++ b/module/atu/include/mod_atu.h @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2023-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -61,60 +61,64 @@ (AXNSE_VAL << ATU_ATUROBA_AXNSE_OFFSET)) /* - * Encode ATU region output bus attributes for accessing Root PAS + * Encode ATU region output bus attributes for accessing Root PAS. + * Set AxNSE to 1 and AxPROT1 to 0. */ #define ATU_ENCODE_ATTRIBUTES_ROOT_PAS \ (ATU_ENCODE_ATTRIBUTES( \ MOD_ATU_ROBA_SET_1, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0)) + MOD_ATU_ROBA_PASSTHROUGH)) /* - * Encode ATU region output bus attributes for accessing Secure PAS + * Encode ATU region output bus attributes for accessing Secure PAS. + * Set AxNSE to 0 and AxPROT1 to 0. */ #define ATU_ENCODE_ATTRIBUTES_SECURE_PAS \ (ATU_ENCODE_ATTRIBUTES( \ MOD_ATU_ROBA_SET_0, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0)) + MOD_ATU_ROBA_PASSTHROUGH)) /* - * Encode ATU region output bus attributes for accessing Non-Secure PAS + * Encode ATU region output bus attributes for accessing Non-Secure PAS. + * Set AxNSE to 0 and AxPROT1 to 1. */ #define ATU_ENCODE_ATTRIBUTES_NON_SECURE_PAS \ (ATU_ENCODE_ATTRIBUTES( \ MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ MOD_ATU_ROBA_SET_1, \ - MOD_ATU_ROBA_SET_0)) + MOD_ATU_ROBA_PASSTHROUGH)) /* - * Encode ATU region output bus attributes for accessing Realm PAS + * Encode ATU region output bus attributes for accessing Realm PAS. + * Set AxNSE to 1 and AxPROT1 to 1. */ #define ATU_ENCODE_ATTRIBUTES_REALM_PAS \ (ATU_ENCODE_ATTRIBUTES( \ MOD_ATU_ROBA_SET_1, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ - MOD_ATU_ROBA_SET_0, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ + MOD_ATU_ROBA_PASSTHROUGH, \ MOD_ATU_ROBA_SET_1, \ - MOD_ATU_ROBA_SET_0)) + MOD_ATU_ROBA_PASSTHROUGH)) /*! * \addtogroup GroupModules Modules diff --git a/module/atu/src/atu_manage.c b/module/atu/src/atu_manage.c index 0c818aa92f9595d9a9c979e196e3bec23bf08688..2b19416901a4107ee94508a27f3bfe4df5930317 100644 --- a/module/atu/src/atu_manage.c +++ b/module/atu/src/atu_manage.c @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2023-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -86,8 +86,13 @@ static int atu_add_region( return status; } - /* Configure the output bus attributes for the ATU region */ - device_ctx->atu->ATUROBA[*region_idx] |= + /* + * Configure the output bus attributes for the ATU region. + * + * Note: The bits [31:16] are read-as-zero or write-ignored (RAZ/WI), so set + * the register value directly. + */ + device_ctx->atu->ATUROBA[*region_idx] = (region->attributes & ATU_REGION_ROBA_MASK); return atu_map_region(region, *region_idx, device_ctx); diff --git a/module/atu/test/mod_atu_unit_test.c b/module/atu/test/mod_atu_unit_test.c index 5c4b8f4f3b3e006541e1b6328f9de286a074a3b8..f78fef1672059632ddd76b186683c9a100a21151 100644 --- a/module/atu/test/mod_atu_unit_test.c +++ b/module/atu/test/mod_atu_unit_test.c @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2023-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -483,6 +483,57 @@ void test_atu_get_available_region_idx_fail(void) TEST_ASSERT_EQUAL(status, FWK_E_PARAM); } +/*! + * \brief atu unit test: atu_add_region(), reconfigure the region attributes. + * + * \details Handle case in atu_add_region() where a region is mapped initially + * with a set of attributes and then the region is removed and a new region + * is mapped in the same index with a different set of attributes. + */ +void test_atu_remap_region_attributes(void) +{ + int status; + uint8_t region_idx; + struct atu_device_ctx *device_ctx; + struct __fwk_id_fmt mock_value; + fwk_id_t atu_device_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_ATU, 0); + + struct atu_region_map region = { + .region_owner_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_ATU), + .log_addr_base = 0x90000000, + .phy_addr_base = 0x80000000, + .region_size = (1 * FWK_MIB), + .attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS, + }; + + fwk_id_get_element_idx_ExpectAnyArgsAndReturn(0); + fwk_module_is_valid_entity_id_ExpectAnyArgsAndReturn(true); + fwk_id_is_equal_ExpectAnyArgsAndReturn(true); + __fwk_id_str_ExpectAnyArgsAndReturn(mock_value); + + /* Map the address translation region */ + status = atu_add_region(®ion, atu_device_id, ®ion_idx); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + __fwk_id_str_ExpectAnyArgsAndReturn(mock_value); + + /* Remove the address translation region */ + status = atu_remove_region(region_idx, atu_device_id, region.region_owner_id); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + fwk_id_get_element_idx_ExpectAnyArgsAndReturn(0); + __fwk_id_str_ExpectAnyArgsAndReturn(mock_value); + + /* Modify the attributes and map the region again */ + region.attributes = ATU_ENCODE_ATTRIBUTES_NON_SECURE_PAS; + status = atu_add_region(®ion, atu_device_id, ®ion_idx); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + /* Validate the ATUROBA register */ + device_ctx = &atu_ctx.device_ctx_table[0]; + TEST_ASSERT_EQUAL(device_ctx->atu->ATUROBA[region_idx], ATU_ENCODE_ATTRIBUTES_NON_SECURE_PAS); +} + int atu_test_main(void) { UNITY_BEGIN(); @@ -503,6 +554,7 @@ int atu_test_main(void) RUN_TEST(test_atu_remove_region_permission_fail); RUN_TEST(test_atu_remove_region_success); RUN_TEST(test_atu_get_available_region_idx_fail); + RUN_TEST(test_atu_remap_region_attributes); return UNITY_END(); }