RISC-V AIA学习3---APLIC 第二部分(APLIC 中断域的内存映射控制区域)

每个中断域都有一个专用的内存映射控制区域,用来处理该中断域的中断。

控制区域的大小是 4KB 的倍数,对齐到 4KB 边界。最小的有效控制区域是 16KB。

1. 控制区域的基本结构:部门文件柜

每个中断域就像公司的一个部门,有自己的 "文件柜"(内存映射控制区域):

  • 大小:至少 16KB(4 个文件柜),必须是 4KB 的整数倍
  • 对齐:文件柜的起始位置必须在 4KB 的边界(如第 0KB、4KB、8KB 等)
  • 文件分类:前 16KB 是通用文件,后面可能有专用任务分配表(IDC 结构)

一个中断域的控制区域,由一组32bit位宽的寄存器组成

2. 通用文件区(前 16KB)

存放所有部门共享的控制文件,例如:

  • 中断使能开关:控制中断域的中断是否启用
  • 优先级阈值:设置可处理的最低优先级任务
  • 全局状态监控:显示当前最高优先级中断等

3. 任务分配表(IDC 结构)

IDC 结构,只有在直接向 harts 传递 interrupt 时使用,而由 MSI 转发interrupt时不会使用。

每个 IDC 结构为 32 字节,并定义如下:

  • 起始位置: 0x4000 (第 16KB 开始)
  • 结构大小:每个hart对应 32 字节的文件袋(包含 5 个寄存器)

寄存器功能

  • idelivery:任务分配开关(允许 / 禁止分配任务给该员工)
  • iforce:强制触发任务(测试用)
  • ithreshold:员工的任务优先级门槛(仅处理高于该优先级的任务)
  • topi:显示该员工当前最高优先级任务(中断 ID)
  • claimi:确认任务完成(清除待处理标记)

总结比喻

APLIC 的中断域内存控制区域就像:

  1. 部门文件柜:前 16KB 是部门共用的文件(如部门规章制度)
  2. 任务分配表:后续区域是每个员工的任务处理文件袋(仅直接分配任务的部门需要)
  3. 文件访问规则:只能用 32 位的方式打开文件,否则会被拒绝
  4. 预留机制:即使没有对应的员工,文件袋依然存在但为空

这种设计确保部门可以灵活管理中断,同时节省内存资源,适用于不同复杂度的中断处理场景。

根据本小节描述,中断域的内存映射空间,其寄存器分布情况,可整理为如下图所示:

2.1 Domain configuration(domaincfg)

domaincfg 就像部门的总控开关,控制整个中断域的行为。它的 32 位布局如下:

IE(Interrupt Eable)位

指示所在中断域的所有有效中断源的全局使能标志。

只有IE=1时,pending和enable同时置位的中断,才会投递到目标hart。

  • 0 → 所有中断被禁用(即使设备触发,部门也不处理)
  • 1 → 允许处理符合条件的中断

DM(Delivery Mode)位

选择中断的投递方式,其定义如下:

  • 0 → 直接传递模式(APLIC 直接发送中断给 Hart)
  • 1 → MSI 转发模式(APLIC 将中断转为电子消息发送给 IMSIC)

如果 Hart 有 IMSIC,且其 eidelivery 寄存器不支持特定值(0x40000000),直接传递模式会被禁用(相当于 IE=0)。也就是说,如果eidelivery不支持0x4000_0000,即便将DM置0,欲使用直接投递,也无法实际投递到Hart。

BE (big-Endian)位

它确定 interrupt domain 的寄存器byte的顺序。(在现今主流的 CPU 中,最常见的字节顺序有两种,分别是 Big-Endian 与 Little-Endian。Big-Endian 是指数据放进内存中的时候,最高位的字节会放在最低的内存地址上;而 Little-Endian 则是刚好相反,它会把最高位的字节放在最高的内存地址上。)

如果BE = 0,表示byte顺序为little-endian

如果 BE = 1,表示为big-endian。

