[PATCH 0/7] Add support for CONFIG_API on RISC-V

From: Mitchell Horne mhorne@FreeBSD.org
FreeBSD makes use of u-boot's CONFIG_API to provide a version of its standard bootloader for embedded architectures. This series adds the necessary support for the RISC-V architecture, along with some small fixes to the API demo program for 64-bit systems.
Mitchell Horne (7): examples: generate demo.bin examples: rename __start to _start on MIPS examples: add a linker script for the API demo examples: fix the type of search_hint examples: fix incompatible type casts riscv: add CONFIG_API support api: enumerate virtio-blk devices
api/Makefile | 1 + api/api_platform-riscv.c | 33 +++++++++++++++++++++++++++++++++ api/api_storage.c | 14 +++++++++++++- examples/api/Makefile | 10 +++++++--- examples/api/crt0.S | 25 +++++++++++++++++++++---- examples/api/demo.c | 21 +++++++++++---------- examples/api/demo.lds | 14 ++++++++++++++ examples/api/glue.c | 6 +++--- examples/api/glue.h | 2 +- include/api_public.h | 1 + 10 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 api/api_platform-riscv.c create mode 100644 examples/api/demo.lds

From: Mitchell Horne mhorne@FreeBSD.org
The CONFIG_API option builds the example program, examples/api/demo, as an ELF file. The make logic exists to create a binary as well, so add the target to do so.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org --- examples/api/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/examples/api/Makefile b/examples/api/Makefile index ca4eb1f71a..9ff793206f 100644 --- a/examples/api/Makefile +++ b/examples/api/Makefile @@ -20,7 +20,7 @@ endif endif
# Resulting ELF and binary exectuables will be named demo and demo.bin -extra-y = demo +extra-y = demo demo.bin
# Source files located in the examples/api directory OBJ-y += crt0.o @@ -56,7 +56,6 @@ cmd_link_demo = $(LD) --gc-sections -Ttext $(LOAD_ADDR) -o $@ $(filter-out $(PHO $(obj)/demo: $(OBJS) FORCE $(call if_changed,link_demo)
-# demo.bin is never genrated. Is this necessary? OBJCOPYFLAGS_demo.bin := -O binary $(obj)/demo.bin: $(obj)/demo FORCE $(call if_changed,objcopy)

On Tue, Apr 21, 2020 at 7:27 AM mhorne@freebsd.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
The CONFIG_API option builds the example program, examples/api/demo, as an ELF file. The make logic exists to create a binary as well, so add the target to do so.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org
examples/api/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

From: Mitchell Horne mhorne@FreeBSD.org
On MIPS, __start marks the entry point to the CONFIG_API demo program. Change the name to _start, to be consistent with all other architectures.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org --- examples/api/crt0.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/examples/api/crt0.S b/examples/api/crt0.S index 57bba9d851..2f75f5a036 100644 --- a/examples/api/crt0.S +++ b/examples/api/crt0.S @@ -42,12 +42,12 @@ syscall: #elif defined(CONFIG_MIPS) #include <asm/asm.h> .text - .globl __start - .ent __start -__start: + .globl _start + .ent _start +_start: PTR_S $sp, search_hint b main - .end __start + .end _start
.globl syscall .ent syscall

On Tue, Apr 21, 2020 at 7:28 AM mhorne@freebsd.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
On MIPS, __start marks the entry point to the CONFIG_API demo program. Change the name to _start, to be consistent with all other architectures.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org
examples/api/crt0.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

+cc Wolfgang, Tom
Am 21.04.20 um 00:34 schrieb mhorne@FreeBSD.org:
From: Mitchell Horne mhorne@FreeBSD.org
On MIPS, __start marks the entry point to the CONFIG_API demo program. Change the name to _start, to be consistent with all other architectures.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org
examples/api/crt0.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/examples/api/crt0.S b/examples/api/crt0.S index 57bba9d851..2f75f5a036 100644 --- a/examples/api/crt0.S +++ b/examples/api/crt0.S @@ -42,12 +42,12 @@ syscall: #elif defined(CONFIG_MIPS) #include <asm/asm.h> .text
- .globl __start
- .ent __start
-__start:
- .globl _start
- .ent _start
+_start: PTR_S $sp, search_hint b main
- .end __start
.end _start
.globl syscall .ent syscall
__start is used by the default binutils linker script for MIPS. For a test you could simply do a "make malta_defconfig", enable CONFIG_API via menuconfig and build. Without this patch you'll get:
$ /opt/gcc-9.2.0-nolibc/mips-linux/bin/mips-linux-readelf -s examples/api/demo | grep __start 64: 80200700 16 FUNC GLOBAL DEFAULT 1 __start
But with this patch __start will now an unresolved symbol:
$ /opt/gcc-9.2.0-nolibc/mips-linux/bin/mips-linux-readelf -s examples/api/demo | grep __start 19: 00000000 0 NOTYPE GLOBAL DEFAULT UND __start
But I'm not sure if the original intention was to use the default linker script or the one provided by U-Boot and if examples/api/ should use the same compiler and linker flags as example/standalone/. Some archs have used a custom linker script. Maybe Wolfgang knows more?

