1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2020-06-16
13 * Description: 硬件GIC内部公共头文件
14 */
15 #ifndef PRT_GIC_EXTERNAL_H
16 #define PRT_GIC_EXTERNAL_H
17
18 #include "prt_lib_external.h"
19 #include "prt_buildef.h"
20
21 // 配置中断优先级,每个寄存器对应4个中断
22 #define GIC_IPRIORITY_INT_NUM 4
23 // 配置中断优先级,每8bit的高4bit有效,低bit预留
24 #define GIC_IPRIORITY_HIGH_BIT 4
25
26 #if (OS_GIC_VER == 2)
27 #define GIC_DIST_BASE 0xff841000
28 #define GIC_CPU_BASE 0xff842000
29 #define IAR_MASK 0x3FFU
30 #define GICC_IAR (GIC_CPU_BASE + 0xc)
31 #define GICC_EOIR (GIC_CPU_BASE + 0x10)
32 #define GICD_SGIR (GIC_DIST_BASE + 0xf00)
33 #elif (OS_GIC_VER == 3)
34 #define ICC_IAR1_EL1 S3_0_C12_C12_0
35 #define ICC_EOIR1_EL1 S3_0_C12_C12_1
36 #define ICC_SGI1R_EL1 S3_0_C12_C11_5
37 #endif
38 #define GIC_REG_BASE g_gicdBase
39 #define MAX_SGI_ID 15 // 系统支持的最大SGI的中断号
40 #define MIN_PPI_ID 16 // 系统支持的最小PPI的中断号
41 #define MAX_PPI_ID 31 // 系统支持的最大PPI的中断号
42 #define MAX_SPI_ID 1019 // 系统可支持的最大SPI的中断号
43 #define MAX_INT_PRIORITY 0xF // 安全可配置的最大优先级
44 #define GIC_INT_ID_MASK 0x3FFU
45 // 使能/去使能中断,每个寄存器对应32个中断
46 #define GIC_IENABLE_INT_NUM 32
47 // 将变参列表字符串化
48 #define PARAS_TO_STRING(x...) #x
49 // 获得变参的值
50 #define REG_ALIAS(x...) PARAS_TO_STRING(x)
51 // 读写GIC寄存器,32位
52 #define GIC_REG_READ(addr) (*(volatile U32 *)((uintptr_t)(addr)))
53 #define GIC_REG_WRITE(addr, data) (*(volatile U32 *)((uintptr_t)(addr)) = (U32)(data))
54
55 enum GicIntState {
56 GIC_DISABLE = 0,
57 GIC_ENABLE = 1
58 };
59
60 /* 存放Core Map值 */
61 union GicCoreMap {
62 struct {
63 U64 aff0 : 8; // bit[7:0]
64 U64 aff1 : 8; // bit[15:8]
65 U64 aff2 : 8; // bit[23:16]
66 U64 mt : 1; // bit[24] 0:single-thread 核号取AFF0, 1: muti-thread 模式,核号取AFF1
67 U64 rsvd0 : 5; // bit[29:25]
68 U64 uni : 1; // bit[30]
69 U64 rsvd1 : 1; // bit[31]
70 U64 aff3 : 8; // bit[39:32]
71 U64 rsvd2 : 24; // bit[63~40]
72 } bits;
73 U64 value;
74 };
75
76 /*
77 * 描述: 按bit设置GIC寄存器, Read-Modify-Write方式
78 */
OsGicRmwReg(uintptr_t base,U32 intNum,U32 intId,U32 val)79 OS_SEC_ALW_INLINE INLINE void OsGicRmwReg(uintptr_t base, U32 intNum, U32 intId, U32 val)
80 {
81 uintptr_t regAddr;
82 U32 regVal;
83 U32 offset;
84 U32 bitWidth;
85 U32 bitMask;
86
87 // 每个寄存器(32位)可配置idNum个硬中断
88 bitWidth = OS_WORD_BIT_NUM / intNum; // 每个硬中断对应的bit位宽:32 / idNum
89 bitMask = (1u << bitWidth) - 1u; // 每个硬中断对应的bit掩码
90 regAddr = base + ((intId / intNum) * sizeof(U32));
91 offset = ((intId % intNum) * bitWidth);
92
93 regVal = GIC_REG_READ(regAddr);
94 regVal &= ~(bitMask << offset); // 清除旧值
95 regVal |= ((val & bitMask) << offset); // 设置新值
96 GIC_REG_WRITE(regAddr, regVal);
97 }
98
99 /*
100 * 描述: 按bit设置GIC寄存器, 直接写,写前不需要先读
101 */
OsGicSetReg(uintptr_t base,U32 intNum,U32 intId,U32 val)102 OS_SEC_ALW_INLINE INLINE void OsGicSetReg(uintptr_t base, U32 intNum, U32 intId, U32 val)
103 {
104 uintptr_t regAddr;
105 U32 regVal;
106 U32 offset;
107 U32 bitWidth;
108 U32 bitMask;
109
110 // 每个寄存器(32位)可配置idNum个硬中断
111 bitWidth = OS_WORD_BIT_NUM / intNum; // 每个硬中断对应的bit位宽:32 / idNum
112 bitMask = (1u << bitWidth) - 1u; // 每个硬中断对应的bit掩码
113 regAddr = base + ((intId / intNum) * sizeof(U32));
114 offset = ((intId % intNum) * bitWidth);
115
116 regVal = ((val & bitMask) << offset); // 设置新值
117 GIC_REG_WRITE(regAddr, regVal);
118 }
119
120 /*
121 * 描述: 按bit读取GIC寄存器的值
122 */
OsGicGetReg(uintptr_t base,U32 idNum,U32 id)123 OS_SEC_ALW_INLINE INLINE U32 OsGicGetReg(uintptr_t base, U32 idNum, U32 id)
124 {
125 U64 regAddr;
126 U32 regVal;
127 U32 offset;
128 U32 bitWidth;
129 U32 bitMask;
130
131 // 每个寄存器有idNum个id,每个id对应的bit位数为sizeof(U32) / idNum
132 bitWidth = OS_WORD_BIT_NUM / idNum;
133 bitMask = (1u << bitWidth) - 1u;
134 regAddr = base + ((id / idNum) * sizeof(U32));
135 offset = ((id % idNum) * bitWidth);
136
137 regVal = GIC_REG_READ(regAddr);
138
139 return (regVal & (bitMask << offset)) >> offset;
140 }
141
142 /* GIC基地址 */
143 extern uintptr_t g_gicdBase;
144 /* GICR相对于GIC基地址偏移向量 */
145 extern uintptr_t g_gicrOffset;
146 /* GICR核间偏移向量配置 */
147 extern uintptr_t g_gicrStride;
148 /* 存放Core Map值 */
149 extern union GicCoreMap g_gicCoreMap;
150
151 extern void OsGicEnableInt(U32 intId);
152 extern void OsGicDisableInt(U32 intId);
153 extern void OsGicTrigIntToCores(U32 intId, U32 targetList);
154 extern void OsGicSetTargetId(U32 intId, U32 targetId);
155 extern U32 OsGicGetPriority(U32 intId);
156 extern U32 OsGicSetPriority(U32 intId, U32 priority);
157
158 extern enum GicIntState OsGicdGetIntState(U32 intId);
159 extern void OsGicdEnableInt(U32 intId);
160 extern void OsGicdDisableInt(U32 intId);
161 extern void OsGicdSetPriority(U32 intId, U32 priority);
162 extern void OsGicdCfgTargetId(U32 intId, U32 targetId);
163 extern U32 OsGicdGetPriority(U32 intId);
164
165 extern enum GicIntState OsGicrGetIntState(U32 coreId, U32 intId);
166 extern void OsGicrEnableInt(U32 coreId, U32 intId);
167 extern void OsGicrDisableInt(U32 coreId, U32 intId);
168 extern void OsGicrSetPriority(U32 coreId, U32 intId, U32 priority);
169 extern U32 OsGicrGetPriority(U32 coreId, U32 intId);
170 extern bool OsGicIsSpi(U32 intId);
171
172 #endif /* PRT_GIC_EXTERNAL_H */
173