中断是如何管理的? CPU之间又是如何通讯的?

搜索 @note_pic 方便理解画的字符图
搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善
搜索 @note_thinking 一点思考和吐槽的地方
搜索 @note_#if0 由第三方项目提供不由内核源码中定义的极为重要的结构体,为方便理解而添加的
搜索 @note_good 给源码点赞
上级 93e46461
...@@ -155,13 +155,13 @@ STATIC INLINE UINT64 OsHwIDGet(VOID) ...@@ -155,13 +155,13 @@ STATIC INLINE UINT64 OsHwIDGet(VOID)
{ {
return ARM_SYSREG_READ(MPIDR); return ARM_SYSREG_READ(MPIDR);
} }
//获取CPU型号,包含CPU各种信息,例如:[15:4]表示 arm 7或arm 9
STATIC INLINE UINT32 OsMainIDGet(VOID) STATIC INLINE UINT32 OsMainIDGet(VOID)
{ {
return ARM_SYSREG_READ(MIDR); return ARM_SYSREG_READ(MIDR);
} }
/* CPU interrupt mask handle implementation */ /* CPU interrupt mask handle implementation */ //CPU中断掩码句柄实现
#if LOSCFG_ARM_ARCH >= 6 #if LOSCFG_ARM_ARCH >= 6
STATIC INLINE UINT32 ArchIntLock(VOID) STATIC INLINE UINT32 ArchIntLock(VOID)
......
...@@ -235,7 +235,7 @@ OsIrqFromKernel: ...@@ -235,7 +235,7 @@ OsIrqFromKernel:
EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R1, R2 EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R1, R2
#endif #endif
BLX HalIrqHandler BLX HalIrqHandler /* 调用硬中断处理程序 */
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK #ifdef LOSCFG_IRQ_USE_STANDALONE_STACK
MOV SP, R4 MOV SP, R4
......
...@@ -292,12 +292,12 @@ extern VOID DCacheInvRange(UINTPTR start, UINTPTR end); ...@@ -292,12 +292,12 @@ extern VOID DCacheInvRange(UINTPTR start, UINTPTR end);
* @par Dependency: * @par Dependency:
* los_hw.h: the header file that contains the API declaration. * los_hw.h: the header file that contains the API declaration.
* @see None. * @see None.
*/ */ //获取CPU信息
STATIC INLINE const CHAR *LOS_CpuInfo(VOID) STATIC INLINE const CHAR *LOS_CpuInfo(VOID)
{ {
INT32 i; INT32 i;
UINT32 midr = OsMainIDGet(); UINT32 midr = OsMainIDGet();
/* [15:4] is the primary part number */ /* [15:4] is the primary part number */ //[15:4]是主要编号
UINT32 partNo = (midr & 0xFFF0) >> 0x4; UINT32 partNo = (midr & 0xFFF0) >> 0x4;
for (i = 0; g_cpuTable[i].partNo != 0; i++) { for (i = 0; g_cpuTable[i].partNo != 0; i++) {
......
...@@ -42,9 +42,21 @@ extern "C" { ...@@ -42,9 +42,21 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/******************************************************* /*******************************************************
多CPU核的操作系统3种处理模式(SMP+AMP+BMP) 鸿蒙实现的是 SMP 的方式 多CPU核的操作系统3种处理模式(SMP+AMP+BMP) 鸿蒙实现的是 SMP 的方式
非对称多处理(Asymmetric multiprocessing,AMP)每个CPU内核运行一个独立的操作系统或同一操作系统的独立实例(instantiation)。 非对称多处理(Asymmetric multiprocessing,AMP)每个CPU内核
对称多处理(Symmetric multiprocessing,SMP)一个操作系统的实例可以同时管理所有CPU内核,且应用并不绑定某一个内核。 运行一个独立的操作系统或同一操作系统的独立实例(instantiation)。
混合多处理(Bound multiprocessing,BMP)一个操作系统的实例可以同时管理所有CPU内核,但每个应用被锁定于某个指定的核心。
对称多处理(Symmetric multiprocessing,SMP)一个操作系统的实例
可以同时管理所有CPU内核,且应用并不绑定某一个内核。
混合多处理(Bound multiprocessing,BMP)一个操作系统的实例可以
同时管理所有CPU内核,但每个应用被锁定于某个指定的核心。
多核多线程处理器的中断
由 PIC(Programmable Interrupt Controller)统一控制。PIC 允许一个
硬件线程中断其他的硬件线程,这种方式被称为核间中断(Inter-Processor Interrupts,IPI)
SGI:软件触发中断(Software Generated Interrupt)。在arm处理器中,
SGI共有16个,硬件中断号分别为ID0~ID15。它通常用于多核间通讯。
********************************************************/ ********************************************************/
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
...@@ -52,8 +64,8 @@ extern "C" { ...@@ -52,8 +64,8 @@ extern "C" {
VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core
{ {
UINT32 cpuid = ArchCurrCpuid(); UINT32 cpuid = ArchCurrCpuid();
target &= ~(1U << cpuid); target &= ~(1U << cpuid);//获取除了自身之外的其他CPU
HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);//处理器间中断(IPI) HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);//向目标CPU发送调度信号,核间中断(Inter-Processor Interrupts),IPI
} }
//硬中断唤醒处理函数 //硬中断唤醒处理函数
VOID OsMpWakeHandler(VOID) VOID OsMpWakeHandler(VOID)
...@@ -85,7 +97,7 @@ VOID OsMpCollectTasks(VOID) ...@@ -85,7 +97,7 @@ VOID OsMpCollectTasks(VOID)
UINT32 ret; UINT32 ret;
/* recursive checking all the available task */ /* recursive checking all the available task */
for (; taskID <= g_taskMaxNum; taskID++) { for (; taskID <= g_taskMaxNum; taskID++) { //递归检查所有可用任务
taskCB = &g_taskCBArray[taskID]; taskCB = &g_taskCBArray[taskID];
if (OsTaskIsUnused(taskCB) || OsTaskIsRunning(taskCB)) { if (OsTaskIsUnused(taskCB) || OsTaskIsRunning(taskCB)) {
...@@ -96,8 +108,8 @@ VOID OsMpCollectTasks(VOID) ...@@ -96,8 +108,8 @@ VOID OsMpCollectTasks(VOID)
* though task status is not atomic, this check may success but not accomplish * though task status is not atomic, this check may success but not accomplish
* the deletion; this deletion will be handled until the next run. * the deletion; this deletion will be handled until the next run.
*/ */
if (taskCB->signal & SIGNAL_KILL) { if (taskCB->signal & SIGNAL_KILL) {//任务收到被干掉信号
ret = LOS_TaskDelete(taskID); ret = LOS_TaskDelete(taskID);//干掉任务,回归任务池
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINT_WARN("GC collect task failed err:0x%x\n", ret); PRINT_WARN("GC collect task failed err:0x%x\n", ret);
} }
......
此差异已折叠。
...@@ -77,7 +77,7 @@ extern UINT32 __heap_end; // 堆区结束地址 ...@@ -77,7 +77,7 @@ extern UINT32 __heap_end; // 堆区结束地址
* time timer clock (unit: HZ) * time timer clock (unit: HZ)
*/ */
#ifndef OS_TIME_TIMER_CLOCK #ifndef OS_TIME_TIMER_CLOCK
#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK #define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK //定时器频率
#endif #endif
/** /**
...@@ -109,16 +109,16 @@ extern UINT32 __heap_end; // 堆区结束地址 ...@@ -109,16 +109,16 @@ extern UINT32 __heap_end; // 堆区结束地址
/** /**
* @ingroup los_config * @ingroup los_config
* Sched clck interval * Sched clock interval
*/ */
#define SCHED_CLOCK_INTETRVAL_TICKS 100 #define SCHED_CLOCK_INTETRVAL_TICKS 100 //调度时间间隔
/** /**
* @ingroup los_config * @ingroup los_config
* External configuration item for timer tailoring * External configuration item for timer tailoring
*/ */
#ifndef LOSCFG_BASE_CORE_TICK_HW_TIME #ifndef LOSCFG_BASE_CORE_TICK_HW_TIME
#define LOSCFG_BASE_CORE_TICK_HW_TIME NO #define LOSCFG_BASE_CORE_TICK_HW_TIME NO //定时器裁剪的外部配置项
#endif #endif
/****************************** Hardware interrupt module configuration ******************************/ /****************************** Hardware interrupt module configuration ******************************/
......
/* /*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* 3. Neither the name of the copyright holder nor the names of its contributors may be used * 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written * to endorse or promote products derived from this software without specific prior written
* permission. * permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "gic_common.h" #include "gic_common.h"
#include "los_hwi_pri.h" #include "los_hwi_pri.h"
#include "los_mp.h" #include "los_mp.h"
STATIC_ASSERT(OS_USER_HWI_MAX <= 1020, "hwi max is too large!"); STATIC_ASSERT(OS_USER_HWI_MAX <= 1020, "hwi max is too large!");
#ifdef LOSCFG_PLATFORM_BSP_GIC_V2 #ifdef LOSCFG_PLATFORM_BSP_GIC_V2
STATIC UINT32 g_curIrqNum = 0; STATIC UINT32 g_curIrqNum = 0;
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
/* /*
* filter description * filter description
* 0b00: forward to the cpu interfaces specified in cpu_mask * 0b00: forward to the cpu interfaces specified in cpu_mask
* 0b01: forward to all cpu interfaces * 0b01: forward to all cpu interfaces
* 0b10: forward only to the cpu interface that request the irq * 0b10: forward only to the cpu interface that request the irq
*/ */
STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter) STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter)
{ {
UINT32 val = ((filter & 0x3) << 24) | ((cpuMask & 0xFF) << 16) | UINT32 val = ((filter & 0x3) << 24) | ((cpuMask & 0xFF) << 16) |
(vector & 0xF); (vector & 0xF);
GIC_REG_32(GICD_SGIR) = val; GIC_REG_32(GICD_SGIR) = val;
} }
VOID HalIrqSendIpi(UINT32 target, UINT32 ipi) VOID HalIrqSendIpi(UINT32 target, UINT32 ipi)
{ {
GicWriteSgi(ipi, target, 0); GicWriteSgi(ipi, target, 0);
} }
VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask) VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask)
{ {
UINT32 offset = vector / 4; UINT32 offset = vector / 4;
UINT32 index = vector & 0x3; UINT32 index = vector & 0x3;
GIC_REG_8(GICD_ITARGETSR(offset) + index) = cpuMask; GIC_REG_8(GICD_ITARGETSR(offset) + index) = cpuMask;
} }
#endif #endif
UINT32 HalCurIrqGet(VOID) UINT32 HalCurIrqGet(VOID)
{ {
return g_curIrqNum; return g_curIrqNum;
} }
//屏蔽中断 //屏蔽中断
VOID HalIrqMask(UINT32 vector) VOID HalIrqMask(UINT32 vector)
{ {
if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) {
return; return;
} }
GIC_REG_32(GICD_ICENABLER(vector / 32)) = 1U << (vector % 32); GIC_REG_32(GICD_ICENABLER(vector / 32)) = 1U << (vector % 32);
} }
//解除屏蔽 //解除屏蔽
VOID HalIrqUnmask(UINT32 vector) VOID HalIrqUnmask(UINT32 vector)
{ {
if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) {
return; return;
} }
GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32); GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32);
} }
VOID HalIrqPending(UINT32 vector) VOID HalIrqPending(UINT32 vector)
{ {
if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) {
return; return;
} }
GIC_REG_32(GICD_ISPENDR(vector >> 5)) = 1U << (vector % 32); GIC_REG_32(GICD_ISPENDR(vector >> 5)) = 1U << (vector % 32);
} }
//清除中断号对应的中断寄存器的状态位,此接口依赖中断控制器版本,非必需
VOID HalIrqClear(UINT32 vector) VOID HalIrqClear(UINT32 vector)
{ {
GIC_REG_32(GICC_EOIR) = vector; GIC_REG_32(GICC_EOIR) = vector;
} }
//给每个CPU core初始化硬件中断 //给每个CPU core初始化硬件中断
VOID HalIrqInitPercpu(VOID) VOID HalIrqInitPercpu(VOID)
{ {
/* unmask interrupts */ //取消屏蔽中断 /* unmask interrupts */ //取消屏蔽中断
GIC_REG_32(GICC_PMR) = 0xFF; GIC_REG_32(GICC_PMR) = 0xFF;
/* enable gic cpu interface */ //启用gic cpu接口 /* enable gic cpu interface */ //启用gic cpu接口
GIC_REG_32(GICC_CTLR) = 1; GIC_REG_32(GICC_CTLR) = 1;
} }
//硬件中断初始化 //硬件中断初始化
VOID HalIrqInit(VOID) VOID HalIrqInit(VOID)
{ {
UINT32 i; UINT32 i;
/* set externel interrupts to be level triggered, active low. */ //将外部中断设置为电平触发,低电平激活 /* set externel interrupts to be level triggered, active low. */ //将外部中断设置为电平触发,低电平激活
for (i = 32; i < OS_HWI_MAX_NUM; i += 16) { for (i = 32; i < OS_HWI_MAX_NUM; i += 16) {
GIC_REG_32(GICD_ICFGR(i / 16)) = 0; GIC_REG_32(GICD_ICFGR(i / 16)) = 0;
} }
/* set externel interrupts to CPU 0 */ //将外部中断设置为CPU 0 /* set externel interrupts to CPU 0 */ //将外部中断设置为CPU 0
for (i = 32; i < OS_HWI_MAX_NUM; i += 4) { for (i = 32; i < OS_HWI_MAX_NUM; i += 4) {
GIC_REG_32(GICD_ITARGETSR(i / 4)) = 0x01010101; GIC_REG_32(GICD_ITARGETSR(i / 4)) = 0x01010101;
} }
/* set priority on all interrupts */ //设置所有中断的优先级 /* set priority on all interrupts */ //设置所有中断的优先级
for (i = 0; i < OS_HWI_MAX_NUM; i += 4) { for (i = 0; i < OS_HWI_MAX_NUM; i += 4) {
GIC_REG_32(GICD_IPRIORITYR(i / 4)) = GICD_INT_DEF_PRI_X4; GIC_REG_32(GICD_IPRIORITYR(i / 4)) = GICD_INT_DEF_PRI_X4;
} }
/* disable all interrupts. */ //禁用所有中断。 /* disable all interrupts. */ //禁用所有中断。
for (i = 0; i < OS_HWI_MAX_NUM; i += 32) { for (i = 0; i < OS_HWI_MAX_NUM; i += 32) {
GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0; GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0;
} }
HalIrqInitPercpu(); HalIrqInitPercpu();
/* enable gic distributor control */ /* enable gic distributor control */
GIC_REG_32(GICD_CTLR) = 1; GIC_REG_32(GICD_CTLR) = 1;
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
/* register inter-processor interrupt *///注册寄存器处理器间中断处理函数,啥意思?就是当前CPU核向其他CPU核发送中断信号 /* register inter-processor interrupt *///注册寄存器处理器间中断处理函数,啥意思?就是当前CPU核向其他CPU核发送中断信号
//处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。 //处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。
LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);//中断处理函数 LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);//中断处理函数
LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数 LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数
LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数 LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数
#endif #endif
} }
//硬中断处理函数,这里由硬件触发 //硬中断处理函数,这里由硬件触发,调用见于 ..\arch\arm\arm\src\los_dispatch.S
VOID HalIrqHandler(VOID) VOID HalIrqHandler(VOID)
{ {
UINT32 iar = GIC_REG_32(GICC_IAR); UINT32 iar = GIC_REG_32(GICC_IAR);
UINT32 vector = iar & 0x3FFU; UINT32 vector = iar & 0x3FFU;
/* /*
* invalid irq number, mainly the spurious interrupts 0x3ff, * invalid irq number, mainly the spurious interrupts 0x3ff,
* gicv2 valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM * gicv2 valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM
* to do the checking. * to do the checking.
*/ */
if (vector >= OS_HWI_MAX_NUM) { if (vector >= OS_HWI_MAX_NUM) {
return; return;
} }
g_curIrqNum = vector; g_curIrqNum = vector;
OsInterrupt(vector); OsInterrupt(vector);
/* use orignal iar to do the EOI */ /* use orignal iar to do the EOI */
GIC_REG_32(GICC_EOIR) = iar; GIC_REG_32(GICC_EOIR) = iar;
} }
//获取中断控制器版本
CHAR *HalIrqVersion(VOID) CHAR *HalIrqVersion(VOID)
{ {
UINT32 pidr = GIC_REG_32(GICD_PIDR2V2); UINT32 pidr = GIC_REG_32(GICD_PIDR2V2);
CHAR *irqVerString = NULL; CHAR *irqVerString = NULL;
switch (pidr >> GIC_REV_OFFSET) { switch (pidr >> GIC_REV_OFFSET) {
case GICV1: case GICV1:
irqVerString = "GICv1"; irqVerString = "GICv1";
break; break;
case GICV2: case GICV2:
irqVerString = "GICv2"; irqVerString = "GICv2";
break; break;
default: default:
irqVerString = "unknown"; irqVerString = "unknown";
} }
return irqVerString; return irqVerString;
} }
#endif #endif
/* /*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* 3. Neither the name of the copyright holder nor the names of its contributors may be used * 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written * to endorse or promote products derived from this software without specific prior written
* permission. * permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "asm/platform.h" #include "asm/platform.h"
#include "los_hwi.h" #include "los_hwi.h"
#include "los_tick_pri.h" #include "los_tick_pri.h"
#define OS_CYCLE_PER_TICK (TIMER_FREQ / LOSCFG_BASE_CORE_TICK_PER_SECOND) #define OS_CYCLE_PER_TICK (TIMER_FREQ / LOSCFG_BASE_CORE_TICK_PER_SECOND)
typedef struct { typedef struct {
UINT32 load; /* Private Timer Load Register */ UINT32 load; /* Private Timer Load Register */
UINT32 count; /* Private Timer Counter Register */ UINT32 count; /* Private Timer Counter Register */
UINT32 control; /* Private Timer Control Register */ UINT32 control; /* Private Timer Control Register */
UINT32 intStatus; /* Private Timer Interrupt Status Register */ UINT32 intStatus; /* Private Timer Interrupt Status Register */
} PrivateTimer; } PrivateTimer;
typedef struct { typedef struct {
UINT32 low; /* Global Timer Counter Registers, low bits */ UINT32 low; /* Global Timer Counter Registers, low bits */
UINT32 high; /* Global Timer Counter Registers, high bits */ UINT32 high; /* Global Timer Counter Registers, high bits */
UINT32 control; /* Global Timer Control Register */ UINT32 control; /* Global Timer Control Register */
UINT32 intStatus; /* Global Timer Interrupt Status Register */ UINT32 intStatus; /* Global Timer Interrupt Status Register */
UINT32 compareLow; /* Comparator Value Registers, low bits */ UINT32 compareLow; /* Comparator Value Registers, low bits */
UINT32 compareHigh; /* Comparator Value Registers, high bits */ UINT32 compareHigh; /* Comparator Value Registers, high bits */
UINT32 increment; /* Auto-increment Register */ UINT32 increment; /* Auto-increment Register */
} GlobalTimer; } GlobalTimer;
PrivateTimer *g_privateTimer = (PrivateTimer *)PRVTIMER_BASE_ADDR; PrivateTimer *g_privateTimer = (PrivateTimer *)PRVTIMER_BASE_ADDR;
GlobalTimer *g_globalTimer = (GlobalTimer *)GTIMER_BASE_ADDR; GlobalTimer *g_globalTimer = (GlobalTimer *)GTIMER_BASE_ADDR;
UINT32 HalClockFreqRead(VOID) UINT32 HalClockFreqRead(VOID)
{ {
return TIMER_FREQ; return TIMER_FREQ;
} }
VOID HalClockFreqWrite(UINT32 freq) VOID HalClockFreqWrite(UINT32 freq)
{ {
PRINT_WARN("private timer does not support setting frequency\n"); PRINT_WARN("private timer does not support setting frequency\n");
} }
VOID HalClockStart(VOID) VOID HalClockStart(VOID)
{ {
HalIrqUnmask(PRVTIMER_INT_NUM); HalIrqUnmask(PRVTIMER_INT_NUM);//取消屏蔽 PRVTIMER_INT_NUM 号中断
g_privateTimer->load = OS_CYCLE_PER_TICK; g_privateTimer->load = OS_CYCLE_PER_TICK;
g_privateTimer->control = 0x06; /* IAE bits = 110, not eanbled yet */ g_privateTimer->control = 0x06; /* IAE bits = 110, not eanbled yet */
g_privateTimer->control |= 0x01; /* enable private timer */ g_privateTimer->control |= 0x01; /* enable private timer */
} }
//硬时钟回调函数
VOID OsTickEntry(VOID) VOID OsTickEntry(VOID)
{ {
OsTickHandler(); OsTickHandler();
/* clear private timer */ /* clear private timer */
g_privateTimer->intStatus = 0x01; g_privateTimer->intStatus = 0x01;
} }
//硬件时钟初始化 //硬时钟初始化
VOID HalClockInit(VOID) VOID HalClockInit(VOID)
{ {
UINT32 ret; UINT32 ret;
//创建一个硬时钟 //创建一个硬中断
ret = LOS_HwiCreate(PRVTIMER_INT_NUM, 0xa0, 0, OsTickEntry, NULL); ret = LOS_HwiCreate(PRVTIMER_INT_NUM, 0xa0, 0, OsTickEntry, NULL);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret); PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret);
} }
} }
UINT64 HalClockGetCycles(VOID) UINT64 HalClockGetCycles(VOID)
{ {
UINT32 low, high; UINT32 low, high;
do { do {
high = g_globalTimer->high; high = g_globalTimer->high;
low = g_globalTimer->low; low = g_globalTimer->low;
} while (g_globalTimer->high != high); } while (g_globalTimer->high != high);
/* combine high and low into 8 bytes cycles */ /* combine high and low into 8 bytes cycles */
return (((UINT64)high << 32) | low); return (((UINT64)high << 32) | low);
} }
VOID HalDelayUs(UINT32 usecs) VOID HalDelayUs(UINT32 usecs)
{ {
UINT64 tmo = LOS_CurrNanosec() + usecs * 1000; UINT64 tmo = LOS_CurrNanosec() + usecs * 1000;
while (LOS_CurrNanosec() < tmo) { while (LOS_CurrNanosec() < tmo) {
__asm__ volatile ("nop"); __asm__ volatile ("nop");
} }
} }
UINT64 hi_sched_clock(VOID) UINT64 hi_sched_clock(VOID)
{ {
return LOS_CurrNanosec(); return LOS_CurrNanosec();
} }
UINT32 HalClockGetTickTimerCycles(VOID) UINT32 HalClockGetTickTimerCycles(VOID)
{ {
return g_privateTimer->count; return g_privateTimer->count;
} }
VOID HalClockTickTimerReload(UINT32 period) VOID HalClockTickTimerReload(UINT32 period)
{ {
HalIrqUnmask(PRVTIMER_INT_NUM); HalIrqUnmask(PRVTIMER_INT_NUM);
/* set control counter regs to defaults */ /* set control counter regs to defaults */
g_privateTimer->load = period; g_privateTimer->load = period;
g_privateTimer->control = 0x06; /* IAE bits = 110, not eanbled yet */ g_privateTimer->control = 0x06; /* IAE bits = 110, not eanbled yet */
g_privateTimer->control |= 0x01; /* reenable private timer */ g_privateTimer->control |= 0x01; /* reenable private timer */
} }
...@@ -89,7 +89,7 @@ enum { ...@@ -89,7 +89,7 @@ enum {
#ifdef LOSCFG_PLATFORM_BSP_GIC_V3 #ifdef LOSCFG_PLATFORM_BSP_GIC_V3
#define GICD_IGRPMODR(n) (GICD_OFFSET + 0x0d00 + (n) * 4) /* Interrupt Group Mode Registers */ //中断组模式寄存器 #define GICD_IGRPMODR(n) (GICD_OFFSET + 0x0d00 + (n) * 4) /* Interrupt Group Mode Registers */ //中断组模式寄存器
#define GICD_IROUTER(n) (GICD_OFFSET + 0x6000 + (n) * 8) /* Interrupt Rounter Registers */ //中断阻断寄存器 #define GICD_IROUTER(n) (GICD_OFFSET + 0x6000 + (n) * 8) /* Interrupt Rounter Registers */ //中断路由寄存器,控制一个IRQ发到哪个CPU进行处理
#endif #endif
#define GIC_REG_8(reg) (*(volatile UINT8 *)((UINTPTR)(GIC_BASE_ADDR + (reg)))) #define GIC_REG_8(reg) (*(volatile UINT8 *)((UINTPTR)(GIC_BASE_ADDR + (reg))))
...@@ -104,7 +104,7 @@ enum { ...@@ -104,7 +104,7 @@ enum {
#define GIC_MIN_SPI_NUM 32 #define GIC_MIN_SPI_NUM 32
/* Interrupt preemption config */ /* Interrupt preemption config */ //中断抢占配置
#define GIC_PRIORITY_MASK 0xFFU #define GIC_PRIORITY_MASK 0xFFU
#define GIC_PRIORITY_OFFSET 8 #define GIC_PRIORITY_OFFSET 8
......
/* /*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* 3. Neither the name of the copyright holder nor the names of its contributors may be used * 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written * to endorse or promote products derived from this software without specific prior written
* permission. * permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _GIC_V3_H_ #ifndef _GIC_V3_H_
#define _GIC_V3_H_ #define _GIC_V3_H_
#include "stdint.h" #include "stdint.h"
#include "asm/platform.h" #include "asm/platform.h"
#include "los_hw_cpu.h" #include "los_hw_cpu.h"
#define BIT_32(bit) (1u << bit) #define BIT_32(bit) (1u << bit)
#define BIT_64(bit) (1ul << bit) #define BIT_64(bit) (1ul << bit)
#define ICC_CTLR_EL1 "S3_0_C12_C12_4" #define ICC_CTLR_EL1 "S3_0_C12_C12_4"
#define ICC_PMR_EL1 "S3_0_C4_C6_0" #define ICC_PMR_EL1 "S3_0_C4_C6_0"
#define ICC_IAR1_EL1 "S3_0_C12_C12_0" #define ICC_IAR1_EL1 "S3_0_C12_C12_0"
#define ICC_SRE_EL1 "S3_0_C12_C12_5" #define ICC_SRE_EL1 "S3_0_C12_C12_5"
#define ICC_BPR0_EL1 "S3_0_C12_C8_3" #define ICC_BPR0_EL1 "S3_0_C12_C8_3"
#define ICC_BPR1_EL1 "S3_0_C12_C12_3" #define ICC_BPR1_EL1 "S3_0_C12_C12_3"
#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6" #define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6"
#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7" #define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7"
#define ICC_EOIR1_EL1 "S3_0_C12_C12_1" #define ICC_EOIR1_EL1 "S3_0_C12_C12_1"
#define ICC_SGI1R_EL1 "S3_0_C12_C11_5" #define ICC_SGI1R_EL1 "S3_0_C12_C11_5"
#define ICC_EOIR0_EL1 "S3_0_c12_c8_1" #define ICC_EOIR0_EL1 "S3_0_c12_c8_1"
#define ICC_IAR0_EL1 "S3_0_C12_C8_0" #define ICC_IAR0_EL1 "S3_0_C12_C8_0"
#define ICC_CTLR_EL3 "S3_6_C12_C12_4" #define ICC_CTLR_EL3 "S3_6_C12_C12_4"
#define ICC_SRE_EL3 "S3_6_C12_C12_5" #define ICC_SRE_EL3 "S3_6_C12_C12_5"
#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7" #define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7"
/* GICD_CTLR bit definitions */ /* GICD_CTLR bit definitions */
#define CTLR_ENALBE_G0 BIT_32(0) #define CTLR_ENALBE_G0 BIT_32(0)
#define CTLR_ENABLE_G1NS BIT_32(1) #define CTLR_ENABLE_G1NS BIT_32(1)
#define CTLR_ENABLE_G1S BIT_32(2) #define CTLR_ENABLE_G1S BIT_32(2)
#define CTLR_RES0 BIT_32(3) #define CTLR_RES0 BIT_32(3)
#define CTLR_ARE_S BIT_32(4) #define CTLR_ARE_S BIT_32(4)
#define CTLR_ARE_NS BIT_32(5) #define CTLR_ARE_NS BIT_32(5)
#define CTLR_DS BIT_32(6) #define CTLR_DS BIT_32(6)
#define CTLR_E1NWF BIT_32(7) #define CTLR_E1NWF BIT_32(7)
#define GICD_CTLR_RWP BIT_32(31) #define GICD_CTLR_RWP BIT_32(31)
//定义GICD: Generic Interrupt Controller Distributor
/* peripheral identification registers */ /* peripheral identification registers */ //外设身份寄存器
#define GICD_CIDR0 (GICD_OFFSET + 0xfff0) #define GICD_CIDR0 (GICD_OFFSET + 0xfff0)
#define GICD_CIDR1 (GICD_OFFSET + 0xfff4) #define GICD_CIDR1 (GICD_OFFSET + 0xfff4)
#define GICD_CIDR2 (GICD_OFFSET + 0xfff8) #define GICD_CIDR2 (GICD_OFFSET + 0xfff8)
#define GICD_CIDR3 (GICD_OFFSET + 0xfffc) #define GICD_CIDR3 (GICD_OFFSET + 0xfffc)
#define GICD_PIDR0 (GICD_OFFSET + 0xffe0) #define GICD_PIDR0 (GICD_OFFSET + 0xffe0)
#define GICD_PIDR1 (GICD_OFFSET + 0xffe4) #define GICD_PIDR1 (GICD_OFFSET + 0xffe4)
#define GICD_PIDR2 (GICD_OFFSET + 0xffe8) #define GICD_PIDR2 (GICD_OFFSET + 0xffe8)
#define GICD_PIDR3 (GICD_OFFSET + 0xffec) #define GICD_PIDR3 (GICD_OFFSET + 0xffec)
/* GICD_PIDR bit definitions and masks */ /* GICD_PIDR bit definitions and masks */
#define GICD_PIDR2_ARCHREV_SHIFT 4 #define GICD_PIDR2_ARCHREV_SHIFT 4
#define GICD_PIDR2_ARCHREV_MASK 0xf #define GICD_PIDR2_ARCHREV_MASK 0xf
//定义GICR: Generic Interrupt Controller Redistributor
/* redistributor registers */ /* redistributor registers */ //再分发寄存器组,每个CPU都对应一个Redistributor
#define GICR_SGI_OFFSET (GICR_OFFSET + 0x10000) #define GICR_SGI_OFFSET (GICR_OFFSET + 0x10000)
#define GICR_CTLR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0000) #define GICR_CTLR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0000) //对Distributor控制使能的寄存器
#define GICR_IIDR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0004) #define GICR_IIDR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0004) //获取SOC平台厂商提供的GIC的具体信息,现在一般提供信息是该GIC能够支持最多多少个IRQ硬件中断源
#define GICR_TYPER(i, n) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0008 + (n)*4) #define GICR_TYPER(i, n) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0008 + (n)*4)
#define GICR_STATUSR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0010) #define GICR_STATUSR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0010)
#define GICR_WAKER(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0014) #define GICR_WAKER(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0014) //用于支持电源管理功能
#define GICR_IGROUPR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0080) #define GICR_IGROUPR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0080)
#define GICR_IGRPMOD0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0d00) #define GICR_IGRPMOD0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0d00)
#define GICR_ISENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0100) #define GICR_ISENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0100)
#define GICR_ICENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0180) #define GICR_ICENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0180)
#define GICR_ISPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0200) #define GICR_ISPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0200)
#define GICR_ICPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0280) #define GICR_ICPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0280)
#define GICR_ISACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0300) #define GICR_ISACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0300) //记录某一个IRQ是否ACTIVE
#define GICR_ICACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0380) #define GICR_ICACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0380)
#define GICR_IPRIORITYR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0400) #define GICR_IPRIORITYR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0400) //记录对应IRQ的优先级别
#define GICR_ICFGR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c00) #define GICR_ICFGR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c00)
#define GICR_ICFGR1(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c04) #define GICR_ICFGR1(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c04)
#define GICR_NSACR(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0e00) #define GICR_NSACR(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0e00)
#define GICR_WAKER_PROCESSORSLEEP_LEN 1U #define GICR_WAKER_PROCESSORSLEEP_LEN 1U
#define GICR_WAKER_PROCESSORSLEEP_OFFSET 1 #define GICR_WAKER_PROCESSORSLEEP_OFFSET 1
#define GICR_WAKER_CHILDRENASLEEP_LEN 1U #define GICR_WAKER_CHILDRENASLEEP_LEN 1U
#define GICR_WAKER_CHILDRENASLEEP_OFFSET 2 #define GICR_WAKER_CHILDRENASLEEP_OFFSET 2
#define GICR_WAKER_PROCESSORSLEEP (GICR_WAKER_PROCESSORSLEEP_LEN << GICR_WAKER_PROCESSORSLEEP_OFFSET) #define GICR_WAKER_PROCESSORSLEEP (GICR_WAKER_PROCESSORSLEEP_LEN << GICR_WAKER_PROCESSORSLEEP_OFFSET)
#define GICR_WAKER_CHILDRENASLEEP (GICR_WAKER_CHILDRENASLEEP_LEN << GICR_WAKER_CHILDRENASLEEP_OFFSET) #define GICR_WAKER_CHILDRENASLEEP (GICR_WAKER_CHILDRENASLEEP_LEN << GICR_WAKER_CHILDRENASLEEP_OFFSET)
STATIC INLINE VOID GiccSetCtlr(UINT32 val) STATIC INLINE VOID GiccSetCtlr(UINT32 val)
{ {
#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE #ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE
__asm__ volatile("msr " ICC_CTLR_EL3 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_CTLR_EL3 ", %0" ::"r"(val));
#else #else
__asm__ volatile("msr " ICC_CTLR_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_CTLR_EL1 ", %0" ::"r"(val));
#endif #endif
ISB; ISB;
} }
STATIC INLINE VOID GiccSetPmr(UINT32 val) STATIC INLINE VOID GiccSetPmr(UINT32 val)
{ {
__asm__ volatile("msr " ICC_PMR_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_PMR_EL1 ", %0" ::"r"(val));
ISB; ISB;
DSB; DSB;
} }
STATIC INLINE VOID GiccSetIgrpen0(UINT32 val) STATIC INLINE VOID GiccSetIgrpen0(UINT32 val)
{ {
__asm__ volatile("msr " ICC_IGRPEN0_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_IGRPEN0_EL1 ", %0" ::"r"(val));
ISB; ISB;
} }
STATIC INLINE VOID GiccSetIgrpen1(UINT32 val) STATIC INLINE VOID GiccSetIgrpen1(UINT32 val)
{ {
#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE #ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE
__asm__ volatile("msr " ICC_IGRPEN1_EL3 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_IGRPEN1_EL3 ", %0" ::"r"(val));
#else #else
__asm__ volatile("msr " ICC_IGRPEN1_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_IGRPEN1_EL1 ", %0" ::"r"(val));
#endif #endif
ISB; ISB;
} }
STATIC INLINE UINT32 GiccGetSre(VOID) STATIC INLINE UINT32 GiccGetSre(VOID)
{ {
UINT32 temp; UINT32 temp;
#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE #ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE
__asm__ volatile("mrs %0, " ICC_SRE_EL3 : "=r"(temp)); __asm__ volatile("mrs %0, " ICC_SRE_EL3 : "=r"(temp));
#else #else
__asm__ volatile("mrs %0, " ICC_SRE_EL1 : "=r"(temp)); __asm__ volatile("mrs %0, " ICC_SRE_EL1 : "=r"(temp));
#endif #endif
return temp; return temp;
} }
STATIC INLINE VOID GiccSetSre(UINT32 val) STATIC INLINE VOID GiccSetSre(UINT32 val)
{ {
#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE #ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE
__asm__ volatile("msr " ICC_SRE_EL3 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_SRE_EL3 ", %0" ::"r"(val));
#else #else
__asm__ volatile("msr " ICC_SRE_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_SRE_EL1 ", %0" ::"r"(val));
#endif #endif
ISB; ISB;
} }
STATIC INLINE VOID GiccSetEoir(UINT32 val) STATIC INLINE VOID GiccSetEoir(UINT32 val)
{ {
#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE #ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE
__asm__ volatile("msr " ICC_EOIR0_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_EOIR0_EL1 ", %0" ::"r"(val));
#else #else
__asm__ volatile("msr " ICC_EOIR1_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_EOIR1_EL1 ", %0" ::"r"(val));
#endif #endif
ISB; ISB;
} }
//获取中断号
STATIC INLINE UINT32 GiccGetIar(VOID) STATIC INLINE UINT32 GiccGetIar(VOID)
{ {
UINT32 temp; UINT32 temp;
#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE #ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE
__asm__ volatile("mrs %0, " ICC_IAR0_EL1 : "=r"(temp)); __asm__ volatile("mrs %0, " ICC_IAR0_EL1 : "=r"(temp));
#else #else
__asm__ volatile("mrs %0, " ICC_IAR1_EL1 : "=r"(temp)); __asm__ volatile("mrs %0, " ICC_IAR1_EL1 : "=r"(temp));
#endif #endif
DSB; DSB;
return temp; return temp;
} }
STATIC INLINE VOID GiccSetSgi1r(UINT64 val) STATIC INLINE VOID GiccSetSgi1r(UINT64 val)
{ {
__asm__ volatile("msr " ICC_SGI1R_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_SGI1R_EL1 ", %0" ::"r"(val));
ISB; ISB;
DSB; DSB;
} }
STATIC INLINE VOID GiccSetBpr0(UINT32 val) STATIC INLINE VOID GiccSetBpr0(UINT32 val)
{ {
__asm__ volatile("msr " ICC_BPR0_EL1 ", %0" ::"r"(val)); __asm__ volatile("msr " ICC_BPR0_EL1 ", %0" ::"r"(val));
ISB; ISB;
DSB; DSB;
} }
#endif #endif
git add -A git add -A
git commit -m '1.主从CPU是如何初始化的 2.搞明白了变量前缀 uc:UINT8 us:UINT16 uw:UINT32 代表的意思 git commit -m '中断是如何管理的? CPU之间又是如何通讯的?
搜索 @note_pic 方便理解画的字符图 搜索 @note_pic 方便理解画的字符图
搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善 搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善
搜索 @note_thinking 一点思考和吐槽的地方 搜索 @note_thinking 一点思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册