1.1 LPI配置表
LPI配置为全局的。GIC是否支持指向LPI配置表的不同拷贝的Redistributor是由实现定义的。
是否在不同Redistributor设置GICR_PROPBASER为不同值是由实现定义的。无论GICR_CTLR.EnableLPIs==1,GICR_TYPER.CommonLPIAff表明哪个Redistributor必须让GICR_PROPBASER设置为相同的值。
实现将GICR_PROPBASER的所有拷贝被要求为相同的值(在访问通用状态)。
当GICR_CTLR.EnableLPIs==1时,在使用通用LPI配置表的Redistributor中对不同的GICR_PROPBASER的拷贝设置为不同的值会导致不可预测行为。
如果GICR_PROPBASER在不同Redistributor中设置为不同值,当GIC读取LPI配置表时由实现决定哪个GICR_PROPBASER被使用。但是,这些使用的拷贝将与GICR_CTLR.EnableLPIs==1的Redistributor相关。
为避免不可预测的行为,软件必须保证LPI配置表的所有拷贝都是唯一的,并且所有的修改都是全局可见的,这时:
(1)在任何Redistributor上写GICR_CTLR.EnableLPI从0到1;
(2)如果支持直接LPI,GICR_CTLR.EnableLPI=1的任何Redistributor写GICR_INVLPIR和GICR_INVALLR;
(3)ITS执行的INV和INVALL命令,实现必须包含至少一个ITS;
内存中的一个LPI配置表保存每个LPI的包含配置信息的条目,这时:
(1)GICR_PROPBASER指定一个4KB对齐的物理地址。它为LPI配置表基地址。
(2)对于任何LPI N,表项的位置由base address + N - 8192定义;
为修改中断的配置,软件写LPI配置表,然后发INV或INVALL命令。在不包含ITS的实现中,软件写GICR_INVALLR或GICR_INVLPIR。
Table 5-1为LPI配置表项位赋值。
Bits |
Name |
Function |
[7:2] |
优先级 |
LPI的优先级。它们为LPI优先级的最高位。优先级bits[1:0]为0。当GICD_CTLR.DS=0,该值与中断优先级的软件访问的安全和优先级规则一起变动。优先级范围为128-254。 如果GICD_CTLR.DS=1,该域值不会变动。 在GICv4中,虚拟LPI配置表行为与GICD_CTLR.DS==1一样,因此优先级不会变动。 |
[1] |
- |
保留 |
[0] |
使能位 |
LPI使能。此位控制LPI是否使能:0表示LPI不使能,1表示LPI使能 |
Caching
Redistributor可以缓冲GICR_PPROPBASER指定的LPI配置表的信息。当GICR_CTLR.EnableLPI=1时,遵守下列所有的规则:
- 是否存在一个或多个缓存由实现定义的。当至少一个缓存存在时,结构体和大小由实现定义;
- 一个LPI配置表项在任何时候可以被分配;
- 一个缓存的LPI配置表项不能保证一直保留在缓存中;
- 一个缓存的LPI配置表欺项不能保证与内存保持一致;
- 对LPI配置的修改只到合适的无效化操作完成时才可以被看到:
- 如果实现一个或多个ITS实现时,使用INV或INVALL命令发送无效化命令。一个SYNC命令可以完成INV和INVALL命令。
- 如果ITS没有实现时,写GICR_INVALLR或GICR_INVLPIR发出无效化命令。
如果没有GICR_CTLR.EnableLPI=1的Redistributor,GIC没有缓存的LPI配置表项。
1.2 LPI pending表
软件配置LPI pending表,通过写GICR_PENDBASER使用有效LPI INTID的实现范围。寄存器提供物理LPI的LPI pending表的基地址。
每个Redistributor会维护一个独立的LPI pending表的条目。当Redistributor中GICR_CTLR.EnableLPIs=1时LPI pending表指明了每个LPI的pending状态。
0 LPI没有pending
1 LPI正处于pending
对于给定的LPI:
(1)LPI pending表中对应byte在位置base_address + (N/8)
(2)bit在byte的位置为N mod 8
仅包含0的LPI pending表(包含前1KB)表明没有pending LPI。
LPI pending表的前1KB是由实现定义的。但是如果LPI pending表的前1KB和剩下的部分仅包含0,这表明没有任何pending LPI。
在初始分配时LPI pending表的前1KB内存必须仅包含0,这必须对Redistributor可见,否则影响不可预测。
在正常情况下,LPI pending表是由Redistributor单独维护的。
如果软件在GICR_CTLR.EnableLPIs=1时写LPI pending表,行为不可预测。当GICR_CTLR.EnableLPIs被清为0时,如果LPI pending表在GICR_CTLR.RWP被读为0时被写,行为也不可预测。
Redistributor被要求共享一个公共的LPI配置表,由GICR_CTLR.CommonLPIAff指定,它将把GICR_PENDBASER的OuterCache, Shareability, 或InnerCache域作为访问通用状态。
当GICR_CTLR.EnableLPI=1时,GICR_PENDBASER的OuterCache, Shareability, 或InnerCache域被在不同的Redistributor上被编程为不同值,这时不可预测的。
对于物理LPI,当GICR_CTLR.EnableLPIs被修改为1时,Redistributor必须从物理LPI pending表中读取物理LPI的pending状态。
NOTE:如果GICR_PENDBASER.PTZ=1时,软件保证LPI pending表仅包含0,包括前1KB。在这种情况下硬件可以不会读取表的任何部分。
如果GICR_CTLR.EnableLPIs=1时,当GICR_CTLR.RWP读为0时,GIC不会再对LPI pending表做更多的访问,LPI pending表的任何缓存都无效。不能保证清GICR_CTLR.EnableLPIs会导致LPI pending表被更新到内存中。
NOTE: 如果实现了一个或多个ITS,Arm强烈建议所有LPI在GICR_CTLR.EnableLPI被清为0时映射到其他的Redistributor中。
对于虚拟LPI,当GICR_CTLR.EnableLPIs=1时,GICR_VPENDBASER.Valid被修改为1时,Redistributor必须从虚拟LPI pending表中读取虚拟LPI的pending状态。
NOTE: 如果GICR_VPENDBASER.IDAI=0时,软件保证LPI pending表被同一个GIC实现写,这意味这硬件可以依赖表的前1KB而不许读取整个表项。
当GICR_CTLR.EnableLPIs=1时,如果GICR_PROPBASER.IDbits 小于0b1101时,GIC可以仍会访问LPI pending表的实现定义的区域。
1.3 虚拟LPI配置表和虚拟LPI pending表
GICv4同样使用内存表来管理虚拟LPI的配置和pending信息。表的格式也与物理LPI一样。