在系统重置时,domaincfg 中的所有可写位,都被初始化为零,包括 IE。

2.2 Source configurations(sourcecfg[1]-sourcecfg[1023])

对于每一个可能的中断源 i,寄存器 sourcecfg [i] 控制着该中断源 i 在这个中断域中的源模式,以及该中断源对子域的任何委托情况。

当中断源 i 未被实现,或者在这个域中看起来未被实现时,sourcecfg [i] 为只读的零值。

如果中断源 i 之前没有被委托到这个域,而后(在父域中)被更改成委托到这个域,那么 sourcecfg [i] 会一直保持为零,直到成功写入一个非零值为止。

sourcecfg [i] 就像每个设备(中断源 i)的配置开关,控制设备在当前部门(中断域)的工作模式。它有两种工作模式:

模式 1:委托给子中断域(D=1)
  • 子域索引:选择将中断源委托给哪个中断域

当中断源i,被委托给子域时,sourcecfg[i]有这样的格式:

具体委托到哪一个child domain,bit9:0指示委托到的child domain index(如果该parent domain包含C个child domain,则child domain index的范围为1-C)。

例如,当 D=1 时,假设某个中断源被委托给子域 3,那么当前域不再处理该中断,而是由子域 3 处理。这时候,sourcecfg [i] 的子域索引字段会被设置为 3。如果当前域是叶子域(无子域),设置 D=1 会导致寄存器被清零。

模式 2:当前中断域处理(D=0)
  • SM 模式:设置设备的触发方式

当中断源i,不委托给子域时,sourcecfg[i]有这样的格式:

此时bit9:0的含义发生变化,仅使用bit2:0来指示SM (Source Mode),表示中断源i是否有效,以及其对应的中断类型。(所有其他的寄存器位,都被保留并读取为零)

SM 模式(Source Mode) 字段是WARL,它控制中断源在这个域中,是否处于活动状态。

如果是,那么入线(incoming wire)上的哪些值或转换,被解释为中断。

下表列出了SM允许的值及其含义:

字段SM始终支持Inactive(默认状态下)。

设备状态与寄存器行为

  • 非激活状态(D=1 或 SM=Inactive):

    • 中断待处理位(eip [i]):只读 0
    • 中断使能位(eie [i]):只读 0
    • 目标寄存器(target [i]):只读 0
  • 激活状态(D=0 且 SM≠Inactive):

    • 如果源i从非活动模式变为活动模式,中断源的pending和enable位保持为零,除非由于本节后面指定的原因自动设置,并且target[i]定义的子字段获得UNSPECIFIED值。

    • 设备信号经过反向处理(rectified input):

      • 如果设备是反向配置(如 Edge0/Level0),输入信号取反
    • 写入 sourcecfg 可能自动设置待处理位:

      • 当新配置的 rectified 输入为高电平时,自动触发中断

以下通过几个例子说明说明

示例 1:委托中断源给子域

场景:公司总部(根域)有一个打印机中断源(编号 5),现在需要将其委托给 IT 部门(子域 3)处理。

  1. 配置步骤

    • 写入 sourcecfg[5] = 0b100_0000_0011(二进制)
      • bit10 (D) = 1:启用委托
      • bits9:0 (Child Index) = 3:指定子域 3
  2. 效果

    • 根域不再处理打印机中断
    • 子域 3 的 sourcecfg[5] 会显示为只读 0(需由子域主动配置)

示例 2:配置边沿触发的键盘中断

场景:部门需要将键盘中断(编号 2)配置为上升沿触发(正常模式)。

  1. 配置步骤

    • 写入 sourcecfg[2] = 0b0100(二进制)
      • bit10 (D) = 0:本地处理
      • bits2:0 (SM) = 4:Edge1 模式
  2. 效果

    • 键盘按下瞬间(物理信号从 0→1)触发中断
    • 松开时(1→0)不会触发

示例 3:反向电平触发的鼠标中断

