更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
gic_v2.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "gic_common.h"
33#include "los_hwi.h"
34#include "los_hwi_pri.h"
35#include "los_mp.h"
36
37STATIC_ASSERT(OS_USER_HWI_MAX <= 1020, "hwi max is too large!");
38
39#ifdef LOSCFG_ARCH_GIC_V2
40
42
43#ifdef LOSCFG_KERNEL_SMP
44/*
45 * filter description
46 * 0b00: forward to the cpu interfaces specified in cpu_mask
47 * 0b01: forward to all cpu interfaces
48 * 0b10: forward only to the cpu interface that request the irq
49 */
50STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter)
51{
52 UINT32 val = ((filter & 0x3) << 24) | ((cpuMask & 0xFF) << 16) |
53 (vector & 0xF);
54
55 GIC_REG_32(GICD_SGIR) = val;
56}
57
58VOID HalIrqSendIpi(UINT32 target, UINT32 ipi)
59{
60 GicWriteSgi(ipi, target, 0);
61}
62
63VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask)
64{
65 UINT32 offset = vector / 4;
66 UINT32 index = vector & 0x3;
67
68 GIC_REG_8(GICD_ITARGETSR(offset) + index) = cpuMask;
69}
70#endif
71/// 获取当前中断号
73{
74 return g_curIrqNum;
75}
76/// 屏蔽中断
77VOID HalIrqMask(UINT32 vector)
78{
79 if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) {
80 return;
81 }
82
83 GIC_REG_32(GICD_ICENABLER(vector / 32)) = 1U << (vector % 32);
84}
85/// 撤销中断屏蔽
86VOID HalIrqUnmask(UINT32 vector)
87{
88 if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) {
89 return;
90 }
91
92 GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32);
93}
94
96{
97 if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) {
98 return;
99 }
100
101 GIC_REG_32(GICD_ISPENDR(vector >> 5)) = 1U << (vector % 32);
102}
103
104VOID HalIrqClear(UINT32 vector)
105{
106 GIC_REG_32(GICC_EOIR) = vector;
107}
108/// 中断控制器与CPU之间的关系初始化
110{
111 /* unmask interrupts */
112 GIC_REG_32(GICC_PMR) = 0xFF;//写中断优先级屏蔽寄存器,0xFF代表开放所有中断
113
114 /* enable gic cpu interface */
115 GIC_REG_32(GICC_CTLR) = 1;//使能GICC_CTLR寄存器,意思是打通控制器和CPU之间的链路
116}
117/// 中断控制器本身初始化
118VOID HalIrqInit(VOID)
119{
120 UINT32 i;
121
122 /* set externel interrupts to be level triggered, active low. | 设置外部中断为电平触发,低电平有效。*/
123 for (i = 32; i < OS_HWI_MAX_NUM; i += 16) {
124 GIC_REG_32(GICD_ICFGR(i / 16)) = 0;
125 }
126
127 /* set externel interrupts to CPU 0 | 将外部中断设置为 CPU 0*/
128 for (i = 32; i < OS_HWI_MAX_NUM; i += 4) {
129 GIC_REG_32(GICD_ITARGETSR(i / 4)) = 0x01010101;
130 }
131
132 /* set priority on all interrupts | 设置所有中断的优先级*/
133 for (i = 0; i < OS_HWI_MAX_NUM; i += 4) {
134 GIC_REG_32(GICD_IPRIORITYR(i / 4)) = GICD_INT_DEF_PRI_X4;
135 }
136
137 /* disable all interrupts. | 禁止所有中断*/
138 for (i = 0; i < OS_HWI_MAX_NUM; i += 32) {
139 GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0;
140 }
141
142 HalIrqInitPercpu();//启动和CPU之间关系
143
144 /* enable gic distributor control */
145 GIC_REG_32(GICD_CTLR) = 1;//使能中断分发寄存器
146
147#ifdef LOSCFG_KERNEL_SMP //多核情况下会出现CPU核间的通讯
148 /* register inter-processor interrupt | 注册核间中断*/
149 (VOID)LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);//由某CPU去唤醒其他CPU继续工作
150 (VOID)LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//由某CPU发起对其他CPU的调度
151 (VOID)LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpHaltHandler, 0);//由某CPU去暂停其他CPU的工作
152#ifdef LOSCFG_KERNEL_SMP_CALL
153 (VOID)LOS_HwiCreate(LOS_MP_IPI_FUNC_CALL, 0xa0, 0, OsMpFuncCallHandler, 0);//触发回调函数
154#endif
155#endif
156}
157
159{
160 UINT32 iar = GIC_REG_32(GICC_IAR);
161 UINT32 vector = iar & 0x3FFU;
162
163 /*
164 * invalid irq number, mainly the spurious interrupts 0x3ff,
165 * gicv2 valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM
166 * to do the checking.
167 */
168 if (vector >= OS_HWI_MAX_NUM) {
169 return;
170 }
171 g_curIrqNum = vector;
172
173 OsInterrupt(vector);
174
175 /* use orignal iar to do the EOI */
176 GIC_REG_32(GICC_EOIR) = iar;
177}
178
180{
181 UINT32 pidr = GIC_REG_32(GICD_PIDR2V2);
182 CHAR *irqVerString = NULL;
183
184 switch (pidr >> GIC_REV_OFFSET) {
185 case GICV1:
186 irqVerString = "GICv1";
187 break;
188 case GICV2:
189 irqVerString = "GICv2";
190 break;
191 default:
192 irqVerString = "unknown";
193 }
194 return irqVerString;
195}
196
197#endif
GIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器 http://weharmonyos.com/blog/44....
@ GICV1
Definition: gic_common.h:55
@ GICV2
Definition: gic_common.h:56
UINT32 HalCurIrqGet(VOID)
获取当前中断号
Definition: gic_v2.c:72
VOID HalIrqInit(VOID)
中断控制器本身初始化
Definition: gic_v2.c:118
VOID HalIrqHandler(VOID)
Definition: gic_v2.c:158
VOID HalIrqSendIpi(UINT32 target, UINT32 ipi)
Definition: gic_v2.c:58
STATIC_ASSERT(OS_USER_HWI_MAX<=1020, "hwi max is too large!")
VOID HalIrqUnmask(UINT32 vector)
撤销中断屏蔽
Definition: gic_v2.c:86
VOID HalIrqPending(UINT32 vector)
Definition: gic_v2.c:95
VOID HalIrqClear(UINT32 vector)
Definition: gic_v2.c:104
VOID HalIrqMask(UINT32 vector)
屏蔽中断
Definition: gic_v2.c:77
VOID HalIrqInitPercpu(VOID)
中断控制器与CPU之间的关系初始化
Definition: gic_v2.c:109
STATIC UINT32 g_curIrqNum
Definition: gic_v2.c:41
VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask)
Definition: gic_v2.c:63
STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter)
Definition: gic_v2.c:50
CHAR * HalIrqVersion(VOID)
Definition: gic_v2.c:179
LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, HWI_PRIOR_T hwiPrio, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler, HwiIrqParam *irqParam)
创建一个硬中断 中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时, handleIrq会调用该中断处理程序
Definition: los_hwi.c:429
VOID OsInterrupt(UINT32 intNum)
Definition: los_hwi.c:180
VOID OsMpWakeHandler(VOID)
硬中断唤醒处理函数
Definition: los_mp.c:83
VOID OsMpFuncCallHandler(VOID)
OsMpFuncCallHandler 回调向当前CPU注册过的函数
Definition: los_mp.c:182
VOID OsMpScheduleHandler(VOID)
硬中断调度处理函数
Definition: los_mp.c:88
VOID OsMpHaltHandler(VOID)
硬中断暂停处理函数
Definition: los_mp.c:97
@ LOS_MP_IPI_SCHEDULE
!< 唤醒CPU
Definition: los_mp.h:51
@ LOS_MP_IPI_WAKEUP
Definition: los_mp.h:50
@ LOS_MP_IPI_FUNC_CALL
!< 停止CPU
Definition: los_mp.h:54
@ LOS_MP_IPI_HALT
!< 调度CPU
Definition: los_mp.h:52
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63