Dear Daniel,
In message aad059da-bc2c-c991-4599-54c47a350dc8@gmail.com you wrote:
But I'm not sure if the original intention was to use the default linker script or the one provided by U-Boot and if examples/api/ should use the same compiler and linker flags as example/standalone/. Some archs have used a custom linker script. Maybe Wolfgang knows more?
Sorry, I can't remember resp. I think I never knew.
Best regards,
Wolfgang Denk

From: Mitchell Horne mhorne@FreeBSD.org
When compiling the API demo program, the first object file in the linker arguments is crt0.o, which contains the _start routine. This is done with the hope that it will appear first in the .text section, but the linker doesn't guarantee this behaviour.
Add a simple linker script that ensures this ordering. This fixes execution of the API demo binary for cases where _start was placed elsewhere in the .text section.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org --- examples/api/Makefile | 4 +++- examples/api/crt0.S | 2 ++ examples/api/demo.lds | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 examples/api/demo.lds
diff --git a/examples/api/Makefile b/examples/api/Makefile index 9ff793206f..8fa9c04118 100644 --- a/examples/api/Makefile +++ b/examples/api/Makefile @@ -48,10 +48,12 @@ OBJS := $(OBJ-y) $(notdir $(EXT_COBJ-y) $(EXT_SOBJ-y)) targets += $(OBJS) OBJS := $(addprefix $(obj)/,$(OBJS))
+LDS = $(obj)/demo.lds #########################################################################
quiet_cmd_link_demo = LD $@ -cmd_link_demo = $(LD) --gc-sections -Ttext $(LOAD_ADDR) -o $@ $(filter-out $(PHONY), $^) $(PLATFORM_LIBS) +cmd_link_demo = $(LD) --gc-sections -Ttext $(LOAD_ADDR) -T $(LDS) \ + -o $@ $(filter-out $(PHONY), $^) $(PLATFORM_LIBS)
$(obj)/demo: $(OBJS) FORCE $(call if_changed,link_demo) diff --git a/examples/api/crt0.S b/examples/api/crt0.S index 2f75f5a036..658bc59a82 100644 --- a/examples/api/crt0.S +++ b/examples/api/crt0.S @@ -62,12 +62,14 @@ syscall: .end syscall
return_addr: + .data .align 8 .long 0 #else #error No support for this arch! #endif
+ .data .globl syscall_ptr syscall_ptr: .align 8 diff --git a/examples/api/demo.lds b/examples/api/demo.lds new file mode 100644 index 0000000000..a6b88dedef --- /dev/null +++ b/examples/api/demo.lds @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Mitchell Horne mhorne@FreeBSD.org + */ + +ENTRY(_start) +SECTIONS +{ + .text : + { + *crt0.S(.text*) + *(.text*) + } +}

On Tue, Apr 21, 2020 at 7:28 AM mhorne@freebsd.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
When compiling the API demo program, the first object file in the linker arguments is crt0.o, which contains the _start routine. This is done with the hope that it will appear first in the .text section, but the linker doesn't guarantee this behaviour.
Add a simple linker script that ensures this ordering. This fixes execution of the API demo binary for cases where _start was placed elsewhere in the .text section.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org
examples/api/Makefile | 4 +++- examples/api/crt0.S | 2 ++ examples/api/demo.lds | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 examples/api/demo.lds
diff --git a/examples/api/Makefile b/examples/api/Makefile index 9ff793206f..8fa9c04118 100644 --- a/examples/api/Makefile +++ b/examples/api/Makefile @@ -48,10 +48,12 @@ OBJS := $(OBJ-y) $(notdir $(EXT_COBJ-y) $(EXT_SOBJ-y)) targets += $(OBJS) OBJS := $(addprefix $(obj)/,$(OBJS))
+LDS = $(obj)/demo.lds #########################################################################
quiet_cmd_link_demo = LD $@ -cmd_link_demo = $(LD) --gc-sections -Ttext $(LOAD_ADDR) -o $@ $(filter-out $(PHONY), $^) $(PLATFORM_LIBS) +cmd_link_demo = $(LD) --gc-sections -Ttext $(LOAD_ADDR) -T $(LDS) \
-o $@ $(filter-out $(PHONY), $^) $(PLATFORM_LIBS)
$(obj)/demo: $(OBJS) FORCE $(call if_changed,link_demo) diff --git a/examples/api/crt0.S b/examples/api/crt0.S index 2f75f5a036..658bc59a82 100644 --- a/examples/api/crt0.S +++ b/examples/api/crt0.S @@ -62,12 +62,14 @@ syscall: .end syscall
return_addr:
.data
I think we need put .data before return_addr: to make it clearer.
.align 8 .long 0
#else #error No support for this arch! #endif
.data
And changing these symbols should be a separate patch.
.globl syscall_ptr
syscall_ptr: .align 8
Regards, Bin

