[U-Boot] [PATCH] vxworks: fixed cpu enable using PSCI on armv8

Without armv8_setup_psci register VBAR_EL3 is not set up property which makes SMC calls jump to invalid location.
smp_kick_all_cpus is required to make slave cpus leave gic_wait_for_interrupt. Without this they will never pursue booting process.
This implementation is very similiar to what is done in boot_jump_linux in arch/arm/lib/bootm.c file.
Tested on VxWorks 7 release SR0520 2017-12-08.
Signed-off-by: Vasyl Vavrychuk vasyl.vavrychuk@globallogic.com --- cmd/elf.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/cmd/elf.c b/cmd/elf.c index 5745a389da..db690fc619 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -372,6 +372,11 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("## Starting vxWorks at 0x%08lx ...\n", addr);
dcache_disable(); +#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) + armv8_setup_psci(); + smp_kick_all_cpus(); +#endif + #ifdef CONFIG_X86 /* VxWorks on x86 uses stack to pass parameters */ ((asmlinkage void (*)(int))addr)(0);

Hi Vasyl,
On Wed, Mar 28, 2018 at 3:29 AM, Vasyl Vavrychuk vvavrychuk@gmail.com wrote:
Without armv8_setup_psci register VBAR_EL3 is not set up property which makes SMC calls jump to invalid location.
smp_kick_all_cpus is required to make slave cpus leave gic_wait_for_interrupt. Without this they will never pursue booting process.
This implementation is very similiar to what is done in boot_jump_linux in arch/arm/lib/bootm.c file.
Tested on VxWorks 7 release SR0520 2017-12-08.
On what board?
As I mentioned before, why do you want to use 'bootvx' to boot a VxWorks 7 kernel? I believe VxWorks 7 ARM kernel is loaded via 'bootm'. See doc/README.vxworks.
Signed-off-by: Vasyl Vavrychuk vasyl.vavrychuk@globallogic.com
cmd/elf.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/cmd/elf.c b/cmd/elf.c index 5745a389da..db690fc619 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -372,6 +372,11 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("## Starting vxWorks at 0x%08lx ...\n", addr);
dcache_disable();
+#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI)
armv8_setup_psci();
smp_kick_all_cpus();
What about ARMv8 32-bit? What about ARMv7? Should we call smp_kick_all_cpus() for ARMv7 as well? Seems to me the logic of #ifdefs here needs to be tuned.
+#endif
#ifdef CONFIG_X86 /* VxWorks on x86 uses stack to pass parameters */ ((asmlinkage void (*)(int))addr)(0); --
Regards, Bin

Hi, Bin Meng,
Thanks for your suggestions. Please find my comments below
On Wed, Mar 28, 2018 at 7:36 AM, Bin Meng bmeng.cn@gmail.com wrote:
Tested on VxWorks 7 release SR0520 2017-12-08.
On what board?
Intel Stratix 10 DevKit
As I mentioned before, why do you want to use 'bootvx' to boot a VxWorks 7 kernel? I believe VxWorks 7 ARM kernel is loaded via 'bootm'. See doc/README.vxworks.
I have just tried what I found first, but I can add support of ARMv8 PSCI to the bootm for vxworks 7 too.
Anyway, if we add support of ARMv8 PSCI to bootm for vxworks 7, then do you think that bootvx should not support this feature?
+#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI)
armv8_setup_psci();
smp_kick_all_cpus();
What about ARMv8 32-bit?
Do you mean ARMv8 32-bit U-Boot or ARMv8 32-bit VxWorks under ARMv8 64-bit U-Boot?
What about ARMv7? Should we call smp_kick_all_cpus() for ARMv7 as well?
As far as I understand from U-Boot code gic_wait_for_interrupt is called only for ARMv8. I think this is related to the difference how cpu cores start from reset on armv7 and armv8.
On armv7 usually only core0 starts after power on and other cores are started by the platform specific means. On armv8 usually all cores starts after power on.
Seems to me the logic of #ifdefs here needs to be tuned.
I have made a minimal set of changes need to implement functionality that are required for our customer, i.e. booting 64-bit vxworks on armv8.
I am not very willing to generalize it without a need. Maybe just no one will require it at all.
Kind regards, Vasyl

