aboutsummaryrefslogtreecommitdiff
path: root/tftf/tests/runtime_services/standard_service/sdei/system_tests/sdei_entrypoint.S
blob: 655bb2480eb9da5a2e5d07c9622823354135ce8a (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

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

	.globl	sdei_state_entrypoint
	.globl	sdei_entrypoint
	.globl	sdei_entrypoint_resume
	.globl	sdei_handler_done

	.local	event_handled
	.comm	event_handled, PLATFORM_CORE_COUNT * 4, 8

#ifdef __aarch64__
func sdei_entrypoint
	stp	xzr, x30, [sp, #-16]!
	bl	sdei_event_handler
	ldp	xzr, x30, [sp],#16
	mov_imm	x0, SDEI_EVENT_COMPLETE
	mov	x1, xzr
	smc	#0
	b	.
endfunc sdei_entrypoint

func sdei_entrypoint_resume
	stp	x2, x30, [sp, #-16]!

	/* Dispatch to C handler */
	bl	sdei_event_handler

	/* Calculate address of event completion variable */
	mrs	x0, mpidr_el1
	mov_imm	x1, MPID_MASK
	and	x0, x0, x1
	bl	platform_get_core_pos
	lsl	x0, x0, #2
	adrp	x1, event_handled
	add	x1, x1, :lo12:event_handled
	add	x1, x0, x1

	/* Mark event handling as complete so `sdei_handler_done` can return */
	mov	w2, #1
	str	w2, [x1]
	sev

	/* Populate `x0` and `x1` to prepare for SMC call */
	ldp	x1, x30, [sp], #16
	mov_imm	x0, SDEI_EVENT_COMPLETE_AND_RESUME
	smc	#0
endfunc sdei_entrypoint_resume

func sdei_handler_done
	stp	x29, x30, [sp, #-16]!
	mov	x29, sp

	/* Calculate address of event completion variable */
	mrs	x0, mpidr_el1
	mov_imm	x1, MPID_MASK
	and	x0, x0, x1
	mov	x29, x30
	bl	platform_get_core_pos
	mov	x30, x29
	lsl	x0, x0, #2
	adrp	x1, event_handled
	add	x1, x1, :lo12:event_handled
	add	x0, x0, x1

again:
	/*
	 * Wait until the timer interrupt fires, which will be handled
	 * as an SDEI event and take us to sdei_entrypoint_resume().
	 */
	wfe
	ldr	w1, [x0]
	cmp	w1, #1
	bne	again

	/* Reset event completion variable for next run */
	mov	w1, #0
	str	w1, [x0]

	ldp	x29, x30, [sp], #16
	ret
endfunc sdei_handler_done

func sdei_state_entrypoint
	stp	x29, x30, [sp, #-16]!
	mov	x29, sp
	blr	x1

	/* Calculate address of event completion variable */
	mrs	x0, mpidr_el1
	mov_imm	x1, MPID_MASK
	and	x0, x0, x1
	bl	platform_get_core_pos
	lsl	x0, x0, #2
	adrp	x1, event_handled
	add	x1, x1, :lo12:event_handled
	add	x1, x0, x1

	/* Mark event handling as complete so `sdei_handler_done` can return */
	mov	w2, #1
	str	w2, [x1]
	sev

	ldp	x29, x30, [sp],#16
	mov_imm	x0, SDEI_EVENT_COMPLETE
	mov_imm	x1, SDEI_EV_HANDLED
	smc	#0
	b	.
endfunc sdei_state_entrypoint

#else /* AARCH32 */
func sdei_entrypoint
	/* SDEI is not supported on AArch32. */
	b	.
endfunc sdei_entrypoint

func sdei_entrypoint_resume
	/* SDEI is not supported on AArch32. */
	b	.
endfunc sdei_entrypoint_resume

func sdei_handler_done
	/* SDEI is not supported on AArch32. */
	b	.
endfunc sdei_handler_done

func sdei_state_entrypoint
	/* SDEI is not supported on AArch32. */
	b	.
endfunc sdei_state_entrypoint
#endif