GIC/ITS代码分析(3)ITS驱动初始化

        这里对ITS再作简要介绍。在GICv3中,外设通过写GITS_TRANSLATER,根据所写内容解析出device_id和event_id,根据device_id找到设备所对应的Device Table,根据event id找到ITT,并最终在Collection Table中找到中断所要发送的GICR上。

        其中通过ITS命令MAPD/MAPTI/MAPC建立起内存的各种表之间的关系。

        ITS驱动是通过ACPI表获取ITS信息,并分配ITS所需要的Device Table/Collection Table内存并设置对应的寄存器,同时分配LPI中断所需要的LPI配置表和LPI pending表。最后为ITS分配并设置irq_domain。

        ITS驱动初始化步骤如下:

其中主要是通过函数its_acpi_probe()识别并使能ITS,函数allocate_lpi_tables()分配LPI配置表和pending表。其中函数its_acpi_probe()详细如下:

它执行操作如下:

  1. 映射ITS寄存器,分配its_node,并设置ITS物理地址和虚拟地址
  2. 分配ITS命令列队,并设置命令队列的基地址
  3. 设置ITS的GITS_TRANSLATER地址
  4. 分配ITS表(Device Table)
  5. 分配Collection Table表,每个CPU一个表
  6. 设置命令队列并使能ITS
  7. 分配并设置irq_domain

其中ITS所对应的irq_domain = its_domain_ops设置如下所示:

(1).alloc = its_irq_domain_alloc 分配nr_irqs个中断,设置irq_chip

它分配nr_irqs个中断,并设置irq_chip为its_irq_chip,各成员函数介绍如下。

序号

函数名

描述

1

.irq_mask=its_mask_irq

屏蔽中断。对于GICv3,将LPI configure表EN位设置为0

2

.irq_unmask=its_unmask_irq

使能中断。对于GICv3,将LPI configure表EN位设置为1,并发INV

3

.irq_eoi=irq_chip_eoi_parent

4

.irq_set_affinity= its_set_affinity

设置亲和性。通过ITS命令MOVI设置中断亲和性

5

.irq_compose_msi_msg=its_irq_compose_msi_msg

设置MSI IOVA地址

6

.irq_set_irqchip_state=its_irq_set_irqchip_state

设置或清除IRQCHIP状态。设置采用INT命令,清除采用CLEAR命令

(2).activate = its_irq_domain_activate 激活中断,建立起ite

      对于ITS命令,在驱动中起了非常重要的作用,以下对ITS命令作简要归纳。

命令

命令参数

描述

CLEAR

DeviceID, EventID

将EventID和DeviceID定义的event转化为ICID和pINTID,并发送到合适的Redistributor移除pending状态

DISCARD

DeviceID, EventID

将EventID和DeviceID定义的event转化为ICID和pINTID,并发送到合适的Redistributor移除pending状态。它也保证与特定的EventID相关的Redistributor的任何缓存与内存中配置保持一致。DISCARD移除了ITT中DeviceID和EventID的映射,保证特定EventID的请求被丢弃。

INT

DeviceID, EventID

将EventID和DeviceID定义的event转化为ICID和pINTID,并发送到合适的Redistributor设置pending状态

INV

DeviceID, EventID

指定ITS必须保证与特定EventID相关的Redistributor的任何缓存与内存中LPI配置表保持一致

INVALL

ICID

指定ITS必须保证由ICID定义的中断collection的任何缓存与所有Redistributor内存中LPI配置表保持一致

INVDB

仅GICv4.1

vPEID

仅GICv4.1。指定ITS必须保证vPEID的默认doorbell相关的任何缓存与所有Redistributor内存中LPI配置表保持一致

MAPC

ICID, RDbase

将ICID定义的collection表映射到RDbase定义的Redistributor

MAPD

DeviceID,ITT_addr,Size

将DeviceID相关的设备表项映射到由ITT_addr和Size定义的ITT

MAPI

DeviceID,EventID, ICID

将EventID和DeviceID定义的event映射到ICID和pINTID=EventID的ITT项

MAPTI

DeviceID,EventID, pINTID, ICID

将EventID和DeviceID定义的event映射到它相关的ITE,ITE由DeviceID相关的ITT中ICID和pINTID定义

MOVALL

RDbase1, RDbase2

让RDbase1指定的Redistributor上所有的中断移到RDbase2指定的Redistributor上

MOVI

DeviceID,EventID, ICID

更新DeviceID和EventID定义的event的ITT表项的ICID域。它也将DeviceID和EventID定义的event转化为ICID和pINTID,并在合适的Redistributor移除pending状态,如果它被设置,将中断移到新的ICID定义的Redistributor,并使用新的ICID更新event相关的ITE

SYNC

RDbase

