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

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