概述
GIC流协议接口描述了IRI(interrupt routing infrastructure——GICD、GICR、ITSs)和PE之间的可选接口,更具体地说,是Redistributor和关联的CPU interface之间的可选接口。该接口支持IRI和PE的独立开发,其中包括对CPU接口的系统寄存器支持。ARM建议GIC实现使用这个流协议接口。
每个方向都需要一个基于AMBA4 AXI-4流协议提供分组接口的通信通道:
- 从Redistributor到CPU interface。
- 从CPU interface到Redistributor。
术语
命令的通信方向称为下游或上游,其中:
- 下游是与Redistributor发起并发送到其相关CPU interface的命令相关联的方向。
- 上游是与CPU interface发起并发送给其关联的Redistributor的命令相关联的方向。
GIC流协议信号线
GIC流协议接口基于单向的AXI4流接口。因此,为了支持双向通信,GIC流协议接口在每个方向上由一个AXI4流协议接口组成,即:
- 一个下游的AXI4-Stream接口,包含从一个或多个redistributor到等量CPU接口的连接。在这个接口上,Redistributor是主服务器,CPU接口是从服务器。
- 上游AXI4-Stream接口,包含从一个或多个CPU接口到等效数量的redistributor的连接。在这个接口上,CPU接口是主接口,Redistributor是从接口。
AXI4-Stream接口上的多个数据包不能交错,即在给定时间内每个方向上只能传输一个数据包。

