diff mbox series

[U-Boot,v2,28/29] riscv: qemu: detect and boot the kernel passed by QEMU

Message ID 20181030125553.5230-29-lukas.auer@aisec.fraunhofer.de
State Superseded
Delegated to: Andes
Headers show
Series General fixes / cleanup for RISC-V and improvements to qemu-riscv | expand

Commit Message

Lukas Auer Oct. 30, 2018, 12:55 p.m. UTC
QEMU embeds the location of the kernel image in the device tree. Store
this address in the environment as variable kernel_start and use it in
CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed by the
prior boot stage to boot Linux.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
---

Changes in v2:
- Rebase onto u-boot-dm/next
- Boot Linux with the device tree provided by the prior boot stage

 board/emulation/qemu-riscv/Kconfig      |  1 +
 board/emulation/qemu-riscv/qemu-riscv.c | 29 +++++++++++++++++++++++++
 configs/qemu-riscv32_defconfig          |  1 +
 configs/qemu-riscv64_defconfig          |  1 +
 include/configs/qemu-riscv.h            | 10 ++++++++-
 5 files changed, 41 insertions(+), 1 deletion(-)

Comments

Lukas Auer Oct. 30, 2018, 3:02 p.m. UTC | #1
On Tue, 2018-10-30 at 13:55 +0100, Lukas Auer wrote:
> QEMU embeds the location of the kernel image in the device tree.
> Store
> this address in the environment as variable kernel_start and use it
> in
> CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed by
> the
> prior boot stage to boot Linux.
> 
> Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> ---
> 
> Changes in v2:
> - Rebase onto u-boot-dm/next
> - Boot Linux with the device tree provided by the prior boot stage
> 
>  board/emulation/qemu-riscv/Kconfig      |  1 +
>  board/emulation/qemu-riscv/qemu-riscv.c | 29
> +++++++++++++++++++++++++
>  configs/qemu-riscv32_defconfig          |  1 +
>  configs/qemu-riscv64_defconfig          |  1 +
>  include/configs/qemu-riscv.h            | 10 ++++++++-
>  5 files changed, 41 insertions(+), 1 deletion(-)
> 
> diff --git a/board/emulation/qemu-riscv/Kconfig
> b/board/emulation/qemu-riscv/Kconfig
> index 37a80db6a9..be5839b7db 100644
> --- a/board/emulation/qemu-riscv/Kconfig
> +++ b/board/emulation/qemu-riscv/Kconfig
> @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>  	imply CMD_EXT2
>  	imply CMD_EXT4
>  	imply CMD_FAT
> +	imply BOARD_LATE_INIT
>  
>  endif
> diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
> b/board/emulation/qemu-riscv/qemu-riscv.c
> index 2ce093e19a..ee20983095 100644
> --- a/board/emulation/qemu-riscv/qemu-riscv.c
> +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> @@ -19,3 +19,32 @@ int board_init(void)
>  
>  	return 0;
>  }
> +
> +int board_late_init(void)
> +{
> +	ulong kernel_start;
> +	ofnode chosen_node;
> +	int ret;
> +
> +	chosen_node = ofnode_path("/chosen");
> +	if (!ofnode_valid(chosen_node)) {
> +		printf("No chosen node found\n");
> +		return 0;
> +	}
> +
> +#ifdef CONFIG_ARCH_RV64I
> +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
> +			      (u64 *)&kernel_start);
> +#else
> +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
> +			      (u32 *)&kernel_start);
> +#endif
> +	if (ret) {
> +		printf("Can't find kernel start address in device
> tree\n");
> +		return 0;
> +	}
> +
> +	env_set_hex("kernel_start", kernel_start);
> +
> +	return 0;
> +}
> diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-
> riscv32_defconfig
> index b55644378a..13dd53a550 100644
> --- a/configs/qemu-riscv32_defconfig
> +++ b/configs/qemu-riscv32_defconfig
> @@ -4,4 +4,5 @@ CONFIG_NR_DRAM_BANKS=1
>  CONFIG_FIT=y
>  CONFIG_DISPLAY_CPUINFO=y
>  CONFIG_DISPLAY_BOARDINFO=y
> +CONFIG_HUSH_PARSER=y
>  CONFIG_OF_PRIOR_STAGE=y
> diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-
> riscv64_defconfig
> index a542ac4893..06eb3042fa 100644
> --- a/configs/qemu-riscv64_defconfig
> +++ b/configs/qemu-riscv64_defconfig
> @@ -5,4 +5,5 @@ CONFIG_NR_DRAM_BANKS=1
>  CONFIG_FIT=y
>  CONFIG_DISPLAY_CPUINFO=y
>  CONFIG_DISPLAY_BOARDINFO=y
> +CONFIG_HUSH_PARSER=y
>  CONFIG_OF_PRIOR_STAGE=y
> diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-
> riscv.h
> index ba6a18f2e6..7c88ba300a 100644
> --- a/include/configs/qemu-riscv.h
> +++ b/include/configs/qemu-riscv.h
> @@ -21,7 +21,15 @@
>  #define CONFIG_ENV_SIZE			SZ_4K
>  
>  #define CONFIG_EXTRA_ENV_SETTINGS \
> -	"fdt_high=0xffffffffffffffff\0" \
> +	"fdt_high=0x82000000\0" \
> +	"bootm_size=0x10000000\0" \
>  	"initrd_high=0xffffffffffffffff\0"
>  
> +#define CONFIG_BOOTCOMMAND \
> +	"if env exists kernel_start; then " \
> +		"bootm ${kernel_start} - ${prior_stage_dtb};" \

As Alexander Graf pointed out in reply to patch 24, we don't need the
separate environment variable "prior_stage_dtb". I will replace it with
"fdtcontroladdr" here and drop patch 24 in the next version.

