Base-hw kernel GIC issue with a Cortex--A7 processor.

Bob Stewart robjsstewart at ...9...
Sun Oct 8 22:06:19 CEST 2017

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/ 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:

Bytes transferred = 686398 (a793e hex)
## Booting kernel from Legacy Image at 82000000 ...
   Image Name:
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    686334 Bytes = 670.2 KiB
   Load Address: 81000000
   Entry Point:  81000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

kernel initialized
In cpu
timer irq is 87
:virt_alloc: Allocator 0x910cc2bc dump:
Block: [00001000,80000000) size=2097148K avail=2097148K max_avail=2097148K
Block: [80105000,81000000) size=15340K avail=15340K max_avail=2097148K
Block: [811a0000,91000000) size=260480K avail=260480K max_avail=2097148K
Block: [912a2000,912a3000) size=4K avail=0 max_avail=0
Block: [912a3000,d0000000) size=1029492K avail=1029492K max_avail=1029492K
Block: [e0000000,e0001000) size=4K avail=0 max_avail=0
Block: [e0001000,f0000000) size=262140K avail=262140K max_avail=1029492K
Block: [f0002000,f0003000) size=4K avail=0 max_avail=0
Block: [f0007000,f0008000) size=4K avail=0 max_avail=262028K
Block: [f000c000,fffef000) size=262028K avail=262028K max_avail=262028K
=> mem_size=4020883456 (3834 MB) / mem_avail=4020867072 (3834 MB)

:phys_alloc: Allocator 0x910cb250 dump:
Block: [80106000,80107000) size=4K avail=0 max_avail=0
Block: [80107000,80108000) size=4K avail=0 max_avail=32K
Block: [80108000,80110000) size=32K avail=32K max_avail=32K
Block: [8025b000,8025c000) size=4K avail=0 max_avail=506240K
Block: [8025c000,8025d000) size=4K avail=0 max_avail=0
Block: [8025d000,81000000) size=13964K avail=13964K max_avail=506240K
Block: [811a0000,a0000000) size=506240K avail=506240K max_avail=506240K
=> mem_size=532738048 (508 MB) / mem_avail=532721664 (508 MB)

:io_mem_alloc: Allocator 0x910cd334 dump:
Block: [00000000,80106000) size=2098200K avail=2098200K max_avail=2098200K
Block: [80110000,8025b000) size=1324K avail=1324K max_avail=2098200K
Block: [81000000,811a0000) size=1664K avail=1664K max_avail=1610612735
Block: [a0000000,ffffffff) size=1610612735 avail=1610612735 max_avail=161061273
=> mem_size=3762229247 (3587 MB) / mem_avail=3762229247 (3587 MB)

:io_port_alloc: Allocator 0x910ce3a0 dump:
=> mem_size=0 (0 MB) / mem_avail=0 (0 MB)

:irq_alloc: Allocator 0x910cf40c dump:
Block: [00000000,00000001) size=1 avail=1 max_avail=1
Block: [00000002,00000057) size=85 avail=85 max_avail=936
Block: [00000058,00000400) size=936 avail=936 max_avail=936
=> mem_size=1022 (0 MB) / mem_avail=1022 (0 MB)

:rom_fs: ROM modules:
ROM: [810e2000,810e2156) config
ROM: [810e3000,811133c4) init
ROM: [81114000,8119b470)<>
ROM: [8119c000,8119f58c) test-log

Genode 17.08 <local changes>
507 MiB RAM and 64535 caps assigned to init
[init -> test-log] hex range:          [0e00,1680)
[init -> test-log] empty hex range:    [0abc0000,0abc0000) (empty!)
[init -> test-log] hex range to limit: [f8,ff]
[init -> test-log] invalid hex range:  [f8,08) (overflow!)
[init -> test-log] negative hex char:  0xfe
[init -> test-log] positive hex char:  0x02
[init -> test-log] multiarg string:    "parent -> child.7"
[init -> test-log] String(Hex(3)):     0x3
[init -> test-log] Test done.

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> { };
Thanks in advance for any help.

Bob Stewart

Get Outlook for Android<>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the users mailing list