GIC体系结构要求GIC具体设计实现包含与每个连接的CPU interface对应的Redistributor,并定义用于标识PEs的枚举符号。在任何AXI4-Stream接口上,每个Redistributor只能与其相应的CPU interface通信。
AMBA4 AXI4-Stream协议规范将数据包定义为通过AXI4-Stream接口一起传输的一组字节。
IRI和CPU interface之间的互连必须确保流数据包序列在流协议接口上以与创建时相同的顺序传输。
信号量
接口需要一个全局的时钟信号ACLK,以及一个复位信号ARESETn
对于GIC流协议,每一个流接口由AXI-4信号名称的前缀标识:
- 从GICR到CPU interface的下行信号前缀为IRI
- 从CPU interface到GICR的上行信号前缀为ICC
信号 | 描述 |
---|---|
IRITVALID | 当设置为1时,这个信号表明主机正在驱动一个有效的传输 |
IRITREADY | 当设置为1时,这个信号表明从机在当前时刻可以接收一个传输 |
IRITDATA[BN:0] | 接口的数据通路 |
IRITLAST | 当设置为1时,该信号表明这是数据包最后一个传输 |
IRITDEST[N:0] | 当流接口支持多个PE时,这个信号表明目标CPU interface的流路由信息 |
信号 | 描述 |
---|---|
ICCTVALID | 当设置为1时,这个信号表明主机正在驱动一个有效的传输 |
ICCTREADY | 当设置为1时,这个信号表明从机在当前可以接收一个传输 |
ICCTDATA[BN:0] | 接口的数据通路 |
ICCTLAST | 当设置为1时,这个信号表明这是数据包最后一个传输 |
ICCTID[N:0] | 当流接口支持多个PE时,这个信号表明发送源CPU interface的流路由信息 |
数据包格式
GIC架构通过GIC流协议接口发送数据包,其中数据包的初始半字节表示数据包类型。
数据包大小始终是流传输实现数据路径宽度的倍数。如果一个数据包所需的字节数小于整个数据包的大小,则未使用的字节被标记为保留并用值0填充。
支持的INTID大小
GIC架构支持16位和24位INTID字段。当INTID是包中的一个参数时,包头中的ID长度字段定义了使用的ID格式,如下所示:
- ID length == 0时,使用16bit宽度INTIDs
- ID length == 1时,使用24bit宽度INTIDs
接口初始化时使用下行控制命令通知CPU interface,IRI是否支持24位intid。
对于bit[23:16]值为0的24位INTID,流接口允许识别并传输16位INTID字段的数据包。
当PE使用24位INTID,并且[23:16]位不全为0,而IRI只支持16位INTID,会产生协议错误。
来自CPU interface的下游控制确认命令,会返回Redistributor和CPU interface都支持的最大INTID长度。Redistributor和CPU interface不能发送包含超过此长度INTID的命令。
当Redistributor和CPU接口都支持大于16位的INTID长度,但是特定数据包中的INTID值只能使用16位编码时,允许发送16位的值,其中ID length == 0b00。
软件产生协议错误和数据包错误
绝不允许软件编程导致硬件协议错误,因为这可能导致PE或GIC不可操作。
如果错误存在于包内字段的值中,则称为包错误。协议和数据包错误可能导致不可预测的行为。报告这些错误的方式是根据具体设计决定的。
硬件产生数据包错误
如果发送的数据包不符合规范中描述的体系结构格式,并且不正确的格式不是软件错误编程的结果,那么体系结构对GIC的行为不做任何保证。在这种情况下,GIC可能以多种方式变得不可操作,这可能导致系统挂起、数据损坏或任何其他影响。在某些实现中不能排除对系统的物理损坏。
在高可靠性系统中,实现可能会选择使用具体设计决定的系统错误报告此类情况,但这超出了体系结构的范围。
GIC流协议
GIC流协议支持两种数据包:
- 用于控制操作的命令数据包
- 用于对命令数据包进行应答的回应数据包
Redistributor命令 | ID | 在前16bits传输中的参数 | 后续传输中的数据 | 描述 |
---|---|---|---|---|
clear | 0x3 | bit[7:6] ID length | INTID | 重置一个指定的pending态物理中断 |
downstream control | 0x8 | bit[15:12] length | ||
bit[11:4] identifier | data的字节数 | 向CPU interface写数据 | ||
字节数应当大于0小于9 | ||||
quiesce | 0x4 | 请求CPU interface进入quiescent状态 | ||
set | 0x1 | bit[15:8] priority | ||
bit[7:6] ID length | ||||
bit[5] GrpMod | ||||
bit[4] group | INTID | 将pending态中最高优先级的物理中断设置给PE | ||
vclear | 0x7 | bit[7:6] ID length | virtual INTID | 重置一个指定的pending态虚拟中断 |
vset | 0x6 | bit[15:8] priority | ||
bit[7:6] ID length | ||||
bit[4] group | virtual INTID | 将pending态中最高优先级的虚拟中断设置给PE |
Redistributor回应 | ID | 在前16bits传输中的参数 | 后续传输中的数据 | 描述 |
---|---|---|---|---|
activate acknowledge | 0xc | bit[4] V | 确认Redistributor收到了activate命令,并确认activate的效果是可见的。 | |
deactivate acknowledge | 0xa | 确认Redistributor收到了deactivate命令,并确认deactivate的效果是可见的。 | ||
generate SGI acknowledge | 0x9 | 确认Redistributor收到了产生SGI的命令,并确认命令的效果对其它PE是可见的。 | ||
Upstream control acknowledge | 0xb | 确认收到上游控制命令,并确认写操作的效果是可见的。 |
CPU interface命令 | ID | 在前16bits传输中的参数 | 后续传输中的数据 | 描述 |
---|---|---|---|---|
activate | 0x1 | bit[7:6] ID length | ||
bit[4] V | INTID | 由于CPU接口上的中断确认而导致的从pending到activate的通知请求。 | ||
deactivate | 0x6 | bit[10:8] groups | ||
bit[7:6] ID length | INTID | 针对指定中断的deactivate请求 | ||
generate SGI | 0x7 | bit[59:56] RS | ||
bit[15:12] SGInum | ||||
bit[9] RSV | ||||
bit[8] A3V | ||||
bit[7] IRM | ||||
bit[6] NS | ||||
bit[5:4] SGT | Affinity Routing Value (A0 to A3) | 请求Redistribuor发布一个SGI | ||
Upstream control | 0x8 | bit[15:12] length | ||
bit[11:4] Identifier | 数据字节长度 | 一个系统控制命令,例如,它可以将配置状态传递给Redistributor。长度必须大于0小于9。 |
CPU interface回应 | ID | 在前16bits传输中的参数 | 后续传输中的数据 | 描述 |
---|---|---|---|---|
clear acknowledge | 0x4 | bit[4] V | 确认CPU interface接收到针对指定中断clear命令 | |
downstream control acknowledge | 0xb | 确认CPU interface接收到来自Redistributor的下行控制命令 | ||
quiesce acknowledge | 0x9 | 确认一个quiesce命令,并且确保Redistributor到CPU interface之间处于quiescent状态 | ||
release | 0x3 | bit[7:6] ID length | ||
bit[4] V | INTID | 当CPU接口不能处理中断时,释放对中断的控制,并提供释放的原因。 |
保留所有其他命令和响应id。如果CPU接口收到保留ID,则为协议错误。
命令报文有一个等价的握手响应报文来确认命令。这条规则有两个例外:
- Clear和VClear命令都通过一个Clear Acknowledge响应来确认,响应头中有一个位字段表示确认哪个命令。
- Set和VSet命令报文由Release响应或Activate命令确认。这意味着Activate命令也具有与Set和VSet命令相关的响应语义。当使用Activate命令时,Redistributor使用activate acknowledge响应来确认该命令。Release、Activate和Activate Acknowledge报文的报头中都有一个位域,用来表示响应的是Set命令还是VSet命令。
对Set或VSet命令的响应取决于系统上下文和CPU interface上的事件。当一个被转发到CPU接口的pending中断不能被CPU接口维持为pending或activated时,就会发生Release响应。这可能发生,例如,当:- 关闭INTID的中断组。
- 最高优先级的pending物理中断在被激活之前由Set命令更新。
- 最高优先级的pending虚拟中断在被激活之前由VSet命令更新。
与下游Redistributor命令关联的规则
- 当GICR_WAKER.ProcessorSleep == 0,则发送到CPU interface的第一个数据包必须是Downstream Control数据包。这个数据包包括支持的安全状态数,以及GIC流协议接口支持的物理和虚拟INTID长度。
- 不能有多个未完成的downstream control command,并且在downstream control command得到确认之前,Redistributor必须只生成响应数据包。
- 在收到Set命令后,需要CPU interface将先前挂起的物理中断释放回Redistributor。
- 除非受到本节中另一条规则的限制,否则可以同时生成和执行两个Set命令,并且在传输Set命令时,Redistributor必须能够接受用于物理中断的Activate命令。
- 接收到VSet命令后,CPU接口需要释放先前挂起的虚拟中断回Redistributor。
- 在VSet命令被传输时,当Redistributor能够接受虚拟中断的activate命令时,才生成VSet命令。
- 永远不会有一个以上的clear命令。在Clear命令得到确认之前,Redistributor不能生成除acknowledge包之外的其他包。
- 永远不会有一个以上的VClear命令。在VClear命令得到确认之前,Redistributor不能生成除确认报文外的其他报文。
- 永远不会有多个未执行的quiesce命令,并且在用静默确认回应静默命令之前,Redistributor必须仅生成响应数据包。
- Redistributor不能向不支持GICv4的CPU接口发送VSet或VClear命令。确定是否支持GICv4的机制是具体设计决定的。
与上游CPU interface命令关联的规则
- 永远不会有超过一个未完成的upstream control命令,并且CPU interface必须在发出另一个upstream control命令之前,对upstream control命令进行确认。
- 永远不会有超过一个未执行的deactivate命令。这意味着CPU interface在发出另一个deactivate命令之前必须等待一个deactivate命令得到确认。CPU interface在收到 deactivate确认响应之前,可以继续发送其他命令。
- 永远不会有超过一个未执行的generate SGI命令。这意味着CPU interface在发出另一个Generate SGI命令之前必须等待Generate SGI命令得到确认。CPU interface在收到Generate SGI确认响应之前,可以继续发送其他命令。
- 在发出一个参数V==0的Clear Acknowledge响应之前,CPU接口必须发出Release命令,该命令将Clear命令中指定的物理中断移动到CPU interface上的inactive状态。
- 在发出一个参数V==1的Clear Acknowledge响应之前,CPU接口必须发出Release命令,该命令将VClear命令中指定的虚拟中断移动到CPU interface上的inactive状态。
- 在发出Quiesce Acknowledge响应之前,必须确认来自Redistributor的所有其他未完成的命令,并且Release命令必须删除CPU interface上的任何pending态中断。
命令和回应数据包格式
activate(ICC)
当确认一个中断时,CPU interface发送activate命令。当Redistributor接收到activate命令时,它将中断设置为active状态。CPU interface当切仅当Redistributor行为需要的时候发送activate命令:
- 对于SPIs、SGIs和PPIs,Redistributor必须清除边沿触发类型的中断的pending bit,并且设置active bit
- 对于LPIs,Redistributor必须清除pending bit
activate命令由CPU interface产生。与其它命令不同,它也可以作为set命令和vset命令的回应。
- Set或VSet命令会在有限时间内产生Release响应或Activate命令。时间的长短取决于挂起的中断在CPU接口内改变其状态的时间。Activate命令确认原来的Set命令。activate命令本身使用来自Redistributor的activate acknowledge响应进行确认。

