summaryrefslogtreecommitdiff
path: root/tftf/tests/misc_tests/inject_serror.S
blob: 0d7dbf2d7519ad80a6a8c1a85e40196bafdf943e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Copyright (c) 2018, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch.h>
#include <asm_macros.S>
#include <sdei.h>


#ifdef AARCH64
	.globl	inject_serror
	.globl	inject_uncontainable
	.globl	serror_sdei_event_handler

/*
 * Program fault injection register, and wait for ever for the fault to trigger.
 * Note that Trusted Firmware must be compiled for ARMv8.4 along with
 * FAULT_INJECTION_SUPPORT=1 for this to work. Besides, the model has to be
 * launched with fault inject support.
 *
 * x0: Fault record number to program
 * x1: Injected fault properties
 * x2: Type of error to be generated
 * x3: Memory location to wait for, or 0 if no waiting is required
 */
func inject_serror_record
	/* Choose Error record 0 on the PE */
	msr	ERRSELR_EL1, x0
	isb

	/* Enable error reporting */
	orr	x1, x1, #ERXCTLR_ED_BIT
	msr	ERXCTLR_EL1, x1

	/* Program count down timer to 1 */
	mov	x0, #1
	msr	ERXPFGCDN_EL1, x0

	/* Start count down to generate error */
	orr	x2, x2, #ERXPFGCTL_CDEN_BIT
	msr	ERXPFGCTL_EL1, x2
	isb

	cbz	x3, 2f

	/* Clear SError received flag */
	str	xzr, [x3, #0]
	sevl

1:
	wfe
	ldr	x0, [x3, #0]
	cbz	x0, 1b

2:
	ret
endfunc inject_serror_record

/*
 * Inject Unrecoverable error through fault record 0. Wait until serror_received
 * is set by the SDEI handler in response to receving the event.
 */
func inject_serror
	/* Inject fault into record 0 */
	mov	x0, #0

	/* Enable error reporting */
	mov	x1, #ERXCTLR_UE_BIT
	msr	ERXCTLR_EL1, x1

	/* Injected fault control */
	mov	x2, #ERXPFGCTL_UEU_BIT

	/* Wait address */
	adrp	x3, serror_received
	add	x3, x3, :lo12:serror_received

	b	inject_serror_record
endfunc inject_serror

/*
 * Inject Uncontainable error through fault record 0. This function doesn't wait
 * as the handling is terminal in EL3.
 */
func inject_uncontainable
	/* Inject fault into record 0 */
	mov	x0, #0

	mov	x1, xzr

	/* Injected fault control */
	mov	x2, #ERXPFGCTL_UC_BIT

	/* Nothing to wait for */
	mov	x3, xzr

	b	inject_serror_record
endfunc inject_uncontainable

/*
 * SDEI event handler for SErrors.
 */
func serror_sdei_event_handler
	stp	x29, x30, [sp, #-16]!
	bl	serror_handler
	ldp	x29, x30, [sp], #16
	mov_imm	x0, SDEI_EVENT_COMPLETE
	mov	x1, xzr
	smc	#0
	b	.
endfunc serror_sdei_event_handler
#endif