diff mbox series

[1/4] newlib: Use mcmodel=medany for RISCV64

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

Commit Message

Alejandro Enedino Hernandez Samaniego May 19, 2024, 5:50 a.m. UTC
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(-)

Comments

Khem Raj May 19, 2024, 6:37 a.m. UTC | #1
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]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Alejandro Enedino Hernandez Samaniego May 20, 2024, 3:32 a.m. UTC | #2
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 mbox series

Patch

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} \