> +	"else " \
> +		"echo Kernel address not found in the device tree;" \
> +	"fi;"
> +
>  #endif /* __CONFIG_H */
Alexander Graf Oct. 30, 2018, 3:27 p.m. UTC | #2
On 30.10.18 16:02, Auer, Lukas wrote:
> On Tue, 2018-10-30 at 13:55 +0100, Lukas Auer wrote:
>> QEMU embeds the location of the kernel image in the device tree.
>> Store
>> this address in the environment as variable kernel_start and use it
>> in
>> CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed by
>> the
>> prior boot stage to boot Linux.
>>
>> Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
>> ---
>>
>> Changes in v2:
>> - Rebase onto u-boot-dm/next
>> - Boot Linux with the device tree provided by the prior boot stage
>>
>>  board/emulation/qemu-riscv/Kconfig      |  1 +
>>  board/emulation/qemu-riscv/qemu-riscv.c | 29
>> +++++++++++++++++++++++++
>>  configs/qemu-riscv32_defconfig          |  1 +
>>  configs/qemu-riscv64_defconfig          |  1 +
>>  include/configs/qemu-riscv.h            | 10 ++++++++-
>>  5 files changed, 41 insertions(+), 1 deletion(-)
>>
>> diff --git a/board/emulation/qemu-riscv/Kconfig
>> b/board/emulation/qemu-riscv/Kconfig
>> index 37a80db6a9..be5839b7db 100644
>> --- a/board/emulation/qemu-riscv/Kconfig
>> +++ b/board/emulation/qemu-riscv/Kconfig
>> @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>>  	imply CMD_EXT2
>>  	imply CMD_EXT4
>>  	imply CMD_FAT
>> +	imply BOARD_LATE_INIT
>>  
>>  endif
>> diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
>> b/board/emulation/qemu-riscv/qemu-riscv.c
>> index 2ce093e19a..ee20983095 100644
>> --- a/board/emulation/qemu-riscv/qemu-riscv.c
>> +++ b/board/emulation/qemu-riscv/qemu-riscv.c
>> @@ -19,3 +19,32 @@ int board_init(void)
>>  
>>  	return 0;
>>  }
>> +
>> +int board_late_init(void)
>> +{
>> +	ulong kernel_start;
>> +	ofnode chosen_node;
>> +	int ret;
>> +
>> +	chosen_node = ofnode_path("/chosen");
>> +	if (!ofnode_valid(chosen_node)) {
>> +		printf("No chosen node found\n");
>> +		return 0;
>> +	}
>> +
>> +#ifdef CONFIG_ARCH_RV64I
>> +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
>> +			      (u64 *)&kernel_start);
>> +#else
>> +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
>> +			      (u32 *)&kernel_start);
>> +#endif
>> +	if (ret) {
>> +		printf("Can't find kernel start address in device
>> tree\n");
>> +		return 0;
>> +	}
>> +
>> +	env_set_hex("kernel_start", kernel_start);
>> +
>> +	return 0;
>> +}
>> diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-
>> riscv32_defconfig
>> index b55644378a..13dd53a550 100644
>> --- a/configs/qemu-riscv32_defconfig
>> +++ b/configs/qemu-riscv32_defconfig
>> @@ -4,4 +4,5 @@ CONFIG_NR_DRAM_BANKS=1
>>  CONFIG_FIT=y
>>  CONFIG_DISPLAY_CPUINFO=y
>>  CONFIG_DISPLAY_BOARDINFO=y
>> +CONFIG_HUSH_PARSER=y
>>  CONFIG_OF_PRIOR_STAGE=y
>> diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-
>> riscv64_defconfig
>> index a542ac4893..06eb3042fa 100644
>> --- a/configs/qemu-riscv64_defconfig
>> +++ b/configs/qemu-riscv64_defconfig
>> @@ -5,4 +5,5 @@ CONFIG_NR_DRAM_BANKS=1
>>  CONFIG_FIT=y
>>  CONFIG_DISPLAY_CPUINFO=y
>>  CONFIG_DISPLAY_BOARDINFO=y
>> +CONFIG_HUSH_PARSER=y
>>  CONFIG_OF_PRIOR_STAGE=y
>> diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-
>> riscv.h
>> index ba6a18f2e6..7c88ba300a 100644
>> --- a/include/configs/qemu-riscv.h
>> +++ b/include/configs/qemu-riscv.h
>> @@ -21,7 +21,15 @@
>>  #define CONFIG_ENV_SIZE			SZ_4K
>>  
>>  #define CONFIG_EXTRA_ENV_SETTINGS \
>> -	"fdt_high=0xffffffffffffffff\0" \
>> +	"fdt_high=0x82000000\0" \
>> +	"bootm_size=0x10000000\0" \
>>  	"initrd_high=0xffffffffffffffff\0"
>>  
>> +#define CONFIG_BOOTCOMMAND \
>> +	"if env exists kernel_start; then " \
>> +		"bootm ${kernel_start} - ${prior_stage_dtb};" \
> 
> As Alexander Graf pointed out in reply to patch 24, we don't need the
> separate environment variable "prior_stage_dtb". I will replace it with
> "fdtcontroladdr" here and drop patch 24 in the next version.

Also, can you please enable distro boot? :)


Thanks,

