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:
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 5 => 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) ld.lib.sohttp://ld.lib.so 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 Androidhttps://aka.ms/ghei36
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
Hi Martin, Thanks for the reply.
Regarding IAR/EOIR register definitions, I too was using version 2.0 of the Architecture document, document number ARM IHI 0048B.b ID072613. What I see on pages 4-135 and 4-138 are tables defining the bit fields as:
[31:13] - Reserved. [12:10] CPUID For SGIs in a multiprocessor implementation, this field identifies the processor that requested the interrupt. It returns the number of the CPU interface that made the request, for example a value of 3 means the request was generated by a write to the GICD_SGIR on CPU interface 3. For all other interrupts this field is RAZ. [9:0] Interrupt ID The interrupt ID.
and,
[31:13] - Reserved. [12:10] CPUID On a multiprocessor implementation, if the write refers to an SGI, this field contains the CPUID value from the corresponding GICC_IAR access. In all other cases this field SBZ. [9:0] EOIINTID The Interrupt ID value from the corresponding GICC_IAR access.
But regarding my problem, the A7 is different than the A9 in several regards -- No control over the SCU; an L2 cache that is tightly integrated with the L1 cache (meaning you can't control it); and no private timer but two generic timers are the main diferences as far as bringing it up are concerned.
I've modeled the code similar to the Cortex A9 implementation I did for an AM436x TI processor, accounting for the diferences in the A7 I mentioned above. The bootstrap code works fine as you can see from the output logging, and the translation table entries all look correct.
In bootstrap, a board object is created whose initializers declare ram and mmio regions. The constructor is:
Bootstrap::Platform::Board::Board() : early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE}), core_mmio(Memory_region { CORTEX_A7_PRIVATE_MEM_BASE, CORTEX_A7_PRIVATE_MEM_SIZE }, Memory_region { UART_1_MMIO_BASE, UART_1_MMIO_SIZE }, Memory_region { GPT1_BASE, GPT1_SIZE } ) {}
CORTEX_A7_PRIVATE_MEM_BASE is set at 0x00A00000, three pages in size and in that region the GIC-400 registers start on the, second page; 0x00A01000 for the distributor and 0x00A02000 for the cpu interface
As a first step in diagnosing the problem I looked in the Allocator outputs from the run script. I expected to see entries in the io_mmio_alloc dump related to the three regions in the above initializer list and none were there. So my question was/is what am I missing in my understanding?
Bob
Get Outlook for Androidhttps://aka.ms/ghei36
From: Martin Stein <martin.stein@...1...> Sent: Monday, October 9, 2017 8:12:50 PM To: Genode OS Framework Mailing List Subject: Re: Base-hw kernel GIC issue with a Cortex--A7 processor.
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
------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Bob,
Am 09.10.2017 um 23:44 schrieb Bob Stewart:
Regarding IAR/EOIR register definitions, I too was using version 2.0 of the Architecture document, document number ARM IHI 0048B.b ID072613. What I see on pages 4-135 and 4-138 are tables defining the bit fields as:
[12:10] CPUID On a multiprocessor implementation, if the write refers to an SGI, this field contai> [9:0] EOIINTID The Interrupt ID value from the corresponding GICC_IAR access.
That's right, as I already said: [9:0] EUOINTID is 10 bits in width - thus Bitfield<0,10> and [12:10] CPUID is 3 bits in width - thus Bitfield<10, 3>.
In bootstrap, a board object is created whose initializers declare ram and mmio regions. The constructor is:
Bootstrap::Platform::Board::Board() : early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE}), core_mmio(Memory_region { CORTEX_A7_PRIVATE_MEM_BASE, CORTEX_A7_PRIVATE_MEM_SIZE }, Memory_region { UART_1_MMIO_BASE, UART_1_MMIO_SIZE }, Memory_region { GPT1_BASE, GPT1_SIZE } ) {}
CORTEX_A7_PRIVATE_MEM_BASE is set at 0x00A00000, three pages in size and in that region the GIC-400 registers start on the, second page; 0x00A01000 for the distributor and 0x00A02000 for the cpu interface
As a first step in diagnosing the problem I looked in the Allocator outputs from the run script. I expected to see entries in the io_mmio_alloc dump related to the three regions in the above initializer list and none were there. So my question was/is what am I missing in my understanding?
Regarding the allocators Output:
: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
Block [00000000,80106000) contains Block [0x00A00000, 0x00A02fff), doesn't it? So the GIC-400 is in the io_mem_alloc. However, this has nothing to do with the core translation table. These allocators are initialized long after the kernel initialization where your troubles with the PIC occur.
Here is a short illustration of how Genode starts up:
1. [bootstrap] _start in bootstrap/spec/<ARCH>/crt0.s - init bss and kernel stack
2. [bootstrap] init bootstrap/init.cc - init core regions (e.g. core_mmio and core elf) - fill core translation table (e.g. with core_mmio and core elf) - enable mmu with core translation table - jump to entry of core elf (kernel)
3. [core (kernel)] _start in core/kernel/init.cc - init kernel objects of the cpus - init kernel object of the first userland thread of core
4. [core (kernel)] kernel in core/kernel/kernel.cc - update kernel state - schedule userland thread (only first core thread available)
5. [core (userland)] _core_start in core/spec/<ARCH>/crt0.s - init core object of the first userland thread of core - init stack pointer
6. [core (userland)] _main in startup/_main.cc - init C++ runtime and other stuff
7. [core (userland)] main in core/main.cc - init core resources (e.g. Platform which creates the allocators like _io_mem_alloc and dumps them) - init core services - start init
The point where the core page table is filled with the core_mmio is in step 2 (see base-hw/src/bootstrap/platform.cc:172 for debugging) whereas the allocator dump is in step 7.
Cheers, Martin
A big oops by me Martin on the register declarations. I had forgotten the bitfield format was a position a followed by length type as opposed to start and end bit positions.
Thanks for defining the steps in start up which I was a bit familiar with through reading code. I only had time today to debug the core_mmio translation table which had the expected physical addresses based on the initialization list for the platform board object. The virtual addresses started at 0xxF0000000.
I'll next figure out why a Pic object can be successfully constructed during the bootstrap where the physical addresses for the distributor and the cpu interface are used in the initialization list but the construction appears to fail in kernel init when a singleton version of it is created using virtual addresses in the initialization list.
I will not be able to get back to this until early next week.
Bob
Get Outlook for Androidhttps://aka.ms/ghei36
________________________________ From: Martin Stein <martin.stein@...1...> Sent: Tuesday, October 10, 2017 8:56:06 AM To: genode-main@lists.sourceforge.net Subject: Re: Base-hw kernel GIC issue with a Cortex--A7 processor.
Hi Bob,
Am 09.10.2017 um 23:44 schrieb Bob Stewart:
Regarding IAR/EOIR register definitions, I too was using version 2.0 of the Architecture document, document number ARM IHI 0048B.b ID072613. What I see on pages 4-135 and 4-138 are tables defining the bit fields as:
[12:10] CPUID On a multiprocessor implementation, if the write refers to an SGI, this field contai> [9:0] EOIINTID The Interrupt ID value from the corresponding GICC_IAR access.
That's right, as I already said: [9:0] EUOINTID is 10 bits in width - thus Bitfield<0,10> and [12:10] CPUID is 3 bits in width - thus Bitfield<10, 3>.
In bootstrap, a board object is created whose initializers declare ram and mmio regions. The constructor is:
Bootstrap::Platform::Board::Board() : early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE}), core_mmio(Memory_region { CORTEX_A7_PRIVATE_MEM_BASE, CORTEX_A7_PRIVATE_MEM_SIZE }, Memory_region { UART_1_MMIO_BASE, UART_1_MMIO_SIZE }, Memory_region { GPT1_BASE, GPT1_SIZE } ) {}
CORTEX_A7_PRIVATE_MEM_BASE is set at 0x00A00000, three pages in size and in that region the GIC-400 registers start on the, second page; 0x00A01000 for the distributor and 0x00A02000 for the cpu interface
As a first step in diagnosing the problem I looked in the Allocator outputs from the run script. I expected to see entries in the io_mmio_alloc dump related to the three regions in the above initializer list and none were there. So my question was/is what am I missing in my understanding?
Regarding the allocators Output:
: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
Block [00000000,80106000) contains Block [0x00A00000, 0x00A02fff), doesn't it? So the GIC-400 is in the io_mem_alloc. However, this has nothing to do with the core translation table. These allocators are initialized long after the kernel initialization where your troubles with the PIC occur.
Here is a short illustration of how Genode starts up:
1. [bootstrap] _start in bootstrap/spec/<ARCH>/crt0.s - init bss and kernel stack
2. [bootstrap] init bootstrap/init.cc - init core regions (e.g. core_mmio and core elf) - fill core translation table (e.g. with core_mmio and core elf) - enable mmu with core translation table - jump to entry of core elf (kernel)
3. [core (kernel)] _start in core/kernel/init.cc - init kernel objects of the cpus - init kernel object of the first userland thread of core
4. [core (kernel)] kernel in core/kernel/kernel.cc - update kernel state - schedule userland thread (only first core thread available)
5. [core (userland)] _core_start in core/spec/<ARCH>/crt0.s - init core object of the first userland thread of core - init stack pointer
6. [core (userland)] _main in startup/_main.cc - init C++ runtime and other stuff
7. [core (userland)] main in core/main.cc - init core resources (e.g. Platform which creates the allocators like _io_mem_alloc and dumps them) - init core services - start init
The point where the core page table is filled with the core_mmio is in step 2 (see base-hw/src/bootstrap/platform.cc:172 for debugging) whereas the allocator dump is in step 7.
Cheers, Martin
------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Bob,
Am 12.10.2017 um 01:33 schrieb Bob Stewart:
A big oops by me Martin on the register declarations. I had forgotten the bitfield format was a position a followed by length type as opposed to start and end bit positions.
This is why I wrote you an explanation of the Bitfield interface two emails ago :-)
Thanks for defining the steps in start up which I was a bit familiar with through reading code. I only had time today to debug the core_mmio translation table which had the expected physical addresses based on the initialization list for the platform board object. The virtual addresses started at 0xxF0000000.
I'll next figure out why a Pic object can be successfully constructed during the bootstrap where the physical addresses for the distributor and the cpu interface are used in the initialization list but the construction appears to fail in kernel init when a singleton version of it is created using virtual addresses in the initialization list.
You said that you do not even enter the constructor but are you sure you don't enter the first initializer in the initializer list or have you only checked whether you enter the constructor body?
I assume that there are several initializers like the distributer and CPU interface MMIO like in our ARM-GIC implementation:
Hw::Pic::Pic() : _distr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE)), _cpui (Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_CPU_BASE)), _last_iar(Cpu_interface::Iar::Irq_id::bits(spurious_id)), _max_irq(_distr.max_irq()) { }
Then, you could print '_base' in the 'Mmio_plain_access' constructor [1] for debugging. If you truely do not enter the first initializer your problem is most likely not related to any PIC IO mappings. I would suggest you to aim for the exact point where your system gets stuck.
Cheers, Martin
[1] base/include/util/mmio.h
Thanks for the reply, Martin. Comments in-line:
On 10/12/2017 07:12 AM, Martin Stein wrote:
Hi Bob,
Am 12.10.2017 um 01:33 schrieb Bob Stewart:
A big oops by me Martin on the register declarations. I had forgotten the bitfield format was a position a followed by length type as opposed to start and end bit positions.
This is why I wrote you an explanation of the Bitfield interface two emails ago :-)
Thanks for defining the steps in start up which I was a bit familiar with through reading code. I only had time today to debug the core_mmio translation table which had the expected physical addresses based on the initialization list for the platform board object. The virtual addresses started at 0xxF0000000. I'll next figure out why a Pic object can be successfully constructed during the bootstrap where the physical addresses for the distributor and the cpu interface are used in the initialization list but the construction appears to fail in kernel init when a singleton version of it is created using virtual addresses in the initialization list.
You said that you do not even enter the constructor but are you sure you don't enter the first initializer in the initializer list or have you only checked whether you enter the constructor body?
It is dying in the Initializers. It never gets to the body of the constructor.
I assume that there are several initializers like the distributer and CPU interface MMIO like in our ARM-GIC implementation:
Hw::Pic::Pic() : _distr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE)), _cpui (Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_CPU_BASE)), _last_iar(Cpu_interface::Iar::Irq_id::bits(spurious_id)), _max_irq(_distr.max_irq()) { }
I'm using core/spec/arm_gic (and therefore the Hw::Pic in lib/hw/spec/arm as the base class). So the only difference between this implementation and the Cortex A9 implementation is what the values are for IRQ_CONTROLLER_DISTR_BASE and IRQ_CONTROLLER_CPU_BASE. In kernel's init.cc I created a local object for Pic and used that to pass to the cpu init method instead of the reference to the unmanaged singleton object. When I did that the kernel init completed successfully and the log code was executed and completed with the expected results. This would indicate that the Pic object is correctly constructed, would it not.
Then, you could print '_base' in the 'Mmio_plain_access' constructor [1] for debugging. If you truely do not enter the first initializer your problem is most likely not related to any PIC IO mappings. I would suggest you to aim for the exact point where your system gets stuck.
For the first initializer, for the distributor object, base() returns 0x0. This would indicate that a Pic object was not being constructed correctly in the placement new operator, which is hard to imagine why. I will go over my core make files again to see if I've got an incorrect include path specified or specified an incorrect location for a source file. Beyond that?
Bob
Cheers, Martin
[1] base/include/util/mmio.h
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Bob,
I wonder whether your problem has to do with a different memory map of the GIC. When looking at the documentation for Cortex A9 and A7, I could see they differ with respect to the offset of distributor and core-specific interface of the GIC within the cpu local private memory.
Please, introduce a new Hw::Cortex_a7_mmio structure analogue to the already existent Hw::Cortex_a9_mmio and Hw::Cortex_a15_mmio variants. You can find the right values for the A7 specific IRQ_CONTROLLER_DISTR_BASE and IRQ_CONTROLLER_CPU_BASE here (page 180):
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0464d/DDI0464D_cortex_a7...
Of course, you'll need to replace the occurrences of Cortex_a9_mmio in your board.h file(s).
I hope it will help you.
Regards Stefan
On 10/16/2017 03:18 PM, Bob Stewart wrote:
Thanks for the reply, Martin. Comments in-line:
On 10/12/2017 07:12 AM, Martin Stein wrote:
Hi Bob,
Am 12.10.2017 um 01:33 schrieb Bob Stewart:
A big oops by me Martin on the register declarations. I had forgotten the bitfield format was a position a followed by length type as opposed to start and end bit positions.
This is why I wrote you an explanation of the Bitfield interface two emails ago :-)
Thanks for defining the steps in start up which I was a bit familiar with through reading code. I only had time today to debug the core_mmio translation table which had the expected physical addresses based on the initialization list for the platform board object. The virtual addresses started at 0xxF0000000. I'll next figure out why a Pic object can be successfully constructed during the bootstrap where the physical addresses for the distributor and the cpu interface are used in the initialization list but the construction appears to fail in kernel init when a singleton version of it is created using virtual addresses in the initialization list.
You said that you do not even enter the constructor but are you sure you don't enter the first initializer in the initializer list or have you only checked whether you enter the constructor body?
It is dying in the Initializers. It never gets to the body of the constructor.
I assume that there are several initializers like the distributer and CPU interface MMIO like in our ARM-GIC implementation:
Hw::Pic::Pic() : _distr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE)),
_cpui (Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_CPU_BASE)), _last_iar(Cpu_interface::Iar::Irq_id::bits(spurious_id)), _max_irq(_distr.max_irq()) { }
I'm using core/spec/arm_gic (and therefore the Hw::Pic in lib/hw/spec/arm as the base class). So the only difference between this implementation and the Cortex A9 implementation is what the values are for IRQ_CONTROLLER_DISTR_BASE and IRQ_CONTROLLER_CPU_BASE. In kernel's init.cc I created a local object for Pic and used that to pass to the cpu init method instead of the reference to the unmanaged singleton object. When I did that the kernel init completed successfully and the log code was executed and completed with the expected results. This would indicate that the Pic object is correctly constructed, would it not.
Then, you could print '_base' in the 'Mmio_plain_access' constructor [1] for debugging. If you truely do not enter the first initializer your problem is most likely not related to any PIC IO mappings. I would suggest you to aim for the exact point where your system gets stuck.
For the first initializer, for the distributor object, base() returns 0x0. This would indicate that a Pic object was not being constructed correctly in the placement new operator, which is hard to imagine why. I will go over my core make files again to see if I've got an incorrect include path specified or specified an incorrect location for a source file. Beyond that?
Bob
Cheers, Martin
[1] base/include/util/mmio.h
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Stefan, Thanks for looking at this.
I've been using that TRM in my efforts and using the 0x1000 and 0x2000 for the distributor and the cpu interface registers. I know they are correct and my base is correct as I can md in u-boot and see the non-zero initialized register values at the locations indicated in the ARM documentation.
I'm now back looking at the placement new operator functioning as my debugging leads me to the Pic constructor call in that operator as the location of the failure. Strangely, creating an instance of the Pic class locally works correctly....in the goodness of time I will figure it out!
Bob
Get Outlook for Androidhttps://aka.ms/ghei36
From: Stefan Kalkowski <stefan.kalkowski@...1...> Sent: Thursday, October 19, 2017 11:30:23 AM To: genode-main@lists.sourceforge.net Subject: Re: Base-hw kernel GIC issue with a Cortex--A7 processor.
Hi Bob,
I wonder whether your problem has to do with a different memory map of the GIC. When looking at the documentation for Cortex A9 and A7, I could see they differ with respect to the offset of distributor and core-specific interface of the GIC within the cpu local private memory.
Please, introduce a new Hw::Cortex_a7_mmio structure analogue to the already existent Hw::Cortex_a9_mmio and Hw::Cortex_a15_mmio variants. You can find the right values for the A7 specific IRQ_CONTROLLER_DISTR_BASE and IRQ_CONTROLLER_CPU_BASE here (page 180):
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0464d/DDI0464D_cortex_a7...
Of course, you'll need to replace the occurrences of Cortex_a9_mmio in your board.h file(s).
I hope it will help you.
Regards Stefan
On 10/16/2017 03:18 PM, Bob Stewart wrote:
Thanks for the reply, Martin. Comments in-line:
On 10/12/2017 07:12 AM, Martin Stein wrote:
Hi Bob,
Am 12.10.2017 um 01:33 schrieb Bob Stewart:
A big oops by me Martin on the register declarations. I had forgotten the bitfield format was a position a followed by length type as opposed to start and end bit positions.
This is why I wrote you an explanation of the Bitfield interface two emails ago :-)
Thanks for defining the steps in start up which I was a bit familiar with through reading code. I only had time today to debug the core_mmio translation table which had the expected physical addresses based on the initialization list for the platform board object. The virtual addresses started at 0xxF0000000. I'll next figure out why a Pic object can be successfully constructed during the bootstrap where the physical addresses for the distributor and the cpu interface are used in the initialization list but the construction appears to fail in kernel init when a singleton version of it is created using virtual addresses in the initialization list.
You said that you do not even enter the constructor but are you sure you don't enter the first initializer in the initializer list or have you only checked whether you enter the constructor body?
It is dying in the Initializers. It never gets to the body of the constructor.
I assume that there are several initializers like the distributer and CPU interface MMIO like in our ARM-GIC implementation:
Hw::Pic::Pic() :
_distr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE)),
_cpui
(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_CPU_BASE)), _last_iar(Cpu_interface::Iar::Irq_id::bits(spurious_id)), _max_irq(_distr.max_irq()) { }
I'm using core/spec/arm_gic (and therefore the Hw::Pic in lib/hw/spec/arm as the base class). So the only difference between this implementation and the Cortex A9 implementation is what the values are for IRQ_CONTROLLER_DISTR_BASE and IRQ_CONTROLLER_CPU_BASE. In kernel's init.cc I created a local object for Pic and used that to pass to the cpu init method instead of the reference to the unmanaged singleton object. When I did that the kernel init completed successfully and the log code was executed and completed with the expected results. This would indicate that the Pic object is correctly constructed, would it not.
Then, you could print '_base' in the 'Mmio_plain_access' constructor [1] for debugging. If you truely do not enter the first initializer your problem is most likely not related to any PIC IO mappings. I would suggest you to aim for the exact point where your system gets stuck.
For the first initializer, for the distributor object, base() returns 0x0. This would indicate that a Pic object was not being constructed correctly in the placement new operator, which is hard to imagine why. I will go over my core make files again to see if I've got an incorrect include path specified or specified an incorrect location for a source file. Beyond that?
Bob
Cheers, Martin
[1] base/include/util/mmio.h
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
-- Stefan Kalkowski Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main