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