Alex
Lukas Auer Oct. 30, 2018, 5:13 p.m. UTC | #3
On Tue, 2018-10-30 at 16:27 +0100, Alexander Graf wrote:
> 
> On 30.10.18 16:02, Auer, Lukas wrote:
> > On Tue, 2018-10-30 at 13:55 +0100, Lukas Auer wrote:
> > > QEMU embeds the location of the kernel image in the device tree.
> > > Store
> > > this address in the environment as variable kernel_start and use
> > > it
> > > in
> > > CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed
> > > by
> > > the
> > > prior boot stage to boot Linux.
> > > 
> > > Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> > > ---
> > > 
> > > Changes in v2:
> > > - Rebase onto u-boot-dm/next
> > > - Boot Linux with the device tree provided by the prior boot
> > > stage
> > > 
> > >  board/emulation/qemu-riscv/Kconfig      |  1 +
> > >  board/emulation/qemu-riscv/qemu-riscv.c | 29
> > > +++++++++++++++++++++++++
> > >  configs/qemu-riscv32_defconfig          |  1 +
> > >  configs/qemu-riscv64_defconfig          |  1 +
> > >  include/configs/qemu-riscv.h            | 10 ++++++++-
> > >  5 files changed, 41 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/board/emulation/qemu-riscv/Kconfig
> > > b/board/emulation/qemu-riscv/Kconfig
> > > index 37a80db6a9..be5839b7db 100644
> > > --- a/board/emulation/qemu-riscv/Kconfig
> > > +++ b/board/emulation/qemu-riscv/Kconfig
> > > @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
> > >  	imply CMD_EXT2
> > >  	imply CMD_EXT4
> > >  	imply CMD_FAT
> > > +	imply BOARD_LATE_INIT
> > >  
> > >  endif
> > > diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
> > > b/board/emulation/qemu-riscv/qemu-riscv.c
> > > index 2ce093e19a..ee20983095 100644
> > > --- a/board/emulation/qemu-riscv/qemu-riscv.c
> > > +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> > > @@ -19,3 +19,32 @@ int board_init(void)
> > >  
> > >  	return 0;
> > >  }
> > > +
> > > +int board_late_init(void)
> > > +{
> > > +	ulong kernel_start;
> > > +	ofnode chosen_node;
> > > +	int ret;
> > > +
> > > +	chosen_node = ofnode_path("/chosen");
> > > +	if (!ofnode_valid(chosen_node)) {
> > > +		printf("No chosen node found\n");
> > > +		return 0;
> > > +	}
> > > +
> > > +#ifdef CONFIG_ARCH_RV64I
> > > +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
> > > +			      (u64 *)&kernel_start);
> > > +#else
> > > +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
> > > +			      (u32 *)&kernel_start);
> > > +#endif
> > > +	if (ret) {
> > > +		printf("Can't find kernel start address in device
> > > tree\n");
> > > +		return 0;
> > > +	}
> > > +
> > > +	env_set_hex("kernel_start", kernel_start);
> > > +
> > > +	return 0;
> > > +}
> > > diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-
> > > riscv32_defconfig
> > > index b55644378a..13dd53a550 100644
> > > --- a/configs/qemu-riscv32_defconfig
> > > +++ b/configs/qemu-riscv32_defconfig
> > > @@ -4,4 +4,5 @@ CONFIG_NR_DRAM_BANKS=1
> > >  CONFIG_FIT=y
> > >  CONFIG_DISPLAY_CPUINFO=y
> > >  CONFIG_DISPLAY_BOARDINFO=y
> > > +CONFIG_HUSH_PARSER=y
> > >  CONFIG_OF_PRIOR_STAGE=y
> > > diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-
> > > riscv64_defconfig
> > > index a542ac4893..06eb3042fa 100644
> > > --- a/configs/qemu-riscv64_defconfig
> > > +++ b/configs/qemu-riscv64_defconfig
> > > @@ -5,4 +5,5 @@ CONFIG_NR_DRAM_BANKS=1
> > >  CONFIG_FIT=y
> > >  CONFIG_DISPLAY_CPUINFO=y
> > >  CONFIG_DISPLAY_BOARDINFO=y
> > > +CONFIG_HUSH_PARSER=y
> > >  CONFIG_OF_PRIOR_STAGE=y
> > > diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-
> > > riscv.h
> > > index ba6a18f2e6..7c88ba300a 100644
> > > --- a/include/configs/qemu-riscv.h
> > > +++ b/include/configs/qemu-riscv.h
> > > @@ -21,7 +21,15 @@
> > >  #define CONFIG_ENV_SIZE			SZ_4K
> > >  
> > >  #define CONFIG_EXTRA_ENV_SETTINGS \
> > > -	"fdt_high=0xffffffffffffffff\0" \
> > > +	"fdt_high=0x82000000\0" \
> > > +	"bootm_size=0x10000000\0" \
> > >  	"initrd_high=0xffffffffffffffff\0"
> > >  
> > > +#define CONFIG_BOOTCOMMAND \
> > > +	"if env exists kernel_start; then " \
> > > +		"bootm ${kernel_start} - ${prior_stage_dtb};" \
> > 
> > As Alexander Graf pointed out in reply to patch 24, we don't need
> > the
> > separate environment variable "prior_stage_dtb". I will replace it
> > with
> > "fdtcontroladdr" here and drop patch 24 in the next version.
> 
> Also, can you please enable distro boot? :)
> 
> 
> Thanks,
> 
> Alex

I haven't used distro boot yet, but I will take a look and see if I can
get it working. :)

Thanks,
Lukas
Lukas Auer Nov. 3, 2018, 5:07 p.m. UTC | #4
On Tue, 2018-10-30 at 16:27 +0100, Alexander Graf wrote:
> 
> On 30.10.18 16:02, Auer, Lukas wrote:
> > On Tue, 2018-10-30 at 13:55 +0100, Lukas Auer wrote:
> > > QEMU embeds the location of the kernel image in the device tree.
> > > Store
> > > this address in the environment as variable kernel_start and use
> > > it
> > > in
> > > CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed
> > > by
> > > the
> > > prior boot stage to boot Linux.
> > > 
> > > Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> > > ---
> > > 
> > > Changes in v2:
> > > - Rebase onto u-boot-dm/next
> > > - Boot Linux with the device tree provided by the prior boot
> > > stage
> > > 
> > >  board/emulation/qemu-riscv/Kconfig      |  1 +
> > >  board/emulation/qemu-riscv/qemu-riscv.c | 29
> > > +++++++++++++++++++++++++
> > >  configs/qemu-riscv32_defconfig          |  1 +
> > >  configs/qemu-riscv64_defconfig          |  1 +
> > >  include/configs/qemu-riscv.h            | 10 ++++++++-
> > >  5 files changed, 41 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/board/emulation/qemu-riscv/Kconfig
> > > b/board/emulation/qemu-riscv/Kconfig
> > > index 37a80db6a9..be5839b7db 100644
> > > --- a/board/emulation/qemu-riscv/Kconfig
> > > +++ b/board/emulation/qemu-riscv/Kconfig
> > > @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
> > >  	imply CMD_EXT2
> > >  	imply CMD_EXT4
> > >  	imply CMD_FAT
> > > +	imply BOARD_LATE_INIT
> > >  
> > >  endif
> > > diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
> > > b/board/emulation/qemu-riscv/qemu-riscv.c
> > > index 2ce093e19a..ee20983095 100644
> > > --- a/board/emulation/qemu-riscv/qemu-riscv.c
> > > +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> > > @@ -19,3 +19,32 @@ int board_init(void)
> > >  
> > >  	return 0;
> > >  }
> > > +
> > > +int board_late_init(void)
> > > +{
> > > +	ulong kernel_start;
> > > +	ofnode chosen_node;
> > > +	int ret;
> > > +
> > > +	chosen_node = ofnode_path("/chosen");
> > > +	if (!ofnode_valid(chosen_node)) {
> > > +		printf("No chosen node found\n");
> > > +		return 0;
> > > +	}
> > > +
> > > +#ifdef CONFIG_ARCH_RV64I
> > > +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
> > > +			      (u64 *)&kernel_start);
> > > +#else
> > > +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
> > > +			      (u32 *)&kernel_start);
> > > +#endif
> > > +	if (ret) {
> > > +		printf("Can't find kernel start address in device
> > > tree\n");
> > > +		return 0;
> > > +	}
> > > +
> > > +	env_set_hex("kernel_start", kernel_start);
> > > +
> > > +	return 0;
> > > +}
> > > diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-
> > > riscv32_defconfig
> > > index b55644378a..13dd53a550 100644
> > > --- a/configs/qemu-riscv32_defconfig
> > > +++ b/configs/qemu-riscv32_defconfig
> > > @@ -4,4 +4,5 @@ CONFIG_NR_DRAM_BANKS=1
> > >  CONFIG_FIT=y
> > >  CONFIG_DISPLAY_CPUINFO=y
> > >  CONFIG_DISPLAY_BOARDINFO=y
> > > +CONFIG_HUSH_PARSER=y
> > >  CONFIG_OF_PRIOR_STAGE=y
> > > diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-
> > > riscv64_defconfig
> > > index a542ac4893..06eb3042fa 100644
> > > --- a/configs/qemu-riscv64_defconfig
> > > +++ b/configs/qemu-riscv64_defconfig
> > > @@ -5,4 +5,5 @@ CONFIG_NR_DRAM_BANKS=1
> > >  CONFIG_FIT=y
> > >  CONFIG_DISPLAY_CPUINFO=y
> > >  CONFIG_DISPLAY_BOARDINFO=y
> > > +CONFIG_HUSH_PARSER=y
> > >  CONFIG_OF_PRIOR_STAGE=y
> > > diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-
> > > riscv.h
> > > index ba6a18f2e6..7c88ba300a 100644
> > > --- a/include/configs/qemu-riscv.h
> > > +++ b/include/configs/qemu-riscv.h
> > > @@ -21,7 +21,15 @@
> > >  #define CONFIG_ENV_SIZE			SZ_4K
> > >  
> > >  #define CONFIG_EXTRA_ENV_SETTINGS \
> > > -	"fdt_high=0xffffffffffffffff\0" \
> > > +	"fdt_high=0x82000000\0" \
> > > +	"bootm_size=0x10000000\0" \
> > >  	"initrd_high=0xffffffffffffffff\0"
> > >  
> > > +#define CONFIG_BOOTCOMMAND \
> > > +	"if env exists kernel_start; then " \
> > > +		"bootm ${kernel_start} - ${prior_stage_dtb};" \
> > 
> > As Alexander Graf pointed out in reply to patch 24, we don't need
> > the
> > separate environment variable "prior_stage_dtb". I will replace it
> > with
> > "fdtcontroladdr" here and drop patch 24 in the next version.
> 
> Also, can you please enable distro boot? :)
> 
> 
> Thanks,
> 
> Alex