场景:部门需要将鼠标中断(编号 3)配置为松开按钮时触发(低电平触发)。

  1. 配置步骤

    • 写入 sourcecfg[3] = 0b0_111(二进制)
      • bit10 (D) = 0:本地处理
      • bits2:0 (SM) = 7:Level0 模式
  2. 效果

    • 鼠标按钮松开时(物理信号 0)触发中断
    • 按下时(1)不触发

示例 4:Detached 模式的软件中断

场景:部门需要创建一个软件模拟的中断(编号 10),通过代码触发。

  1. 配置步骤

    • 写入 sourcecfg[10] = 0b0_001(二进制)
      • bit10 (D) = 0:本地处理
      • bits2:0 (SM) = 1:Detached 模式
  2. 效果

    • 忽略物理信号
    • 可通过 setipnum = 10 手动触发中断

示例 5:叶子域的委托失败

场景:某个部门是叶子域(无子域),尝试将设备 7 委托给子域 0。

  1. 配置步骤

    • 写入 sourcecfg[7] = 0b1_00000000000(二进制)
  2. 效果

    • 硬件检测到无子域,自动将 sourcecfg[7] 清零
    • 委托失败,设备 7 仍由当前域处理

总结

通过这些示例,可以看到 sourcecfg 寄存器通过 委托机制触发模式配置,实现了中断源的灵活管理:

  1. 委托机制:将任务分配给子部门(子域)处理
  2. 触发模式:支持按钮、开关等不同类型的硬件设备
  3. 反向配置:允许设备使用相反的逻辑电平
  4. 软件触发 :通过 setipnum 实现完全软件控制的中断

这种设计让中断控制器既能处理硬件设备的多样性,又能支持复杂的分层管理需求。

2.3 machine MSI address configuration(mmsiaddrcfg and mmsiaddrcfgh)

对于machine level的中断域,寄存器mmsiaddrcfg和mmsiaddrcfgh将提供传出的MSI地址参数。

如果APLIC的中断域,没有支持MSI投递模式,则此两个寄存器没有作用。

对于支持MSI投递模式的APLIC:

a. 在根中断域,需要实现这两个寄存器,且寄存器的属性是只写;

b. 对于其他的Machine level的中断域,可以选择性的支持,且寄存器的属性是只读;

c. 对于Supervisor level的中断域,不能实现这两个寄存器,且只读0。

mmisaddrcfg格式如下:

mmsiaddrcfgh格式如下:

mmsiaddrcfgh.High Base PPN与mmsiaddrcfg.Low Base PPN连接成一个44 bit的物理页基地址(PPN base)。

这个值(PPN base)和字段HHXs (High Hart Index Shift)、LHXS (Low Hart Index Shift)、HHXW (High Hart Index Width)和LHXW (Low Hart Index Width),用于确定msi的目标地址的使用(将在后续章节描述)。

示例 1:公司总部配置 MSI 地址(根域)

场景:公司总部(根域)需要为所有部门(Hart)配置 MSI(电子消息)的目标地址。

  1. 寄存器配置

    • mmsiaddrcfg = 0x12345678(低 32 位 PPN)
    • mmsiaddrcfgh = 0x80000000(高 12 位 PPN=0,L=1)
  2. 生成的 44 位 Base PPN

    • 高 12 位(来自 mmsiaddrcfgh):0x000
    • 低 32 位(来自 mmsiaddrcfg):0x12345678
    • 完整 Base PPN:0x00012345678
  3. 地址生成逻辑

    • 每个 Hart 的地址 = Base PPN + Hart 索引偏移
    • 例如,Hart 5 的地址 = 0x00012345678 + 5*4 = 0x00012345690

示例 2:锁定寄存器配置(L 位 = 1)

场景:总部配置完成后,希望防止后续修改。

  1. 操作步骤

    • 写入 mmsiaddrcfgh.L = 1
    • 寄存器被锁定,无法再写入,只可读
  2. 效果

    • 其他域(如分公司)只能读取锁定的配置
    • 即使根域尝试修改,写入会被忽略
    • 之前的配置值(如 Base PPN)被保留,但无法通过寄存器读取