Hi Vasyl,
On Wed, Mar 28, 2018 at 7:27 PM, Vasyl Vavrychuk vasyl.vavrychuk@globallogic.com wrote:
Hi, Bin Meng,
Thanks for your suggestions. Please find my comments below
On Wed, Mar 28, 2018 at 7:36 AM, Bin Meng bmeng.cn@gmail.com wrote:
Tested on VxWorks 7 release SR0520 2017-12-08.
On what board?
Intel Stratix 10 DevKit
Thanks for the info.
As I mentioned before, why do you want to use 'bootvx' to boot a VxWorks 7 kernel? I believe VxWorks 7 ARM kernel is loaded via 'bootm'. See doc/README.vxworks.
I have just tried what I found first, but I can add support of ARMv8 PSCI to the bootm for vxworks 7 too.
Hold on..
Anyway, if we add support of ARMv8 PSCI to bootm for vxworks 7, then do you think that bootvx should not support this feature?
Why I mentioned the 'bootm' command, is that AFAIK the only official way of booting a VxWorks 7 ARM kernel is to use 'bootm'. Are you saying that 'bootm' command does not work on your Intel Stratix 10 DevKit board? If that's the case, we have something to fix.
Having said that, having 'bootvx' to support booting a 64-bit VxWorks 7 ARM kernel is a nice to have.
+#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI)
armv8_setup_psci();
smp_kick_all_cpus();
What about ARMv8 32-bit?
Do you mean ARMv8 32-bit U-Boot or ARMv8 32-bit VxWorks under ARMv8 64-bit U-Boot?
I meant to say ARMv8 32-bit U-Boot. I am not sure if 32-bit U-Boot can load a 64-bit VxWorks kernel..
What about ARMv7? Should we call smp_kick_all_cpus() for ARMv7 as well?
As far as I understand from U-Boot code gic_wait_for_interrupt is called only for ARMv8. I think this is related to the difference how cpu cores start from reset on armv7 and armv8.
On armv7 usually only core0 starts after power on and other cores are started by the platform specific means. On armv8 usually all cores starts after power on.
Seems to me the logic of #ifdefs here needs to be tuned.
I have made a minimal set of changes need to implement functionality that are required for our customer, i.e. booting 64-bit vxworks on armv8.
I am not very willing to generalize it without a need. Maybe just no one will require it at all.
Understood. Thanks for the clarification. I was trying to understand the reason of modifying this as I believe 'bootm' should work out of the box.
Regards, Bin

Hi Bin,
On Sun, Apr 1, 2018 at 4:51 PM, Bin Meng bmeng.cn@gmail.com wrote:
Why I mentioned the 'bootm' command, is that AFAIK the only official way of booting a VxWorks 7 ARM kernel is to use 'bootm'. Are you saying that 'bootm' command does not work on your Intel Stratix 10 DevKit board? If that's the case, we have something to fix.
Having said that, having 'bootvx' to support booting a 64-bit VxWorks 7 ARM kernel is a nice to have.
Yes, there is the same issue with bootm for ARMv8. It works but only one CPU core is enabled.
+#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI)
armv8_setup_psci();
smp_kick_all_cpus();
What about ARMv8 32-bit?
Do you mean ARMv8 32-bit U-Boot or ARMv8 32-bit VxWorks under ARMv8 64-bit U-Boot?
I meant to say ARMv8 32-bit U-Boot. I am not sure if 32-bit U-Boot can load a 64-bit VxWorks kernel..
Is ARMv8 32-bit U-Boot supported?
I was trying to understand the reason of modifying this as I believe 'bootm' should work out of the box.
I will submit patch for bootm command in the next email.
Kind regards, Vasyl

Without armv8_setup_psci register VBAR_EL3 is not set up property which makes SMC calls jump to invalid location.
smp_kick_all_cpus is required to make slave cpus leave gic_wait_for_interrupt. Without this they will never pursue booting process.
Fix was applied to the two ways of booting VxWorks: bootvx and bootm commands.
This implementation is very similiar to what is done in boot_jump_linux in arch/arm/lib/bootm.c file.
Tested on VxWorks 7 release SR0520 2017-12-08.
Signed-off-by: Vasyl Vavrychuk vasyl.vavrychuk@globallogic.com --- arch/arm/lib/bootm.c | 5 +++++ cmd/elf.c | 5 +++++ 2 files changed, 10 insertions(+)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index cfc236f964..91a64bec34 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -448,6 +448,11 @@ void boot_prep_vxworks(bootm_headers_t *images) } void boot_jump_vxworks(bootm_headers_t *images) { +#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) + armv8_setup_psci(); + smp_kick_all_cpus(); +#endif + /* ARM VxWorks requires device tree physical address to be passed */ ((void (*)(void *))images->ep)(images->ft_addr); } diff --git a/cmd/elf.c b/cmd/elf.c index 5b59fc6329..b476202908 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -368,6 +368,11 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("## Starting vxWorks at 0x%08lx ...\n", addr);
dcache_disable(); +#if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) + armv8_setup_psci(); + smp_kick_all_cpus(); +#endif + #ifdef CONFIG_X86 /* VxWorks on x86 uses stack to pass parameters */ ((asmlinkage void (*)(int))addr)(0);
participants (3)
-
Bin Meng
-
Vasyl Vavrychuk
-
Vasyl Vavrychuk