I just had a closer look at distro boot and it's actually quite easy to
use. I will update this patch to enable it and will add a bootcmd for
virtio block devices (virtio support is currently in u-boot-dm/next).

I was looking into testing bootefi on U-Boot and tried to run the hello
world and selftest EFI binaries, however I could not get them running.
After starting them I immediately get a load access fault. The faulting
instruction is at 0xfe77c1fa, which is strange since the binary is
loaded to 0x80200000. Do you know what this could be caused by?
Also note that I completed the list of exception codes in this patch
series. U-Boot master will not indicate this exception occurred.

Thanks,
Lukas
Alexander Graf Nov. 3, 2018, 7:33 p.m. UTC | #5
On 03.11.18 18:07, Auer, Lukas wrote:
> On Tue, 2018-10-30 at 16:27 +0100, Alexander Graf wrote:
>>
>> On 30.10.18 16:02, Auer, Lukas wrote:
>>> On Tue, 2018-10-30 at 13:55 +0100, Lukas Auer wrote:
>>>> QEMU embeds the location of the kernel image in the device tree.
>>>> Store
>>>> this address in the environment as variable kernel_start and use
>>>> it
>>>> in
>>>> CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed
>>>> by
>>>> the
>>>> prior boot stage to boot Linux.
>>>>
>>>> Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
>>>> ---
>>>>
>>>> Changes in v2:
>>>> - Rebase onto u-boot-dm/next
>>>> - Boot Linux with the device tree provided by the prior boot
>>>> stage
>>>>
>>>>  board/emulation/qemu-riscv/Kconfig      |  1 +
>>>>  board/emulation/qemu-riscv/qemu-riscv.c | 29
>>>> +++++++++++++++++++++++++
>>>>  configs/qemu-riscv32_defconfig          |  1 +
>>>>  configs/qemu-riscv64_defconfig          |  1 +
>>>>  include/configs/qemu-riscv.h            | 10 ++++++++-
>>>>  5 files changed, 41 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/board/emulation/qemu-riscv/Kconfig
>>>> b/board/emulation/qemu-riscv/Kconfig
>>>> index 37a80db6a9..be5839b7db 100644
>>>> --- a/board/emulation/qemu-riscv/Kconfig
>>>> +++ b/board/emulation/qemu-riscv/Kconfig
>>>> @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>>>>  	imply CMD_EXT2
>>>>  	imply CMD_EXT4
>>>>  	imply CMD_FAT
>>>> +	imply BOARD_LATE_INIT
>>>>  
>>>>  endif
>>>> diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
>>>> b/board/emulation/qemu-riscv/qemu-riscv.c
>>>> index 2ce093e19a..ee20983095 100644
>>>> --- a/board/emulation/qemu-riscv/qemu-riscv.c
>>>> +++ b/board/emulation/qemu-riscv/qemu-riscv.c
>>>> @@ -19,3 +19,32 @@ int board_init(void)
>>>>  
>>>>  	return 0;
>>>>  }
>>>> +
>>>> +int board_late_init(void)
>>>> +{
>>>> +	ulong kernel_start;
>>>> +	ofnode chosen_node;
>>>> +	int ret;
>>>> +
>>>> +	chosen_node = ofnode_path("/chosen");
>>>> +	if (!ofnode_valid(chosen_node)) {
>>>> +		printf("No chosen node found\n");
>>>> +		return 0;
>>>> +	}
>>>> +
>>>> +#ifdef CONFIG_ARCH_RV64I
>>>> +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
>>>> +			      (u64 *)&kernel_start);
>>>> +#else
>>>> +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
>>>> +			      (u32 *)&kernel_start);
>>>> +#endif
>>>> +	if (ret) {
>>>> +		printf("Can't find kernel start address in device
>>>> tree\n");
>>>> +		return 0;
>>>> +	}
>>>> +
>>>> +	env_set_hex("kernel_start", kernel_start);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-
>>>> riscv32_defconfig
>>>> index b55644378a..13dd53a550 100644
>>>> --- a/configs/qemu-riscv32_defconfig
>>>> +++ b/configs/qemu-riscv32_defconfig
>>>> @@ -4,4 +4,5 @@ CONFIG_NR_DRAM_BANKS=1
>>>>  CONFIG_FIT=y
>>>>  CONFIG_DISPLAY_CPUINFO=y
>>>>  CONFIG_DISPLAY_BOARDINFO=y
>>>> +CONFIG_HUSH_PARSER=y
>>>>  CONFIG_OF_PRIOR_STAGE=y
>>>> diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-
>>>> riscv64_defconfig
>>>> index a542ac4893..06eb3042fa 100644
>>>> --- a/configs/qemu-riscv64_defconfig
>>>> +++ b/configs/qemu-riscv64_defconfig
>>>> @@ -5,4 +5,5 @@ CONFIG_NR_DRAM_BANKS=1
>>>>  CONFIG_FIT=y
>>>>  CONFIG_DISPLAY_CPUINFO=y
>>>>  CONFIG_DISPLAY_BOARDINFO=y
>>>> +CONFIG_HUSH_PARSER=y
>>>>  CONFIG_OF_PRIOR_STAGE=y
>>>> diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-
>>>> riscv.h
>>>> index ba6a18f2e6..7c88ba300a 100644
>>>> --- a/include/configs/qemu-riscv.h
>>>> +++ b/include/configs/qemu-riscv.h
>>>> @@ -21,7 +21,15 @@
>>>>  #define CONFIG_ENV_SIZE			SZ_4K
>>>>  
>>>>  #define CONFIG_EXTRA_ENV_SETTINGS \
>>>> -	"fdt_high=0xffffffffffffffff\0" \
>>>> +	"fdt_high=0x82000000\0" \
>>>> +	"bootm_size=0x10000000\0" \
>>>>  	"initrd_high=0xffffffffffffffff\0"
>>>>  
>>>> +#define CONFIG_BOOTCOMMAND \
>>>> +	"if env exists kernel_start; then " \
>>>> +		"bootm ${kernel_start} - ${prior_stage_dtb};" \
>>>
>>> As Alexander Graf pointed out in reply to patch 24, we don't need
>>> the
>>> separate environment variable "prior_stage_dtb". I will replace it
>>> with
>>> "fdtcontroladdr" here and drop patch 24 in the next version.
>>
>> Also, can you please enable distro boot? :)
>>
>>
>> Thanks,
>>
>> Alex
> 
> I just had a closer look at distro boot and it's actually quite easy to
> use. I will update this patch to enable it and will add a bootcmd for
> virtio block devices (virtio support is currently in u-boot-dm/next).
> 
> I was looking into testing bootefi on U-Boot and tried to run the hello
> world and selftest EFI binaries, however I could not get them running.
> After starting them I immediately get a load access fault. The faulting
> instruction is at 0xfe77c1fa, which is strange since the binary is
> loaded to 0x80200000. Do you know what this could be caused by?

