登录后台

页面导航

本文编写于 478 天前,最后修改于 450 天前,其中某些信息可能已经过时。

LPIs

locality- specific peripheral interrupt(lpi)是一种基于消息的边沿触发的中断。在具体的架构实现中,它可以使用interrupt translation service(its)将自身路由到特定的gicr以及连接的核上。gicv3提供了两种支持lpi的方式

  • 通过its将来自外设的事件id转化为lpi的中断id
  • 通过gicr_setlpir寄存器将lpi的中断id直接发给gicr

在具体的架构实现中,如果包含了lpi功能,则最少需要支持8192个lpi中断。由于lpi中断数量较多,所以并不能像sgi、ppi、spi一样将配置信息与pending信息保存在寄存器中。lpi的配置信息与pending状态信息都是保存在内存中,而它们的基地址则是保存在gicr中。

当架构中有安全与非安全两种模式时,lpi总是非安全group1类型的中断。如果架构只支持一种安全模式,则lpi总是group1类型的中断。

由于整个架构中只有唯一的全局物理lpi空间,所以lpi可以在所有的gicr上路由。

LPI Configuration tables

lpi的配置是全局的。gic是否支持gicr指向不同的lpi配置表的副本,是具体实现中来决定的。为了避免系统产生不可预测的行为,软件保证所有lpi配置表的副本都是一致的。

lpi配置表的每一个表项,代表了一个lpi的配置信息。配置表的基地址要求4KB对齐。在改变某一个lpi的配置,即修改了lpi配置表内容后,需要执行INV和INVALL指令。如果架构中不包含ITS,则需要软件去写gicr_invallr寄存器或者gicr_invlpir寄存器。

在lpi配置表中,每一个表项有8bits。具体分配如下

E0967A21-DC60-4A9C-AB09-8EF06E7B42E4.jpeg

lpi优先级的低2位永远为0。enable位为1时表示该lpi被启用。

gicr可以cache存储来自lpi配置表中信息。它遵循以下规则:

  • cache数量和大小都是由架构实现时具体决定的,至少有一个cache
  • 一个lpi配置表项可能在任何时刻分配到cache中
  • 一个cached表项不一定保留在cache中
  • 对lpi配置表的更改在使用作废指令之前不一定可见

LPI Pending tables

软件通过gicr_pendbaser寄存器来配置LPIpending表。该寄存器提供了lpi pending表的基地址信息。
每一个gicr都会在单独的lpi pending表中维护自己拥有的表项。
如果表中所有数据全为0,包括表前1KB地址空间,则表明当前没有lpi处于pending状态。表开头1KB地址空间的作用是由架构实现具体决定的。但是需要保证在初始化时,该地址空间内全为0,并且对gicr都为可见的,否则会产生不可预测的影响。
当gicr_ctlr的lpi使能位被打开时,对lpi pending表的写操作会造成不可预测的后果。

在虚拟的lpi中也有对应的虚拟lpi pending表。与上述的物理lpi pending表有相同的概念,区别在于虚拟lpi pending表的基地址由对应的gicr_vpendbaser寄存器提供。

ITS

its将来自外设(由deviceID进行区分)的event ID进行转换:

  • 该event ID对应的中断ID
  • 该中断ID的目标gicr
    在gicv3架构中,its将外设的事件转化为对应的lpi中断。lpi可以通过its转发到目标gicr上,或者可以通过gicr_setlpir寄存器直接在gicr上产生一个lpi。具体的实现中只能支持这两种方法中的一个。
    在gicv4架构中,its还支持直接注入虚拟lpi中断

its对于sgi、ppi、spi都是无效的。

its的转换流程如下所示:

  1. 根据device ID在外设表(device table)中选择对应的表项(device table entry DTE)。该表项描述了要使用哪一个中断转换表(interrupt translation table ITT)
  2. 根据event ID在上述确定的ITT中找到对应的表项(interrupt translation entry ITE)。该表项描述了对应的中断ID以及interrupt collection number(ICID)
  3. 根据ICID在collection table(CT)中选择对应的表项。该表项描述了目标的gicr

这些表是通过its命令来创建并维护的。架构规定不能直接访问这些表的地址,并且这些表必须通过its命令进行配置。

ITS Table

为了让软件给its私有的表提供地址空间,gic提供了一组寄存器用于配置以下信息:

  • 需要的its私有表的数量
  • 每个表的表项大小
  • 每个表的类型

所有的its表都处于非安全的物理地址空间

its表的状态与配置信息都存放在一组内存中的表内。这段地址空间需要在使能its之前由软件对其进行分配。gits_baser寄存器指明了its表的基地址与大小。its表拥有两种结构:

  • 一级表:一段连续的地址空间被分配作为its表
  • 二级表:level1表项为64位长。第63位为valid位用于控制该表项是否指向level2表。62到52位为保留位,为0。第51到第N位代表level2表的基地址,N由page size决定(gits_baser.page_size)。第N到0位为保留位,为0。

下图展示了its表是如何执行转换操作的

BF6B1C35-AD26-4896-A67B-BD967704A622.jpeg

Interrupt collections

在gic v3架构中,its认为产生的所有物理lpi都是集合的成员。与集合相关的数据可以保存在ITS中,也可以保存在外部存储器中,或者同时保存在两者中。

The Device table

设备表的每一个表项DTE描述了一个设备ID和一个ITT基地址之间的映射关系。its使用itt来存储指定设备ID的每个event ID的转换。设备ID是分配给每个设备的唯一标识符,可以创建一系列的event ID

The Interrupt translation table

中断转换表itt是特定于每个可创建被编号事件的设备。itt中每一个表项被称为ite

The collection table

集合表提供了一个中断集合项CTE的表格。对于物理lpi来说,每一个cte描述了itt产生的icid与目标gicr之间的映射关系。

Command interface

its是由存储在内存中的命令队列来控制的。它是一个循环buffer,由以下三个寄存器定义

  • gits_cbaser:该寄存器定义了命令队列的基地址和他的大小。命令队列必须是64KB对齐,并且大小必须是4KB的倍数。命令队列的每一个条目是32bytes。该寄存器还定义了命令队列的cacheability以及shareability属性
  • gits_creadr:这个寄存器指向its将要执行的下一条命令
  • gits_cwriter:这个寄存器指向下一条写入命令的队列条目

477AF866-746B-41B8-8758-EEAC439093CF.jpeg