Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/uefi/Bsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
../../test_pool/ras/ras014.c
../../test_pool/ras/ras016.c
../../test_pool/ras/ras017.c
../../test_pool/ras/ras018.c
../../test_pool/ete/ete001.c
../../test_pool/ete/ete002.c
../../test_pool/ete/ete003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/Sbsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@
../../test_pool/ras/ras014.c
../../test_pool/ras/ras016.c
../../test_pool/ras/ras017.c
../../test_pool/ras/ras018.c
../../test_pool/ete/ete001.c
../../test_pool/ete/ete002.c
../../test_pool/ete/ete003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/SbsaNist.inf
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
../../test_pool/ras/ras014.c
../../test_pool/ras/ras016.c
../../test_pool/ras/ras017.c
../../test_pool/ras/ras018.c
../../test_pool/ete/ete001.c
../../test_pool/ete/ete002.c
../../test_pool/ete/ete003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/Vbsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@
../../test_pool/ras/ras014.c
../../test_pool/ras/ras016.c
../../test_pool/ras/ras017.c
../../test_pool/ras/ras018.c
../../test_pool/ete/ete001.c
../../test_pool/ete/ete002.c
../../test_pool/ete/ete003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/pc_bsa.inf
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@
../../test_pool/ras/ras014.c
../../test_pool/ras/ras016.c
../../test_pool/ras/ras017.c
../../test_pool/ras/ras018.c
../../test_pool/ete/ete001.c
../../test_pool/ete/ete002.c
../../test_pool/ete/ete003.c
Expand Down
1 change: 1 addition & 0 deletions apps/uefi/xbsa_acpi.inf
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@
../../test_pool/ras/ras014.c
../../test_pool/ras/ras016.c
../../test_pool/ras/ras017.c
../../test_pool/ras/ras018.c
../../test_pool/ete/ete001.c
../../test_pool/ete/ete002.c
../../test_pool/ete/ete003.c
Expand Down
21 changes: 19 additions & 2 deletions test_pool/ras/ras009.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @file
* Copyright (c) 2023-2025, Arm Limited or its affiliates. All rights reserved.
* Copyright (c) 2023-2026, Arm Limited or its affiliates. All rights reserved.
* SPDX-License-Identifier : Apache-2.0

* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -54,6 +54,7 @@ payload()
uint64_t node_type;
uint64_t err_inj_addr;
uint64_t prox_base_addr;
uint64_t anerr = 0;

uint32_t status;
uint32_t fail_cnt = 0, test_skip = 0;
Expand All @@ -65,6 +66,22 @@ payload()
RAS_ERR_IN_t err_in_params;
RAS_ERR_OUT_t err_out_params;

/* Read ID_AA64MMFR3_EL1.ANERR[47:44] == 0b0010 or 0b0011 indicate FEAT_ANERR support */
anerr = VAL_EXTRACT_BITS(val_pe_reg_read(ID_AA64MMFR3_EL1), 44, 47);

val_print(ACS_PRINT_INFO, "\n ID_AA64MMFR3_EL1.ANERR field = 0x%llx", anerr);

if (anerr == FEAT_ANERR_VAL2 || anerr == FEAT_ANERR_VAL3) {
val_print(ACS_PRINT_INFO, "\n FEAT_ANERR implemented.", 0);
val_set_status(index, RESULT_PASS(TEST_NUM, 01));
return;
}

val_print(ACS_PRINT_INFO,
"\n FEAT_ANERR not implemented."
" Proceeding to synchronous Data Abort test.\n",
0);

/* get number of nodes with RAS functionality */
status = val_ras_get_info(RAS_INFO_NUM_NODES, 0, &num_node);
if (status || (num_node == 0)) {
Expand Down Expand Up @@ -188,7 +205,7 @@ payload()
return;
}

val_set_status(index, RESULT_PASS(TEST_NUM, 01));
val_set_status(index, RESULT_PASS(TEST_NUM, 02));
}

uint32_t
Expand Down
219 changes: 219 additions & 0 deletions test_pool/ras/ras018.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/** @file
* Copyright (c) 2026, Arm Limited or its affiliates. All rights reserved.
* SPDX-License-Identifier : Apache-2.0

* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

#include "val/include/acs_val.h"
#include "val/include/acs_common.h"
#include "val/include/acs_pe.h"
#include "val/include/val_interface.h"
#include "val/include/acs_memory.h"
#include "val/include/acs_mpam.h"
#include "val/include/acs_ras.h"

#define TEST_NUM (ACS_RAS_TEST_NUM_BASE + 18)
#define TEST_RULE "KBRZG"
#define TEST_DESC "Data abort on containable device err "

static uint32_t esr_pending = 1;
static void *branch_to_test;

static
void
esr(uint64_t interrupt_type, void *context)
{
esr_pending = 0;

/* Update the ELR to return to test specified address */
val_pe_update_elr(context, (uint64_t)branch_to_test);