From: Mitchell Horne mhorne@FreeBSD.org
search_hint is defined in assembly as a .long, and is intended to hold the initial stack pointer as a hint to the api_search_sig() routine. Convert this to a uintptr_t, to avoid possible truncation on 64-bit systems.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org --- examples/api/glue.c | 6 +++--- examples/api/glue.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/examples/api/glue.c b/examples/api/glue.c index 91d13157a1..c223306319 100644 --- a/examples/api/glue.c +++ b/examples/api/glue.c @@ -42,8 +42,8 @@ static int valid_sig(struct api_signature *sig) int api_search_sig(struct api_signature **sig) { unsigned char *sp; - uint32_t search_start = 0; - uint32_t search_end = 0; + uintptr_t search_start = 0; + uintptr_t search_end = 0;
if (sig == NULL) return 0; @@ -51,7 +51,7 @@ int api_search_sig(struct api_signature **sig) if (search_hint == 0) search_hint = 255 * 1024 * 1024;
- search_start = search_hint & ~0x000fffff; + search_start = search_hint & ~0xffffful; search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN;
sp = (unsigned char *)search_start; diff --git a/examples/api/glue.h b/examples/api/glue.h index f9745604b6..dd662fc872 100644 --- a/examples/api/glue.h +++ b/examples/api/glue.h @@ -18,7 +18,7 @@ #define UB_MAX_DEV 6 /* max devices number */
extern void *syscall_ptr; -extern uint32_t search_hint; +extern unsigned long search_hint;
int syscall(int, int *, ...); int api_search_sig(struct api_signature **sig);

On Tue, Apr 21, 2020 at 7:28 AM mhorne@freebsd.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
search_hint is defined in assembly as a .long, and is intended to hold the initial stack pointer as a hint to the api_search_sig() routine. Convert this to a uintptr_t, to avoid possible truncation on 64-bit systems.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org
examples/api/glue.c | 6 +++--- examples/api/glue.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

From: Mitchell Horne mhorne@FreeBSD.org
Some printf statements in the API demo assume pointers to be 32-bits long, presumably since it was originally developed for 32-bit arm. This generates a number of warnings when compiling for 64-bit architectures, and may result in truncation of these values. Fix this by avoiding casts where possible or casting to a more appropriate type.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org --- examples/api/demo.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/examples/api/demo.c b/examples/api/demo.c index e7523786b4..f81466c5cf 100644 --- a/examples/api/demo.c +++ b/examples/api/demo.c @@ -43,12 +43,12 @@ int main(int argc, char * const argv[]) if (sig->version > API_SIG_VERSION) return -3;
- printf("API signature found @%x\n", (unsigned int)sig); + printf("API signature found @%lx\n", (uintptr_t)sig); test_dump_sig(sig);
printf("\n*** Consumer API test ***\n"); - printf("syscall ptr 0x%08x@%08x\n", (unsigned int)syscall_ptr, - (unsigned int)&syscall_ptr); + printf("syscall ptr 0x%08lx@%08lx\n", (uintptr_t)syscall_ptr, + (uintptr_t)&syscall_ptr);
/* console activities */ ub_putc('B'); @@ -203,7 +203,7 @@ void test_dump_sig(struct api_signature *sig) printf("signature:\n"); printf(" version\t= %d\n", sig->version); printf(" checksum\t= 0x%08x\n", sig->checksum); - printf(" sc entry\t= 0x%08x\n", (unsigned int)sig->syscall); + printf(" sc entry\t= 0x%08lx\n", (uintptr_t)sig->syscall); }
void test_dump_si(struct sys_info *si) @@ -211,9 +211,9 @@ void test_dump_si(struct sys_info *si) int i;
printf("sys info:\n"); - printf(" clkbus\t= 0x%08x\n", (unsigned int)si->clk_bus); - printf(" clkcpu\t= 0x%08x\n", (unsigned int)si->clk_cpu); - printf(" bar\t\t= 0x%08x\n", (unsigned int)si->bar); + printf(" clkbus\t= 0x%08lx\n", si->clk_bus); + printf(" clkcpu\t= 0x%08lx\n", si->clk_cpu); + printf(" bar\t\t= 0x%08lx\n", si->bar);
printf("---\n"); for (i = 0; i < si->mr_no; i++) { @@ -296,7 +296,7 @@ void test_dump_di(int handle) struct device_info *di = ub_dev_get(handle);
printf("device info (%d):\n", handle); - printf(" cookie\t= 0x%08x\n", (uint32_t)di->cookie); + printf(" cookie\t= 0x%08lx\n", (uintptr_t)di->cookie); printf(" type\t\t= 0x%08x\n", di->type);
if (di->type == DEV_TYP_NET) { @@ -308,7 +308,8 @@ void test_dump_di(int handle)
} else if (di->type & DEV_TYP_STOR) { printf(" type\t\t= %s\n", test_stor_typ(di->type)); - printf(" blk size\t\t= %d\n", (unsigned int)di->di_stor.block_size); - printf(" blk count\t\t= %d\n", (unsigned int)di->di_stor.block_count); + printf(" blk size\t\t= %lu\n", di->di_stor.block_size); + printf(" blk count\t\t= %llu\n", + (uint64_t)di->di_stor.block_count); } }

