1*69e9ad1bSHuang Borong /* SPDX-License-Identifier: BSD-2-Clause */
2*69e9ad1bSHuang Borong /*
3*69e9ad1bSHuang Borong * Copyright (c) 2021 Western Digital Corporation or its affiliates.
4*69e9ad1bSHuang Borong * Copyright (c) 2022 Ventana Micro Systems Inc.
5*69e9ad1bSHuang Borong * Copyright (c) 2025 Beijing Institute of Open Source Chip (BOSC)
6*69e9ad1bSHuang Borong *
7*69e9ad1bSHuang Borong * Authors:
8*69e9ad1bSHuang Borong * Anup Patel <anup.patel@wdc.com>
9*69e9ad1bSHuang Borong * Huang Borong <huangborong@bosc.ac.cn>
10*69e9ad1bSHuang Borong */
11*69e9ad1bSHuang Borong
12*69e9ad1bSHuang Borong #ifndef __DRIVERS_APLIC_PRIV_H
13*69e9ad1bSHuang Borong #define __DRIVERS_APLIC_PRIV_H
14*69e9ad1bSHuang Borong
15*69e9ad1bSHuang Borong #include <io.h>
16*69e9ad1bSHuang Borong #include <kernel/interrupt.h>
17*69e9ad1bSHuang Borong #include <types_ext.h>
18*69e9ad1bSHuang Borong #include <util.h>
19*69e9ad1bSHuang Borong
20*69e9ad1bSHuang Borong #define APLIC_MAX_SOURCE 1024
21*69e9ad1bSHuang Borong #define APLIC_COMPATIBLE "riscv,aplic"
22*69e9ad1bSHuang Borong
23*69e9ad1bSHuang Borong /* APLIC registers */
24*69e9ad1bSHuang Borong #define APLIC_DOMAINCFG 0x0000
25*69e9ad1bSHuang Borong #define APLIC_DOMAINCFG_RDONLY 0x80000000
26*69e9ad1bSHuang Borong #define APLIC_DOMAINCFG_IE BIT(8)
27*69e9ad1bSHuang Borong #define APLIC_DOMAINCFG_DM BIT(2)
28*69e9ad1bSHuang Borong #define APLIC_DOMAINCFG_BE BIT(0)
29*69e9ad1bSHuang Borong
30*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_BASE 0x0004 /* sourcecfg[1] */
31*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_D BIT(10)
32*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_CHILDIDX_MASK GENMASK_32(9, 0)
33*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_SM_MASK GENMASK_32(2, 0)
34*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_SM_INACTIVE 0x0
35*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_SM_DETACHED 0x1
36*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_SM_EDGE_RISE 0x4
37*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_SM_EDGE_FALL 0x5
38*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_SM_LEVEL_HIGH 0x6
39*69e9ad1bSHuang Borong #define APLIC_SOURCECFG_SM_LEVEL_LOW 0x7
40*69e9ad1bSHuang Borong
41*69e9ad1bSHuang Borong #define APLIC_MMSIADDRCFG 0x1BC0
42*69e9ad1bSHuang Borong #define APLIC_MMSIADDRCFGH 0x1BC4
43*69e9ad1bSHuang Borong #define APLIC_SMSIADDRCFG 0x1BC8
44*69e9ad1bSHuang Borong #define APLIC_SMSIADDRCFGH 0x1BCC
45*69e9ad1bSHuang Borong
46*69e9ad1bSHuang Borong #define APLIC_SETIP_BASE 0x1C00
47*69e9ad1bSHuang Borong #define APLIC_SETIPNUM 0x1CDC
48*69e9ad1bSHuang Borong #define APLIC_IN_CLRIP_BASE 0x1D00
49*69e9ad1bSHuang Borong #define APLIC_CLRIPNUM 0x1DDC
50*69e9ad1bSHuang Borong #define APLIC_SETIE_BASE 0x1E00
51*69e9ad1bSHuang Borong #define APLIC_SETIENUM 0x1EDC
52*69e9ad1bSHuang Borong #define APLIC_CLRIE_BASE 0x1F00
53*69e9ad1bSHuang Borong #define APLIC_CLRIENUM 0x1FDC
54*69e9ad1bSHuang Borong #define APLIC_SETIPNUM_LE 0x2000
55*69e9ad1bSHuang Borong #define APLIC_SETIPNUM_BE 0x2004
56*69e9ad1bSHuang Borong #define APLIC_GENMSI 0x3000
57*69e9ad1bSHuang Borong
58*69e9ad1bSHuang Borong #define APLIC_TARGET_BASE 0x3004 /* target[1] */
59*69e9ad1bSHuang Borong #define APLIC_TARGET_HART_IDX_SHIFT 18
60*69e9ad1bSHuang Borong #define APLIC_TARGET_HART_IDX_MASK GENMASK_32(31, 18)
61*69e9ad1bSHuang Borong #define APLIC_TARGET_GUEST_IDX_SHIFT 12
62*69e9ad1bSHuang Borong #define APLIC_TARGET_GUEST_IDX_MASK GENMASK_32(17, 12)
63*69e9ad1bSHuang Borong #define APLIC_TARGET_EIID_MASK GENMASK_32(10, 0)
64*69e9ad1bSHuang Borong #define APLIC_TARGET_IPRIO_MASK GENMASK_32(7, 0)
65*69e9ad1bSHuang Borong
66*69e9ad1bSHuang Borong /*
67*69e9ad1bSHuang Borong * struct aplic_data - APLIC interrupt controller
68*69e9ad1bSHuang Borong * @aplic_base: Base address of the APLIC
69*69e9ad1bSHuang Borong * @size: Size of the APLIC in bytes
70*69e9ad1bSHuang Borong * @targets_mmode: Indicates if APLIC targets Machine mode (true) or not (false)
71*69e9ad1bSHuang Borong * @num_idc: Number of interrupt delivery control structures supported by APLIC
72*69e9ad1bSHuang Borong * @num_source: Number of interrupt sources supported by APLIC
73*69e9ad1bSHuang Borong * @chip: Interrupt controller base class
74*69e9ad1bSHuang Borong */
75*69e9ad1bSHuang Borong struct aplic_data {
76*69e9ad1bSHuang Borong vaddr_t aplic_base;
77*69e9ad1bSHuang Borong uint32_t size;
78*69e9ad1bSHuang Borong bool targets_mmode;
79*69e9ad1bSHuang Borong uint32_t num_idc;
80*69e9ad1bSHuang Borong uint32_t num_source;
81*69e9ad1bSHuang Borong struct itr_chip chip;
82*69e9ad1bSHuang Borong };
83*69e9ad1bSHuang Borong
aplic_enable_interrupt(struct aplic_data * aplic,uint32_t source)84*69e9ad1bSHuang Borong static inline void aplic_enable_interrupt(struct aplic_data *aplic,
85*69e9ad1bSHuang Borong uint32_t source)
86*69e9ad1bSHuang Borong {
87*69e9ad1bSHuang Borong io_write32(aplic->aplic_base + APLIC_SETIENUM, source);
88*69e9ad1bSHuang Borong }
89*69e9ad1bSHuang Borong
aplic_disable_interrupt(struct aplic_data * aplic,uint32_t source)90*69e9ad1bSHuang Borong static inline void aplic_disable_interrupt(struct aplic_data *aplic,
91*69e9ad1bSHuang Borong uint32_t source)
92*69e9ad1bSHuang Borong {
93*69e9ad1bSHuang Borong io_write32(aplic->aplic_base + APLIC_CLRIENUM, source);
94*69e9ad1bSHuang Borong }
95*69e9ad1bSHuang Borong
aplic_set_pending(struct aplic_data * aplic,uint32_t source)96*69e9ad1bSHuang Borong static inline void aplic_set_pending(struct aplic_data *aplic, uint32_t source)
97*69e9ad1bSHuang Borong {
98*69e9ad1bSHuang Borong io_write32(aplic->aplic_base + APLIC_SETIPNUM, source);
99*69e9ad1bSHuang Borong }
100*69e9ad1bSHuang Borong
aplic_clear_pending(struct aplic_data * aplic,uint32_t source)101*69e9ad1bSHuang Borong static inline void aplic_clear_pending(struct aplic_data *aplic,
102*69e9ad1bSHuang Borong uint32_t source)
103*69e9ad1bSHuang Borong {
104*69e9ad1bSHuang Borong io_write32(aplic->aplic_base + APLIC_CLRIPNUM, source);
105*69e9ad1bSHuang Borong }
106*69e9ad1bSHuang Borong
aplic_is_bad_it(struct aplic_data * aplic,size_t it)107*69e9ad1bSHuang Borong static inline bool aplic_is_bad_it(struct aplic_data *aplic, size_t it)
108*69e9ad1bSHuang Borong {
109*69e9ad1bSHuang Borong return !it || it > aplic->num_source;
110*69e9ad1bSHuang Borong }
111*69e9ad1bSHuang Borong
112*69e9ad1bSHuang Borong TEE_Result aplic_init_from_device_tree(struct aplic_data *aplic);
113*69e9ad1bSHuang Borong TEE_Result aplic_set_source_mode(struct aplic_data *aplic, uint32_t source,
114*69e9ad1bSHuang Borong uint32_t type);
115*69e9ad1bSHuang Borong
116*69e9ad1bSHuang Borong #endif /* __DRIVERS_APLIC_PRIV_H */
117