保证RDbase指定的Redistributor的物理中断相关的所有未完成ITS操作在执行任何更多ITS命令之前全局可见。跟随SYNC的执行,所有之前命令必须应用于后续写入GITS_TRANSLATE。

VINVALL

vPEID

保证与vPEID相关的任何缓存的Redistributor信息与内存中相关的LPI配置表保持一致

VMAPI

DeviceID, EventID,Dbell_pINTID,

vPEID

将由DeviceID和EventID定义的event映射到ITT表项,该表项vPEID, vINTID=EventID, Dbell_pINTID,一个doorbell

VMAPP

GICv4.0

vPEID,RDbase,VPT_addr,

VPT_size

将vPEID定义的vPE表项映射到目标RDbase,包括相关的虚拟LPI pending表(VPT_addr, VPT_size)

VMAPP

GICv4.1

vPEID,RDbase, VCONF_addr,VPT_addr,

VPT_size, PTZ, Alloc,

Default_Doorbell_pINTID

映射vPEID定义的vPE,包括相关的虚拟LPI配置和pending表。可选的指定默认doorbell。

VMAPTI

DeviceID, EventID, vINTID, Dbell_pINTID,vPEID

使用vPEID,vINTID,Dbell_pINTID和doorbell将DeviceID和EventID定义的event映射到ITT表项

VMOVI

DeviceID, EventID, vPEID

为DeviceID和EventID定义的event更新ITT表项的vPEID域。将DeviceID和EventID定义的event转化为vPEID和pINTID,让合适的Redistributor移除pending状态,如果有设置,将中断发送到新vPEID定义的Redistributor,使用新的vPEID更新event相关的ITE

VMOVP

GICv4.0

vPEID, RDbase, SequenceNumber, ITSList

更新vPEID定义的vPE表项到由RDbase定义的目标Redistributor。软件必须使用SequenceNumber和ITSList在超过一个ITS的情况下同步VMOVP命令的执行

VMOVP

GICv4.1

vPEID, RDbase, SequenceNumber, ITSList, Default_Doorbell_pINTID

将vPEID定义的vPE映射更新到RDbase定义的目标Redistributor

VSGI

仅GICv4.1

vPEID, Priority, G, C, E, vPEID

仅GICv4.1。对于vPEID定义的vPE,设置配置或更新由vINTID定义的中断状态

VSYNC

vPEID

保证在任何更多ITS命令被执行之前所有未完成的ITS操作被全局可见。VSYNC接下来的执行,所有之前的命令必须应用到后续写GITS_TRANSLATER。

这里对重要的ITS命令作介绍。

- MAPD命令

        每个DeviceID都有自己的ITT用于保持EventID到INTID的映射。软件使用MAPD命令用于将DeviceID映射到ITT。

MAPD <DeviceID>, <ITT_Address>, <Size>

- MAPT/MAPTI命令

        不同的EventID被映射到不同的INTID,INTID必须被映射到collection,而每个collection被映射到一个Redistributor。软件使用MAPT/MAPTI命令将INTID映射到一个collection。

        当EventID=INTID时,使用MAPT如下:

MAPT <DeviceID>, <EventID>, <Collection ID>

        当EventID!=INTID时,使用MAPTI如下:

MAPTI <DeviceID>, <EventID>, <INTID>, <Collection ID>

- MAPC命令

        软件使用MAPC命令将collection映射到一个Redistributor。

MAPC <Collection ID>, <Target Redistributor>

        其中对于Target Redistributor的识别,依赖于GITS_TYPER.PTA。当GITS_TYPER.PTA=0时,Redistributor可以通过处理器ID识别;当GITS_TYPER.PTA=1时,Redistributor可以通过物理地址识别。

- MOVI命令

        软件使用MOVI命令将DeviceID和EventID表示的中断重新映射到一个CollectionID。

MOVI <DeviceID>, <EventID>, <CollectionID>

- CLEAR命令

        软件使用CLEAR命令清除DeviceID和EventID表示的中断的pending状态。

CLEAR <DeviceID>, <EventID>

- INT命令

 软件使用INT命令设置DeviceID和EventID表示的中断的pending状态。

INT <DeviceID>, <EventID>

- MOVALL命令

        软件使用MOVALL命令将RDbase1表示的Redistributor上所有中断移到RDbase2表示的Redistributor上。

MOVALL <RDbase1>, <RDbase2>

- INV命令

        软件使用INV命令保证DeviceID和EventID表示的中断所对应的LPI配置表项与Redistributor中的缓冲保持一致。

INV <DeviceID>, <EventID>

- INVALL命令

        软件使用INVALL命令保证CollectionID所对应的LPI配置表项与Redistributor中缓冲保持一致。

INVALL <CollectionID>

- SYNC命令

        软件使用SYNC命令保证Redistributor上未完成的物理中断对应的ITS操作完成。

SYNC <RDbase>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值