xref: /optee_os/core/drivers/hfic.c (revision 769cbbd704592f9fa940f52dabb0511ff10cf78a)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2022, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <config.h>
8 #include <drivers/hfic.h>
9 #include <hafnium.h>
10 #include <kernel/interrupt.h>
11 #include <kernel/panic.h>
12 #include <kernel/thread.h>
13 
14 static void hfic_op_add(struct itr_chip *chip __unused, size_t it __unused,
15 			uint32_t type __unused, uint32_t prio __unused)
16 {
17 }
18 
19 static void hfic_op_enable(struct itr_chip *chip __unused, size_t it)
20 {
21 	uint32_t res __maybe_unused = 0;
22 
23 	res = thread_hvc(HF_INTERRUPT_ENABLE, it, HF_ENABLE,
24 			 HF_INTERRUPT_TYPE_IRQ);
25 	assert(!res);
26 }
27 
28 static void hfic_op_disable(struct itr_chip *chip __unused, size_t it)
29 {
30 	uint32_t res __maybe_unused = 0;
31 
32 	res = thread_hvc(HF_INTERRUPT_ENABLE, it, HF_DISABLE,
33 			 HF_INTERRUPT_TYPE_IRQ);
34 	assert(!res);
35 }
36 
37 static void hfic_op_raise_pi(struct itr_chip *chip __unused, size_t it __unused)
38 {
39 	panic();
40 }
41 
42 static void hfic_op_raise_sgi(struct itr_chip *chip __unused,
43 			      size_t it __unused, uint8_t cpu_mask __unused)
44 {
45 	panic();
46 }
47 
48 static void hfic_op_set_affinity(struct itr_chip *chip __unused,
49 				 size_t it __unused, uint8_t cpu_mask __unused)
50 {
51 	panic();
52 }
53 
54 static const struct itr_ops hfic_ops = {
55 	.add = hfic_op_add,
56 	.enable = hfic_op_enable,
57 	.disable = hfic_op_disable,
58 	.raise_pi = hfic_op_raise_pi,
59 	.raise_sgi = hfic_op_raise_sgi,
60 	.set_affinity = hfic_op_set_affinity,
61 };
62 
63 void hfic_init(struct hfic_data *hd)
64 {
65 	hd->chip.ops = &hfic_ops;
66 }
67 
68 void hfic_it_handle(struct hfic_data *hd __unused)
69 {
70 	uint32_t id = 0;
71 	uint32_t res __maybe_unused = 0;
72 
73 	id = thread_hvc(HF_INTERRUPT_GET, 0, 0, 0);
74 	if (id == HF_INVALID_INTID) {
75 		DMSG("ignoring invalid interrupt %#"PRIx32, id);
76 		return;
77 	}
78 
79 	itr_handle(id);
80 	res = thread_hvc(HF_INTERRUPT_DEACTIVATE, id, id, 0);
81 	assert(!res);
82 }
83