IDU

简介

Nuclei IDU(中断分发单元)与处理器内核接口紧密耦合,这使得中断处理延迟低,并能高效处理迟到的中断。

所有中断,包括中断、事件、不可屏蔽中断(NMI),均来自子系统。IDU可提供核间中断(ICI)和信号量机制。

idu_arch

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

设置每一位,IDU 将把 soc_int0 分发到对应的 Core

ex: 当 bit0 被置位时,soc_int0 将分发给 core 0

  • SOC_INT4095_INDICATOR

    Address offset: 0x7FFC.

字段

位域

访问属性

复位值

描述

SOC_INT4095_INDICATOR

31:0

RW

0xffff_ffff

设置每一位,IDU 将把 soc_int0 分发到对应的 Core

ex: 当 bit0 被置位时,soc_int0 将分发给 core 0

  • 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 的数量