val_print(ACS_PRINT_ERR, "\n Received exception of type: 0x%llx", interrupt_type);
}

static
void
payload()
{
uint64_t num_node;
uint64_t intf_type;
uint64_t dev_addr;
uint64_t attr = 0;
uint32_t read_data;

uint32_t status;
uint32_t fail_cnt = 0;
uint32_t test_skip = 0;
uint32_t node_index;
uint32_t usable_node_cnt = 0;
uint64_t aderr = 0;
uint64_t num_err;

uint32_t index = val_pe_get_index_mpid(val_pe_get_mpid());

RAS_ERR_IN_t err_in_params;
RAS_ERR_OUT_t err_out_params;

/* Read ID_AA64MMFR3_EL1.ADERR[59:56] == 0b0010 or 0b0011 indicate FEAT_ADERR support */
aderr = VAL_EXTRACT_BITS(val_pe_reg_read(ID_AA64MMFR3_EL1), 56, 59);

val_print(ACS_PRINT_INFO, "\n ID_AA64MMFR3_EL1.ADERR field = 0x%llx", aderr);

if (aderr == FEAT_ADERR_VAL2 || aderr == FEAT_ADERR_VAL3) {
val_print(ACS_PRINT_INFO, "\n FEAT_ADERR implemented.", 0);
val_set_status(index, RESULT_PASS(TEST_NUM, 01));
return;
}

val_print(ACS_PRINT_INFO,
"\n FEAT_ADERR not implemented. "
"Proceeding to synchronous Data Abort test.",
0);

/* get number of nodes with RAS functionality */
status = val_ras_get_info(RAS_INFO_NUM_NODES, 0, &num_node);
if (status || (num_node == 0)) {
val_print(ACS_PRINT_ERR,
"\n RAS nodes not found. "
"Firmware interface is missing. Please conduct a paper-based analysis.",
0);
val_set_status(index, RESULT_WARN(TEST_NUM, 01));
return;
}

for (node_index = 0; node_index < num_node; node_index++) {

esr_pending = 1;

/* MMIO-only filter */
status = val_ras_get_info(RAS_INFO_INTF_TYPE, node_index, &intf_type);
status |= val_ras_get_info(RAS_INFO_NUM_ERR_REC, node_index, &num_err);

if (status || (intf_type != RAS_INTERFACE_MMIO) || (num_err == 0)) {
val_print(ACS_PRINT_DEBUG, "\n intf_type: 0x%llx", intf_type);
val_print(ACS_PRINT_DEBUG, "\n num_err: 0x%llx", num_err);
continue;
}

usable_node_cnt++;

dev_addr = val_memory_get_addr(MEM_TYPE_DEVICE, 0, &attr);

if (!dev_addr) {
val_print(ACS_PRINT_ERR,
"\n Failed to obtain Device memory address.\n", 0);
val_set_status(index, RESULT_FAIL(TEST_NUM, 01));
return;
}

val_print(ACS_PRINT_INFO,
"\n Using Device memory address: 0x%llx\n", dev_addr);

/* Install sync and async handlers to handle exceptions.*/
status = val_pe_install_esr(EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, esr);
status |= val_pe_install_esr(EXCEPT_AARCH64_SERROR, esr);
if (status) {
val_print(ACS_PRINT_ERR, "\n Failed in installing the exception handler", 0);
val_set_status(index, RESULT_FAIL(TEST_NUM, 02));
return;
}
branch_to_test = &&exception_return;

/* Inject error with following parameters */
err_in_params.rec_index = 0; /* not applicable for scenario*/
err_in_params.node_index = node_index;
err_in_params.ras_error_type = ERR_CONTAINABLE; /* containable error */
err_in_params.error_pa = dev_addr; /* address of the location where error
needs to be injected */
err_in_params.is_pfg_check = 0; /* not a pseudo fault check */

/* Setup error in an implementation defined way */
status = val_ras_setup_error(err_in_params, &err_out_params);
if (status) {
val_print(ACS_PRINT_ERR, "\n val_ras_setup_error failed, node %d", node_index);
fail_cnt++;
break;
}

/* Inject error in an implementation defined way.
Inject error at an address, which will cause system to
record the error on reading with address syndrome in one of
the error records present for the current RAS node */
status = val_ras_inject_error(err_in_params, &err_out_params);
if (status) {
val_print(ACS_PRINT_ERR, "\n val_ras_inject_error failed, node %d", node_index);
fail_cnt++;
break;
}

/* wait loop to allow system to inject the error */
val_ras_wait_timeout(10);

/* Perform a read to error-injected address, which will cause
* system to record the error with address syndrome in one of
* the error records present for the current RAS node */
read_data = val_mmio_read(dev_addr);
val_print(ACS_PRINT_DEBUG, "\n Error injected address: 0x%llx", dev_addr);
val_print(ACS_PRINT_DEBUG, "\n Data read: 0x%lx", read_data);

exception_return:
val_print(ACS_PRINT_INFO, "\n value esr_pending, %d", esr_pending);
/* Check that a synchronous Data Abort was received */
if (esr_pending) {
val_print(ACS_PRINT_DEBUG, "\n Data abort Check Fail, for node %d", node_index);
fail_cnt++;
continue;
}
}

if (usable_node_cnt == 0) {
val_print(ACS_PRINT_INFO,
"\n No usable MMIO RAS nodes -- skipping test.\n", 0);
val_set_status(index, RESULT_SKIP(TEST_NUM, 01));
return;
}

if (fail_cnt) {
val_set_status(index, RESULT_FAIL(TEST_NUM, 03));
return;
}
else if (test_skip) {
val_set_status(index, RESULT_SKIP(TEST_NUM, 02));
return;
}

val_set_status(index, RESULT_PASS(TEST_NUM, 02));
}