On Tue, Apr 21, 2020 at 7:28 AM mhorne@freebsd.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
Some printf statements in the API demo assume pointers to be 32-bits long, presumably since it was originally developed for 32-bit arm. This generates a number of warnings when compiling for 64-bit architectures, and may result in truncation of these values. Fix this by avoiding casts where possible or casting to a more appropriate type.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org
examples/api/demo.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/examples/api/demo.c b/examples/api/demo.c index e7523786b4..f81466c5cf 100644 --- a/examples/api/demo.c +++ b/examples/api/demo.c @@ -43,12 +43,12 @@ int main(int argc, char * const argv[]) if (sig->version > API_SIG_VERSION) return -3;
printf("API signature found @%x\n", (unsigned int)sig);
printf("API signature found @%lx\n", (uintptr_t)sig); test_dump_sig(sig); printf("\n*** Consumer API test ***\n");
printf("syscall ptr 0x%08x@%08x\n", (unsigned int)syscall_ptr,
(unsigned int)&syscall_ptr);
printf("syscall ptr 0x%08lx@%08lx\n", (uintptr_t)syscall_ptr,
(uintptr_t)&syscall_ptr); /* console activities */ ub_putc('B');
@@ -203,7 +203,7 @@ void test_dump_sig(struct api_signature *sig) printf("signature:\n"); printf(" version\t= %d\n", sig->version); printf(" checksum\t= 0x%08x\n", sig->checksum);
printf(" sc entry\t= 0x%08x\n", (unsigned int)sig->syscall);
printf(" sc entry\t= 0x%08lx\n", (uintptr_t)sig->syscall);
}
void test_dump_si(struct sys_info *si) @@ -211,9 +211,9 @@ void test_dump_si(struct sys_info *si) int i;
printf("sys info:\n");
printf(" clkbus\t= 0x%08x\n", (unsigned int)si->clk_bus);
printf(" clkcpu\t= 0x%08x\n", (unsigned int)si->clk_cpu);
printf(" bar\t\t= 0x%08x\n", (unsigned int)si->bar);
printf(" clkbus\t= 0x%08lx\n", si->clk_bus);
printf(" clkcpu\t= 0x%08lx\n", si->clk_cpu);
printf(" bar\t\t= 0x%08lx\n", si->bar); printf("---\n"); for (i = 0; i < si->mr_no; i++) {
@@ -296,7 +296,7 @@ void test_dump_di(int handle) struct device_info *di = ub_dev_get(handle);
printf("device info (%d):\n", handle);
printf(" cookie\t= 0x%08x\n", (uint32_t)di->cookie);
printf(" cookie\t= 0x%08lx\n", (uintptr_t)di->cookie); printf(" type\t\t= 0x%08x\n", di->type); if (di->type == DEV_TYP_NET) {
@@ -308,7 +308,8 @@ void test_dump_di(int handle)
} else if (di->type & DEV_TYP_STOR) { printf(" type\t\t= %s\n", test_stor_typ(di->type));
printf(" blk size\t\t= %d\n", (unsigned int)di->di_stor.block_size);
printf(" blk count\t\t= %d\n", (unsigned int)di->di_stor.block_count);
printf(" blk size\t\t= %lu\n", di->di_stor.block_size);
printf(" blk count\t\t= %llu\n",
Use LBAF from include/blk.h ?
Also I am not sure why CONFIG_SYS_64BIT_LBA is undefined in include/api_public.h ?
(uint64_t)di->di_stor.block_count); }
}
Regards, Bin

