xref: /optee_os/core/include/drivers/imsic.h (revision f4b54213e855ff3b67f052923fab966614797036)
1*f4b54213SHuang Borong /* SPDX-License-Identifier: BSD-2-Clause */
2*f4b54213SHuang Borong /*
3*f4b54213SHuang Borong  * Copyright (c) 2021 Western Digital Corporation or its affiliates.
4*f4b54213SHuang Borong  * Copyright (c) 2022 Ventana Micro Systems Inc.
5*f4b54213SHuang Borong  * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
6*f4b54213SHuang Borong  *
7*f4b54213SHuang Borong  * Authors:
8*f4b54213SHuang Borong  *   Anup Patel <anup.patel@wdc.com>
9*f4b54213SHuang Borong  *   Huang Borong <huangborong@bosc.ac.cn>
10*f4b54213SHuang Borong  */
11*f4b54213SHuang Borong 
12*f4b54213SHuang Borong #ifndef __DRIVERS_IMSIC_H
13*f4b54213SHuang Borong #define __DRIVERS_IMSIC_H
14*f4b54213SHuang Borong 
15*f4b54213SHuang Borong #include <kernel/interrupt.h>
16*f4b54213SHuang Borong #include <tee_api_defines.h>
17*f4b54213SHuang Borong #include <types_ext.h>
18*f4b54213SHuang Borong 
19*f4b54213SHuang Borong /*
20*f4b54213SHuang Borong  * struct imsic_data - IMISC interrupt controller
21*f4b54213SHuang Borong  * @imsic_base: Base address of the interrupt file
22*f4b54213SHuang Borong  * @size: Size of the interrupt file in bytes
23*f4b54213SHuang Borong  * @targets_mmode: Indicates if IMSIC targets Machine mode (true) or not (false)
24*f4b54213SHuang Borong  * @num_ids: Number of interrupt identities supported by an interrupt file
25*f4b54213SHuang Borong  * @guest_index_bits: Number of guest index bits in the MSI target address
26*f4b54213SHuang Borong  * @hart_index_bits: Number of hart index bits in the MSI target address
27*f4b54213SHuang Borong  * @group_index_bits: Number of group index bits in the MSI target address
28*f4b54213SHuang Borong  * @group_index_shift: Number of bits to shift the group index
29*f4b54213SHuang Borong  * @aplic_chip: Pointer to the associated APLIC's itr_chip
30*f4b54213SHuang Borong  * @chip: Interrupt controller base class
31*f4b54213SHuang Borong  */
32*f4b54213SHuang Borong struct imsic_data {
33*f4b54213SHuang Borong 	vaddr_t imsic_base;
34*f4b54213SHuang Borong 	uint32_t size;
35*f4b54213SHuang Borong 	bool targets_mmode;
36*f4b54213SHuang Borong 	uint32_t num_ids;
37*f4b54213SHuang Borong 	uint32_t guest_index_bits;
38*f4b54213SHuang Borong 	uint32_t hart_index_bits;
39*f4b54213SHuang Borong 	uint32_t group_index_bits;
40*f4b54213SHuang Borong 	uint32_t group_index_shift;
41*f4b54213SHuang Borong 	struct itr_chip *aplic_chip;
42*f4b54213SHuang Borong 	struct itr_chip chip;
43*f4b54213SHuang Borong };
44*f4b54213SHuang Borong 
45*f4b54213SHuang Borong /*
46*f4b54213SHuang Borong  * The imsic_init() function initializes the struct imsic_data which
47*f4b54213SHuang Borong  * is then used by other functions. This function also initializes
48*f4b54213SHuang Borong  * the IMSIC and should only be called from the primary boot hart.
49*f4b54213SHuang Borong  */
50*f4b54213SHuang Borong void imsic_init(paddr_t imsic_base_pa);
51*f4b54213SHuang Borong 
52*f4b54213SHuang Borong /*
53*f4b54213SHuang Borong  * Does per-hart specific IMSIC initialization, should be called by all
54*f4b54213SHuang Borong  * secondary harts when booting.
55*f4b54213SHuang Borong  */
56*f4b54213SHuang Borong void imsic_init_per_hart(void);
57*f4b54213SHuang Borong 
58*f4b54213SHuang Borong /* Handle external interrupts */
59*f4b54213SHuang Borong void imsic_it_handle(void);
60*f4b54213SHuang Borong 
61*f4b54213SHuang Borong /* Print IMSIC state to console */
62*f4b54213SHuang Borong void imsic_dump_state(void);
63*f4b54213SHuang Borong 
64*f4b54213SHuang Borong #if defined(CFG_DT) && defined(CFG_RISCV_IMSIC)
65*f4b54213SHuang Borong /*
66*f4b54213SHuang Borong  * imisc_parse_fdt_node() - Parse the IMSIC node from the device tree
67*f4b54213SHuang Borong  *
68*f4b54213SHuang Borong  * @fdt: Device tree to work on
69*f4b54213SHuang Borong  * @nodeoff: Offset of the node in the device tree
70*f4b54213SHuang Borong  * @imsic: Pointer to an imsic_data structure to store parsed information
71*f4b54213SHuang Borong  *
72*f4b54213SHuang Borong  * Returns TEE_Result value
73*f4b54213SHuang Borong  */
74*f4b54213SHuang Borong TEE_Result imisc_parse_fdt_node(const void *fdt, int nodeoff,
75*f4b54213SHuang Borong 				struct imsic_data *imsic);
76*f4b54213SHuang Borong #else
77*f4b54213SHuang Borong static inline TEE_Result
imisc_parse_fdt_node(const void * fdt __unused,int nodeoff __unused,struct imsic_data * imsic __unused)78*f4b54213SHuang Borong imisc_parse_fdt_node(const void *fdt __unused,
79*f4b54213SHuang Borong 		     int nodeoff __unused, struct imsic_data *imsic __unused)
80*f4b54213SHuang Borong {
81*f4b54213SHuang Borong 	return TEE_ERROR_NOT_SUPPORTED;
82*f4b54213SHuang Borong }
83*f4b54213SHuang Borong #endif
84*f4b54213SHuang Borong 
85*f4b54213SHuang Borong #endif /* __DRIVERS_IMSIC_H */
86