• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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