IDU
简介
Nuclei IDU(中断分发单元)与处理器内核接口紧密耦合,这使得中断处理延迟低,并能高效处理迟到的中断。
所有中断,包括中断、事件、不可屏蔽中断(NMI),均来自子系统。IDU可提供核间中断(ICI)和信号量机制。
IDU架构
注: 以*号开头的信号表示,该信号是否可用取决于其与IDU是否异步。
主要功能
IDU的主要功能如下:
支持多达32个核间中断(ICI)分发。这里的ICI-INT为电平式。
如果核心数量小于24,则支持将核心间中断(ICI)信息从源核心传输到目标核心。
支持最多128个来自SoC的事件分发。这里的SoC事件应为脉冲。
支持最多4096个SoC-IRQ(来自SoC)的分发。这里的SoC-IRQ应为电平型。
支持最多128个SoC-NMI(无屏蔽中断)分发。这里的SoC-NMI应为电平型。
支持最多32个信号量寄存器机制。
系统控制寄存器的实现。
支持针对特定SoC-NMI的锁定模式机制,可用于CPU安全模式。
支持SoC-IRQs可被视为Soc-事件机制。
低延迟异常和中断处理。
功能描述
外部中断分配
IDU 在子系统中充当中断分发器,它支持:
将所有外部中断广播到特定内核或所有目标内核。
让特定核心申请特定中断,该中断仅由该特定核心响应,其他核心无法申请此中断。
中断分配广播模式
如果用户想使用IDU将外部中断广播到部分或全部目标核心,只需打开相关中断INTn_INDICATOR寄存器的响应位。每个INTn_INDICATOR寄存器的响应位指示所有目标核心的各个核心ID号。
例如:在多核模式下,INTn_INDICATOR[i] 表示中断号 N 已启用并发送到内核编号 i。
中断分配先到先得模式
如果用户想使用IDU将外部中断广播到部分或全部目标核心,则让第一个到达的核心申请该中断。除了INTn_INDICATOR寄存器外,还需要INTn_MASK寄存器配合使用。
例如:在多核模式下,如果用户希望仅由CORE1响应INT1,则应将寄存器INT1_INDICATOR[1]和INT1_MASK[1]写为“1”。
要点如下:
将正确的值写入INTn_Indicator寄存器。
当外部中断到来时,它将被广播到所有启用INTn_Indicator相应位的目标核心。在所有核心的中断N处理程序中,首先将其核心ID(而非mhartid)写入INTn_MASK,然后读取INTn_MASK的值。如果该值与核心ID匹配,则表示已成功申请到该中断,随后正常继续处理该中断。如果不匹配,则表示其他核心已申请到该中断,因此退出中断处理程序。
当核心成功申请中断并处理中断时,在执行mret之前,应将复位值(全1)写入INTn_MASK。
核间中断
核心间中断(ICI)是指在多核系统中,一个核心可以向另一个核心发送中断。IDU实现了一种良好的核心间中断机制,包含以下两种寄存器:
SEND_CORE_ID 寄存器:发送此核心间中断的核心 ID
接收核心ID寄存器:接收此核心间中断的核心ID
如果核心n(核心ID=n)想将ICI发送给核心m(核心ID=m),那么流程很简单:
核心n将值n写入SEND_CORE_ID(ICI_SHADOW_REG[31:16]),并将值m写入RE-CEIVE_CORE_ID(ICI_SHADOW_REG[15:0])。
然后nCOREm_INT_STATUS寄存器会更新,并且IDU触发ICI自动发送到Corem
当Core m接收到ICI并进入ICI中断服务例程(ISR)时,它可以查询Corem_INI_STATUS寄存器,并得知当前的ICI是由Core n触发的。此外,Core m还需在ISR返回前向源ICI发送的CoreID位写入1以清除该位。
此外,如果您的系统中core_num<=24,idu支持通过(ICI_SHADOW_REG[31:24])传输ICI中断信息(8位)。目标(Core m)可以通过读取其自身的COREm_INT_STATUS寄存器[31:24]来获取这些信息。
注: 在ICI的ISR中,应清除其自身COREn_INT_STATUS的相应位。如果ISR已完成Core_n的ICI工作,则清除Core n;如果已完成Core_n和Core_ms的工作,则同时清除这两个位等。
在单核模式下,核间中断是针对自身进行发送和接收的。当soc_irq_num<=32时,该寄存器的位范围为soc_irq_num。但当soc_irq_num>32时,则存在n个32位寄存器(n=soc_irq_num/32)。
IDU信号量
IDU 还提供多达 32 个信号量,供用户进行配置和使用。信号量对于多核系统非常有用。
相关寄存器是 SEMAPHOREn。
使用信号量的软件要点如下:
系统中的所有内核都同意使用信号量寄存器来保护关键资源(例如UART设备)。
如果核心n想要访问临界资源,它应尝试通过向该寄存器写入其核心ID来获取信号量寄存器SEMAPHOREn的拥有权,然后读取SEMAPHOREn的值并与自己的核心ID进行比较。如果匹配,则成功获取了信号量并可以访问临界资源;如果不匹配,则显然未获取到信号量,无法访问临界资源。
当核心n拥有寄存器SEMAPHOREn并完成与关键资源相关的任务后,它应通过向该寄存器写入全1来释放该寄存器。
事件分发广播模式
IDU 在子系统中充当事件分发器,它支持:
将所有外部事件广播到特定核心或所有目标核心。
将任何外部中断视为外部事件。
如果用户想使用IDU将外部事件广播到某些/所有目标核心,只需打开相关中断COREn_EVENT_SEL寄存器的响应位即可。每个COREn_EVENT_SEL寄存器的响应位指示了各个外部事件源。
例如:在某些双核系统中,如果用户设置CORE0_EVENT_SEL[5],则表示核心0将接收外部事件5。
如果用户希望将任何外部中断视为事件,请设置INT_AS_EVENT_EN寄存器的相应位。
例如:将INT_AS_EVENT_EN[5]写为”1”,这意味着外部中断5被视为事件
NMI分发广播模式
如果用户想使用IDU将外部nmi(无屏蔽中断)广播到某些/所有目标核,只需打开相关中断COREn_NMI_SEL寄存器的响应位即可。每个COREn_NMI_SEL寄存器的响应位指示各个外部事件源。 例如:在某些双核系统中,如果用户设置CORE1_EVENT_SEL[7],则表示核心1将接收外部事件7。
锁定模式机制
当软件依次写入0x1234_5678和0x90CD_EFAB时,所有SoC-NMI分发寄存器都将被锁定,且在重置IDU模块之前无法更改。
寄存器
寄存器偏移及简单描述列表
偏移 |
寄存器名 |
复位值 |
功能描述 |
|---|---|---|---|
0x0000 |
CORE0_ICI_STATUS |
0x0000_0000 |
核心 0 的核间中断状态寄存器 |
… |
… |
… |
… |
0x007C |
COREn_ICI_STATUS |
0x0000_0000 |
核心 n 的核间中断状态寄存器 |
0x0080 |
SEMAPHORE0 |
0x0000_0000 |
信号量 0 寄存器 |
… |
… |
… |
… |
0x00FC |
SEMAPHOREn |
0x0000_0000 |
信号量 n 寄存器 |
0x0100 |
HART0_EVENT_SEL_GRP0 |
0x0000_0001 |
Hart 0 的外部事件选择寄存器(组 0) |
… |
… |
… |
… |
0x017C |
HARTn_EVENT_SEL_GRP0 |
0x0000_0001 |
Hart n 的外部事件选择寄存器(组 0) |
0x0180 |
SOC_IRQ_AS_EVENT_EN_GRP0 |
0x0000_0000 |
将 SoC 发出的每个外部中断作为事件发送给 Hart |
… |
… |
… |
… |
0x037C |
SOC_IRQ_AS_EVENT_EN_GRP127 |
0x0000_0000 |
将 SoC 发出的每个外部中断作为事件发送给 Hart |
0x3FFC |
REG_ICI |
0x0000_0000 |
内部核心中断分发寄存器 |
0x4000 |
SOC_INT0_INDICATOR |
0xFFFF_FFFF |
soc_irq0 发送到哪些核心 |
… |
… |
… |
… |
0x7FFC |
SOC_INT4095_INDICATOR |
0xFFFF_FFFF |
soc_irq4095 发送到哪些核心 |
0x8000 |
SOC_INDO_MASK |
0x0000_0000 |
soc_irq0_indicator 掩码寄存器 |
… |
… |
… |
… |
0xBFFC |
SOC_IND4095_MASK |
0x0000_0000 |
soc_irq4095_indicator 掩码寄存器 |
0xC000 |
CORE0_NMI_SEL_GRP0 |
0x0000_0000 |
核心 0 的 NMI 中断选择寄存器(组 0) |
… |
… |
… |
… |
0xC07C |
CORE31_NMI_SEL_GRP0 |
0x0000_0000 |
核心 31 的 NMI 中断选择寄存器(组 0) |
0xC080 |
CORE_NMI_LOCK_KEY |
0x0000_0000 |
所有 CORE_NMI_SEL 寄存器的 NMI 锁定寄存器 |
0xC084 |
CORE_NUM |
0x0000_0000 |
只读寄存器,其值取决于系统中核心的数量 |
0xC088 |
HART_NUM |
0x0000_0000 |
只读寄存器,其值取决于系统中 Hart 的数量 |
0xC090 |
SOC_IRQ_NUM |
0x0000_0000 |
只读寄存器,其值取决于系统中 SoC_IRQ 的数量 |
0xC094 |
SOC_EVENT_NUM |
0x0000_0000 |
只读寄存器,其值取决于系统中 SoC_EVENT 的数量 |
0xC098 |
SOC_NMI_NUM |
0x0000_0000 |
只读寄存器,其值取决于系统中 SoC_NMI 的数量 |
寄存器详细说明
CORE0_ICI_STATUS
Address offset: 0x0000.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
CORE0_ICI_STATUS |
23:0 |
W1C |
0x0 |
核心 0 的核间中断状态寄存器 |
CORE0_ICI_INFO |
31:24 |
RO |
0x0 |
核心 0 的核间中断信息 |
COREn_ICI_STATUS
Address offset: 0x007C.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
COREn_ICI_STATUS |
23:0 |
W1C |
0x0 |
核心 n 的核间中断状态寄存器 |
COREn_ICI_INFO |
31:24 |
RO |
0x0 |
核心 n 的核间中断信息 |
SEMAPHORE0
Address offset: 0x0080.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
HART_STATUS |
3:0 |
RW |
0xf |
复位值为 0xf,其他值表示特定 Hart 拥有信号量 |
CORE_STATUS |
9:4 |
RW |
0x3f |
复位值为 0x3f,其他值表示特定核心拥有信号量 |
Reserved |
31:10 |
/ |
/ |
保留位 |
SEMAPHOREn
Address offset: 0x00FC.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
HART_STATUS |
3:0 |
RW |
0xf |
复位值为 0xf,其他值表示特定 Hart 拥有信号量 |
CORE_STATUS |
9:4 |
RW |
0x3f |
复位值为 0x3f,其他值表示特定核心拥有信号量 |
Reserved |
31:10 |
/ |
/ |
保留位 |
HART0_EVENT_SEL_GRP0
Address offset: 0x0100.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
HART0_EVENT_SEL_GRP0 |
31:0 |
RW |
0x1 |
Hart 0 的外部事件选择寄存器(组 0) |
HARTn_EVENT_SEL_GRP0
Address offset: 0x017C.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
HARTn_EVENT_SEL_GRP0 |
31:0 |
RW |
0x1 |
Hart n 的外部事件选择寄存器(组 0) |
SOC_IRQ_AS_EVENT_EN_GRP0
Address offset: 0x0180.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_IRQ_AS_EVENT_EN_GRP0 |
31:0 |
RW |
0x0 |
将 soc_irq (0-31) 作为事件发送给 Hart |
SOC_IRQ_AS_EVENT_EN_GRP127
Address offset: 0x037C.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_IRQ_AS_EVENT_EN_GRP127 |
31:0 |
RW |
0x0 |
将 soc_irq (4064~4095) 作为事件发送给 Hart |
REG_ICI
Address offset: 0x3FFC.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOURCE |
23:16 |
WO |
0x0 |
发送该核间中断的 Core ID |
ICL_INT_INFO |
31:24 |
WO |
0x0 |
源核心将 8 位中断信息写入目标核心 |
DESTINATION |
15:0 |
WO |
0x0 |
接收该核间中断的 Core ID |
SOC_INT0_INDICATOR
Address offset: 0x4000.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_INT0_INDICATOR |
31:0 |
RW |
0xffff_ffff |
|
SOC_INT4095_INDICATOR
Address offset: 0x7FFC.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_INT4095_INDICATOR |
31:0 |
RW |
0xffff_ffff |
|
SOC_INDO_MASK
Address offset: 0x8000.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_INDO_MASK |
31:0 |
RW |
0xffff_ffff |
当指示寄存器位被置位时,启用 soc_irq0 到各核心(Core0 ~ Core31) 注意:掩码寄存器可基于其复位值进行更改。这意味着,如果某个核心更新了 掩码寄存器值,则应将其写回复位值(释放掩码寄存器),以便其他核心后续使用 |
SOC_IND4095_MASK
Address offset: 0xBFFC.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_IND4095_MASK |
31:0 |
RW |
0xffff_ffff |
当指示寄存器位被置位时,启用 soc_irq4095 到各核心(Core0 ~ Core31) 注意:掩码寄存器可基于其复位值进行更改。这意味着,如果某个核心更新了 掩码寄存器值,则应将其写回复位值(释放掩码寄存器),以便其他核心后续使用 |
CORE0_NMI_SEL_GRP0
Address offset: 0xC000.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
CORE0_NMI_SEL_GRP0 |
31:0 |
RW |
0x1 |
该寄存器指示 core0 接收哪些 NMI 事件 |
CORE31_NMI_SEL_GRP0
Address offset: 0xC07C.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
CORE31_NMI_SEL_GRP0 |
31:0 |
RW |
0x1 |
该寄存器指示 core31 接收哪些 NMI 事件 |
CORE_NMI_LOCK_KEY
Address offset: 0xC080.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
CORE_NMI_LOCK_KEY |
31:0 |
WO |
0x0 |
所有 COREn_NMI_SEL_GRP_SEL 寄存器的锁键寄存器。 当依次写入 0x1234_5678 和 0x90CD_EFAB 后,所有 COREn_NMI_GRP_SEL 寄存器将被锁定,直到 IDU 模块复位前无法更改 |
CORE_NUM
Address offset: 0xC084.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
CORE_NUM |
31:0 |
RO |
CONF |
只读寄存器,其值取决于系统中 Core 的数量 |
HART_NUM
Address offset: 0xC088.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
HART_NUM |
31:0 |
RO |
CONF |
只读寄存器,其值取决于系统中 Hart 的数量 |
SOC_IRQ_NUM
Address offset: 0xC090.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_IRQ_NUM |
31:0 |
RO |
CONF |
只读寄存器,其值取决于系统中 soc irq 的数量 |
SOC_EVENT_NUM
Address offset: 0xC094.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_EVENT_NUM |
31:0 |
RO |
CONF |
只读寄存器,其值取决于系统中 soc event 的数量 |
SOC_NMI_NUM
Address offset: 0xC098.
字段 |
位域 |
访问属性 |
复位值 |
描述 |
|---|---|---|---|---|
SOC_NMI_NUM |
31:0 |
RO |
CONF |
只读寄存器,其值取决于系统中 soc nmi 的数量 |