From: Mitchell Horne mhorne@FreeBSD.org
Add the necessary changes to allow building the CONFIG_API option on the RISC-V architecture. The downstream consumer of this API is the u-boot version of FreeBSD's loader(8). This enables the loader to be ported to RISC-V.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org Cc: rick@andestech.com Cc: bmeng.cn@gmail.com Cc: atish.patra@wdc.com --- api/Makefile | 1 + api/api_platform-riscv.c | 33 +++++++++++++++++++++++++++++++++ examples/api/Makefile | 3 +++ examples/api/crt0.S | 15 +++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 api/api_platform-riscv.c
diff --git a/api/Makefile b/api/Makefile index bd2d035fcd..737854e2c6 100644 --- a/api/Makefile +++ b/api/Makefile @@ -6,3 +6,4 @@ obj-y += api.o api_display.o api_net.o api_storage.o obj-$(CONFIG_ARM) += api_platform-arm.o obj-$(CONFIG_PPC) += api_platform-powerpc.o obj-$(CONFIG_MIPS) += api_platform-mips.o +obj-$(CONFIG_RISCV) += api_platform-riscv.o diff --git a/api/api_platform-riscv.c b/api/api_platform-riscv.c new file mode 100644 index 0000000000..33a56535f3 --- /dev/null +++ b/api/api_platform-riscv.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2007 Stanislav Galabov sgalabov@gmail.com + * + * This file contains routines that fetch data from bd_info sources + */ + +#include <config.h> +#include <linux/types.h> +#include <api_public.h> + +#include <asm/u-boot.h> +#include <asm/global_data.h> + +#include "api_private.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Important notice: handling of individual fields MUST be kept in sync with + * include/asm-generic/u-boot.h, so any changes + * need to reflect their current state and layout of structures involved! + */ +int platform_sys_info(struct sys_info *si) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) + platform_set_mr(si, gd->bd->bi_dram[i].start, + gd->bd->bi_dram[i].size, MR_ATTR_DRAM); + + return 1; +} diff --git a/examples/api/Makefile b/examples/api/Makefile index 8fa9c04118..0f9d0e013f 100644 --- a/examples/api/Makefile +++ b/examples/api/Makefile @@ -18,6 +18,9 @@ else LOAD_ADDR = 0x80200000 endif endif +ifeq ($(ARCH),riscv) +LOAD_ADDR = 0x84000000 +endif
# Resulting ELF and binary exectuables will be named demo and demo.bin extra-y = demo demo.bin diff --git a/examples/api/crt0.S b/examples/api/crt0.S index 658bc59a82..2ba23331df 100644 --- a/examples/api/crt0.S +++ b/examples/api/crt0.S @@ -65,6 +65,21 @@ return_addr: .data .align 8 .long 0 + +#elif defined(CONFIG_RISCV) +#include <asm/asm.h> + .text + .globl _start +_start: + lla t0, search_hint + REG_S sp, 0(t0) + tail main + + .globl syscall +syscall: + lla t0, syscall_ptr + REG_L t2, 0(t0) + jr t2 #else #error No support for this arch! #endif

On Tue, Apr 21, 2020 at 6:35 AM mhorne@freebsd.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
Add the necessary changes to allow building the CONFIG_API option on the RISC-V architecture. The downstream consumer of this API is the u-boot version of FreeBSD's loader(8). This enables the loader to be ported to
Could you please include a URL for FreeBSD's loader(8)?
RISC-V.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org Cc: rick@andestech.com Cc: bmeng.cn@gmail.com Cc: atish.patra@wdc.com
api/Makefile | 1 + api/api_platform-riscv.c | 33 +++++++++++++++++++++++++++++++++ examples/api/Makefile | 3 +++ examples/api/crt0.S | 15 +++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 api/api_platform-riscv.c
diff --git a/api/Makefile b/api/Makefile index bd2d035fcd..737854e2c6 100644 --- a/api/Makefile +++ b/api/Makefile @@ -6,3 +6,4 @@ obj-y += api.o api_display.o api_net.o api_storage.o obj-$(CONFIG_ARM) += api_platform-arm.o obj-$(CONFIG_PPC) += api_platform-powerpc.o obj-$(CONFIG_MIPS) += api_platform-mips.o +obj-$(CONFIG_RISCV) += api_platform-riscv.o diff --git a/api/api_platform-riscv.c b/api/api_platform-riscv.c new file mode 100644 index 0000000000..33a56535f3 --- /dev/null +++ b/api/api_platform-riscv.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2007 Stanislav Galabov sgalabov@gmail.com
- This file contains routines that fetch data from bd_info sources
- */
+#include <config.h> +#include <linux/types.h> +#include <api_public.h>
+#include <asm/u-boot.h> +#include <asm/global_data.h>
+#include "api_private.h"
+DECLARE_GLOBAL_DATA_PTR;
+/*
- Important notice: handling of individual fields MUST be kept in sync with
- include/asm-generic/u-boot.h, so any changes
- need to reflect their current state and layout of structures involved!
- */
+int platform_sys_info(struct sys_info *si) +{
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
platform_set_mr(si, gd->bd->bi_dram[i].start,
gd->bd->bi_dram[i].size, MR_ATTR_DRAM);
return 1;
+} diff --git a/examples/api/Makefile b/examples/api/Makefile index 8fa9c04118..0f9d0e013f 100644 --- a/examples/api/Makefile +++ b/examples/api/Makefile @@ -18,6 +18,9 @@ else LOAD_ADDR = 0x80200000 endif endif +ifeq ($(ARCH),riscv) +LOAD_ADDR = 0x84000000 +endif
# Resulting ELF and binary exectuables will be named demo and demo.bin extra-y = demo demo.bin diff --git a/examples/api/crt0.S b/examples/api/crt0.S index 658bc59a82..2ba23331df 100644 --- a/examples/api/crt0.S +++ b/examples/api/crt0.S @@ -65,6 +65,21 @@ return_addr: .data .align 8 .long 0
+#elif defined(CONFIG_RISCV) +#include <asm/asm.h>
.text
.globl _start
+_start:
lla t0, search_hint
Looks lla is only supported in newer assemblers?
REG_S sp, 0(t0)
tail main
.globl syscall
+syscall:
lla t0, syscall_ptr
REG_L t2, 0(t0)
jr t2
#else #error No support for this arch!
#endif
Regards, Bin

