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 Borongimisc_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