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
|