From: Mitchell Horne mhorne@FreeBSD.org
API clients can make a syscall requesting the enumeration of network and storage devices. However, this does not check for virtio-blk storage devices, which API consumers may wish to use. Add the support to enumerate these devices as well.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org --- api/api_storage.c | 14 +++++++++++++- include/api_public.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/api/api_storage.c b/api/api_storage.c index 7ae03ac230..866c82d7ec 100644 --- a/api/api_storage.c +++ b/api/api_storage.c @@ -30,7 +30,8 @@ #define ENUM_SCSI 2 #define ENUM_MMC 3 #define ENUM_SATA 4 -#define ENUM_MAX 5 +#define ENUM_VIRTIO 5 +#define ENUM_MAX 6
struct stor_spec { int max_dev; @@ -46,6 +47,10 @@ static struct stor_spec specs[ENUM_MAX] = { { 0, 0, 0, 0, NULL }, }; #define CONFIG_SYS_MMC_MAX_DEVICE 1 #endif
+#ifndef CONFIG_SYS_VIRTIO_BLK_MAX_DEVICE +#define CONFIG_SYS_VIRTIO_BLK_MAX_DEVICE 1 +#endif + void dev_stor_init(void) { #if defined(CONFIG_IDE) @@ -83,6 +88,13 @@ void dev_stor_init(void) specs[ENUM_USB].type = DEV_TYP_STOR | DT_STOR_USB; specs[ENUM_USB].name = "usb"; #endif +#if defined(CONFIG_VIRTIO_BLK) + specs[ENUM_VIRTIO].max_dev = CONFIG_SYS_VIRTIO_BLK_MAX_DEVICE; + specs[ENUM_VIRTIO].enum_started = 0; + specs[ENUM_VIRTIO].enum_ended = 0; + specs[ENUM_VIRTIO].type = DEV_TYP_STOR | DT_STOR_VIRTIO; + specs[ENUM_VIRTIO].name = "virtio"; +#endif }
/* diff --git a/include/api_public.h b/include/api_public.h index def103ce22..1f9ff49b0b 100644 --- a/include/api_public.h +++ b/include/api_public.h @@ -87,6 +87,7 @@ typedef unsigned long lbastart_t; #define DT_STOR_USB 0x0040 #define DT_STOR_MMC 0x0080 #define DT_STOR_SATA 0x0100 +#define DT_STOR_VIRTIO 0x0200
#define DEV_STA_CLOSED 0x0000 /* invalid, closed */ #define DEV_STA_OPEN 0x0001 /* open i.e. active */

On Tue, Apr 21, 2020 at 7:29 AM mhorne@freebsd.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
API clients can make a syscall requesting the enumeration of network and storage devices. However, this does not check for virtio-blk storage devices, which API consumers may wish to use. Add the support to enumerate these devices as well.
Signed-off-by: Mitchell Horne mhorne@FreeBSD.org
api/api_storage.c | 14 +++++++++++++- include/api_public.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/api/api_storage.c b/api/api_storage.c index 7ae03ac230..866c82d7ec 100644 --- a/api/api_storage.c +++ b/api/api_storage.c @@ -30,7 +30,8 @@ #define ENUM_SCSI 2 #define ENUM_MMC 3 #define ENUM_SATA 4 -#define ENUM_MAX 5 +#define ENUM_VIRTIO 5 +#define ENUM_MAX 6
struct stor_spec { int max_dev; @@ -46,6 +47,10 @@ static struct stor_spec specs[ENUM_MAX] = { { 0, 0, 0, 0, NULL }, }; #define CONFIG_SYS_MMC_MAX_DEVICE 1 #endif
+#ifndef CONFIG_SYS_VIRTIO_BLK_MAX_DEVICE +#define CONFIG_SYS_VIRTIO_BLK_MAX_DEVICE 1
At some time we need turn all these macros to Kconfig options in this file.
+#endif
void dev_stor_init(void) { #if defined(CONFIG_IDE) @@ -83,6 +88,13 @@ void dev_stor_init(void) specs[ENUM_USB].type = DEV_TYP_STOR | DT_STOR_USB; specs[ENUM_USB].name = "usb"; #endif +#if defined(CONFIG_VIRTIO_BLK)
specs[ENUM_VIRTIO].max_dev = CONFIG_SYS_VIRTIO_BLK_MAX_DEVICE;
specs[ENUM_VIRTIO].enum_started = 0;
specs[ENUM_VIRTIO].enum_ended = 0;
specs[ENUM_VIRTIO].type = DEV_TYP_STOR | DT_STOR_VIRTIO;
specs[ENUM_VIRTIO].name = "virtio";
+#endif }
/* diff --git a/include/api_public.h b/include/api_public.h index def103ce22..1f9ff49b0b 100644 --- a/include/api_public.h +++ b/include/api_public.h @@ -87,6 +87,7 @@ typedef unsigned long lbastart_t; #define DT_STOR_USB 0x0040 #define DT_STOR_MMC 0x0080 #define DT_STOR_SATA 0x0100 +#define DT_STOR_VIRTIO 0x0200
#define DEV_STA_CLOSED 0x0000 /* invalid, closed */ #define DEV_STA_OPEN 0x0001 /* open i.e. active */
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Apr 20, 2020 at 06:34:11PM -0400, mhorne@FreeBSD.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
FreeBSD makes use of u-boot's CONFIG_API to provide a version of its standard bootloader for embedded architectures. This series adds the necessary support for the RISC-V architecture, along with some small fixes to the API demo program for 64-bit systems.
Adding in the RISC-V maintainer and EFI maintainer. I thought the intention was for OSes to use the EFI loader here, even for "embedded" ? Thanks!

On Fri, Apr 24, 2020 at 1:52 PM Tom Rini trini@konsulko.com wrote:
On Mon, Apr 20, 2020 at 06:34:11PM -0400, mhorne@FreeBSD.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
FreeBSD makes use of u-boot's CONFIG_API to provide a version of its standard bootloader for embedded architectures. This series adds the necessary support for the RISC-V architecture, along with some small fixes to the API demo program for 64-bit systems.
Adding in the RISC-V maintainer and EFI maintainer. I thought the intention was for OSes to use the EFI loader here, even for "embedded" ? Thanks!
Hi Tom,
You are right, EFI is preferred. FreeBSD's loader has two implementations on arm: one that is an EFI application, and one based on this u-boot API (known as "ubldr"). ubldr precedes the EFI implementation by a few years.
For RISC-V my intention is also to implement both versions, and ubldr was simpler on FreeBSD's side, so I chose to do that first. Do you think this series is still worth pursuing if u-boot is going the way of EFI?
Cheers, Mitchell
-- Tom

On Fri, Apr 24, 2020 at 05:46:43PM -0300, Mitchell Horne wrote:
On Fri, Apr 24, 2020 at 1:52 PM Tom Rini trini@konsulko.com wrote:
On Mon, Apr 20, 2020 at 06:34:11PM -0400, mhorne@FreeBSD.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
FreeBSD makes use of u-boot's CONFIG_API to provide a version of its standard bootloader for embedded architectures. This series adds the necessary support for the RISC-V architecture, along with some small fixes to the API demo program for 64-bit systems.
Adding in the RISC-V maintainer and EFI maintainer. I thought the intention was for OSes to use the EFI loader here, even for "embedded" ? Thanks!
Hi Tom,
You are right, EFI is preferred. FreeBSD's loader has two implementations on arm: one that is an EFI application, and one based on this u-boot API (known as "ubldr"). ubldr precedes the EFI implementation by a few years.
For RISC-V my intention is also to implement both versions, and ubldr was simpler on FreeBSD's side, so I chose to do that first. Do you think this series is still worth pursuing if u-boot is going the way of EFI?
In my mind at least, the EFI interface is preferred as it's a defined external standard interface. If the architecture maintainers want to support both the U-Boot API and EFI on RISC-V, I don't object. But one of the intentions is to have there be less work for OS folks to have to do for example. So that you found this a good first step for your use case means perhaps we need to continue to have the U-Boot API method be around (not that we had planned any sort of removal). Thanks!

On 4/24/20 10:52 PM, Tom Rini wrote:
On Fri, Apr 24, 2020 at 05:46:43PM -0300, Mitchell Horne wrote:
On Fri, Apr 24, 2020 at 1:52 PM Tom Rini trini@konsulko.com wrote:
On Mon, Apr 20, 2020 at 06:34:11PM -0400, mhorne@FreeBSD.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
FreeBSD makes use of u-boot's CONFIG_API to provide a version of its standard bootloader for embedded architectures. This series adds the necessary support for the RISC-V architecture, along with some small fixes to the API demo program for 64-bit systems.
Adding in the RISC-V maintainer and EFI maintainer. I thought the intention was for OSes to use the EFI loader here, even for "embedded" ? Thanks!
Hi Tom,
You are right, EFI is preferred. FreeBSD's loader has two implementations on arm: one that is an EFI application, and one based on this u-boot API (known as "ubldr"). ubldr precedes the EFI implementation by a few years.
For RISC-V my intention is also to implement both versions, and ubldr was simpler on FreeBSD's side, so I chose to do that first. Do you think this series is still worth pursuing if u-boot is going the way of EFI?
In my mind at least, the EFI interface is preferred as it's a defined external standard interface. If the architecture maintainers want to support both the U-Boot API and EFI on RISC-V, I don't object. But one of the intentions is to have there be less work for OS folks to have to do for example. So that you found this a good first step for your use case means perhaps we need to continue to have the U-Boot API method be around (not that we had planned any sort of removal). Thanks!
Hello Mitchell,
let me just give me an overview of where we currently are with UEFI support for RISC-V:
U-Boot supports UEFI to the point that we can start GRUB as EFI binary.
In Linux the UEFI support for RISC-V is being set up, cf. https://lkml.org/lkml/2020/4/20/1800
In EDK2 RISC-V support is under active development (https://edk2.groups.io/g/devel/search?q=RISC-V). In EDK2's staging repository (https://github.com/tianocore/edk2-staging.git) you can find a branch RISC-V-V2-CI-log-all-archs.
One challenge is the transfer of the HART id which is used for booting. In U-Boot this has been addressed by the patch 5370478d1c7a ("riscv: Add boot hartid to device tree").
@Atish: Is there a corresponding patch for EDK2?
Best regards
Heinrich

On Sat, Apr 25, 2020 at 4:31 AM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 4/24/20 10:52 PM, Tom Rini wrote:
On Fri, Apr 24, 2020 at 05:46:43PM -0300, Mitchell Horne wrote:
On Fri, Apr 24, 2020 at 1:52 PM Tom Rini trini@konsulko.com wrote:
On Mon, Apr 20, 2020 at 06:34:11PM -0400, mhorne@FreeBSD.org wrote:
From: Mitchell Horne mhorne@FreeBSD.org
FreeBSD makes use of u-boot's CONFIG_API to provide a version of its standard bootloader for embedded architectures. This series adds the necessary support for the RISC-V architecture, along with some small fixes to the API demo program for 64-bit systems.
Adding in the RISC-V maintainer and EFI maintainer. I thought the intention was for OSes to use the EFI loader here, even for "embedded" ? Thanks!
Hi Tom,
You are right, EFI is preferred. FreeBSD's loader has two implementations on arm: one that is an EFI application, and one based on this u-boot API (known as "ubldr"). ubldr precedes the EFI implementation by a few years.
For RISC-V my intention is also to implement both versions, and ubldr was simpler on FreeBSD's side, so I chose to do that first. Do you think this series is still worth pursuing if u-boot is going the way of EFI?
In my mind at least, the EFI interface is preferred as it's a defined external standard interface. If the architecture maintainers want to support both the U-Boot API and EFI on RISC-V, I don't object. But one of the intentions is to have there be less work for OS folks to have to do for example. So that you found this a good first step for your use case means perhaps we need to continue to have the U-Boot API method be around (not that we had planned any sort of removal). Thanks!
Hello Mitchell,
let me just give me an overview of where we currently are with UEFI support for RISC-V:
U-Boot supports UEFI to the point that we can start GRUB as EFI binary.
In Linux the UEFI support for RISC-V is being set up, cf. https://lkml.org/lkml/2020/4/20/1800
In EDK2 RISC-V support is under active development (https://edk2.groups.io/g/devel/search?q=RISC-V). In EDK2's staging repository (https://github.com/tianocore/edk2-staging.git) you can find a branch RISC-V-V2-CI-log-all-archs.
One challenge is the transfer of the HART id which is used for booting. In U-Boot this has been addressed by the patch 5370478d1c7a ("riscv: Add boot hartid to device tree").
Hi, just so this thread isn't left dangling, I eventually went the EFI route. I found this to be easier because the hart-id fixups aren't applied when executing plain binaries via the "go" command. I don't think this patchset will be needed. Thanks!
Mitchell
@Atish: Is there a corresponding patch for EDK2?
Best regards
Heinrich
participants (7)
-
Bin Meng
-
Daniel Schwierzeck
-
Heinrich Schuchardt
-
mhorne@FreeBSD.org
-
Mitchell Horne
-
Tom Rini
-
Wolfgang Denk