uint32_t
ras018_entry(uint32_t num_pe)
{

uint32_t status = ACS_STATUS_FAIL;

num_pe = 1; /* This test is run on single processor */

val_log_context((char8_t *)__FILE__, (char8_t *)__func__, __LINE__);
status = val_initialize_test(TEST_NUM, TEST_DESC, num_pe);

if (status != ACS_STATUS_SKIP)
val_run_test_payload(TEST_NUM, num_pe, payload, 0);

/* get the result from all PE and check for failure */
status = val_check_for_error(TEST_NUM, num_pe, TEST_RULE);

val_report_status(0, ACS_END(TEST_NUM), TEST_RULE);

return status;
}
1 change: 1 addition & 0 deletions tools/cmake/infra/sbsa_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ ras013.c
ras014.c
ras016.c
ras017.c
ras018.c
ete001.c
ete002.c
ete003.c
Expand Down
4 changes: 3 additions & 1 deletion val/include/acs_pe.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @file
* Copyright (c) 2016-2020,2022-2025, Arm Limited or its affiliates. All rights reserved.
* Copyright (c) 2016-2020,2022-2026, Arm Limited or its affiliates. All rights reserved.
* SPDX-License-Identifier : Apache-2.0

* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -104,6 +104,7 @@ typedef enum {
ID_AA64MMFR0_EL1,
ID_AA64MMFR1_EL1,
ID_AA64MMFR2_EL1,
ID_AA64MMFR3_EL1,
ID_AA64DFR0_EL1,
ID_AA64DFR1_EL1,
CTR_EL0,
Expand Down Expand Up @@ -201,6 +202,7 @@ uint64_t ArmReadIdPfr1(void);
uint64_t AA64ReadMmfr0(void);
uint64_t AA64ReadMmfr1(void);
uint64_t AA64ReadMmfr2(void);
uint64_t AA64ReadMmfr3(void);
uint64_t AA64ReadCtr(void);
uint64_t AA64ReadIsar0(void);
uint64_t AA64ReadIsar1(void);
Expand Down
6 changes: 6 additions & 0 deletions val/include/acs_ras.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@

#define RAS_VERSION_2 0x3

#define FEAT_ANERR_VAL2 0x2
#define FEAT_ANERR_VAL3 0x3
#define FEAT_ADERR_VAL2 0x2
#define FEAT_ADERR_VAL3 0x3

#define ACS_ALL_1_64BIT 0xFFFFFFFFFFFFFFFF

typedef enum {
Expand Down Expand Up @@ -124,6 +129,7 @@ uint32_t ras014_entry(uint32_t num_pe);
uint32_t ras015_entry(uint32_t num_pe);
uint32_t ras016_entry(uint32_t num_pe);
uint32_t ras017_entry(uint32_t num_pe);
uint32_t ras018_entry(uint32_t num_pe);

uint64_t AA64ReadErrIdr1(void);
uint64_t AA64ReadErrAddr1(void);
Expand Down
1 change: 1 addition & 0 deletions val/include/rule_based_execution_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ typedef enum {
RAS013_ENTRY,
RAS016_ENTRY,
RAS017_ENTRY,
RAS018_ENTRY,
I001_ENTRY,
I007_ENTRY,
I002_ENTRY,
Expand Down
Loading