• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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: 2022-11-18
13  * Description: 硬件GICR相关的处理。
14  */
15 #include "prt_gic_external.h"
16 #include "prt_gic_internal.h"
17 #include "prt_attr_external.h"
18 
19 /* GICR_CTRL */
20 union GicrCtrl {
21     struct {
22         U32 enLpis : 1;  // bit[0] LPIs中断使能控制寄存器
23         U32 res2   : 2;  // bit[2:1]
24         U32 rwp    : 1;  // bit[3] 标识前面一次写GICR寄存器的配置信息是否生效
25         U32 res1   : 20; // bit[23:4]
26         U32 dpg0   : 1;  // bit[24]
27         U32 dpg1ns : 1;  // bit[25]
28         U32 dpg1s  : 1;  // bit[26]
29         U32 res0   : 4;  // bit[30:27]
30         U32 uwp    : 1;  // bit[31] GICD对Upstream Write和Generate SGI是否可见
31     } bits;
32     U32    value;
33 };
34 
35 /*
36  * 描述: 等待写寄存器操作生效
37  */
OsGicrWaitCfgWork(U32 coreId)38 OS_SEC_TEXT void OsGicrWaitCfgWork(U32 coreId)
39 {
40     union GicrCtrl gicrCtrl;
41     uintptr_t regAddr;
42 
43     regAddr = GICR_CTRL_ADDR + (coreId * GICR_ADDR_OFFSET_PER_CORE);
44     do {
45         gicrCtrl.value = GIC_REG_READ(regAddr);
46     } while (gicrCtrl.bits.rwp == 1);
47 }
48 
49 /*
50  * 描述: 获取PPI, SGI, NNSPI的使能状态, 调用者保证入参的有效性
51  */
OsGicrGetIntState(U32 coreId,U32 intId)52 OS_SEC_TEXT enum GicIntState OsGicrGetIntState(U32 coreId, U32 intId)
53 {
54     // 每个寄存器对应32个中断
55     return OsGicGetReg(GICR_ISENABLER0_ADDR + coreId * GICR_ADDR_OFFSET_PER_CORE,
56                        GIC_IENABLE_INT_NUM, intId);
57 }
58 
59 /*
60  * 描述: 使能PPI, SGI, NNSPI, 调用者保证入参的有效性
61  */
OsGicrEnableInt(U32 coreId,U32 intId)62 OS_SEC_TEXT void OsGicrEnableInt(U32 coreId, U32 intId)
63 {
64     // 每个寄存器对应32个中断,写1使能中断,写0无效
65     OsGicSetReg(GICR_ISENABLER0_ADDR + coreId * GICR_ADDR_OFFSET_PER_CORE,
66                 GIC_IENABLE_INT_NUM, intId, 1);
67 
68     OsGicrWaitCfgWork(coreId); // 确保操作生效
69 }
70 
71 /*
72  * 描述: 去使能PPI, SGI, NNSPI, 调用者保证入参的有效性
73  */
OsGicrDisableInt(U32 coreId,U32 intId)74 OS_SEC_TEXT void OsGicrDisableInt(U32 coreId, U32 intId)
75 {
76     // 每个寄存器对应32个中断,写1去使能中断,写0无效
77     OsGicSetReg(GICR_ICENABLER0_ADDR + coreId * GICR_ADDR_OFFSET_PER_CORE,
78                 GIC_IENABLE_INT_NUM, intId, 1);
79 
80     OsGicrWaitCfgWork(coreId);  // 确保操作生效
81 }
82 
83 /*
84  * 描述: 设置SGI, PPI, NNSPI中断的优先级, 调用者保证入参的有效性
85  */
OsGicrSetPriority(U32 coreId,U32 intId,U32 priority)86 OS_SEC_L4_TEXT void OsGicrSetPriority(U32 coreId, U32 intId, U32 priority)
87 {
88     // 每个寄存器对应4个中断, 每8bit中的高4bit对应一个中断优先级
89     OsGicRmwReg(GICR_IPRIORITY_SGI_S_ADDR + coreId * GICR_ADDR_OFFSET_PER_CORE,
90                 GIC_IPRIORITY_INT_NUM, intId, priority << GIC_IPRIORITY_HIGH_BIT);
91 }
92 
93 /*
94  * 描述: 获取SGI, PPI, NNSPI中断的优先级, 调用者保证入参的有效性
95  */
OsGicrGetPriority(U32 coreId,U32 intId)96 OS_SEC_L2_TEXT U32 OsGicrGetPriority(U32 coreId, U32 intId)
97 {
98     U32 gicrPrio;
99 
100     // 每个寄存器(32位)对应4个中断, 即每8bit对应1个中断
101     gicrPrio = OsGicGetReg(GICR_IPRIORITY_SGI_S_ADDR + coreId * GICR_ADDR_OFFSET_PER_CORE,
102                            GIC_IPRIORITY_INT_NUM, intId);
103 
104     return (gicrPrio >> GIC_IPRIORITY_HIGH_BIT); // 4: 每8bit中的高4bit对应一个中断的优先级, 低4bit预留。
105 }
106