I'm not quite sure yet what goes wrong. I tested and verified the riscv
uefi port on andes targets (where at least grub still works), but I can
confirm that the same code just falls apart for me on the qemu target.

Any help to debug it down a bit further is much appreciated.

> Also note that I completed the list of exception codes in this patch
> series. U-Boot master will not indicate this exception occurred.

Ah nice, that will definitely help to debug what's going wrong :).


Alex
Lukas Auer Nov. 4, 2018, 12:52 p.m. UTC | #6
On Sat, 2018-11-03 at 20:33 +0100, Alexander Graf wrote:
> 
> On 03.11.18 18:07, Auer, Lukas wrote:
> > On Tue, 2018-10-30 at 16:27 +0100, Alexander Graf wrote:
> > > 
> > > On 30.10.18 16:02, Auer, Lukas wrote:
> > > > On Tue, 2018-10-30 at 13:55 +0100, Lukas Auer wrote:
> > > > > QEMU embeds the location of the kernel image in the device
> > > > > tree.
> > > > > Store
> > > > > this address in the environment as variable kernel_start and
> > > > > use
> > > > > it
> > > > > in
> > > > > CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree
> > > > > passed
> > > > > by
> > > > > the
> > > > > prior boot stage to boot Linux.
> > > > > 
> > > > > Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> > > > > ---
> > > > > 
> > > > > Changes in v2:
> > > > > - Rebase onto u-boot-dm/next
> > > > > - Boot Linux with the device tree provided by the prior boot
> > > > > stage
> > > > > 
> > > > >  board/emulation/qemu-riscv/Kconfig      |  1 +
> > > > >  board/emulation/qemu-riscv/qemu-riscv.c | 29
> > > > > +++++++++++++++++++++++++
> > > > >  configs/qemu-riscv32_defconfig          |  1 +
> > > > >  configs/qemu-riscv64_defconfig          |  1 +
> > > > >  include/configs/qemu-riscv.h            | 10 ++++++++-
> > > > >  5 files changed, 41 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/board/emulation/qemu-riscv/Kconfig
> > > > > b/board/emulation/qemu-riscv/Kconfig
> > > > > index 37a80db6a9..be5839b7db 100644
> > > > > --- a/board/emulation/qemu-riscv/Kconfig
> > > > > +++ b/board/emulation/qemu-riscv/Kconfig
> > > > > @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
> > > > >  	imply CMD_EXT2
> > > > >  	imply CMD_EXT4
> > > > >  	imply CMD_FAT
> > > > > +	imply BOARD_LATE_INIT
> > > > >  
> > > > >  endif
> > > > > diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
> > > > > b/board/emulation/qemu-riscv/qemu-riscv.c
> > > > > index 2ce093e19a..ee20983095 100644
> > > > > --- a/board/emulation/qemu-riscv/qemu-riscv.c
> > > > > +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> > > > > @@ -19,3 +19,32 @@ int board_init(void)
> > > > >  
> > > > >  	return 0;
> > > > >  }
> > > > > +
> > > > > +int board_late_init(void)
> > > > > +{
> > > > > +	ulong kernel_start;
> > > > > +	ofnode chosen_node;
> > > > > +	int ret;
> > > > > +
> > > > > +	chosen_node = ofnode_path("/chosen");
> > > > > +	if (!ofnode_valid(chosen_node)) {
> > > > > +		printf("No chosen node found\n");
> > > > > +		return 0;
> > > > > +	}
> > > > > +
> > > > > +#ifdef CONFIG_ARCH_RV64I
> > > > > +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-
> > > > > start",
> > > > > +			      (u64 *)&kernel_start);
> > > > > +#else
> > > > > +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-
> > > > > start",
> > > > > +			      (u32 *)&kernel_start);
> > > > > +#endif
> > > > > +	if (ret) {
> > > > > +		printf("Can't find kernel start address in
> > > > > device
> > > > > tree\n");
> > > > > +		return 0;
> > > > > +	}
> > > > > +
> > > > > +	env_set_hex("kernel_start", kernel_start);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-
> > > > > riscv32_defconfig
> > > > > index b55644378a..13dd53a550 100644
> > > > > --- a/configs/qemu-riscv32_defconfig
> > > > > +++ b/configs/qemu-riscv32_defconfig
> > > > > @@ -4,4 +4,5 @@ CONFIG_NR_DRAM_BANKS=1
> > > > >  CONFIG_FIT=y
> > > > >  CONFIG_DISPLAY_CPUINFO=y
> > > > >  CONFIG_DISPLAY_BOARDINFO=y
> > > > > +CONFIG_HUSH_PARSER=y
> > > > >  CONFIG_OF_PRIOR_STAGE=y
> > > > > diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-
> > > > > riscv64_defconfig
> > > > > index a542ac4893..06eb3042fa 100644
> > > > > --- a/configs/qemu-riscv64_defconfig
> > > > > +++ b/configs/qemu-riscv64_defconfig
> > > > > @@ -5,4 +5,5 @@ CONFIG_NR_DRAM_BANKS=1
> > > > >  CONFIG_FIT=y
> > > > >  CONFIG_DISPLAY_CPUINFO=y
> > > > >  CONFIG_DISPLAY_BOARDINFO=y
> > > > > +CONFIG_HUSH_PARSER=y
> > > > >  CONFIG_OF_PRIOR_STAGE=y
> > > > > diff --git a/include/configs/qemu-riscv.h
> > > > > b/include/configs/qemu-
> > > > > riscv.h
> > > > > index ba6a18f2e6..7c88ba300a 100644
> > > > > --- a/include/configs/qemu-riscv.h
> > > > > +++ b/include/configs/qemu-riscv.h
> > > > > @@ -21,7 +21,15 @@
> > > > >  #define CONFIG_ENV_SIZE			SZ_4K
> > > > >  
> > > > >  #define CONFIG_EXTRA_ENV_SETTINGS \
> > > > > -	"fdt_high=0xffffffffffffffff\0" \
> > > > > +	"fdt_high=0x82000000\0" \
> > > > > +	"bootm_size=0x10000000\0" \
> > > > >  	"initrd_high=0xffffffffffffffff\0"
> > > > >  
> > > > > +#define CONFIG_BOOTCOMMAND \
> > > > > +	"if env exists kernel_start; then " \
> > > > > +		"bootm ${kernel_start} - ${prior_stage_dtb};" \
> > > > 
> > > > As Alexander Graf pointed out in reply to patch 24, we don't
> > > > need
> > > > the
> > > > separate environment variable "prior_stage_dtb". I will replace
> > > > it
> > > > with
> > > > "fdtcontroladdr" here and drop patch 24 in the next version.
> > > 
> > > Also, can you please enable distro boot? :)
> > > 
> > > 
> > > Thanks,
> > > 
> > > Alex
> > 
> > I just had a closer look at distro boot and it's actually quite
> > easy to
> > use. I will update this patch to enable it and will add a bootcmd
> > for
> > virtio block devices (virtio support is currently in u-boot-
> > dm/next).
> > 
> > I was looking into testing bootefi on U-Boot and tried to run the
> > hello
> > world and selftest EFI binaries, however I could not get them
> > running.
> > After starting them I immediately get a load access fault. The
> > faulting
> > instruction is at 0xfe77c1fa, which is strange since the binary is
> > loaded to 0x80200000. Do you know what this could be caused by?
> 
> I'm not quite sure yet what goes wrong. I tested and verified the
> riscv
> uefi port on andes targets (where at least grub still works), but I
> can
> confirm that the same code just falls apart for me on the qemu
> target.
> 
> Any help to debug it down a bit further is much appreciated.
> 

