Message ID | 20240519055050.2331637-1-alejandro@enedino.org |
---|---|
State | Accepted, archived |
Commit | 3ed0a2fab5dbc37dd352ead8846da6aae5de5c20 |
Headers | show |
Series | [1/4] newlib: Use mcmodel=medany for RISCV64 | expand |
On Sat, May 18, 2024 at 10:48 PM Alejandro Hernandez Samaniego via lists.openembedded.org <alejandro=enedino.org@lists.openembedded.org> wrote: > > It was previously discovered that mcmodel=medany should be used for RISCV64, > however this was only being set for the applications themselves, but not for > newlib, this meant that we ended up with C library that used a code model and > an application that used another one which is not something we want. > > Pass mcmodel=medany when building newlib for RISCV64 as well. > > Also, s/CFLAGS/TARGET_CFLAGS to standarize across recipes, the variable > expansion provides no functional difference at this point. > > Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandro@enedino.org> > --- > meta/classes-recipe/baremetal-image.bbclass | 2 +- > meta/recipes-core/newlib/newlib.inc | 8 ++++++++ > 2 files changed, 9 insertions(+), 1 deletion(-) > > diff --git a/meta/classes-recipe/baremetal-image.bbclass b/meta/classes-recipe/baremetal-image.bbclass > index b9a584351a..4e7d413626 100644 > --- a/meta/classes-recipe/baremetal-image.bbclass > +++ b/meta/classes-recipe/baremetal-image.bbclass > @@ -103,7 +103,7 @@ QB_OPT_APPEND:append:qemuriscv32 = " -bios none" > # since medlow can only access addresses below 0x80000000 and RAM > # starts at 0x80000000 on RISC-V 64 > # Keep RISC-V 32 using -mcmodel=medlow (symbols lie between -2GB:2GB) > -CFLAGS:append:qemuriscv64 = " -mcmodel=medany" > +TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany" > > > ## Emulate image.bbclass > diff --git a/meta/recipes-core/newlib/newlib.inc b/meta/recipes-core/newlib/newlib.inc > index 6113f5e831..34b0f3f747 100644 > --- a/meta/recipes-core/newlib/newlib.inc > +++ b/meta/recipes-core/newlib/newlib.inc > @@ -28,6 +28,14 @@ B = "${WORKDIR}/build" > ## disable stdlib > TARGET_CC_ARCH:append = " -nostdlib" > > +# Both the C library and the application should share the same mcmodel. > +# Use the medium-any code model for the RISC-V 64 bit implementation, > +# since medlow can only access addresses below 0x80000000 and RAM > +# starts at 0x80000000 on RISC-V 64 > +# Keep RISC-V 32 using -mcmodel=medlow (symbols lie between -2GB:2GB) > +TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany" > + > + medany can be slow, and medlow is default on RISCV so I wonder if the ram address you are mentioning is so on all RV64 baremetal apps using newlib or is it specific to the hardware you are testing. > EXTRA_OECONF = " \ > --build=${BUILD_SYS} \ > --target=${TARGET_SYS} \ > -- > 2.45.1 > > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#199544): https://lists.openembedded.org/g/openembedded-core/message/199544 > Mute This Topic: https://lists.openembedded.org/mt/106182788/1997914 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [raj.khem@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=- >
On Sun, 19 May 2024 at 00:37, Khem Raj <raj.khem@gmail.com> wrote: > On Sat, May 18, 2024 at 10:48 PM Alejandro Hernandez Samaniego via > lists.openembedded.org <alejandro=enedino.org@lists.openembedded.org> > wrote: > > > > It was previously discovered that mcmodel=medany should be used for > RISCV64, > > however this was only being set for the applications themselves, but not > for > > newlib, this meant that we ended up with C library that used a code > model and > > an application that used another one which is not something we want. > > > > Pass mcmodel=medany when building newlib for RISCV64 as well. > > > > Also, s/CFLAGS/TARGET_CFLAGS to standarize across recipes, the variable > > expansion provides no functional difference at this point. > > > > Signed-off-by: Alejandro Enedino Hernandez Samaniego < > alejandro@enedino.org> > > --- > > meta/classes-recipe/baremetal-image.bbclass | 2 +- > > meta/recipes-core/newlib/newlib.inc | 8 ++++++++ > > 2 files changed, 9 insertions(+), 1 deletion(-) > > > > diff --git a/meta/classes-recipe/baremetal-image.bbclass > b/meta/classes-recipe/baremetal-image.bbclass > > index b9a584351a..4e7d413626 100644 > > --- a/meta/classes-recipe/baremetal-image.bbclass > > +++ b/meta/classes-recipe/baremetal-image.bbclass > > @@ -103,7 +103,7 @@ QB_OPT_APPEND:append:qemuriscv32 = " -bios none" > > # since medlow can only access addresses below 0x80000000 and RAM > > # starts at 0x80000000 on RISC-V 64 > > # Keep RISC-V 32 using -mcmodel=medlow (symbols lie between -2GB:2GB) > > -CFLAGS:append:qemuriscv64 = " -mcmodel=medany" > > +TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany" > > > > > > ## Emulate image.bbclass > > diff --git a/meta/recipes-core/newlib/newlib.inc > b/meta/recipes-core/newlib/newlib.inc > > index 6113f5e831..34b0f3f747 100644 > > --- a/meta/recipes-core/newlib/newlib.inc > > +++ b/meta/recipes-core/newlib/newlib.inc > > @@ -28,6 +28,14 @@ B = "${WORKDIR}/build" > > ## disable stdlib > > TARGET_CC_ARCH:append = " -nostdlib" > > > > +# Both the C library and the application should share the same mcmodel. > > +# Use the medium-any code model for the RISC-V 64 bit implementation, > > +# since medlow can only access addresses below 0x80000000 and RAM > > +# starts at 0x80000000 on RISC-V 64 > > +# Keep RISC-V 32 using -mcmodel=medlow (symbols lie between -2GB:2GB) > > +TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany" > > + > > + > > medany can be slow, and medlow is default on RISCV so I wonder if the > ram address > you are mentioning is so on all RV64 baremetal apps using newlib or is > it specific to > the hardware you are testing. > Hey Khem, We actually sort of had this discussion before so I'm copy-pasting the references I used the last time, but adding a few more datapoints :) Original thread from when I brought in the initial riscv64 baremetal port: https://lists.openembedded.org/g/openembedded-core/message/151483 For riscv64 (QEMU) the RAM address starts at 0x80000000 [1], which is what we're setting the _start global symbol to, as far as I understand using medany switches the usage of lui for auipc instructions making data accesses pc-relative, making it possible to load pointers above 0x800000000 where the RAM is. The medany code model seems to be widely used: riscv-probe [2], libgloss-htif [3], and riscv64-in-qemu [4], Zephyr had some problems with their SDK and enforced it as well for CONFIG_64 [5], and the RISC-V Large Code Model Software Workaround from SiFive states the following [6]: In Summary: -mcmodel=medlow — Used for 32-bit architectures, this code model requires that the program and its statically defined symbols must lie between the absolute addresses -2 GiB and +2 GiB, which covers the full 32-bit address range. Code is generally linked around address 0x00000000, and instruction pairs lui and ld are used to generate addresses for global symbols. -mcmodel=medany — Used for 64-bit architectures, this code model also generates a 32-bit signed offset to refer to global symbols. Linked code can reside at any address, and instruction pairs auipc and ld are used to generate global symbol addresses in a +/- 2GiB window from the code area. There's currently an open issue on riscv-gcc to change the default code model to medany for 64 bit targets [7]. Also, this time I purposely didn't set this at the beginning to see if it was required but I do get the following error if not using medany: (.init+0x0): relocation truncated to fit: R_RISCV_HI20 against symbol `__data_source' defined in *ABS* section in hello_picolibc_qemuriscv64.elf This is happening on the picolibc example which is completely different code than the other one I was using but its the exact same error, unless there is an extra cmdline argument that I'm not aware of that can be passed to the linker to bypass this, I don't know how this would be solved. I'm not sure, but perhaps medany needs to be used on 64 bits RISCV before virtual addressing is set up? which to me it would explain why it needs to be used for baremetal. I also found a few other references from RTEMS [8] and risc-gnu-toolchain [9] where medany its being used by default for riscv64. Picolibc also uses medany by default for riscv64 specifically [10] [1] QEMU: https://github.com/qemu/qemu/blob/d90f154867ec0ec22fd719164b88716e8fd48672/hw/riscv/virt.c#L60 [2] https://github.com/michaeljclark/riscv-probe/blob/891ac1df30c3cc7f49c0ac175ecb6d390ec5db34/Makefile#L5 [3] https://github.com/ucb-bar/libgloss-htif/blob/290b605e4a7340b584602eda183edab07f4bad45/util/htif.specs#L11 [4] https://github.com/rtfb/riscv64-in-qemu/blob/93f7dbf85a5a45a492f324a7ccc3d29d96e8f238/Makefile#L92 [5] https://github.com/zephyrproject-rtos/zephyr/blob/0c4e9d29bbc1b142ca738f86facb6e88218b629d/cmake/compiler/gcc/target_riscv.cmake#L10 [6] https://sifive.cdn.prismic.io/sifive%2F15d1d90e-f60e-42a2-b6bf-c805c6c73b0d_riscv-large-code-model-workaround.pdf [7] https://github.com/riscv/riscv-gcc/issues/164 [8] https://docs.rtems.org/branches/master/user/bsps/bsps-riscv.html [9] https://github.com/riscv-collab/riscv-gnu-toolchain/issues/733 [10] https://github.com/picolibc/picolibc/blob/main/scripts/cross-riscv64-unknown-elf.txt Cheers, Alejandro > > > EXTRA_OECONF = " \ > > --build=${BUILD_SYS} \ > > --target=${TARGET_SYS} \ > > -- > > 2.45.1 > > > > > > -=-=-=-=-=-=-=-=-=-=-=- > > Links: You receive all messages sent to this group. > > View/Reply Online (#199544): > https://lists.openembedded.org/g/openembedded-core/message/199544 > > Mute This Topic: https://lists.openembedded.org/mt/106182788/1997914 > > Group Owner: openembedded-core+owner@lists.openembedded.org > > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [ > raj.khem@gmail.com] > > -=-=-=-=-=-=-=-=-=-=-=- > > > >
diff --git a/meta/classes-recipe/baremetal-image.bbclass b/meta/classes-recipe/baremetal-image.bbclass index b9a584351a..4e7d413626 100644 --- a/meta/classes-recipe/baremetal-image.bbclass +++ b/meta/classes-recipe/baremetal-image.bbclass @@ -103,7 +103,7 @@ QB_OPT_APPEND:append:qemuriscv32 = " -bios none" # since medlow can only access addresses below 0x80000000 and RAM # starts at 0x80000000 on RISC-V 64 # Keep RISC-V 32 using -mcmodel=medlow (symbols lie between -2GB:2GB) -CFLAGS:append:qemuriscv64 = " -mcmodel=medany" +TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany" ## Emulate image.bbclass diff --git a/meta/recipes-core/newlib/newlib.inc b/meta/recipes-core/newlib/newlib.inc index 6113f5e831..34b0f3f747 100644 --- a/meta/recipes-core/newlib/newlib.inc +++ b/meta/recipes-core/newlib/newlib.inc @@ -28,6 +28,14 @@ B = "${WORKDIR}/build" ## disable stdlib TARGET_CC_ARCH:append = " -nostdlib" +# Both the C library and the application should share the same mcmodel. +# Use the medium-any code model for the RISC-V 64 bit implementation, +# since medlow can only access addresses below 0x80000000 and RAM +# starts at 0x80000000 on RISC-V 64 +# Keep RISC-V 32 using -mcmodel=medlow (symbols lie between -2GB:2GB) +TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany" + + EXTRA_OECONF = " \ --build=${BUILD_SYS} \ --target=${TARGET_SYS} \
It was previously discovered that mcmodel=medany should be used for RISCV64, however this was only being set for the applications themselves, but not for newlib, this meant that we ended up with C library that used a code model and an application that used another one which is not something we want. Pass mcmodel=medany when building newlib for RISCV64 as well. Also, s/CFLAGS/TARGET_CFLAGS to standarize across recipes, the variable expansion provides no functional difference at this point. Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandro@enedino.org> --- meta/classes-recipe/baremetal-image.bbclass | 2 +- meta/recipes-core/newlib/newlib.inc | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-)