1. ITS操作
一个外设通过写ITS中的GITS_TRANSLATER来产生LPI。写操作提供给ITS如下信息:
(1)EventID
该值会写往GITS_TRANSLATER。EventID标识外设发送的是哪个中断。EventID可能与INTID一样,或通过ITS将INTID转换为EventID。
(2)DeviceID
DeviceID标识外设。DeviceID的产生由实现定义的。
ITS转换EventID,该EventID被通过外设写到GITS_TRANSLATER。如何将EventID转化为INTID对每个设备是特殊的,这也是为什么要求DeviceID。
ITS使用三种类型的表来处理事务和LPI的路由。这些表如下:
(1)Device Tables
用来将DeviceID映射到时中断转换表ITT。
(2)Interrupt Translation Tables
它包含DeviceID相关的从EventID到INTID之间的映射。它也包含Collection,其中INTID为Collection的成员。
(3)Collection Tables
用来将Collection映射到Redistributor。
当外设写GITS_TRANSLATER,ITS:
- 用DeviceID来选择Device Table中合适的条目。这个条目标识使用的是哪个中断转换表ITT;
- 使用EventID从ITT中选择合适的条目。这个条目提供INTID和Collection ID;
- 使用Collection ID选择Collection Table中合适的条目,Collection Table返回路由信息;
- 将中断传递给目标Redistributor。
NOTE: ITS可以选择性的支持部分硬件Collection。硬件Collection为ITS在内部保持配置,而不是将其存储在内存中。GITS_TYPER.HCC表示支持的硬件Collection数目。
2. 命令队列
通过使用内存中的命令队列来控制ITS。命令队列是环形buffer并由三个寄存定义:
(1)GITS_CBASER
该寄存器表明命令队列的基地址和大小。命令队列必须64KB对齐,大小必须是4KB的整数倍。命令队列中的每项为32byte。GITS_CBASER指明了在ITS访问命令队列时CACHE和共享能力。
(2)GITS_CREADR
该寄存器指向ITS下一个将要处理的命令。
(3)GITS_CWRITER
该寄存器指向在队列中下一个将要写的新的命令。
下图显示一个命令队列的简要表示:
3. ITS的初始配置
为了在系统启动时配置ITS,软件需要:
(1)为Device Table和Collection Table分配内存
GITS_BASER[0..7]寄存器表明ITS中Device Table和Collection Table的基地址和大小。软件使用寄存器发现ITS支持的表数目和类型。软件必须分配要求的内存,并设置GITS_BASERn寄存器指向分配的内存。
(2)为命令队列分配内存
软件必须为命令队列分配内存,并设置GITS_CBASER和GITS_CWRITER指向分配内存的开始。
(3)使能ITS
当上述表和命令队列已分配时,可以使能ITS,设置GITS_CTLR.Enable位为1。
一旦GITS_CTLR.Enable被设置,GITS_BASERn和GITS_CBASER寄存变为只读。
4. Collection和Device Table的size和layout
Collection和Device Table的位置和大小通过GITS_BASERn寄存器配置。软件须分配为这些表分配足够的内存,并在使能ITS之前配置GITS_BASERn寄存器。
软件可以分配一级表,或两级表。这由GITS_BASERn.Indirect。
NOTE: 对两级表的支持是可选的。若ITS只支持一级表,GITS_BASERn.Indirect为RAZ/WI。
(1)一级表
对于一级表,需要为ITS分配一块连续的内存来记录映射。要求软件在使能ITS之前填充内存。之后ITS从命令队列处理命令,由ITS populate表。
表格的规模由DeviceID和CollectionID的宽度决定。可以通过如下计算出来:
Size = 2~ID_width * entry_size
其中entry_size是每个表项的bytes数,由GITS_BASERn.Entry_size。
当配置GITS_BASERn寄存器,表的大小是一些页。每个页的size由GITS_BASERn.Page_Size,可以为4KB,16KB或64KB。因此,公式结果必须向上舍入整个页。
比如,若系统实现了8bit DeviceID,每个表项的bytes为8,4K页:
2~8 *8 = 2048bytes -> 4K
(2)二级表
对于二级表,软件分配一个一级表,数个二级表。
软件来找到一级表,一级表中的每个项要么指向二级表或标识为无效。在二级表分配给ITS之前必须以0来填充。
当ITS被使能(GITS_CTLR.Enabled = 1),软件分配更多的二级表,并更新将一级表指向二级表。在ITS使能时,软件不能移除分配,或改变已存在的分配。
每个二级表的大小为一个页。由于二级表为flat表,由GITS_BASERn.Page_Size配置。因此它包含(PAGE_SIZE/ENTRY_SIZE)个项。
每个一级表项代表(PAGE_SIZE/ENTRY_SIZE)ID,可以指向二级表或标识为无效。任何指向无效项的ITS命令都会被丢弃。
一级表要求的大小可计算:
SIZE = 2~ID_width / (PAGE_SIZE/ENTRY_SIZE) *8
对于单级表,一级表的大小为页的整数倍。因此公式的结果必须向上舍入到页大小。