activate acknowledge(IRI)
Redistributor发送Activate Acknowledge响应以确认收到Activate命令,并确认Activate操作的效果对Redistributor和其他PE是可见的。

clear(IRI)
clear命令清除指定的pending态中断

clear acknowledge(ICC)
CPU interface发送clear acknowledge回应clear或vclear命令

deactivate(ICC)
如果初始异常级别和安全状态可以访问INTID所属的中断组,则Deactivate命令deactivate中断。Redistributor发送deactivate acknowledge以响应deactivate命令。

- bit[10]为1:安全group1中断
- bit[9]为1:非安全group1中断
- bit[8]为1:group0中断
deactivate acknowledge(IRI)

downstream control(IRI)
下行控制命令用来向CPU接口传输指定字节数的数据。

- length表明有效数据字节数
- identifier用于指定数据的格式
- 0x0:settings(configure interface)length==1 。 data[0]数据携带了Redistributor全局设置(bit[7:6]——VL表明支持的vINTID长度; bit[5:4]——PL表明支持的pINTID长度; bit[3:2]——保留字段0; bit[1]——RSS表明GICD_TYPER.RSS的值; bit[0]——DS表明GICD_TYPER.DS的值)
- 0x01-0x7f 保留值
- 0x80-0xff 保留给具体设计实现
downstream control acknowledge(ICC)

