2.3 亲和路由
亲和路由是一种基于分层地址的方案,用于识别中断路由的特定PE节点。
 对于 PE,AArch64 状态的亲和性值在 MPIDR_EL1 中定义,AArch32 状态的亲和性值在 MPIDR 中定义:
 • 关联路由是一个由四个8 位关联字段组成的32 位值。 这些字段是节点 a、b、c 和 d。
 • 使用AArch64 状态的GICv3 可以支持:
      — 四级路由层次结构,a.b.c.d.
      — 三级路由层次结构,0.b.c.d.
 • 使用AArch32 状态的GICv3 仅支持三个亲和性级别。
 • ICC_CTLR_EL3.A3V、ICC_CTLR_EL1.A3V 和GICD_TYPER.A3V 指示是实现四个级别还是三个级别的关联性。
 注
 需要四个关联级别的实现必须仅支持 AArch64 状态。
用于指定关联层次结构中的节点的枚举符号采用以下形式,其中 Affx 是关联级别 x:
 Aff3.Aff2.Aff1.Aff0
 使用关联路由启用 (ARE) 位在Distributor中启用安全状态的关联路由。
 启用关联路由:
 • 对于安全中断,如果GICD_CTLR.ARE_S 设置为1。
 • 对于非安全中断,如果GICD_CTLR.ARE_NS 位设置为1。
 如果永久启用关联路由,则 GICD_CTLR.ARE_S 和 GICD_CTLR.ARE_NS 是 RAO/WI。
 为了在启用关联路由时处理物理中断,还必须启用系统寄存器访问,请参阅第 11-197 页的 GIC 系统寄存器访问。 对于其他情况,请参见第 13 章传统操作和非对称配置。
2.3.1 通过PE亲和性路由SPI和SGI
SPI 使用关联地址和 GICD_IROUTER<n> 中保存的路由模式信息进行路由。
 SGI 使用关联地址和路由模式信息进行路由,这些信息由软件生成 SGI 时写入。
 SGI 使用以下寄存器生成:
 • ICC_SGI0R_EL1。
 • ICC_SGI1R_EL1。
 • ICC_ASGI1R_EL1。
 Arm 强烈建议在亲和力级别 0 上仅使用 0-15 范围内的值,以与 SGI 目标列表功能保持一致。 请参见第 4-55 页的软件生成的中断。
 SPI 和 SGI 使用不同的寄存器进行路由:
 • SPI 使用GICD_IROUTER<n>.Interrupt_Routing_Mode 进行路由:
      — 如果 GICD_IROUTER<n>.Interrupt_Routing_Mode 清除为 0,则 SPI 将路由到由 a.b.c.d 指定的单个 PE。
      — 如果 GICD_IROUTER<n>.Interrupt_Routing_Mode 设置为 1,则 SPI 将路由到定义为参与节点的任何 PE:
      - IRI 选择目标 PE 的机制是实现定义的。
      - 当 ICC_CTLR_EL3.PMHE == 1 或 ICC_CTLR_EL1.PMHE == 1 时,IRI 可能会使用与 PE 关联的 ICC_PMR_EL1 寄存器来确定目标 PE。
     
 • SGI 使用 ICC_SGI0R_EL1.IRM 和 ICC_SGI1R_EL1.IRM 进行路由:
      — 如果 IRM 位设置为 1,则 SGI 将路由到系统中所有参与的 PE,不包括始发 PE。
      — 如果 IRM 位清除为 0,则 SGI 将路由到由 a.b.c.targetlist 指定的一组 PE。
2.3.2 参与节点
配置为使用 1 of N 分发模型的已启用 SPI 可以在以下情况下以 PE 为目标:
 • GICR_WAKER.ProcessorSleep == 0 并且中断的中断组在PE 上启用。
 • GICD_CTLR.E1NWF == 1。
 • GICR_TYPER.DPGS == 1,对于该中断的中断组,GICR_CTLR.{DPG1S, DPG1NS, DPG0} == 0。
 有关使用 1 of N 分发模型时是否可以选择 PE 作为目标的更多信息,请参阅 GICR_CTLR,Redistributor控制寄存器(第 11-588 页)。
 有关启用中断和中断组的更多信息,请参阅第 4-63 页的启用中断分配。
2.3.3 更改关联路由启用
本手册介绍了启用关联路由的系统中的 GICv3 架构。 这意味着:
 • GICD_CTLR.ARE_NS == 1。
 • GICD_CTLR.ARE_S == 1。
 如果 GICD_CTLR.ARE_NS 或 GICD_CTLR.ARE_S 的值从 1 更改为 0,则结果是不可预测的。
 当GICD_CTLR. DS == 0,则:
 • 将 GICD_CTLR.ARE_S 从 0 更改为 1 是不可预测的,除非满足以下所有条件:
      — GICD_CTLR.EnableGrp0 == 0。
      — GICD_CTLR.EnableGrp1S == 0。
      — GICD_CTLR.EnableGrp1NS == 0。
 • 将GICD_CTLR.ARE_NS 从0 更改为1 是不可预测的,除非GICD_CTLR。 启用Grp1NS == 0。
 当 GICD_CTLR.DS == 1 时,则:
 • 将 GICD_CTLR.ARE 从 0 更改为 1 是不可预测的,除非满足以下所有条件:
      — GICD_CTLR.EnableGrp0 == 0。
      — GICD_CTLR.EnableGrp1 == 0。
 注
 当将 GICD_CTLR.ARE_S 或 GICD_CTLR.ARE_NS 从 0 更改为 1 时,清除 GICD_CTLR.EnableGrp0、GICD_CTLR.EnableGrp1S 或 GICD_CTLR.EnableGrp1NS 的效果必须是可见的(视情况而定)。软件可以轮询 GICD_CTLR.RWP 以检查清除 GICD_CTLR 的写入 .EnableGrp0、GICD_CTLR.EnableGrp1S 或 GICD_CTLR.EnableGrp1NS 位已完成。