示例 3:分公司域的只读权限

场景:分公司域(非根域)需要使用总部配置的 MSI 地址。

  1. 寄存器状态

    • mmsiaddrcfg:只读,值与根域相同
    • mmsiaddrcfgh:只读,L=1,其他字段与根域相同
  2. 地址生成

    • 分公司域使用总部的 Base PPN 生成自己的 MSI 地址
    • 无法修改配置,确保所有域的地址一致

示例 4:硬件固定地址的简化实现

场景:某些 APLIC 硬件直接固定 MSI 地址,无需软件配置。

  1. 寄存器配置

    • mmsiaddrcfg = 0x00000000
    • mmsiaddrcfgh = 0x80000000(L=1)
  2. 地址生成

    • Base PPN = 0x00000000000
    • Hart 地址直接使用固定公式(如 0x40000000 + Hart索引*4
    • 寄存器配置不影响实际地址,仅用于兼容

关键注意事项

  1. 权限控制

    • 只有根域可以写入这些寄存器
    • 其他域只能读取,确保配置一致性
  2. 锁定机制

    • L 位 = 1 时,寄存器变为只读
    • 防止未授权修改,提高系统安全性
  3. 地址生成

    • Base PPN 由高低 PPN 拼接而成
    • HHXS/LHXS 调整 Hart 索引的偏移
    • HHXW/LHXW 确定 Hart 索引的有效范围
  4. 硬件兼容性

    • 硬件可固定地址,寄存器配置为默认值
    • 复杂地址生成可通过自定义机制实现

总结

通过这些示例,可以看到 mmsiaddrcfgmmsiaddrcfgh 寄存器通过 物理页号配置Hart 索引调整,实现了 MSI 地址的灵活生成:

  1. 根域权限:只有总部(根域)可以设置和锁定地址
  2. 地址生成:根据 Base PPN 和 Hart 索引生成目标地址
  3. 锁定机制:防止配置被篡改,确保系统稳定性
  4. 硬件适配:支持固定地址或复杂地址生成方式

这种设计让 APLIC 能够兼容不同硬件架构,同时提供安全的中断消息路由功能。

2.4 supervisor MSI address configuration(smsiaddrcfg and smsiaddrcfgh)

核心概念

  • MSI:消息信号中断(Message Signaled Interrupt),通过写入特定内存地址触发中断。
  • smsiaddrcfg/smsiaddrcfgh :寄存器,用于配置超级用户级(Supervisor)域发送 MSI 时的目标地址。

1. 寄存器的存在条件

  • 只有机器级(Machine)域实现了mmsiaddrcfg/mmsiaddrcfgh寄存器,且APLIC存在至少一个超级用户级中断域。否则这两个寄存器的地址位置是只读的零(像其他保留位一样)。

2. 可写性规则

  • 根域(Root Domain) :可以写入这两个寄存器(但受mmsiaddrcfgh.L位限制)。
  • 其他机器级域:寄存器是只读的,且内容与根域的相同。

3. 寄存器结构

  • smsiaddrcfg (32 位):
    • 低 32 位:低基物理页号(Low Base PPN)
  • smsiaddrcfgh (32 位):
    • 高 12 位:高基物理页号(High Base PPN)。
    • LHXS 字段(位 22-20):用于调整目标地址的低 hart 索引偏移
    • 其他位:保留,读为零。

4. 地址组合方式

  • 44 位基物理页号 :由High Base PPN(12 位)和Low Base PPN(32 位)拼接而成。
  • LHXS 的作用:可能用于调整 hart 索引的偏移量,从而生成不同的目标地址

5. 锁定机制(mmsiaddrcfgh.L 位)

  • 当 L 位 = 1 时
    • mmsiaddrcfg/mmsiaddrcfghsmsiaddrcfg/smsiaddrcfgh均被锁定为只读。
    • 如果mmsiaddrcfgmmsiaddrcfgh的可见值为00x80000000,则smsiaddrcfg/smsiaddrcfgh也会被隐藏,读为零。
    • 例外:根域在 L 位设置前写入的值会被保留,但无法再通过寄存器读取。

6. 系统复位的特殊情况

  • 如果复位时根域的mmsiaddrcfgh.L=1,且所有 MSI 地址配置字段始终为零:
    • APLIC 可能使用非标准方法确定 MSI 地址

7. 非根域的行为

  • 非根域的smsiaddrcfg/smsiaddrcfgh是根域寄存器的只读副本。
  • 它们的值无法修改,完全由根域控制。

示例 1:根域配置 Supervisor MSI 地址

场景:公司总部(根域)需要为所有 Supervisor 级部门配置 MSI(电子消息)的目标地址。

  1. 寄存器配置

    • smsiaddrcfg = 0x9ABCDEF0(低 32 位 PPN)
    • smsiaddrcfgh = 0x001(高 12 位 PPN=1,LHXS=0)
  2. 生成的 44 位 Base PPN

    • 高 12 位(来自 smsiaddrcfgh):0x001
    • 低 32 位(来自 smsiaddrcfg):0x9ABCDEF0
    • 完整 Base PPN:0x0019ABCDEF0
  3. 地址生成逻辑

    • 每个 Hart 的地址 = Base PPN + Hart 索引 * 4
    • 例如,Hart 3 的地址 = 0x0019ABCDEF0 + 3*4 = 0x0019ABCDEF0 + 0xC = 0x0019ABCDEF0C

示例 2:锁定寄存器配置(L 位 = 1)

场景:总部配置完成后,希望防止后续修改。

  1. 操作步骤

    • 写入 mmsiaddrcfgh.L = 1(machine 级寄存器)
    • 同时锁定 smsiaddrcfgsmsiaddrcfgh
  2. 效果

    • 根域无法再写入这些寄存器
    • 其他域(如分公司)只能读取锁定的配置
    • 之前的配置值(如 Base PPN)被保留,但无法通过寄存器读取

示例 3:分公司域的只读权限

场景:分公司域(非根域)需要使用总部配置的 Supervisor MSI 地址。

  1. 寄存器状态

    • smsiaddrcfg :只读,值与根域相同(0x9ABCDEF0
    • smsiaddrcfgh :只读,值与根域相同(0x001
  2. 地址生成

    • 分公司域使用总部的 Base PPN 生成自己的 MSI 地址
    • 无法修改配置,确保所有域的地址一致

示例 4:硬件固定地址的简化实现

场景:某些 APLIC 硬件直接固定 Supervisor MSI 地址,无需软件配置。

  1. 寄存器配置

    • smsiaddrcfg = 0x00000000
    • smsiaddrcfgh = 0x000(LHXS=0)
  2. 地址生成

    • Base PPN = 0x00000000000
    • Hart 地址直接使用固定公式(如 0x80000000 + Hart索引*4
    • 寄存器配置不影响实际地址,仅用于兼容

2.6 set interrupt-pending bits(setip[0]-setip[31])

设置中断挂起位。

a. 在写入setip寄存器时,对于写入的32位值中为1的每一位,如果该位位置是有效的中断源(active interrupt source),则该源的pending位将设置为1

b. 读取setip,会返回相对应的中断源的pending位,假设该中断源并未实现,则读取setip相对应的位,其值为 0。

写入setip[k],可以修改中断源k * 32k * 32 + 31的pending位。

想象一个公司有很多部门,每个部门有 32 个员工。setip[k] 就像是一个记录板,k 代表部门编号。每个员工对应记录板上的一个位置(位),用来表示该员工是否有紧急任务(中断待处理)。

  • 读取操作 :当你读取 setip[k] 时,就相当于查看第 k 个部门哪些员工有紧急任务。如果某个员工对应的位是 1,说明他有紧急任务;如果是 0,则没有。对于没有员工的位置(未实现的中断源),就显示为 0。

    例如,读取 setip[0] 时,如果返回 0x00000003(二进制 0000 0000 0000 0000 0000 0000 0000 0011),表示第 0 个部门的第 0 号和第 1 号员工有紧急任务。

  • 写入操作 :当你向 setip[k] 写入一个 32 位的值时,就相当于给第 k 个部门的员工分配紧急任务。如果写入的值中某一位是 1,且对应的员工是活跃状态(有工作能力,即对应活跃的中断源),就会把该员工的紧急任务标志(中断待处理位)设为 1。

    比如,向 setip[0] 写入 0x00000004(二进制 0000 0000 0000 0000 0000 0000 0000 0100),如果第 0 个部门的第 2 号员工是活跃的,那么他的紧急任务标志就会被设为 1。

2.6 set interrupt - pending bit by number (setipnum)

使用中断源ID,设置中断挂起位。

  • 如果i是一个中断域中的有效中断源ID,则将i写到setipnum会让对应pending位置1。如果i不是该中断域中的有效中断源ID,则忽略 setipnum 的写入。
  • 对该寄存器的读请求都会返回0。

这就像是公司的老板可以直接指定某个员工有紧急任务。setipnum 就像是老板的指令单,你把员工编号(32 位值 i)写在上面,如果这个员工是活跃的,就会把他的紧急任务标志设为 1。

例如,你向 setipnum 写入 5,如果第 5 号员工是活跃的,他的紧急任务标志就会被设为 1。如果写入的编号对应的员工不活跃,这个指令就会被忽略。

2.7 Rectified inputs, clear interrupt-pending bits (in clrip[0]--in clrip[31])

清除中断挂起位

a. 读取寄存器in_clrip,会返回相对应的中断源的校正输入值(Rectified inputs)。假设该中断源并未实现(超出了中断编号的范围),则读取in_clrip相对应的位置为 0。

b. 写入setip寄存器时,对于写入的32位值中为1的每一位,如果该位位置是有效的中断源(active interrupt source),则该源的pending位将被清零。

把in clrip[k] 看成一个记录板,不过它有两个功能。

  • 读取操作 :读取 in clrip[k] 时,返回的是第 k 个部门员工经过处理后的工作状态(整流输入值)。对于没有员工的位置,显示为 0。
  • 写入操作 :当你向 in clrip[k] 写入一个 32 位的值时,如果某一位是 1,且对应的员工是活跃的,就会尝试清除该员工的紧急任务标志。
    比如,向 in clrip[0] 写入 0x00000002(二进制 0000 0000 0000 0000 0000 0000 0000 0010),如果第 0 个部门的第 1 号员工是活跃的,就会清除他的紧急任务标志。

2.8 Clear interrupt-pending bit by number (clripnum)

使用中断源ID,清除中断挂起位

  • 如果i是一个中断域中的有效中断源标识,则将i写到clripnum会让该源的pending位被清零。如果i不是该中断域中的有效中断源标识,则忽略 clripnum 的写入。
  • 对该寄存器的读请求都会返回0。

这就像是老板直接指定清除某个员工的紧急任务。你把员工编号(32 位值 i)写入 clripnum,如果这个员工是活跃的,就会清除他的紧急任务标志。如果写入的编号对应的员工不活跃,这个操作就会被忽略。读取 clripnum 总是返回 0。

2.9 Set interrupt-enable bits (setie[0]--setie[31])

  1. 寄存器功能

    • 读操作:返回中断源 k×32 到 k×32+31 的使能位状态
    • 写操作:设置这些中断源的使能位
    • 未实现的中断源位读时返回 0

例如,向 setie[0] 写入 0x00000001(二进制 0000 0000 0000 0000 0000 0000 0000 0001),如果第 0 个部门的第 0 号员工是活跃的,他就会被允许接收紧急任务。

2.10 Set interrupt-enable bit by number (setienum)

使用中断源ID,设置中断使能位。

  • 如果i是一个中断域中的有效中断源ID,则将i写到setienum会让对应enable位置1。如果i不是该中断域中的有效中断源ID,则忽略 setienum的写入。
  • 对该寄存器的读请求都会返回0。

这就像是老板直接指定某个员工被允许接收紧急任务。你把员工编号(32 位值 i)写入 setienum,如果这个员工是活跃的,就会把他的接收紧急任务权限设为 1。如果写入的编号对应的员工不活跃,这个操作就会被忽略。读取 setienum 总是返回 0。

2.11 Clear interrupt-enable bits

清除中断使能位(clrie [0]-clrie [31])

  • 作用:专门用于批量清除中断使能位
  • 原理:
    1. 每个 clrie [k] 控制 32 个中断源(编号 k×32 到 k×32+31)
    2. 写入 1 的位会清除对应中断源的使能状态
    3. 例如:
      • clrie [0] 控制中断源 0-31
      • clrie [1] 控制中断源 32-63
    4. 只读零特性:读取这些寄存器永远返回 0,只能写操作

clrie[k] 用于清除第 k 个部门员工的接收紧急任务权限。当你向 clrie[k] 写入一个 32 位的值时,如果某一位是 1,就会清除对应员工的接收紧急任务权限。读取 clrie[k] 总是返回 0。

例如,向 clrie[0] 写入 0x00000003(二进制 0000 0000 0000 0000 0000 0000 0000 0011),会清除第 0 个部门第 0 号和第 1 号员工的接收紧急任务权限。

2.12 clear interrupt-enable bit by number

按编号清除中断使能位(clrienum)

  • 作用:精准清除单个中断源的使能位
  • 操作方法:
    1. 写入中断源编号 i(32 位值)
    2. 仅对有效中断源(active)有效
    3. 无效写入(非 active 编号)会被忽略
    4. 读取永远返回 0

这就像是老板直接指定清除某个员工的接收紧急任务权限。你把员工编号(32 位值 i)写入 clrienum,如果这个员工是活跃的,就会清除他的接收紧急任务权限。如果写入的编号对应的员工不活跃,这个操作就会被忽略。读取 clrienum 总是返回 0。

2.13 set interrupt-pending bit by bumber,little-endian

小端模式按编号设置中断挂起位(setipnum le)

  • 特点:
    1. 功能与 setipnum 完全相同
    2. 强制使用小端字节序
    3. 系统设计:
      • 大端系统(BE=1)中可省略实现
      • 存在时用于支持小端设备的 MSI 写入
      • 读写行为与 setipnum 一致

2.14 set interrupt-pending bit by bumber,big-endian

  • 特点:
    1. 功能与 setipnum 完全相同
    2. 强制使用大端字节序
    3. 系统设计:
      • 小端系统(BE=0)中可省略实现
      • 存在时用于支持大端设备的 MSI 写入
      • 读写行为与 setipnum 一致

2.15 Generate MSI(genmsi)

genmsi就像部门里的 "紧急快递员",专门用于在 MSI 模式下发送即时中断(类似 "闪送" 服务)。

使用场景

示例:老板需要立即通知程序员小明(hart 5)处理紧急 bug:

  1. 写入genmsi
    • Hart Index = 5
    • EIID = 0x123(表示 "紧急 bug 修复")
  2. Busy 位自动变为 1,表示快递员正在路上
  3. APLIC 立即发送 MSI 到小明的电脑(IMSIC)
  4. Busy 位自动变回 0,表示快递已送达

关键特性

  • 无视 IE 位:即使部门总开关(IE)关闭,也能强制发送 MSI(类似 "总统特令")
  • 顺序保证:确保之前发送给同一 hart 的所有 MSI 已送达,再发送当前 MSI
  • 模式限制:仅在 MSI 模式(DM=1)可用,直接模式(DM=0)时为只读 0

操作流程

步骤 1:检查 Busy 位

  • 读取genmsi,确认 Busy=0(快递员空闲)

步骤 2:写入参数

  • Hart Index:目标 hart 编号(如 5)
  • EIID:中断标识(如 0x123)

步骤 3:等待发送

  • Busy 自动变为 1(快递员出发)
  • APLIC 立即发送 MSI(快递送达)
  • Busy 自动变回 0(快递员返回)

注意事项

  • 性能瓶颈:频繁使用可能导致延迟,建议直接写入 IMSIC(类似 "自己送文件")
  • 地址验证:Hart Index 必须是有效编号,否则 MSI 可能丢失
  • 中断标识:EIID 值需与目标 hart 的 IMSIC 配置匹配

2.16 Interrupt targets(target[1]-target[1023])

target[i]就像每个设备(中断源 i)的 "任务分配表",决定该设备的中断会被发送到哪个员工(hart),以及相关参数。

2. 直接传递模式(DM=0)

场景:部门直接分配任务给员工

示例 1:打印机中断分配给员工 5
  1. 配置

    • target[3] = 0b00000000000000000000000000000101(二进制)
      • Hart Index = 5
      • IPRIO = 1(最低有效位)
  2. 效果

    • 打印机中断(源 3)会直接发送给员工 5
    • 优先级为 1(最高)
示例 2:键盘中断设置优先级为 3
  1. 配置

    • target[2] = 0b00000000000000000000000000000011(二进制)
      • Hart Index = 0
      • IPRIO = 3
  2. 效果

    • 键盘中断(源 2)发送给员工 0
    • 优先级为 3(比优先级 1 低)

3. MSI 模式(DM=1)

场景:部门将任务转为电子消息发送给 IMSIC

示例 3:发送软件中断给员工 5
  1. 配置

    • target[10] = 0b00000000000000000000000000000101(二进制)
      • Hart Index = 5
      • EIID = 1(任务编号)
  2. 效果

    • APLIC 生成 MSI 消息:地址 = 员工 5 的 IMSIC 地址,数据 = 0x1
    • IMSIC 收到后触发中断
示例 4:超级用户级域的客户中断
  1. 配置

    • target[7] = 0b00000000000000000000000000000011(二进制)
      • Hart Index = 2
      • Guest Index = 1(客户文件柜 1)
      • EIID = 3
  2. 效果

    • MSI 发送到员工 2 的客户文件柜 1,数据 = 0x3
    • IMSIC 将中断传递给对应的客户系统

4. 关键规则

优先级规则
  • 数值越小优先级越高:优先级 1 > 优先级 3
  • 相同优先级:中断源编号较小的优先级更高(源 2 > 源 3)
IPRIO 写入限制
  • 不允许写入 0,会自动转为 1
  • 实际有效位数由 APLIC 参数 IPRIOLEN 决定(1-8 位)
MSI 地址生成
  • 地址 = Hart 地址 + Guest Index 偏移(如果有的话)
  • 数据 = EIID(任务编号)

5. 模式切换影响

场景:部门从直接模式切换到 MSI 模式

  1. 操作

    • 设置domaincfg.DM = 1
  2. 效果

    • 所有激活中断源的 target 寄存器会被清空
    • 需要重新配置 Hart Index、Guest Index、EIID

6. 实际应用示例

场景:系统初始化时配置中断路由

  1. 直接传递模式

    • 键盘(源 2)→ 员工 0,优先级 1
    • 鼠标(源 3)→ 员工 1,优先级 2
  2. MSI 模式

    • 软件中断(源 10)→ 员工 5,任务编号 0x123
    • 网络中断(源 15)→ 员工 3,客户文件柜 0,任务编号 0x456

总结比喻

target寄存器就像部门的 "任务派遣系统":

  1. 直接传递模式
    • Hart Index:指定具体员工
    • IPRIO:任务紧急程度(数字越小越紧急)
  2. MSI 模式
    • Hart Index:目标员工编号
    • Guest Index:客户文件柜编号(高级功能)
    • EIID:任务编号(用于生成电子消息内容)
  3. 模式切换:部门调整工作方式时,所有任务分配表会被重置

这种设计让部门可以灵活选择中断处理方式,同时确保任务按优先级和目标精准分配。

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习