generate SGI(ICC)

- SGInum表明生成的SGI的INTID
- RSV表明RS字段是否有效
- 0 RS为RES0
- 1 RS表明affinities被target list覆盖
- A3V表明命令是否包含A3字段
- IRM表明使用的中断路由模式
- NS表明生成的SGI的来源的安全状态
- SGT表明生成SGI的来源寄存器
- 0b00 ICC_SGI0R_EL1
- 0b01 ICC_SGI1R_EL1
- 0b10 ICC_ASGI1R_EL1
- 0b11 Reserved
- Target list是由路由模式决定的目标PE的分组
- A1 A2 A3是affinity values
generate SGI acknowledge(IRI)

quiesce(IRI)

当没有挂起的中断并且所有未完成的操作都完成时,CPU接口处于静止状态。为了保证静态,CPU接口必须:
- 通过发送clear acknowledge命令来响应任何未完成的clear和vclear命令。
- 释放任何挂起的虚拟或物理中断。
- 确保收到来自Redistributor的确认回复,表明所有未完成的工作已完成;
- 生成SGI请求。
- activate请求。
- deactivate请求。
- upstream control。
- 通过发送一个Quiesce Acknowledge响应作为最后的传输来响应Quiesce命令。
此外,软件必须确保在CPU接口发送静默确认响应后,Redistributor不会接收到任何流量。不保证这一点会导致不可预测的行为。在实践中,因为这样的时间是不可预测的,所以软件必须确保在GICR_WAKER的ProcessorSleep位设置为1之后不会产生流量。具体见GICv3电源管理。
如果downstream control acknowledge未完成,CPU接口将无法接收到静默命令。
quiesce acknowledge(ICC)

release(ICC)
当CPU interface无法处理当前的中断时,CPU interface会发送一个Release 响应

set(IRI)
set命令会将pending状态中最高优先级的中断发送给PE。

如果Redistributor发送Set命令,命令中指定的中断将替换任何未完成的最高优先级pending中断。也就是说,该命令将设置一个新的最高优先级pending中断。当一个pending的中断被替换时,CPU接口必须将它释放回Redistributor。
在以下情况下不会发送set命令:
- INTID是特殊中断号(1020-1023)
- 亲和路由对中断分组是enable的,并且INTID大于1023小于8192
- 亲和路由对中断分组是disable的,并且INTID大于1023小于8192,bits[9:4]不全为0
- 亲和路由对中断分组是disable的,并且INTID大于8192
- 当前set命令和前一个set命令有相同的INTID,除非Redistributor已经接收到了一个activate命令或release命令
upstream control(ICC)
该命令发送数据到Redistributor

data value | identifier | length | contents of data[0] field |
---|---|---|---|
physical interface enables | 0x00 | 0x1 | 这个值保存了物理CPU interface使能位的值 |
【2】:EnableGrp1 Secure | |||
【1】: EnableGrp1 non-secure | |||
【0】:EnableGrp0 Secure | |||
virtual interface enables | 0x01 | 0x1 | 这个值包含了虚拟CPU interface使能位的值 |
【1】:EnableGrp1——ICH_VMCR_EL2.VENG1 | |||
【0】:EnableGrp0——ICH_VMCR_EL2.VENG0 | |||
physical priority | 0x02 | 0x1 | 这个值包含了当前priority mask register(PMR)的值 |
0x03-0x07 | reserved | ||
0x80-0xff | implementation defined |
upstream control acknowledge(IRI)

vclear(IRI)
vclear命令重置最高优先级的pending态虚拟中断

vset(IRI)

当vINTID指定的虚拟中断在虚拟LPI pending表中被设置为pending时,Redistributor发送VSet命令。CPU接口必须发送V == 1的activate命令来激活虚拟中断,或者将虚拟中断release给Redistributor。
如果Redistributor发送一个VSet命令,命令中指定的中断总是替换任何先前的中断,也就是说,命令设置一个新的最高优先级的pending中断。如果被替换的中断仍然有效并且挂起,CPU接口必须将其释放回Redistributor。