Hi,
I'll try to quickly move discussion about rpi to new thread to not pollute thread about Roadmap 2019.
Bob Stewart robjsstewart@gmail.com writes:
I'm working on implementing a base-hw kernel on a Cortex A53 platform (not Rpi) which is what the Rpi 3x is based on. So, that means a significant amount of work to convert from the existing Genode code supporting the armv7 architecture to support the armv8 architecture. I'm focused initially on only the aarch64 instruction set, but will later add support for aarch32. This is a retirement project for me so my progress is not driven by any great need and is slow. After about six months of casual working I'm at the stage of debugging a virtual memory translation table enhancements need to support 64-bit memory (a new Level-0 table in the page table code in lpae.h). The means all the assembly code changes required have been made (and about 12 other areas of change) and I clean compile a from a log run script.
My plans did not include targetting 64 bit implementation as seems to be too big target for amount of time I can devote to it. I just wanted to fix/workaround some problems which I expected to find when dealing with device drivers - not earlier. And only trying to use code available in Genode already (so 32bit for ARMv7). If I correctly understand 32bit instruction set for ARMv8 should be compatible with ARMv7. Am I wrong with this assumption?
For debugging at this level, you really only have two choices: Either delve into the ARM hardware debugging facilites (CoreSight) or insert small pieces of code to poke variable values or a trace number into a currently unused region of memory. Code like:
using ull = unsigned long long; ull volatile * debug_ptr = (ull *)0x91000600; *debug_ptr = MAX_ENTRIES; debug_ptr += 0x01; *debug_ptr = BLOCK_SIZE_LOG2; debug_ptr += 0x01;
if your booting into uboot to start up, you can inspect the memory region through uboots' md command. Breakpoints can be implemented with the assembly code line: asm volatile("hlt #01\n"); . Objdump gives you the assembly code listing if you need it.
Do I correctly understand, that I can go back to u-boot after running Genode with 'hlt #01' and analyze content of memory there? I would be surprised but definitely it would be useful.
I sincerely hope Genode does not implement a version of the Linux DT. It is an error prone approach developed many years ago in the embedded world. There are more elegant, syntax checkable, configuration description approaches available today.
Could you give some hints about those alternatives? I have no experience in this area and what seems to be tempting in device tree is that when you look into linux sources there are already dts files for all flavours of RPI including mine. U-boot uses this too - I wanted to use source from this due to smaller amount of code but that probably doesn't matter much.
Let me know if I can help with any compile/link issues you have, I probably came across most of them in my work to-date. I'm using a Linaro tool chain for aarch64. There is a separate one for aarch32 which I don't currently use.
Currently my "problem" is that my RPI doesn't pass through marked line in crt0.s
/***************************************************** ** Setup multiprocessor-aware kernel stack-pointer ** *****************************************************/
mov sp, #0 /* for boot cpu use id 0 */ --> cps #31 /* change to system mode */
.global _start_setup_stack /* entrypoint for all cpus */ _start_setup_stack:
I think it is due to RPI firmware is leaving processor in HYP mode - not SVC. But currently this is all I know.
I tried to put code from FOC that is used switch processor back to SVC mode but as I don't understand details of it yet something is not working. There is some similar code in Genode implementation for Arndale board.
On the other hand - maybe running in HYP mode is what is better for Genode? Some hints?
If I comment out section with 'cps #31' it goes further and I it does not return from 'Bootstrap::Platform & p = Bootstrap::platform();' in 'extern "C" void init()' and last place which I found that is executing is constructor: Bootstrap::Platform::Board::Board in 'repos/base-hw/src/bootstrap/spec/rpi/platform.cc'
I'll try to find out more and ask more specific questions about this part.
Tomasz Gajewski
On the other hand - maybe running in HYP mode is what is better for Genode? Some hints?
Answering to myself, I've just found:
https://genode.org/documentation/articles/arm_virtualization
so probably I'll find answers there for this question.
Tomasz Gajewski
Tomasz, see comments in-line.
Bob
On 1/2/19 10:24 AM, Tomasz Gajewski wrote:
Hi,
I'll try to quickly move discussion about rpi to new thread to not pollute thread about Roadmap 2019.
Bob Stewart robjsstewart@gmail.com writes:
I'm working on implementing a base-hw kernel on a Cortex A53 platform (not Rpi) which is what the Rpi 3x is based on. So, that means a significant amount of work to convert from the existing Genode code supporting the armv7 architecture to support the armv8 architecture. I'm focused initially on only the aarch64 instruction set, but will later add support for aarch32. This is a retirement project for me so my progress is not driven by any great need and is slow. After about six months of casual working I'm at the stage of debugging a virtual memory translation table enhancements need to support 64-bit memory (a new Level-0 table in the page table code in lpae.h). The means all the assembly code changes required have been made (and about 12 other areas of change) and I clean compile a from a log run script.
My plans did not include targetting 64 bit implementation as seems to be too big target for amount of time I can devote to it. I just wanted to fix/workaround some problems which I expected to find when dealing with device drivers - not earlier. And only trying to use code available in Genode already (so 32bit for ARMv7). If I correctly understand 32bit instruction set for ARMv8 should be compatible with ARMv7. Am I wrong with this assumption?
I believe your assumption is correct, although I have not verified that it is true.
I'd carefully read Chapter E1, The AArch32 Application Level Programmer's Model in the ARM Architecture Reference Manual, Armv8, for ARMv8-A architecture profile, for any difference they may mention espactially related to exception handle or system level register changes that affect running in the AArch32 state.
For debugging at this level, you really only have two choices: Either delve into the ARM hardware debugging facilites (CoreSight) or insert small pieces of code to poke variable values or a trace number into a currently unused region of memory. Code like:
using ull = unsigned long long; ull volatile * debug_ptr = (ull *)0x91000600; *debug_ptr = MAX_ENTRIES; debug_ptr += 0x01; *debug_ptr = BLOCK_SIZE_LOG2; debug_ptr += 0x01;
if your booting into uboot to start up, you can inspect the memory region through uboots' md command. Breakpoints can be implemented with the assembly code line: asm volatile("hlt #01\n"); . Objdump gives you the assembly code listing if you need it.
Do I correctly understand, that I can go back to u-boot after running Genode with 'hlt #01' and analyze content of memory there? I would be surprised but definitely it would be useful.
Yes, you can do that and the memory addresses you poked values into will be there. Same if you just hit the reset button.
I sincerely hope Genode does not implement a version of the Linux DT. It is an error prone approach developed many years ago in the embedded world. There are more elegant, syntax checkable, configuration description approaches available today.
Could you give some hints about those alternatives? I have no experience in this area and what seems to be tempting in device tree is that when you look into linux sources there are already dts files for all flavours of RPI including mine. U-boot uses this too - I wanted to use source from this due to smaller amount of code but that probably doesn't matter much.
Approaches that use xml where the defined syntax provides a human readable and understandable descriptions in comments in provided xml templates. But what's really wrong with the current configuration approach with Scupt?
Let me know if I can help with any compile/link issues you have, I probably came across most of them in my work to-date. I'm using a Linaro tool chain for aarch64. There is a separate one for aarch32 which I don't currently use.
Currently my "problem" is that my RPI doesn't pass through marked line in crt0.s
/***************************************************** ** Setup multiprocessor-aware kernel stack-pointer ** *****************************************************/ mov sp, #0 /* for boot cpu use id 0 */
--> cps #31 /* change to system mode */
.global _start_setup_stack /* entrypoint for all cpus */ _start_setup_stack:
I think it is due to RPI firmware is leaving processor in HYP mode - not SVC. But currently this is all I know.
I tried to put code from FOC that is used switch processor back to SVC mode but as I don't understand details of it yet something is not working. There is some similar code in Genode implementation for Arndale board.
On the other hand - maybe running in HYP mode is what is better for Genode? Some hints?
I'd suspect that the PE is in AArch64 state and not AArch32, cps is not a valid instruction in AArch64.
You need to change crt0.s first read what exception level your in then the exection state:
/* ** Check that we are in EL1 not EL0 ** */ mrs x11, CurrentEL cmp w11, #04 beq 0f hlt #00 0:
/* ** check the execution state halt if not 32 bit */ mrs x2, spsr_el1 and w2, #0x10 /* M[4] is the execution state bit 0 = aarch64 1 = aarch32 */ bne 1f hlt #01
1: ...
Then comes the hard part, since your in aarch64, the only way you can change execution state is through a return from a change in exception level, that's the architectural rule. I'd query the rpi community for the simplest way of doing that. If you don't get any joy that way, I'll see if i can come up with a generic way of using a reset exception handler response to invoke the change.
Bob
If I comment out section with 'cps #31' it goes further and I it does not return from 'Bootstrap::Platform & p = Bootstrap::platform();' in 'extern "C" void init()' and last place which I found that is executing is constructor: Bootstrap::Platform::Board::Board in 'repos/base-hw/src/bootstrap/spec/rpi/platform.cc'
I'll try to find out more and ask more specific questions about this part.
Tomasz Gajewski
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Looks like your problem is simply that the boot loader is leaving the pe in the aarch64 execution state and you need to add code in crt0.s to create a small exception handler and an exception vector table for executing the handler on some exception you choose. The needs to be done before the first cps instruction.
Bob
Get Outlook for Androidhttps://aka.ms/ghei36
________________________________ From: Bob Stewart robjsstewart@gmail.com Sent: Wednesday, January 2, 2019 4:10:53 PM To: users@lists.genode.org Subject: Re: Genode on RPI
Tomasz, see comments in-line.
Bob
On 1/2/19 10:24 AM, Tomasz Gajewski wrote:
Hi,
I'll try to quickly move discussion about rpi to new thread to not pollute thread about Roadmap 2019.
Bob Stewart robjsstewart@gmail.com writes:
I'm working on implementing a base-hw kernel on a Cortex A53 platform (not Rpi) which is what the Rpi 3x is based on. So, that means a significant amount of work to convert from the existing Genode code supporting the armv7 architecture to support the armv8 architecture. I'm focused initially on only the aarch64 instruction set, but will later add support for aarch32. This is a retirement project for me so my progress is not driven by any great need and is slow. After about six months of casual working I'm at the stage of debugging a virtual memory translation table enhancements need to support 64-bit memory (a new Level-0 table in the page table code in lpae.h). The means all the assembly code changes required have been made (and about 12 other areas of change) and I clean compile a from a log run script.
My plans did not include targetting 64 bit implementation as seems to be too big target for amount of time I can devote to it. I just wanted to fix/workaround some problems which I expected to find when dealing with device drivers - not earlier. And only trying to use code available in Genode already (so 32bit for ARMv7). If I correctly understand 32bit instruction set for ARMv8 should be compatible with ARMv7. Am I wrong with this assumption?
I believe your assumption is correct, although I have not verified that it is true.
I'd carefully read Chapter E1, The AArch32 Application Level Programmer's Model in the ARM Architecture Reference Manual, Armv8, for ARMv8-A architecture profile, for any difference they may mention espactially related to exception handle or system level register changes that affect running in the AArch32 state.
For debugging at this level, you really only have two choices: Either delve into the ARM hardware debugging facilites (CoreSight) or insert small pieces of code to poke variable values or a trace number into a currently unused region of memory. Code like:
using ull = unsigned long long; ull volatile * debug_ptr = (ull *)0x91000600; *debug_ptr = MAX_ENTRIES; debug_ptr += 0x01; *debug_ptr = BLOCK_SIZE_LOG2; debug_ptr += 0x01;
if your booting into uboot to start up, you can inspect the memory region through uboots' md command. Breakpoints can be implemented with the assembly code line: asm volatile("hlt #01\n"); . Objdump gives you the assembly code listing if you need it.
Do I correctly understand, that I can go back to u-boot after running Genode with 'hlt #01' and analyze content of memory there? I would be surprised but definitely it would be useful.
Yes, you can do that and the memory addresses you poked values into will be there. Same if you just hit the reset button.
I sincerely hope Genode does not implement a version of the Linux DT. It is an error prone approach developed many years ago in the embedded world. There are more elegant, syntax checkable, configuration description approaches available today.
Could you give some hints about those alternatives? I have no experience in this area and what seems to be tempting in device tree is that when you look into linux sources there are already dts files for all flavours of RPI including mine. U-boot uses this too - I wanted to use source from this due to smaller amount of code but that probably doesn't matter much.
Approaches that use xml where the defined syntax provides a human readable and understandable descriptions in comments in provided xml templates. But what's really wrong with the current configuration approach with Scupt?
Let me know if I can help with any compile/link issues you have, I probably came across most of them in my work to-date. I'm using a Linaro tool chain for aarch64. There is a separate one for aarch32 which I don't currently use.
Currently my "problem" is that my RPI doesn't pass through marked line in crt0.s
/***************************************************** ** Setup multiprocessor-aware kernel stack-pointer ** *****************************************************/ mov sp, #0 /* for boot cpu use id 0 */
--> cps #31 /* change to system mode */
.global _start_setup_stack /* entrypoint for all cpus */ _start_setup_stack:
I think it is due to RPI firmware is leaving processor in HYP mode - not SVC. But currently this is all I know.
I tried to put code from FOC that is used switch processor back to SVC mode but as I don't understand details of it yet something is not working. There is some similar code in Genode implementation for Arndale board.
On the other hand - maybe running in HYP mode is what is better for Genode? Some hints?
I'd suspect that the PE is in AArch64 state and not AArch32, cps is not a valid instruction in AArch64.
You need to change crt0.s first read what exception level your in then the exection state:
/* ** Check that we are in EL1 not EL0 ** */ mrs x11, CurrentEL cmp w11, #04 beq 0f hlt #00 0:
/* ** check the execution state halt if not 32 bit */ mrs x2, spsr_el1 and w2, #0x10 /* M[4] is the execution state bit 0 = aarch64 1 = aarch32 */ bne 1f hlt #01
1: ...
Then comes the hard part, since your in aarch64, the only way you can change execution state is through a return from a change in exception level, that's the architectural rule. I'd query the rpi community for the simplest way of doing that. If you don't get any joy that way, I'll see if i can come up with a generic way of using a reset exception handler response to invoke the change.
Bob
If I comment out section with 'cps #31' it goes further and I it does not return from 'Bootstrap::Platform & p = Bootstrap::platform();' in 'extern "C" void init()' and last place which I found that is executing is constructor: Bootstrap::Platform::Board::Board in 'repos/base-hw/src/bootstrap/spec/rpi/platform.cc'
I'll try to find out more and ask more specific questions about this part.
Tomasz Gajewski
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Bob Stewart robjsstewart@gmail.com writes:
Looks like your problem is simply that the boot loader is leaving the pe in the aarch64 execution state and you need to add code in crt0.s to create a small exception handler and an exception vector table for executing the handler on some exception you choose. The needs to be done before the first cps instruction.
Thank you very much. I'll check this as soon as I can.
Tomasz Gajewski
Bob Stewart robjsstewart@gmail.com writes:
Do I correctly understand, that I can go back to u-boot after running Genode with 'hlt #01' and analyze content of memory there? I would be surprised but definitely it would be useful.
Yes, you can do that and the memory addresses you poked values into will be there. Same if you just hit the reset button.
This is something I wouldn't have guessed. I always thought about reset as a "total reset". This seems like a usuful technique. Thanks.
I sincerely hope Genode does not implement a version of the Linux DT. It is an error prone approach developed many years ago in the embedded world. There are more elegant, syntax checkable, configuration description approaches available today.
Could you give some hints about those alternatives? I have no experience in this area and what seems to be tempting in device tree is that when you look into linux sources there are already dts files for all flavours of RPI including mine. U-boot uses this too - I wanted to use source from this due to smaller amount of code but that probably doesn't matter much.
Approaches that use xml where the defined syntax provides a human readable and understandable descriptions in comments in provided xml templates. But what's really wrong with the current configuration approach with Scupt?
I didn't think about that level as Sculpt (although some kind of a converter from device tree to configuration could be implemented probably). I may be totally wrong but I thought that device tree can remove a need to write code dedicated to concrete boards. As I see it now there are classes that define some base addresses, memory ranges, etc. for different boards. I know for sure there is one for Raspberry Pi 1. Due to fact that that Raspberry Pi 3B+ has different base address for all devices I had to make changes in code to reflect this. My understanding is that this information could be obtained from boot loader and there wouldn't have to be a need for specific builds for version 1 and version 3. Obviously I've found out that there are other (much more important) differences than addresses so maybe I'll have to change my mind about using device tree.
I'd suspect that the PE is in AArch64 state and not AArch32, cps is not a valid instruction in AArch64.
You need to change crt0.s first read what exception level your in then the exection state:
/* ** Check that we are in EL1 not EL0 ** */ mrs x11, CurrentEL cmp w11, #04 beq 0f hlt #00 0:
/* ** check the execution state halt if not 32 bit */ mrs x2, spsr_el1 and w2, #0x10 /* M[4] is the execution state bit 0 = aarch64 1 = aarch32 */ bne 1f hlt #01
1: ...
I can't quickly test this as, at least currently, this file is compiled for 32bit instruction set and CurrentEL and spsr_el1 are not valid.
However maybe this mode is AArch32. I've seen some patches to u-boot that were supposed to detect if loaded kernel is for AArch32 and switch mode accordingly so maybe state is not AArch64. Additionally if this code is compiled for AArch32 would it work at all in AArch64 state? I haven't found answer for this with quick search. Will continue, but not now.
Thanks for your suggestions. I'll read and experiment and hopefully get back with not only questions.
Tomasz Gajewski
Hi Tomasz, I should have thought about you not having access to a 64 bit compiler, sorry! There are many significant assembly changes and system register changes that make it impossible to get very far if 32 bit code is executed while in the aarch64 state. You've come across one with the cps instruction. Processor state is reported completely differently in aarch64, there is no cp15 "coprocessor" to control the pe any more, and you cannot write to the pc, to name just a few of the more significant changes.
Since my focus has purely been aarch64, I'll take a look at the aarch32 sections and section D.20 on interprocessing (changing execution state) in the architectural ref manual to see what i can find, tomorrow. This appears to be more difficult than it should be.
I'd suggest you try to get the u-boot patch to set the execution state to aarch32 for sure, it will save you a lot of reading time!
Bob
Get Outlook for Androidhttps://aka.ms/ghei36
________________________________ From: Tomasz Gajewski tomga@wp.pl Sent: Thursday, January 3, 2019 6:07:45 PM To: Bob Stewart Cc: users@lists.genode.org Subject: Re: Genode on RPI
Bob Stewart robjsstewart@gmail.com writes:
Do I correctly understand, that I can go back to u-boot after running Genode with 'hlt #01' and analyze content of memory there? I would be surprised but definitely it would be useful.
Yes, you can do that and the memory addresses you poked values into will be there. Same if you just hit the reset button.
This is something I wouldn't have guessed. I always thought about reset as a "total reset". This seems like a usuful technique. Thanks.
I sincerely hope Genode does not implement a version of the Linux DT. It is an error prone approach developed many years ago in the embedded world. There are more elegant, syntax checkable, configuration description approaches available today.
Could you give some hints about those alternatives? I have no experience in this area and what seems to be tempting in device tree is that when you look into linux sources there are already dts files for all flavours of RPI including mine. U-boot uses this too - I wanted to use source from this due to smaller amount of code but that probably doesn't matter much.
Approaches that use xml where the defined syntax provides a human readable and understandable descriptions in comments in provided xml templates. But what's really wrong with the current configuration approach with Scupt?
I didn't think about that level as Sculpt (although some kind of a converter from device tree to configuration could be implemented probably). I may be totally wrong but I thought that device tree can remove a need to write code dedicated to concrete boards. As I see it now there are classes that define some base addresses, memory ranges, etc. for different boards. I know for sure there is one for Raspberry Pi 1. Due to fact that that Raspberry Pi 3B+ has different base address for all devices I had to make changes in code to reflect this. My understanding is that this information could be obtained from boot loader and there wouldn't have to be a need for specific builds for version 1 and version 3. Obviously I've found out that there are other (much more important) differences than addresses so maybe I'll have to change my mind about using device tree.
I'd suspect that the PE is in AArch64 state and not AArch32, cps is not a valid instruction in AArch64.
You need to change crt0.s first read what exception level your in then the exection state:
/* ** Check that we are in EL1 not EL0 ** */ mrs x11, CurrentEL cmp w11, #04 beq 0f hlt #00 0:
/* ** check the execution state halt if not 32 bit */ mrs x2, spsr_el1 and w2, #0x10 /* M[4] is the execution state bit 0 = aarch64 1 =
aarch32 */ bne 1f hlt #01
1: ...
I can't quickly test this as, at least currently, this file is compiled for 32bit instruction set and CurrentEL and spsr_el1 are not valid.
However maybe this mode is AArch32. I've seen some patches to u-boot that were supposed to detect if loaded kernel is for AArch32 and switch mode accordingly so maybe state is not AArch64. Additionally if this code is compiled for AArch32 would it work at all in AArch64 state? I haven't found answer for this with quick search. Will continue, but not now.
Thanks for your suggestions. I'll read and experiment and hopefully get back with not only questions.
Tomasz Gajewski
Hi,
On Fri, Jan 04, 2019 at 12:34:10AM +0000, Bob Stewart wrote:
I'd suggest you try to get the u-boot patch to set the execution state to aarch32 for sure, it will save you a lot of reading time!
I'm not an U-Boot expert but as I understand it the loader sensibly handles the boot-image format [1] [2] by switching to AArch32 or AArch64 depending on the image-header information. So, it should be a matter of
mkimage -A arm vs. mkimage -A arm64
Or Am I wrong?
[1] https://github.com/u-boot/u-boot/blob/94905e1db8d8d42c4f39f14dbee2f9788390db... [2] https://github.com/u-boot/u-boot/blob/94905e1db8d8d42c4f39f14dbee2f9788390db...
Regards
Christian Helmuth christian.helmuth@genode-labs.com writes:
Hi,
On Fri, Jan 04, 2019 at 12:34:10AM +0000, Bob Stewart wrote:
I'd suggest you try to get the u-boot patch to set the execution state to aarch32 for sure, it will save you a lot of reading time!
I'm not an U-Boot expert but as I understand it the loader sensibly handles the boot-image format [1] [2] by switching to AArch32 or AArch64 depending on the image-header information. So, it should be a matter of
mkimage -A arm vs. mkimage -A arm64
Or Am I wrong?
That's what I was suggesting when writing about patches but it seems I did not write that clearly enough. I've seen informations about those patches in mailing lists from 2016 and assumed that u-boot does the switch to Aarch32.
I'll try to make some tests during the weekend that will somehow clarify what is happening.
Tomasz Gajewski
Christian Helmuth christian.helmuth@genode-labs.com writes:
I'm not an U-Boot expert but as I understand it the loader sensibly handles the boot-image format [1] [2] by switching to AArch32 or AArch64 depending on the image-header information. So, it should be a matter of
mkimage -A arm vs. mkimage -A arm64
Or Am I wrong?
That's what I was suggesting when writing about patches but it seems I did not write that clearly enough. I've seen informations about those patches in mailing lists from 2016 and assumed that u-boot does the switch to Aarch32.
I'll try to make some tests during the weekend that will somehow clarify what is happening.
u-boot switches to Aarch32 in my current configuration.
Using suggested by Bob method (writing to memory and checking it after reset) I confirmed that code crt0.s from bootstrap is started in HYP mode and using code:
mrs r0,cpsr bic r0,r0,#0x1F orr r0,r0,#0x13 msr spsr_cxsf,r0 add r0,pc,#4 msr ELR_hyp,r0 eret
taken from [1] I could switch to SVC mode what allowed to continue boot.
Currently I don't know how far it goes (but further than in my earlier attempts) because write after enabling address translation in repos/base-hw/src/bootstrap/spec/rpi/platform.cc with:
sctlr = Cpu::Sctlr::read(); Cpu::Sctlr::C::set(sctlr, 1); Cpu::Sctlr::I::set(sctlr, 1); Cpu::Sctlr::M::set(sctlr, 1); Cpu::Sctlr::write(sctlr);
I loose ability to write debug to memory.
At least I'm now in a state that I think I understand what is going on and I'll continue research when time permits.
Thanks for help.
[1] https://github.com/dwelch67/raspberrypi/tree/master/boards/pi3/aarch32/SVC
Tomasz Gajewski
Hi Tomasz,
Are you saying that the instruction cps #31 to set SVC state in crt0.s failed after u-boot left you in the aarch32 execution state? If so that would mean armv7 code does not run on an armv8 platform. Crt0.s should run without any changes.
I suspect your loosing debug output because the MMU is failing on a table walk. Easy way to find out is to insert a halt after SCTRL write which should get you back to u-boot for a reset. Comment out enabling the mmu (the M bit) and you'll hit the halt. Then run it again with M set and if the halt isn't executed, the MMU wandered off into oblivion. Then the problem is the physical differences between the platform the rpi code your using and the Model 3 version you are running. I usual start that debugging by check the translation tables starting from the base address you wrote to TTBR0.
Good Luck,
Bob
Get Outlook for Androidhttps://aka.ms/ghei36
________________________________ From: Tomasz Gajewski tomga@wp.pl Sent: Sunday, January 6, 2019 6:08:33 PM To: users@lists.genode.org Subject: Re: Genode on RPI
Christian Helmuth christian.helmuth@genode-labs.com writes:
I'm not an U-Boot expert but as I understand it the loader sensibly handles the boot-image format [1] [2] by switching to AArch32 or AArch64 depending on the image-header information. So, it should be a matter of
mkimage -A arm vs. mkimage -A arm64
Or Am I wrong?
That's what I was suggesting when writing about patches but it seems I did not write that clearly enough. I've seen informations about those patches in mailing lists from 2016 and assumed that u-boot does the switch to Aarch32.
I'll try to make some tests during the weekend that will somehow clarify what is happening.
u-boot switches to Aarch32 in my current configuration.
Using suggested by Bob method (writing to memory and checking it after reset) I confirmed that code crt0.s from bootstrap is started in HYP mode and using code:
mrs r0,cpsr bic r0,r0,#0x1F orr r0,r0,#0x13 msr spsr_cxsf,r0 add r0,pc,#4 msr ELR_hyp,r0 eret
taken from [1] I could switch to SVC mode what allowed to continue boot.
Currently I don't know how far it goes (but further than in my earlier attempts) because write after enabling address translation in repos/base-hw/src/bootstrap/spec/rpi/platform.cc with:
sctlr = Cpu::Sctlr::read(); Cpu::Sctlr::C::set(sctlr, 1); Cpu::Sctlr::I::set(sctlr, 1); Cpu::Sctlr::M::set(sctlr, 1); Cpu::Sctlr::write(sctlr);
I loose ability to write debug to memory.
At least I'm now in a state that I think I understand what is going on and I'll continue research when time permits.
Thanks for help.
[1] https://github.com/dwelch67/raspberrypi/tree/master/boards/pi3/aarch32/SVC
Tomasz Gajewski
_______________________________________________ Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Bob Stewart robjsstewart@gmail.com writes:
Hi Tomasz,
Are you saying that the instruction cps #31 to set SVC state in crt0.s failed after u-boot left you in the aarch32 execution state?
As I understand it things are different on Raspberry Pi since some version of firmware for RPI2 and later (those with hypervisor capabilities). Firmware provider decided that firmare should start system in Hyp mode. In my case the system is U-boot. U-boot is happy to work in Hyp mode and after downloading Genode image (currently I have tftp server set up for ease of testing) it checks the architecture of image to be Aarch32. In this case it switches to Aarch32 mode but leaving Hyp mode so crt0.s is run in Hyp mode in Aarch32 mode.
Hyp mode (according to [1]) is associated with PL2 privilege level and cps #31 is trying to change processor mode to Secure Monitor Mode which is associated with privilege level PL1. And changing exception levels is allowed only by ERET.
If so that would mean armv7 code does not run on an armv8 platform. Crt0.s should run without any changes.
No. Difference armv7 vs. armv8 has nothing to do with root of the problem. Only different privilege level when it is started is important and that is why crt0.s required a change.
Tomasz Gajewski
[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch03s02...
So the cps instruction will work in aarch32 and backward instruction set compatibility is preserved.
I did not realize the exception level model was fully implemented in aarch32, which means the exception handling and the setting up of the vector table changes considerably, as it does in aarch64.
Bob
Get Outlook for Androidhttps://aka.ms/ghei36
________________________________ From: Tomasz Gajewski tomga@wp.pl Sent: Monday, January 7, 2019 11:50:18 AM To: Bob Stewart Cc: Genode users mailing list Subject: Re: Genode on RPI
Bob Stewart robjsstewart@gmail.com writes:
Hi Tomasz,
Are you saying that the instruction cps #31 to set SVC state in crt0.s failed after u-boot left you in the aarch32 execution state?
As I understand it things are different on Raspberry Pi since some version of firmware for RPI2 and later (those with hypervisor capabilities). Firmware provider decided that firmare should start system in Hyp mode. In my case the system is U-boot. U-boot is happy to work in Hyp mode and after downloading Genode image (currently I have tftp server set up for ease of testing) it checks the architecture of image to be Aarch32. In this case it switches to Aarch32 mode but leaving Hyp mode so crt0.s is run in Hyp mode in Aarch32 mode.
Hyp mode (according to [1]) is associated with PL2 privilege level and cps #31 is trying to change processor mode to Secure Monitor Mode which is associated with privilege level PL1. And changing exception levels is allowed only by ERET.
If so that would mean armv7 code does not run on an armv8 platform. Crt0.s should run without any changes.
No. Difference armv7 vs. armv8 has nothing to do with root of the problem. Only different privilege level when it is started is important and that is why crt0.s required a change.
Tomasz Gajewski
[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch03s02...
Hi,
last weeks of attempts gave me some small progress with code, understanding of some aspects of ARM (AArch32) architecture and some knowledge about how low level hw kernel is implemented.
I have some thoughts and questions about how some issues should/could be implemented that I'd like to discuss.
Firstly I think that in my ignorance I took a wrong path to experiment with Raspberry Pi 3B+. It has a Cortex A53 (ARMv8-A) processor but as I want to target AArch32 (and initially without SMP) I thought that modifying current rpi target is the best choice. Now I think that I should have started with the newest supported by hw ARM processor (Cortex A15 if I correctly understand) and I would not be stopped by issues I had. Or maybe not...
When last time I wrote about my progress I couldn't pass through following code:
sctlr = Cpu::Sctlr::read(); Cpu::Sctlr::C::set(sctlr, 1); // enable data cache Cpu::Sctlr::I::set(sctlr, 1); // enable instruction cache Cpu::Sctlr::M::set(sctlr, 1); // enable mmu Cpu::Sctlr::write(sctlr);
After reading and making different attempts I checked that enabling instruction cache does not cause problems, enabling data cache or mmu individually does allow to go further but enabling both does not. But I thought that for initial experiments I can live without data cache. But soon I found out that I was wrong.
After many attempts I found a place where it halted. It was deep inside Genode::log in ... assembly in atomic.h in cmpxchg. And reading gave me another unpleasent surprise that it will not work if I don't have data cache enabled... So I had to go back.
After two weeks of poking around finally I found a workaround that allowed me to go further. I've changed Page_flags for all types from CACHED to UNCACHED and it allowed to pass through enabling mmu with data cache enabled (of course without real caching) and through spinlock in atomic.h.
Next thing was to make UART working. Unfortunately version 3 has different UART device enabled by default (it has two) and it required a different driver which I implemented.
Seeing "kernel initialized" passed through serial connection was a real pleasure after analyzing logs in memory for two weeks.
So I thought that it is a good moment to write my thoughts and questions.
For writing traces to memory I've created a simple utility (set of macros in assembly and C++) to write simple debug values to a buffer in memory. I used it to diagnose what is going on before serial connection is working.
It is specified by a buffer address and size. At the beginning a pointer to current position in buffer is stored. A 1-1 mapping is inserted into TLB for this region and I had to make changes in virtual memory layout of core. Currently addresses are hardcoded but I can polish it to a state where it could be enabled/disabled with some build option or some defines in one place in the code if you'd like to use this. I pushed current state of my work [1] (without any cleanup yet). Utility macros are in: - repos/base/include/base/memtrace.h - repos/base-hw/src/bootstrap/spec/arm/crt0.s Would you be interested in adding something like this to Genode? I would create issue and propose some version.
I have some general doubts about how some issues could be resolved. I started experimenting with an idea to make it possible to have a Sculpt for Raspberry Pi. And I thought it could be created one in such a way that single binary could run on any Pi. I knew that they are all ARM devices and even though some are 64bit they can work in AArch32 so I wanted to treat all version as just 32bit ARM boards.
I knew that they differ in list of devices so I thought that some kind of configuration would have to be passed during booting process so proper device drivers could be loaded and with proper configuration. I checked that a solution for this problem (using one binary for different ARM boards) used by at least Linux and U-boot is device tree. My plan was (and still is unless something better is proposed) to try to experiment with incorporating support for device tree to a platform driver - if I correctly understand it is a place where similar functionality is implemented for x86_64.
Browsing through bootstrap and core code in base-hw for past weeks made me realise that to support one binary for different Pi devices which have different generations of processors other problems would have to be resolved.
If I correctly understand currently whe building base-hw for a specific ARM board all configuration is provided during build process. It is performed by:
a. specifying target processor version (-m for g++)
b. specifying list of files to compile and include to binary that contain implementations of functions that differ between different processor generations and to enable some functionality (e.g. for virtualization support for ARM)
c. constants in code - to provide proper memory ranges, MMIO addresses, etc. for device drivers
Having all this information during build allows to:
- optimize code by inlining even processor specific code
- minimize resulting binary (maybe not so important) and therefore memory footprint on runnig system (more importand)
On the other hand wikipedia (here [2]) currently mentions 15 models of Raspberry Pi which differ in:
- processor generations (ARM11, Cortex-A7, Cortex-A53) - that breaks point (a)
- have different devices (with/without ethernet, wireless, etc.) - that breaks point (b)
- have different runtime configurations that can be changed by configuring firmware (e.g. different partitioning of RAM for used by graphics and operating system can be performed using a configuration option) - that contradicts with (c)
When thinking about supporting different Pi devices (and more generally other ARM boards) I think that there are two areas to consider:
A. support for runtime/startup configuration of devices that will have drivers running in different processes - this is a part that I knew about from the beginning of my experimentation. I still think that implementing support for device tree (or some alternative) is a proper solution for this part (what whould be a method of passing configuration to device drivers is an open question)
B. support for passing configuration that is required by bootstrap and core. Here drivers are selected with C++ code e.g.:
//using Serial = Genode::Pl011_uart; using Serial = Genode::Mini_uart;
Selecting UART driver is an interesting example as RPI3B+ has two UART devices and which one is available is decided by using proper configuration for firmware (mini uart is available by default and Pl011 uart is used internally for communcation with Bluetooth but it can be changed with configuration before starting operating system).
Now questions:
1. Do you (Genode) plan to have or would like to have such configurable support for different ARM devices?
2. Do you think that creating generic platform driver for ARM (to support A) that work using informations provided by device tree support is generally a good idea? What alternatives you consider better?
3. Do you see any way to implement suport for B?
I'd very much like to receive some comments about it.
Hello Tomasz,
thank you very much for sharing your experimentation efforts and insights and for starting the discussion. Please, see my comments inline below.
On Mon, Jan 28, 2019 at 06:31:33PM +0100, Tomasz Gajewski wrote:
Hi,
last weeks of attempts gave me some small progress with code, understanding of some aspects of ARM (AArch32) architecture and some knowledge about how low level hw kernel is implemented.
I have some thoughts and questions about how some issues should/could be implemented that I'd like to discuss.
Firstly I think that in my ignorance I took a wrong path to experiment with Raspberry Pi 3B+. It has a Cortex A53 (ARMv8-A) processor but as I want to target AArch32 (and initially without SMP) I thought that modifying current rpi target is the best choice. Now I think that I should have started with the newest supported by hw ARM processor (Cortex A15 if I correctly understand) and I would not be stopped by issues I had. Or maybe not...
Indeed, starting with a fork of the most recent processor in hw as a starting point might be better.
When last time I wrote about my progress I couldn't pass through following code:
sctlr = Cpu::Sctlr::read(); Cpu::Sctlr::C::set(sctlr, 1); // enable data cache Cpu::Sctlr::I::set(sctlr, 1); // enable instruction cache Cpu::Sctlr::M::set(sctlr, 1); // enable mmu Cpu::Sctlr::write(sctlr);
After reading and making different attempts I checked that enabling instruction cache does not cause problems, enabling data cache or mmu individually does allow to go further but enabling both does not. But I thought that for initial experiments I can live without data cache. But soon I found out that I was wrong.
After many attempts I found a place where it halted. It was deep inside Genode::log in ... assembly in atomic.h in cmpxchg. And reading gave me another unpleasent surprise that it will not work if I don't have data cache enabled... So I had to go back.
Yes, we are using ldrex/strex especially to support multi-processor systems. Those instructions use cache-coherency mechanisms of the processors when working on "cacheable" memory. I you did not turn on caches and the snoop-control-unit (SMP bit in Armv7) the cmpxchg won't work properly.
After two weeks of poking around finally I found a workaround that allowed me to go further. I've changed Page_flags for all types from CACHED to UNCACHED and it allowed to pass through enabling mmu with data cache enabled (of course without real caching) and through spinlock in atomic.h.
Next thing was to make UART working. Unfortunately version 3 has different UART device enabled by default (it has two) and it required a different driver which I implemented.
Seeing "kernel initialized" passed through serial connection was a real pleasure after analyzing logs in memory for two weeks.
So I thought that it is a good moment to write my thoughts and questions.
For writing traces to memory I've created a simple utility (set of macros in assembly and C++) to write simple debug values to a buffer in memory. I used it to diagnose what is going on before serial connection is working.
It is specified by a buffer address and size. At the beginning a pointer to current position in buffer is stored. A 1-1 mapping is inserted into TLB for this region and I had to make changes in virtual memory layout of core. Currently addresses are hardcoded but I can polish it to a state where it could be enabled/disabled with some build option or some defines in one place in the code if you'd like to use this. I pushed current state of my work [1] (without any cleanup yet). Utility macros are in:
- repos/base/include/base/memtrace.h
- repos/base-hw/src/bootstrap/spec/arm/crt0.s
Would you be interested in adding something like this to Genode? I would create issue and propose some version.
Very cool that you could help yourself that way! In general, we already have a tracing mechanism in Genode, where tracing points are collected in memory, and might get aggregated even from many different components for debug or optimization reasons. Anyway, that mechanism is based on core's functionality and therefore only appropriated for components running on top of core/kernel.
Another option used in NOVA/Genode is to write all kernel messages into a memory buffer and export it to the userland. Thereby, you can aggregate messages in headless systems or systems without AMT or serial line. I think this way might be appropriated to be used in base-hw too. Anyway, I would not introduce new debug macros, but just add a simple serial driver, which isn't using a special device but a portion of memory for printing. Then one can switch UART to that model if there is no one, or it is troublesome. What do you think about that approach?
I have to admit that usually I can use a JTAG debugger on most platforms to tackle such early initialization problems. On the other hand I'm quite cautious in adding pure debug feature in the "microkernel" ;-).
I have some general doubts about how some issues could be resolved. I started experimenting with an idea to make it possible to have a Sculpt for Raspberry Pi. And I thought it could be created one in such a way that single binary could run on any Pi. I knew that they are all ARM devices and even though some are 64bit they can work in AArch32 so I wanted to treat all version as just 32bit ARM boards.
I knew that they differ in list of devices so I thought that some kind of configuration would have to be passed during booting process so proper device drivers could be loaded and with proper configuration. I checked that a solution for this problem (using one binary for different ARM boards) used by at least Linux and U-boot is device tree. My plan was (and still is unless something better is proposed) to try to experiment with incorporating support for device tree to a platform driver - if I correctly understand it is a place where similar functionality is implemented for x86_64.
Browsing through bootstrap and core code in base-hw for past weeks made me realise that to support one binary for different Pi devices which have different generations of processors other problems would have to be resolved.
If I correctly understand currently whe building base-hw for a specific ARM board all configuration is provided during build process. It is performed by:
a. specifying target processor version (-m for g++)
b. specifying list of files to compile and include to binary that contain implementations of functions that differ between different processor generations and to enable some functionality (e.g. for virtualization support for ARM)
c. constants in code - to provide proper memory ranges, MMIO addresses, etc. for device drivers
Don't get me wrong, striving for the stars is welcome, but I think the goal of having a generic kernel image for all RPIs or even all ARM devices is a bit too ambitious right now. Although, Linux ARM developers are working on it since many years, they aren't there yet. Look at current RPI distro images like Raspian, they deliver at least two different kernels _and_ multiple device trees. The bootloader code has to decide, which one is loaded. Currently, there is no generic convention followed by all SoC/board vendors, bootloaders etc.. We have to be pragmatic here. Given the current state of e.g. the Rasperry Pi universe, where you have to decide what needs to be loaded, I do not see in general the advantage to differentiate in between configuration data and some small, statically linked image.
Having all this information during build allows to:
optimize code by inlining even processor specific code
minimize resulting binary (maybe not so important) and therefore memory footprint on runnig system (more importand)
On the other hand wikipedia (here [2]) currently mentions 15 models of Raspberry Pi which differ in:
processor generations (ARM11, Cortex-A7, Cortex-A53) - that breaks point (a)
have different devices (with/without ethernet, wireless, etc.) - that breaks point (b)
have different runtime configurations that can be changed by configuring firmware (e.g. different partitioning of RAM for used by graphics and operating system can be performed using a configuration option) - that contradicts with (c)
Surely, those are too much dimensions to provide different fully fledged system images. Also, we do not want too much platform differentiations in the codebase. Again, I vote for pragmaticsm and to target the different platforms step-by-step and not all-in-one. Currently, I would think that having different targets for the different architectures (Armv6, Armv7, Armv8) is a good starting point. It is a natural boundary, and we can compile all components to target the correct one. Then the question is whether there is a mechanism in the Broadcom SoC to identify the correct model at runtime, e.g. some identification registers. If possible, we can of course hide the model differences in the platform/bootstrap code within one image. I would omit different runtime configurations of the firmware for the moment and just support the default one.
When thinking about supporting different Pi devices (and more generally other ARM boards) I think that there are two areas to consider:
A. support for runtime/startup configuration of devices that will have drivers running in different processes - this is a part that I knew about from the beginning of my experimentation. I still think that implementing support for device tree (or some alternative) is a proper solution for this part (what whould be a method of passing configuration to device drivers is an open question)
B. support for passing configuration that is required by bootstrap and core. Here drivers are selected with C++ code e.g.:
//using Serial = Genode::Pl011_uart; using Serial = Genode::Mini_uart; Selecting UART driver is an interesting example as RPI3B+ has two UART devices and which one is available is decided by using proper configuration for firmware (mini uart is available by default and Pl011 uart is used internally for communcation with Bluetooth but it can be changed with configuration before starting operating system).
Now questions:
- Do you (Genode) plan to have or would like to have such configurable support for different ARM devices?
I only state my point of view that does not necessarily be the way it will go, but anyway: nowadays, configuration starts above core/kernel. We should keep this for the time-being to limit the risk of over-engineering in this minimal, critical code-base. I can imagine, that we weaken this claim for the bootstrap component in the future, because that code is critical in the boot-stage only, but then gets thrown away anyway.
Above core, we need to know:
* What devices exists * What resources do they need * Are there additional configuration aspects needed by the driver, beyond the resources, e.g.: operation mode of the PHY interface for ethernet devices ... * Resp. how to power/clock the device at runtime if dynamic power consumption is a topic
- Do you think that creating generic platform driver for ARM (to support A) that work using informations provided by device tree support is generally a good idea? What alternatives you consider better?
All functionality described above is realized using open firmware / flattened device tree in Linux and Co. I agree that it is appealing to be able to access all the platform data for free. But this only half the truth for the following reasons:
# Device tree support was a moving target within the last years with lots of changes in the implementation and in the trees themselfs, it is not forseeable that this will change # There are reams of device-specific attributes. Please, have a look at Documentation/devicetree in the Linux kernel. There are over 3000 files. The whole "of_" bureaucracy in the Linux kernel shows its complexity. # Different device trees and its "generic" language should not suggest that we will have one platform driver to rule them all. There are tons of "platform devices" in the Linux kernel necessary to provide the resources that toplevel devices need. That means for each SoC you still need a specific platform driver that support all the multiplexing units for pins, power, clocking etc. # Device trees describe also a lot of relations in between devices. For instance, a device might get its interrupts from the interrupt controller or from a GPIO controller. All routes to some kind of multiplexer device are part of the tree. It is much easier if you want to apply this configuration to a monolithic component containing all multiplexer devices than to split this in multiple components.
To sum it up. I'm not sure whether it is the right way to go to support device trees by Genode's ARM platform driver, but I do not want to exclude it completely. Maybe I'm wrong and the complexity of the core functionality is over-estimated by me. Surely we need something comparable at some point. Maybe, it would be good to start it as an experiment for one specific SoC.
- Do you see any way to implement suport for B?
Surely, but at least here at Genode Labs it is not highly prioritized right now. Currently, we try to limit the platform support and care to the NXP i.MX* platforms. Here, we plan to support i.MX8 as soon as possible, which has Cortex A53 too.
I'd very much like to receive some comments about it.
Than you very much for sharing your thoughts.
Best regards Stefan
-- Tomasz Gajewski
[1] https://github.com/tomga/genode/tree/rpi3bplus [2] https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications
Genode users mailing list users@lists.genode.org https://lists.genode.org/listinfo/users
Hello,
thanks for your response. My comments also inline.
Stefan Kalkowski stefan.kalkowski@genode-labs.com writes:
Hello Tomasz,
thank you very much for sharing your experimentation efforts and insights and for starting the discussion. Please, see my comments inline below.
...
For writing traces to memory I've created a simple utility (set of macros in assembly and C++) to write simple debug values to a buffer in memory. I used it to diagnose what is going on before serial connection is working.
It is specified by a buffer address and size. At the beginning a pointer to current position in buffer is stored. A 1-1 mapping is inserted into TLB for this region and I had to make changes in virtual memory layout of core. Currently addresses are hardcoded but I can polish it to a state where it could be enabled/disabled with some build option or some defines in one place in the code if you'd like to use this. I pushed current state of my work [1] (without any cleanup yet). Utility macros are in:
- repos/base/include/base/memtrace.h
- repos/base-hw/src/bootstrap/spec/arm/crt0.s
Would you be interested in adding something like this to Genode? I would create issue and propose some version.
Very cool that you could help yourself that way! In general, we already have a tracing mechanism in Genode, where tracing points are collected in memory, and might get aggregated even from many different components for debug or optimization reasons. Anyway, that mechanism is based on core's functionality and therefore only appropriated for components running on top of core/kernel.
It was meant only for debugging parts before I could access Genode::log.
Another option used in NOVA/Genode is to write all kernel messages into a memory buffer and export it to the userland. Thereby, you can aggregate messages in headless systems or systems without AMT or serial line. I think this way might be appropriated to be used in base-hw too. Anyway, I would not introduce new debug macros, but just add a simple serial driver, which isn't using a special device but a portion of memory for printing. Then one can switch UART to that model if there is no one, or it is troublesome. What do you think about that approach?
I have to admit that usually I can use a JTAG debugger on most platforms to tackle such early initialization problems. On the other hand I'm quite cautious in adding pure debug feature in the "microkernel" ;-).
Well, I had problems with getting out of crt0.s and didn't have stack yet. And second place with problem was during enabling mmu. I suppose this driver could be made to work just after this part. Am I wrong?
I don't have a JTAG debugger. At least not yet, so I use those macros as a substitute for it.
Anyway I didn't propose adding much debug messages but only a tool for that could be used if someone would need to debug early boot process like me. And only with a dedicated option to enable it.
Generally an idea of dummy serial driver that would write to memory if UART is not available is nice, but it would not help me much as on Raspberry Pi there is UART available.
...
Don't get me wrong, striving for the stars is welcome, but I think the goal of having a generic kernel image for all RPIs or even all ARM devices is a bit too ambitious right now. Although, Linux ARM developers are working on it since many years, they aren't there yet. Look at current RPI distro images like Raspian, they deliver at least two different kernels _and_ multiple device trees. The bootloader code has to decide, which one is loaded. Currently, there is no generic convention followed by all SoC/board vendors, bootloaders etc.. We have to be pragmatic here.
Ok.
Given the current state of e.g. the Rasperry Pi universe, where you have to decide what needs to be loaded, I do not see in general the advantage to differentiate in between configuration data and some small, statically linked image.
As I understand proper dts is selected by firmware part. I wouldn't have to decide what to load. I'll confirm that when I have a diffent model at hand.
...
- Do you think that creating generic platform driver for ARM (to support A) that work using informations provided by device tree support is generally a good idea? What alternatives you consider better?
All functionality described above is realized using open firmware / flattened device tree in Linux and Co. I agree that it is appealing to be able to access all the platform data for free. But this only half the truth for the following reasons:
# Device tree support was a moving target within the last years with lots of changes in the implementation and in the trees themselfs, it is not forseeable that this will change # There are reams of device-specific attributes. Please, have a look at Documentation/devicetree in the Linux kernel. There are over 3000 files. The whole "of_" bureaucracy in the Linux kernel shows its complexity. # Different device trees and its "generic" language should not suggest that we will have one platform driver to rule them all. There are tons of "platform devices" in the Linux kernel necessary to provide the resources that toplevel devices need. That means for each SoC you still need a specific platform driver that support all the multiplexing units for pins, power, clocking etc. # Device trees describe also a lot of relations in between devices. For instance, a device might get its interrupts from the interrupt controller or from a GPIO controller. All routes to some kind of multiplexer device are part of the tree. It is much easier if you want to apply this configuration to a monolithic component containing all multiplexer devices than to split this in multiple components.
To sum it up. I'm not sure whether it is the right way to go to support device trees by Genode's ARM platform driver, but I do not want to exclude it completely. Maybe I'm wrong and the complexity of the core functionality is over-estimated by me. Surely we need something comparable at some point. Maybe, it would be good to start it as an experiment for one specific SoC.
Ok. I have very little experience and it is very probable that I'm underestimating the complexity.
Now I'm starting again from start but with different knowledge level.
Thanks again.
Tomasz Gajewski