test(fuzzing): adding variable coverage
Adding the capability to produce coverage of the arguments of the
SMC calls as generated by the fuzzer. The output from the FVP will
be routed to UART3 where a python flow will read the data to create
tables of each SMC call with its fields shown and values given. The
option is enabled by adding SMC_FUZZ_VARIABLE_COVERAGE=1 to the
corresponding TFTF config.
Change-Id: I2d4d310976aa2c0447efbd8ec0676bb9f8699828
Signed-off-by: Mark Dykes <mark.dykes@arm.com>
diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S
index 0d607b9..9e25bca 100644
--- a/drivers/arm/pl011/aarch64/pl011_console.S
+++ b/drivers/arm/pl011/aarch64/pl011_console.S
@@ -18,6 +18,10 @@
.globl console_core_putc
.globl console_core_getc
.globl console_core_flush
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+ .globl console_init_fuzzer
+ .globl console_pl011_putc_fuzzer
+#endif
/*
* The console base is in the data section and not in .bss
@@ -28,7 +32,14 @@
*/
.section .data.console_base
.align 3
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+ .section .data.console_base_fuzzer
+ .align 3
+#endif
console_base: .quad 0x0
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+console_base_fuzzer: .quad 0x0
+#endif
/* -----------------------------------------------
* int console_init(uintptr_t base_addr,
@@ -43,6 +54,24 @@
b console_core_init
endfunc console_init
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+ /* -----------------------------------------------
+ * int console_init_fuzzer(uintptr_t base_addr,
+ * unsigned int uart_clk, unsigned int baud_rate)
+ *
+ * Clobber list : x1 - x3
+ * x1: Base address
+ * x2: UART clock
+ * x3: Baud rate
+ * -----------------------------------------------
+ */
+func console_init_fuzzer
+ adrp x3, console_base_fuzzer
+ str x0, [x3, :lo12:console_base_fuzzer]
+ b console_core_init
+endfunc console_init_fuzzer
+#endif
+
/* -----------------------------------------------
* int console_core_init(uintptr_t base_addr,
* unsigned int uart_clk, unsigned int baud_rate)
@@ -108,6 +137,26 @@
b console_core_putc
endfunc console_pl011_putc
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+ /* -------------------------------------------------
+ * To allow alternate implementation of putc, pl011
+ * is appended in the function name.
+ *
+ * int console_pl011_putc_fuzzer(int c)
+ *
+ * Clobber list : x0-x2
+ * x0: Character to be printed
+ * x1: Base address
+ * x2: Overwritten by function
+ * -------------------------------------------------
+ */
+func console_pl011_putc_fuzzer
+ adrp x1, console_base_fuzzer
+ ldr x1, [x1, :lo12:console_base_fuzzer]
+ b console_core_putc
+endfunc console_pl011_putc_fuzzer
+#endif
+
/* ---------------------------------------------
* int console_core_putc(int c, uintptr_t base_addr)
* Function to output a character over the console. It
diff --git a/drivers/console/console.c b/drivers/console/console.c
index b2bae28..ea7087c 100644
--- a/drivers/console/console.c
+++ b/drivers/console/console.c
@@ -10,3 +10,21 @@
{
return console_pl011_putc(c);
}
+
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+int console_putc_fuzzer(int c)
+{
+ return console_pl011_putc_fuzzer(c);
+}
+
+void tftf_switch_console_state(int state)
+{
+ tftf_console_state = state;
+}
+
+int tftf_get_console_state(void)
+{
+ return tftf_console_state;
+}
+
+#endif
diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h
index 3e19ee8..42dd838 100644
--- a/include/drivers/arm/pl011.h
+++ b/include/drivers/arm/pl011.h
@@ -81,6 +81,10 @@
/* Functions */
int console_pl011_putc(int);
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+int console_pl011_putc_fuzzer(int);
+static int tftf_console_state;
+#endif
#endif /* __ASSEMBLER__ */
diff --git a/include/drivers/console.h b/include/drivers/console.h
index 4c22a99..98826fa 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -16,6 +16,11 @@
#include <stdint.h>
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+#define CONSOLE_FLAG_PLAT_UART 0
+#define CONSOLE_FLAG_SMC_FUZZER 1
+#endif
+
/*
* Function to initialize the console without a C Runtime to print debug
* information. It saves the console base to the data section. Returns 1 on
@@ -24,12 +29,33 @@
int console_init(uintptr_t base_addr,
unsigned int uart_clk, unsigned int baud_rate);
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+/*
+ * Function to initialize the console without a C Runtime to print debug
+ * information. It saves the console base to the data section. Returns 1 on
+ * success, 0 on error.
+ */
+int console_init_fuzzer(uintptr_t base_addr,
+ unsigned int uart_clk, unsigned int baud_rate);
+void tftf_switch_console_state(int state);
+int tftf_get_console_state(void);
+#endif
+
/*
* Function to output a character over the console. It returns the character
* printed on success or an error code.
*/
int console_putc(int c);
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+/*
+ * Function to output a character over the console. It returns the character
+ * printed on success or an error code.
+ */
+int console_putc_fuzzer(int c);
+#endif
+
+
/*
* Function to get a character from the console. It returns the character
* grabbed on success or an error code on error. This function is blocking, it
diff --git a/lib/libc/putchar.c b/lib/libc/putchar.c
index 037e28a..de69f5c 100644
--- a/lib/libc/putchar.c
+++ b/lib/libc/putchar.c
@@ -11,10 +11,24 @@
int putchar(int c)
{
int res;
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+ if(tftf_get_console_state() == CONSOLE_FLAG_SMC_FUZZER) {
+ if (console_putc_fuzzer((unsigned char)c) >= 0)
+ res = c;
+ else
+ res = EOF;
+ }
+ else {
+ if (console_putc((unsigned char)c) >= 0)
+ res = c;
+ else
+ res = EOF;
+ }
+#else
if (console_putc((unsigned char)c) >= 0)
res = c;
else
res = EOF;
-
+#endif
return res;
}
diff --git a/lib/smc/aarch64/smc.c b/lib/smc/aarch64/smc.c
index b0fea4b..72f01c6 100644
--- a/lib/smc/aarch64/smc.c
+++ b/lib/smc/aarch64/smc.c
@@ -6,12 +6,15 @@
#include <arch.h>
#include <arch_features.h>
+#include <drivers/console.h>
#include <lib/extensions/sve.h>
-#include <stdint.h>
#include <smccc.h>
+#include <stdint.h>
+#include <stdio.h>
#include <tftf.h>
#include <utils_def.h>
+
static void sve_enable(void)
{
if (IS_IN_EL2()) {
@@ -93,14 +96,20 @@
fid &= ~MASK(FUNCID_SVE_HINT);
}
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+ tftf_switch_console_state(CONSOLE_FLAG_SMC_FUZZER);
+ printf("SMC FUZZER CALL fid:%x arg1:%lx arg2:%lx arg3:%lx arg4:%lx arg5:%lx arg6:%lx arg7:%lx\n",
+ fid, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5, args->arg6, args->arg7);
+ tftf_switch_console_state(CONSOLE_FLAG_PLAT_UART);
+#endif
return asm_tftf_smc64(fid,
- args->arg1,
- args->arg2,
- args->arg3,
- args->arg4,
- args->arg5,
- args->arg6,
- args->arg7);
+ args->arg1,
+ args->arg2,
+ args->arg3,
+ args->arg4,
+ args->arg5,
+ args->arg6,
+ args->arg7);
}
void tftf_smc_no_retval_x8(const smc_args_ext *args, smc_ret_values_ext *ret)
diff --git a/plat/arm/common/arm_setup.c b/plat/arm/common/arm_setup.c
index e345fd8..732597a 100644
--- a/plat/arm/common/arm_setup.c
+++ b/plat/arm/common/arm_setup.c
@@ -49,5 +49,10 @@
void tftf_early_platform_setup(void)
{
console_init(PLAT_ARM_UART_BASE, PLAT_ARM_UART_CLK_IN_HZ,
- PL011_BAUDRATE);
+ PL011_BAUDRATE);
+#ifdef SMC_FUZZ_VARIABLE_COVERAGE
+ console_init_fuzzer(PLAT_ARM_SMC_FUZZER_UART_BASE, PLAT_ARM_SMC_FUZZER_UART_CLK_IN_HZ,
+ PL011_BAUDRATE);
+ tftf_console_state = 0;
+#endif
}
diff --git a/plat/arm/fvp/fvp_def.h b/plat/arm/fvp/fvp_def.h
index 4b5bd59..222fadd 100644
--- a/plat/arm/fvp/fvp_def.h
+++ b/plat/arm/fvp/fvp_def.h
@@ -86,4 +86,7 @@
#define PLAT_ARM_UART_BASE PL011_UART0_BASE
#define PLAT_ARM_UART_CLK_IN_HZ PL011_UART0_CLK_IN_HZ
+#define PLAT_ARM_SMC_FUZZER_UART_BASE PL011_UART3_BASE
+#define PLAT_ARM_SMC_FUZZER_UART_CLK_IN_HZ PL011_UART3_CLK_IN_HZ
+
#endif /* __FVP_DEF_H__ */
diff --git a/smc_fuzz/script/generate_var_coverage.py b/smc_fuzz/script/generate_var_coverage.py
new file mode 100755
index 0000000..2227f7a
--- /dev/null
+++ b/smc_fuzz/script/generate_var_coverage.py
@@ -0,0 +1,88 @@
+# !/usr/bin/env python
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+#python3 generate_var_coverage.py -sd <smc definition file> -df <SMC data file>
+#This script generates variable coverage tables from SMC definition file and output of FVP SMC calls
+import re
+import copy
+import sys
+import argparse
+import readsmclist
+from tabulate import tabulate
+
+parser = argparse.ArgumentParser(
+ prog='generate_var_coverage.py',
+ description='Creates coverage data from SMC calls in FVP model',
+ epilog='two arguments input')
+
+parser.add_argument('-df', '--datafile',help="Data from UART output of the model .")
+parser.add_argument('-sd', '--smcdefinition',help="SMC definition file .")
+
+args = parser.parse_args()
+
+print("starting variable coverage")
+
+seq = 0
+
+readsmclist.readsmclist(args.smcdefinition,seq)
+
+arglst = readsmclist.arglst
+argnumfield = readsmclist.argnumfield
+argfieldname = readsmclist.argfieldname
+argstartbit = readsmclist.argstartbit
+argendbit = readsmclist.argendbit
+argdefval = readsmclist.argdefval
+smcname = readsmclist.smcname
+argnum = readsmclist.argnum
+argname = readsmclist.argname
+smcid = readsmclist.smcid
+
+varcovvalues = {}
+
+for sn in argfieldname:
+ varcovvalues[sn] = {}
+ for an in argfieldname[sn]:
+ for fn in argfieldname[sn][an]:
+ varcovvalues[sn][fn] = set()
+
+datafile = open(args.datafile, "r")
+data_lines = datafile.readlines()
+datafile.close()
+for dline in data_lines:
+ dl = dline.strip()
+ dinstr = re.search(r'^SMC FUZZER CALL fid:([a-fA-F0-9]+)\s+arg1:([a-fA-F0-9]+)\s+arg2:([a-fA-F0-9]+)\s+arg3:([a-fA-F0-9]+)\s+arg4:([a-fA-F0-9]+)\s+arg5:([a-fA-F0-9]+)\s+arg6:([a-fA-F0-9]+)\s+arg7:([a-fA-F0-9]+)$',dl)
+ if dinstr:
+ if dinstr.group(1) in smcid:
+ scall = smcid[dinstr.group(1)]
+ for an in argfieldname[scall]:
+ for fn in argfieldname[scall][an]:
+ if int(argnumfield[scall][an][fn]) < 8:
+ argval = dinstr.group(int(argnumfield[scall][an][fn])+1)
+ astbit = int(argstartbit[scall][an][fn])
+ aenbit = int(argendbit[scall][an][fn])
+ vval = hex((int(argval,16) >> astbit) & ((2 ** (aenbit - astbit + 1)) - 1))
+ varcovvalues[scall][fn].add(vval)
+
+for sn in varcovvalues:
+ print(sn)
+ largest = 0
+ hdrs = []
+ for fn in varcovvalues[sn]:
+ if len(varcovvalues[sn][fn]) > largest:
+ largest = len(varcovvalues[sn][fn])
+ te = [["-" for x in range(len(varcovvalues[sn]))] for x in range(largest)]
+ k = 0
+ for fn in varcovvalues[sn]:
+ i = 0
+ hdrs.append(fn)
+ for val in varcovvalues[sn][fn]:
+ te[i][k] = val
+ i = i + 1
+ k = k + 1
+ print(tabulate(te, headers=hdrs, tablefmt="grid"))
+ print()
diff --git a/smc_fuzz/script/readsmclist.py b/smc_fuzz/script/readsmclist.py
index 3bfcb6a..d351552 100755
--- a/smc_fuzz/script/readsmclist.py
+++ b/smc_fuzz/script/readsmclist.py
@@ -14,6 +14,9 @@
argstartbit = {}
argendbit = {}
argdefval = {}
+smcid = {}
+defval = {}
+sdef = {}
smcname = ""
argnum = ""
argname = ""
@@ -23,9 +26,54 @@
smclist_lines = smclistfile.readlines()
smclistfile.close()
for sline in smclist_lines:
+ svar = 0
lcon = 0
sl = sline.strip()
- sinstr = re.search(r'^smc:\s*([a-zA-Z0-9_]+)$',sl)
+ sinstr = re.search(r'^smc:\s*([a-zA-Z0-9_]+)\s*0x([a-fA-F0-9]+)\s*$',sl)
+ if sinstr:
+ smcname = sinstr.group(1)
+ arglst[sinstr.group(1)] = []
+ argnumfield[sinstr.group(1)] = {}
+ argfieldname[sinstr.group(1)] = {}
+ argstartbit[sinstr.group(1)] = {}
+ argendbit[sinstr.group(1)] = {}
+ argdefval[sinstr.group(1)] = {}
+ smcid[sinstr.group(2)] = sinstr.group(1)
+ svar = 1
+ lcon = 1
+ argoccupy = {}
+ if not seq:
+ seq = seq + 1
+ else:
+ if seq != 2:
+ print("Error: out of sequence for smc call",end=" ")
+ print(smcname)
+ sys.exit()
+ else:
+ seq = 1
+ sinstr = re.search(r'^smc:\s*([a-zA-Z0-9_]+)\s*([a-zA-Z0-9_]+)\s*$',sl)
+ if sinstr and (svar == 0):
+ smcname = sinstr.group(1)
+ arglst[sinstr.group(1)] = []
+ argnumfield[sinstr.group(1)] = {}
+ argfieldname[sinstr.group(1)] = {}
+ argstartbit[sinstr.group(1)] = {}
+ argendbit[sinstr.group(1)] = {}
+ argdefval[sinstr.group(1)] = {}
+ sdef[sinstr.group(1)] = sinstr.group(2)
+ smcid[sinstr.group(2)] = sinstr.group(1)
+ lcon = 1
+ argoccupy = {}
+ if not seq:
+ seq = seq + 1
+ else:
+ if seq != 2:
+ print("Error: out of sequence for smc call",end=" ")
+ print(smcname)
+ sys.exit()
+ else:
+ seq = 1
+ sinstr = re.search(r'^smc:\s*([a-zA-Z0-9_]+)\s*$',sl)
if sinstr:
smcname = sinstr.group(1)
arglst[sinstr.group(1)] = []
@@ -181,6 +229,10 @@
if seq != 2:
print("Error: out of sequence for field")
sys.exit()
+ sinstr = re.search(r'^define ([a-zA-Z0-9_]+)\s*=\s*0x([a-fA-F0-9]+|\d+)$',sl)
+ if sinstr:
+ defval[sinstr.group(1)] = sinstr.group(2)
+ lcon = 1
if not lcon:
cline = re.search(r'^#',sl)
if not cline:
@@ -191,3 +243,11 @@
if(seq != 2):
print("incorrect ending for smc specification")
sys.exit()
+
+ for smccal,dval in sdef.items():
+ if dval in defval:
+ smcid[defval[dval]] = smccal
+ else:
+ print("Error: cannot find define value",end=" ")
+ print(dval)
+ sys.exit()
diff --git a/smc_fuzz/sdei_smc_calls.txt b/smc_fuzz/sdei_smc_calls.txt
index 3017630..ccf8992 100644
--- a/smc_fuzz/sdei_smc_calls.txt
+++ b/smc_fuzz/sdei_smc_calls.txt
@@ -4,15 +4,35 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-smc: SDEI_EVENT_STATUS_CALL
+define SDEI_EVENT_STATUS_CALL_SMCID = 0xc4000028
+define SDEI_INTERRUPT_BIND_CALL_SMCID = 0xc400002d
+define SDEI_VERSION_CALL_SMCID = 0xc4000020
+define SDEI_EVENT_REGISTER_CALL_SMCID = 0xc4000021
+define SDEI_EVENT_ENABLE_CALL_SMCID = 0xc4000022
+define SDEI_FEATURES_CALL_SMCID = 0xc4000030
+define SDEI_EVENT_DISABLE_CALL_SMCID = 0xc4000023
+define SDEI_EVENT_CONTEXT_CALL_SMCID = 0xc4000024
+define SDEI_EVENT_COMPLETE_CALL_SMCID = 0xc4000025
+define SDEI_EVENT_COMPLETE_AND_RESUME_CALL_SMCID = 0xc4000026
+define SDEI_EVENT_UNREGISTER_CALL_SMCID = 0xc4000027
+define SDEI_EVENT_GET_INFO_CALL_SMCID = 0xc4000029
+define SDEI_EVENT_ROUTING_SET_CALL_SMCID = 0xc400002a
+define SDEI_PE_MASK_CALL_SMCID = 0xc400002b
+define SDEI_PE_UNMASK_CALL_SMCID = 0xc400002c
+define SDEI_INTERRUPT_RELEASE_CALL_SMCID = 0xc400002e
+define SDEI_EVENT_SIGNAL_CALL_SMCID = 0xc400002f
+define SDEI_PRIVATE_RESET_CALL_SMCID = 0xc4000031
+define SDEI_SHARED_RESET_CALL_SMCID = 0xc4000032
+
+smc: SDEI_EVENT_STATUS_CALL SDEI_EVENT_STATUS_CALL_SMCID
arg1:bev
field:bev:[0,31] = 0
-smc: SDEI_INTERRUPT_BIND_CALL
+smc: SDEI_INTERRUPT_BIND_CALL SDEI_INTERRUPT_BIND_CALL_SMCID
arg1:interruptnum
field:inum:[0,31] = 1
-smc: SDEI_VERSION_CALL
+smc: SDEI_VERSION_CALL SDEI_VERSION_CALL_SMCID
arg1-arg17 = 0
-smc: SDEI_EVENT_REGISTER_CALL
+smc: SDEI_EVENT_REGISTER_CALL SDEI_EVENT_REGISTER_CALL_SMCID
arg1:eventnum
field:enum:[0,31] = 0
arg2:entryaddr
@@ -25,33 +45,33 @@
field:reserved:[2,63] = 0
arg5:affinity
field:aff:[0,63] = 0
-smc: SDEI_EVENT_ENABLE_CALL
+smc: SDEI_EVENT_ENABLE_CALL SDEI_EVENT_ENABLE_CALL_SMCID
arg1:eventnum
field:enum:[0,31] = 0
-smc: SDEI_FEATURES_CALL
+smc: SDEI_FEATURES_CALL SDEI_FEATURES_CALL_SMCID
arg1:feature
field:feat:[0,31] = 0
-smc: SDEI_EVENT_DISABLE_CALL
+smc: SDEI_EVENT_DISABLE_CALL SDEI_EVENT_DISABLE_CALL_SMCID
arg1:eventnum
field:enum:[0,31] = 0
-smc: SDEI_EVENT_CONTEXT_CALL
+smc: SDEI_EVENT_CONTEXT_CALL SDEI_EVENT_CONTEXT_CALL_SMCID
arg1:paramid
field:param:[0,31] = 0
-smc: SDEI_EVENT_COMPLETE_CALL
+smc: SDEI_EVENT_COMPLETE_CALL SDEI_EVENT_COMPLETE_CALL_SMCID
arg1:status
field:stat:[0,31] = 0
-smc: SDEI_EVENT_COMPLETE_AND_RESUME_CALL
+smc: SDEI_EVENT_COMPLETE_AND_RESUME_CALL SDEI_EVENT_COMPLETE_AND_RESUME_CALL_SMCID
arg1:resumeaddr
field:addr:[0,63] = 0
-smc: SDEI_EVENT_UNREGISTER_CALL
+smc: SDEI_EVENT_UNREGISTER_CALL SDEI_EVENT_UNREGISTER_CALL_SMCID
arg1:event
field:enum:[0,31] = 0
-smc: SDEI_EVENT_GET_INFO_CALL
+smc: SDEI_EVENT_GET_INFO_CALL SDEI_EVENT_GET_INFO_CALL_SMCID
arg1:event
field:enum:[0,31] = 0
arg2:info
field:info:[0,31] = 0
-smc: SDEI_EVENT_ROUTING_SET_CALL
+smc: SDEI_EVENT_ROUTING_SET_CALL SDEI_EVENT_ROUTING_SET_CALL_SMCID
arg1:event
field:enum:[0,31] = 0
arg2:routingmode
@@ -59,19 +79,19 @@
field:constant:[1,63] = 0
arg3:affinity
field:aff:[0,63] = 0
-smc: SDEI_PE_MASK_CALL
+smc: SDEI_PE_MASK_CALL SDEI_PE_MASK_CALL_SMCID
arg1 = 0
-smc: SDEI_PE_UNMASK_CALL
+smc: SDEI_PE_UNMASK_CALL SDEI_PE_UNMASK_CALL_SMCID
arg1 = 0
-smc: SDEI_INTERRUPT_RELEASE_CALL
+smc: SDEI_INTERRUPT_RELEASE_CALL SDEI_INTERRUPT_RELEASE_CALL_SMCID
arg1:event
field:enum:[0,31] = 0
-smc: SDEI_EVENT_SIGNAL_CALL
+smc: SDEI_EVENT_SIGNAL_CALL SDEI_EVENT_SIGNAL_CALL_SMCID
arg1:event
field:enum:[0,31] = 0
arg2:targetpe
field:pe:[0,31] = 0
-smc: SDEI_PRIVATE_RESET_CALL
+smc: SDEI_PRIVATE_RESET_CALL SDEI_PRIVATE_RESET_CALL_SMCID
arg1 = 0
-smc: SDEI_SHARED_RESET_CALL
+smc: SDEI_SHARED_RESET_CALL SDEI_SHARED_RESET_CALL_SMCID
arg1 = 0
diff --git a/tftf/tests/tests-smcfuzzing.mk b/tftf/tests/tests-smcfuzzing.mk
index ca93469..8a05674 100644
--- a/tftf/tests/tests-smcfuzzing.mk
+++ b/tftf/tests/tests-smcfuzzing.mk
@@ -72,6 +72,9 @@
$(eval $(call add_define,TFTF_DEFINES,CONSTRAIN_EVENTS))
$(eval $(call add_define,TFTF_DEFINES,EXCLUDE_FUNCID))
$(eval $(call add_define,TFTF_DEFINES,INTR_ASSERT))
+ifeq ($(SMC_FUZZ_VARIABLE_COVERAGE),1)
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_VARIABLE_COVERAGE))
+endif
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/standard_service/sdei/system_tests/, \