I started to narrow it down further. The hello EFI application faults
at the very beginning of its efi_main. The first thing it does is to
print "Hello World". For that, it needs the con_out protocol from the
systable. This is where it goes wrong. con_out is listed to be at
0x17ffd8638, which is above the available system memory. Once it is
accessed, the system throws the load access fault.
So, I think something with the relocation of the systable entries does
not work.

Thanks,
Lukas

> > Also note that I completed the list of exception codes in this
> > patch
> > series. U-Boot master will not indicate this exception occurred.
> 
> Ah nice, that will definitely help to debug what's going wrong :).
> 
> 
> Alex
Bin Meng Nov. 4, 2018, 2:39 p.m. UTC | #7
Hi Lukas,

On Tue, Oct 30, 2018 at 8:57 PM Lukas Auer
<lukas.auer@aisec.fraunhofer.de> wrote:
>
> QEMU embeds the location of the kernel image in the device tree. Store
> this address in the environment as variable kernel_start and use it in
> CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed by the
> prior boot stage to boot Linux.
>
> Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> ---
>
> Changes in v2:
> - Rebase onto u-boot-dm/next
> - Boot Linux with the device tree provided by the prior boot stage
>
>  board/emulation/qemu-riscv/Kconfig      |  1 +
>  board/emulation/qemu-riscv/qemu-riscv.c | 29 +++++++++++++++++++++++++
>  configs/qemu-riscv32_defconfig          |  1 +
>  configs/qemu-riscv64_defconfig          |  1 +
>  include/configs/qemu-riscv.h            | 10 ++++++++-
>  5 files changed, 41 insertions(+), 1 deletion(-)
>
> diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
> index 37a80db6a9..be5839b7db 100644
> --- a/board/emulation/qemu-riscv/Kconfig
> +++ b/board/emulation/qemu-riscv/Kconfig
> @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>         imply CMD_EXT2
>         imply CMD_EXT4
>         imply CMD_FAT
> +       imply BOARD_LATE_INIT
>
>  endif
> diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
> index 2ce093e19a..ee20983095 100644
> --- a/board/emulation/qemu-riscv/qemu-riscv.c
> +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> @@ -19,3 +19,32 @@ int board_init(void)
>
>         return 0;
>  }
> +
> +int board_late_init(void)
> +{
> +       ulong kernel_start;
> +       ofnode chosen_node;
> +       int ret;
> +
> +       chosen_node = ofnode_path("/chosen");
> +       if (!ofnode_valid(chosen_node)) {
> +               printf("No chosen node found\n");
> +               return 0;
> +       }
> +
> +#ifdef CONFIG_ARCH_RV64I
> +       ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
> +                             (u64 *)&kernel_start);
> +#else
> +       ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
> +                             (u32 *)&kernel_start);
> +#endif
> +       if (ret) {
> +               printf("Can't find kernel start address in device tree\n");

I think we need use 'debug' instead of 'printf' here, for situation
that kernel is not passed to QEMU.

> +               return 0;
> +       }
> +
> +       env_set_hex("kernel_start", kernel_start);
> +
> +       return 0;
> +}

[snip]

Regards,
Bin
Lukas Auer Nov. 4, 2018, 7:41 p.m. UTC | #8
Hi Bin,

