Hi Bob,
Am 08.10.2017 um 22:06 schrieb Bob Stewart:
Hi, I'm bringing up the 17.08 base-hw kernel/core on an NXP IMX6ULL SoC, which uses a Cortex A7 single core processor, and am having issues creating the singleton instance of the GIC after kernel initialization. In short the attempt to create the singleton causing the processor to die!
The PIC code is all existing ARM code, I supply the addresses of the GIC-400 interrupt distributor and its cpu interface from the NXP documentation. Using the u-boot command line I see that the GIC register addresses in memory agree with the documentation. The physical addresses are 0x00A01000 and 0x00A02000 which are translated to virtual addresses 0xF0001000 and 0xF002000.
The core initialization code in ../base-hw/src/core/kernel/init.cc first creates a cpu pool object then creates a cpu object in the pool passing to it the address of the unmanaged singleton object for the PIC.The cpu initialization code would use this object to unmask an interrupt for a timer, if it ever got that far! It appears to die in the execution of the placement new operator in ../base/src/include/base/internal/unmanaged_singleton.h:
template <typename T, typename... ARGS> static void call(char * const dst, ARGS &&... args) { new (dst) T(args...); }
(Where T would be Kernel::Pic)
The Pic constructor is never called when the new executes.
I was testing using the log run script which does not need a timer to execute the test, so I removed the creation of the Pic object and its use in the cpu object initialization. The test ran successfully to completion and provided the memory allocator outputs and the print test output:
I guess I don't understand the allocator outputs as I would have expected the two pages at address 0xA01000 for the GIC-400 to show up in the io_mem_alloc allocator output with zero availability. I hope that has something to do with this problem as don't see a good way of debugging the placement new operation> As an aside, I noticed a lurking bug in the Pic cpu interface register definitions in ...base-hw/src/lib/hw/arm/pic.h: The struct Irq_id inside both struct Iar and struct Eoir are sized as struct Irq_id : Bitfield<0:10> { }; . They both should be { struct Irq_id : Bitfield<0:9> { }; struct Cpu_id : Bitfield<10:12> { }; };
I cannot confirm this. I think you misunderstood the parameters of Bitfield. It's Bitfield<FIRST_BIT, BIT_WIDTH> and _not_ Bitfield<FIRST_BIT, LAST_BIT>. The document "ARM Generic Interrupt Controller Architecture version 2.0" states that IRQ_ID reaches from bit 0 and is 10 bits wide while CPU_ID starts with bit 10 and is 3 bits wide.
By the way, if you're reusing our imx6 code, please be aware that it is currently used only with the USB Armory and the Wandboard Quad. Both have i.MX 6Dual/6Quad SOCs that are Cortex-A9 based and _not_ Cortex A7. I cannot say how much, for instance, the GIC-400 of your platform differs from the PL390 GIC our driver is made for.
To see how the GIC memory region is initialized on the currently supported imx6 platforms you can do:
grep -r "CORTEX_A9_PRIVATE_MEM_BASE" base-hw | grep wand_quad
The Cortex A9 private memory region contains the GIC on Cortex-A9 platforms.
Cheers, Martin