在ATF的架构下,我使用ATF Github上提供的Test Secure Payload(TSP)当做是BL32,然后使用Test Secure Payload Dispatcher(TSPD)当做是BL31 runtime service。
但是在移植TSP时遇到了些问题,我的平台是ARMv8架构的。
在整个ATF流程中,每个阶段皆可正常的初始化,其中BL32我没有做额外的初始,如MMU、timer、GICv3,只有使用ATF的默认值去设定中断处理interrupt handler(vector table)
目前我只是想把TSP移植至ATF,然后跳至BL33完整的开机完成。
目前的状况是,如果没有加BL32(TSP)进去,当然TSPD也就没有启动,那BL31可正常的带起BL33,并且linux kernel也可正常的开完。
但是如果将TSP移植进BL32,并且ATF的流程也将BL32初始完成回至BL31再开始进入BL33开机流程的话,会开到一半卡住,有点像卡在一个loop,trace的结果可能是卡在generic_handle_irq、gic_handle_irq
我现在不太确定GIC的设定是否会影响至BL33开机?
且目前有观查到AArch32 GIC system register的值有些异常,但因为BL31、BL32、BL33皆是64bits的,所以不确定是否有直接的影响?
Ref : github.com/.../arm-trusted-firmware
你确定是卡在generic_handle_irq这样地方,这是到BL33后的KERNEL里面了吧,如果是到这里,应该可以看到是哪个IRQ,这个IRQ是哪个IRQ LINE, 是否BL32里面隐式打开了,导致这个中断到来(是TIMER对应的中断?)?
是卡在BL33后的kernel,BL33算是一个u-boot来带起kernel,至于是哪个IRQ我再查看看,不过目前是卡在kernel初始化完timer后,就会hang住。
想请教”BL32里面隐式打开”,是指从BL32发出interrupt,经由BL31配送至BL33(Non-Trusted OS),而非从BL31自主的发出interrupt?
这应该是对了,BL32我看了下里面会START TIMER,你可以看下,在KERNEL 里面TIME刚初始化,而现在一般的TIMER 都ROUTE 到KERNEL 里面。不是从BL31发出的,GIC 是在BL31里面设置的,并不发出,这个中断应该是TIMER硬件终端,只是可能在BL32里面开启了,这样IRQ 过早到KERNEL ,可能使这个导致的,不过需要验证下,看下你捕捉到的是不是TIMER 的IRQ LINE.
刚刚捕捉到的IRQ确实是timer的。目前我先把BL32中的START TIMER的地方关掉,整个linux就可以初始完了,谢谢大神。Ref : github.com/.../tsp_main.c
不客气。呵呵!
请教一下,IRQ过早到达到KERNEL会造成问题的原因是因为IRQ的handler的vector table尚未被初始化到,而收到了无法handle的IRQ,才会hang在IRQ handler的吗?
应该不是的,TABLE是更早设置的,TIMER初始化了,说明TABLE 已经OK 了,我没有看到具体的信息,但是怀疑可能是TIMER在KERNEL对应的IRQ注册没有真正意义上走完,或者说即使软件配置好了到GIC的硬件上信息完成有时差,毕竟现在IRQ是先到GIC,然后处理也是在KERNEL里面,generic_handle_irq里面才去找到MAPPING的具体的IRQ处理。要看看你generic_handle_irq里面具体哪个阶段有问题啊。仅供你参考。
补充下,你可以看看KERNEL 里面arch timer设置最后部分,就是开启timer前有哪些特别设置,这些没走完,就有对应中断上来,是有问题的。
去trace code的想法是,因为在arch timer中才去setup_irq (Linux内核提供用来注册中断处理的函数),有可能如您所说的”软件配置好了到GIC的硬件上信息完成有时差”,那软件设置还没结束就收到了中断,而变成无法找到相对应的handler。
是的,你想法有道理。TIMER 是个特殊的硬件DEVICE,对应irq来的早而且频繁,硬件IRQ LINE和软件侧IRQ_DESC要设置完成且MAPPING,才能在后面执行处理时候找到。你可以按照你的思路往下试试。
Hi R.W.
你用的什么平台,建议你检查下GICv3的初始化配置,看看把Secure Timer interrupt配置到哪个group,如果你使用的GICv3 programming mode的话,建议你把Secure Timer interrupt配置到Secure Group 1.
谢谢!!
我是拿mtk的平台,GICv3当初是在BL31配置的,但那一块我没有很熟,之后再来研读一下。因为曾经有想这个timer应该是secure timer,理论上不会把interrupt导至linux这边才对,但不是很确定。
gic_cpuif_init{
......
/* set all SGI/PPI as non-secure GROUP1 by default. rdist_base + 64K == SGI_base */ mmio_write_32(rdist_base+SZ_64K+GICE_V3_IGROUP0, 0xffffffff); mmio_write_32(rdist_base+SZ_64K+GICE_V3_IGRPMOD0, 0x0);
}
如果是MTK ,那比较直接,我这有的是X20代码为例子,所有PPI 终端配置到NS-G1(这里是KERNEL),
包含SECURITY TIMER,不知道你那边具体哪个平台。
你可以查看下PLAT_ARM_G1S_IRQS里面是否包含Secure Timer interrupt,Secure timer是给Secure world来用的,但是需要配置到Secure Group 1,如果配置到Non-secure Group 1的话,可能会存在问题,