On Sun, 2018-11-04 at 22:39 +0800, Bin Meng wrote:
> Hi Lukas,
> 
> On Tue, Oct 30, 2018 at 8:57 PM Lukas Auer
> <lukas.auer@aisec.fraunhofer.de> wrote:
> > 
> > QEMU embeds the location of the kernel image in the device tree.
> > Store
> > this address in the environment as variable kernel_start and use it
> > in
> > CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree passed
> > by the
> > prior boot stage to boot Linux.
> > 
> > Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> > ---
> > 
> > Changes in v2:
> > - Rebase onto u-boot-dm/next
> > - Boot Linux with the device tree provided by the prior boot stage
> > 
> >  board/emulation/qemu-riscv/Kconfig      |  1 +
> >  board/emulation/qemu-riscv/qemu-riscv.c | 29
> > +++++++++++++++++++++++++
> >  configs/qemu-riscv32_defconfig          |  1 +
> >  configs/qemu-riscv64_defconfig          |  1 +
> >  include/configs/qemu-riscv.h            | 10 ++++++++-
> >  5 files changed, 41 insertions(+), 1 deletion(-)
> > 
> > diff --git a/board/emulation/qemu-riscv/Kconfig
> > b/board/emulation/qemu-riscv/Kconfig
> > index 37a80db6a9..be5839b7db 100644
> > --- a/board/emulation/qemu-riscv/Kconfig
> > +++ b/board/emulation/qemu-riscv/Kconfig
> > @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
> >         imply CMD_EXT2
> >         imply CMD_EXT4
> >         imply CMD_FAT
> > +       imply BOARD_LATE_INIT
> > 
> >  endif
> > diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
> > b/board/emulation/qemu-riscv/qemu-riscv.c
> > index 2ce093e19a..ee20983095 100644
> > --- a/board/emulation/qemu-riscv/qemu-riscv.c
> > +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> > @@ -19,3 +19,32 @@ int board_init(void)
> > 
> >         return 0;
> >  }
> > +
> > +int board_late_init(void)
> > +{
> > +       ulong kernel_start;
> > +       ofnode chosen_node;
> > +       int ret;
> > +
> > +       chosen_node = ofnode_path("/chosen");
> > +       if (!ofnode_valid(chosen_node)) {
> > +               printf("No chosen node found\n");
> > +               return 0;
> > +       }
> > +
> > +#ifdef CONFIG_ARCH_RV64I
> > +       ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
> > +                             (u64 *)&kernel_start);
> > +#else
> > +       ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
> > +                             (u32 *)&kernel_start);
> > +#endif
> > +       if (ret) {
> > +               printf("Can't find kernel start address in device
> > tree\n");
> 
> I think we need use 'debug' instead of 'printf' here, for situation
> that kernel is not passed to QEMU.
> 

Yes, you are right. What is the current best-practice here? Should I
use one of the pr_* functions or just debug?

Looking at the function, I am also not sure how useful the printf above
is (no chosen node found). I could replace it with the same text as in
the last printf. What do you think?

Thanks,
Lukas

> > +               return 0;
> > +       }
> > +
> > +       env_set_hex("kernel_start", kernel_start);
> > +
> > +       return 0;
> > +}
> 
> [snip]
> 
> Regards,
> Bin
Alexander Graf Nov. 4, 2018, 9:19 p.m. UTC | #9
On 04.11.18 13:52, Auer, Lukas wrote:
> On Sat, 2018-11-03 at 20:33 +0100, Alexander Graf wrote:
>>
>> On 03.11.18 18:07, Auer, Lukas wrote:
>>> On Tue, 2018-10-30 at 16:27 +0100, Alexander Graf wrote:
>>>>
>>>> On 30.10.18 16:02, Auer, Lukas wrote:
>>>>> On Tue, 2018-10-30 at 13:55 +0100, Lukas Auer wrote:
>>>>>> QEMU embeds the location of the kernel image in the device
>>>>>> tree.
>>>>>> Store
>>>>>> this address in the environment as variable kernel_start and
>>>>>> use
>>>>>> it
>>>>>> in
>>>>>> CONFIG_BOOTCOMMAND to boot the kernel. Use the device tree
>>>>>> passed
>>>>>> by
>>>>>> the
>>>>>> prior boot stage to boot Linux.
>>>>>>
>>>>>> Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
>>>>>> ---
>>>>>>
>>>>>> Changes in v2:
>>>>>> - Rebase onto u-boot-dm/next
>>>>>> - Boot Linux with the device tree provided by the prior boot
>>>>>> stage
>>>>>>
>>>>>>  board/emulation/qemu-riscv/Kconfig      |  1 +
>>>>>>  board/emulation/qemu-riscv/qemu-riscv.c | 29
>>>>>> +++++++++++++++++++++++++
>>>>>>  configs/qemu-riscv32_defconfig          |  1 +
>>>>>>  configs/qemu-riscv64_defconfig          |  1 +
>>>>>>  include/configs/qemu-riscv.h            | 10 ++++++++-
>>>>>>  5 files changed, 41 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/board/emulation/qemu-riscv/Kconfig
>>>>>> b/board/emulation/qemu-riscv/Kconfig
>>>>>> index 37a80db6a9..be5839b7db 100644
>>>>>> --- a/board/emulation/qemu-riscv/Kconfig
>>>>>> +++ b/board/emulation/qemu-riscv/Kconfig
>>>>>> @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>>>>>>  	imply CMD_EXT2
>>>>>>  	imply CMD_EXT4
>>>>>>  	imply CMD_FAT
>>>>>> +	imply BOARD_LATE_INIT
>>>>>>  
>>>>>>  endif
>>>>>> diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
>>>>>> b/board/emulation/qemu-riscv/qemu-riscv.c
>>>>>> index 2ce093e19a..ee20983095 100644
>>>>>> --- a/board/emulation/qemu-riscv/qemu-riscv.c
>>>>>> +++ b/board/emulation/qemu-riscv/qemu-riscv.c
>>>>>> @@ -19,3 +19,32 @@ int board_init(void)
>>>>>>  
>>>>>>  	return 0;
>>>>>>  }
>>>>>> +
>>>>>> +int board_late_init(void)
>>>>>> +{
>>>>>> +	ulong kernel_start;
>>>>>> +	ofnode chosen_node;
>>>>>> +	int ret;
>>>>>> +
>>>>>> +	chosen_node = ofnode_path("/chosen");
>>>>>> +	if (!ofnode_valid(chosen_node)) {
>>>>>> +		printf("No chosen node found\n");
>>>>>> +		return 0;
>>>>>> +	}
>>>>>> +
>>>>>> +#ifdef CONFIG_ARCH_RV64I
>>>>>> +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-
>>>>>> start",
>>>>>> +			      (u64 *)&kernel_start);
>>>>>> +#else
>>>>>> +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-
>>>>>> start",
>>>>>> +			      (u32 *)&kernel_start);
>>>>>> +#endif
>>>>>> +	if (ret) {
>>>>>> +		printf("Can't find kernel start address in
>>>>>> device
>>>>>> tree\n");
>>>>>> +		return 0;
>>>>>> +	}
>>>>>> +
>>>>>> +	env_set_hex("kernel_start", kernel_start);
>>>>>> +
>>>>>> +	return 0;
>>>>>> +}
>>>>>> diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-
>>>>>> riscv32_defconfig
>>>>>> index b55644378a..13dd53a550 100644
>>>>>> --- a/configs/qemu-riscv32_defconfig
>>>>>> +++ b/configs/qemu-riscv32_defconfig
>>>>>> @@ -4,4 +4,5 @@ CONFIG_NR_DRAM_BANKS=1
>>>>>>  CONFIG_FIT=y
>>>>>>  CONFIG_DISPLAY_CPUINFO=y
>>>>>>  CONFIG_DISPLAY_BOARDINFO=y
>>>>>> +CONFIG_HUSH_PARSER=y
>>>>>>  CONFIG_OF_PRIOR_STAGE=y
>>>>>> diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-
>>>>>> riscv64_defconfig
>>>>>> index a542ac4893..06eb3042fa 100644
>>>>>> --- a/configs/qemu-riscv64_defconfig
>>>>>> +++ b/configs/qemu-riscv64_defconfig
>>>>>> @@ -5,4 +5,5 @@ CONFIG_NR_DRAM_BANKS=1
>>>>>>  CONFIG_FIT=y
>>>>>>  CONFIG_DISPLAY_CPUINFO=y
>>>>>>  CONFIG_DISPLAY_BOARDINFO=y
>>>>>> +CONFIG_HUSH_PARSER=y
>>>>>>  CONFIG_OF_PRIOR_STAGE=y
>>>>>> diff --git a/include/configs/qemu-riscv.h
>>>>>> b/include/configs/qemu-
>>>>>> riscv.h
>>>>>> index ba6a18f2e6..7c88ba300a 100644
>>>>>> --- a/include/configs/qemu-riscv.h
>>>>>> +++ b/include/configs/qemu-riscv.h
>>>>>> @@ -21,7 +21,15 @@
>>>>>>  #define CONFIG_ENV_SIZE			SZ_4K
>>>>>>  
>>>>>>  #define CONFIG_EXTRA_ENV_SETTINGS \
>>>>>> -	"fdt_high=0xffffffffffffffff\0" \
>>>>>> +	"fdt_high=0x82000000\0" \
>>>>>> +	"bootm_size=0x10000000\0" \
>>>>>>  	"initrd_high=0xffffffffffffffff\0"
>>>>>>  
>>>>>> +#define CONFIG_BOOTCOMMAND \
>>>>>> +	"if env exists kernel_start; then " \
>>>>>> +		"bootm ${kernel_start} - ${prior_stage_dtb};" \
>>>>>
>>>>> As Alexander Graf pointed out in reply to patch 24, we don't
>>>>> need
>>>>> the
>>>>> separate environment variable "prior_stage_dtb". I will replace
>>>>> it
>>>>> with
>>>>> "fdtcontroladdr" here and drop patch 24 in the next version.
>>>>
>>>> Also, can you please enable distro boot? :)
>>>>
>>>>
>>>> Thanks,
>>>>
>>>> Alex
>>>
>>> I just had a closer look at distro boot and it's actually quite
>>> easy to
>>> use. I will update this patch to enable it and will add a bootcmd
>>> for
>>> virtio block devices (virtio support is currently in u-boot-
>>> dm/next).
>>>
>>> I was looking into testing bootefi on U-Boot and tried to run the
>>> hello
>>> world and selftest EFI binaries, however I could not get them
>>> running.
>>> After starting them I immediately get a load access fault. The
>>> faulting
>>> instruction is at 0xfe77c1fa, which is strange since the binary is
>>> loaded to 0x80200000. Do you know what this could be caused by?
>>
>> I'm not quite sure yet what goes wrong. I tested and verified the
>> riscv
>> uefi port on andes targets (where at least grub still works), but I
>> can
>> confirm that the same code just falls apart for me on the qemu
>> target.
>>
>> Any help to debug it down a bit further is much appreciated.
>>
> 
> I started to narrow it down further. The hello EFI application faults
> at the very beginning of its efi_main. The first thing it does is to
> print "Hello World". For that, it needs the con_out protocol from the
> systable. This is where it goes wrong. con_out is listed to be at
> 0x17ffd8638, which is above the available system memory. Once it is
> accessed, the system throws the load access fault.
> So, I think something with the relocation of the systable entries does
> not work.

Thanks for digging it to that. Relocations for runtime code are broken
(efi_runtime_relocate()). The R_ABSOLUTE path doesn't properly handle
dynsyms.


Alex
diff mbox series

Patch

diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
index 37a80db6a9..be5839b7db 100644
--- a/board/emulation/qemu-riscv/Kconfig
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -29,5 +29,6 @@  config BOARD_SPECIFIC_OPTIONS # dummy
 	imply CMD_EXT2
 	imply CMD_EXT4
 	imply CMD_FAT
+	imply BOARD_LATE_INIT
 
 endif
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
index 2ce093e19a..ee20983095 100644
--- a/board/emulation/qemu-riscv/qemu-riscv.c
+++ b/board/emulation/qemu-riscv/qemu-riscv.c
@@ -19,3 +19,32 @@  int board_init(void)
 
 	return 0;
 }
+
+int board_late_init(void)
+{
+	ulong kernel_start;
+	ofnode chosen_node;
+	int ret;
+
+	chosen_node = ofnode_path("/chosen");
+	if (!ofnode_valid(chosen_node)) {
+		printf("No chosen node found\n");
+		return 0;
+	}
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
+			      (u64 *)&kernel_start);
+#else
+	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
+			      (u32 *)&kernel_start);
+#endif
+	if (ret) {
+		printf("Can't find kernel start address in device tree\n");
+		return 0;
+	}
+
+	env_set_hex("kernel_start", kernel_start);
+
+	return 0;
+}
diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig
index b55644378a..13dd53a550 100644
--- a/configs/qemu-riscv32_defconfig
+++ b/configs/qemu-riscv32_defconfig
@@ -4,4 +4,5 @@  CONFIG_NR_DRAM_BANKS=1
 CONFIG_FIT=y
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_HUSH_PARSER=y
 CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig
index a542ac4893..06eb3042fa 100644
--- a/configs/qemu-riscv64_defconfig
+++ b/configs/qemu-riscv64_defconfig
@@ -5,4 +5,5 @@  CONFIG_NR_DRAM_BANKS=1
 CONFIG_FIT=y
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_HUSH_PARSER=y
 CONFIG_OF_PRIOR_STAGE=y
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index ba6a18f2e6..7c88ba300a 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -21,7 +21,15 @@ 
 #define CONFIG_ENV_SIZE			SZ_4K
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
-	"fdt_high=0xffffffffffffffff\0" \
+	"fdt_high=0x82000000\0" \
+	"bootm_size=0x10000000\0" \
 	"initrd_high=0xffffffffffffffff\0"
 
+#define CONFIG_BOOTCOMMAND \
+	"if env exists kernel_start; then " \
+		"bootm ${kernel_start} - ${prior_stage_dtb};" \
+	"else " \
+		"echo Kernel address not found in the device tree;" \
+	"fi;"
+
 #endif /* __CONFIG_H */