-
Notifications
You must be signed in to change notification settings - Fork 6.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib/libc: Add picolibc support (aarch32, aarch64 and RISC-V) [v14] #39563
Conversation
6a2b97a
to
be60960
Compare
@keith-packard Good to see you again. Could you give a brief overview of the differences between this PR and the old stale PR #26545 are ? |
There's a second PR (#39564) which demonstrates how to take advantage of Picolibc's stdio architecture to replace printk and cbprintf. |
be60960
to
289dd30
Compare
@stephanosio @tejlmand @cfriedt could you please review this? |
@keith-packard would you please rebase this on top of the latest tip of |
V7-A also supports TPIDRURO, so go ahead and use that for TLS, enabling thread local storage for the other ARM architectures. Add __aeabi_read_tp function in case code was compiled to use that. Signed-off-by: Keith Packard <keithp@keithp.com>
289dd30
to
4811f64
Compare
Happy to! Note that this doesn't pass the tests yet; there's a minor picolibc bug and a bunch of tests make assumptions about the C library implementation that aren't true (like rand() uses a specific PRNG implementation). |
That's OK for now, I just wanted to keep this updated while we wait for reviews. Thanks for rebasing. |
4811f64
to
95ef04c
Compare
Would be great if we could get zephyrproject-rtos/sdk-ng#287 merged so that picolibc support was available in sdk-ng. That would make reviewing and testing this PR far easier. |
|
||
GDATA(z_arm_tls_ptr) | ||
|
||
SECTION_FUNC(text, __aeabi_read_tp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any chance that you could instead make this as a cmsis function, probably putting it in include/arch/arm/aarch32/cortex_a_r/cmsis.h until it could be moved to the true arm cmsis module? I assume you probably copied this structure from Cortex-M, but since this uses a mrc, it makes sense to abstract this access.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other side of this operation, storing the TLS value into the register, is done in swap_helper.S without any abstraction, so I'm not sure it makes sense to create an abstraction here?
I also don't think we should use this function anywhere; it's a part of EABI, but should only be used in code compiled with -mtp=soft. However, as Zephyr is the code base storing the TLS base address, it makes sense for Zephyr to offer the standard ABI that also fetches it, so I went ahead and added it.
Should all of the reviews happen on #39564 instead? Looks like people were commenting on these changes there as well. |
#39564 is supposed to reference only the printf-related optimizations possible with picolibc and not the basic library integration, but you're correct in noting that most of the review for the library integration happened there. I think I'd like guidance on how to proceed:
|
config PICOLIBC | ||
bool "Picolibc library" | ||
depends on !NATIVE_APPLICATION | ||
select THREAD_LOCAL_STORAGE if ARCH_HAS_THREAD_LOCAL_STORAGE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering why TLS is always enabled. Can picolib work without TLS if choose to do so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TLS must be enabled in zephyr if picolibc is built with TLS support. Otherwise, any TLS variables in picolibc will not work. I'm using 'ARCH_HAS_THREAD_LOCAL_STORAGE' as a proxy for whether picolibc was built with TLS support as I don't know how to check for that at configure time (picolibc has settings in picolibc.h which could be used, is there some way to look at those?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If picolibc TLS is also always enabled when building for those architectures, this is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, that depends on the toolchain. ARM ships their GCC embedded toolchain with TLS disabled. As there is no impact on code not using TLS in either case, I assume the ARM people just don't realize they've disabled it. Crosstool-ng and debian both ship with toolchains that enable TLS support in the compiler and picolibc. Once the sdk-ng PR for picolibc is merged, then zephyr can rely on that toolchain for picolibc, where TLS is enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, might want to add "&& !(arm toolchain)" for the if condition, since TLS is not required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be a lot better to figure out if picolibc has TLS support automatically; anyone know enough cmake to do that?
Picolibc is a fork of newlib designed and tested on embedded systems. It offers a smaller memory footprint (both ROM and RAM), and native TLS support, which uses the Zephyr TLS support. By default, the full printf version is included in the executable, which includes exact floating point and long long input and output. A configuration option has been added to switch to the integer-only version (which also omits long long support). Here are some size comparisons using qemu-cortex-m3 and this application (parameters passed to printf to avoid GCC optimizing it into puts): void main(void) { printf("Hello World! %s %d\n", CONFIG_BOARD, 12); } FLASH SRAM minimal 8696 3952 picolibc int 7600 3960 picolibc float 12304 3960 newlib-nano int 11696 4128 newlib-nano float 30516 4496 newlib 34800 6112 --- v2: Include picolibc-tls.ld v3: Document usage in guides/c_library.rst and getting_started/toolchain_other_x_compilers.rst v4: Lost the lib/libc/picolibc directory somehow! v5: Add PICOLIBC_ALIGNED_HEAP_SIZE configuration option. Delete PICOLIBC_SEMIHOST option support code v6: Don't allocate static RAM for TLS values; TLS values only need to be allocated for each thread. v7: Use arm coprocessor for TLS pointer storage where supported for compatibility with the -mtp=cp15 compiler option (or when the target cpu type selects this option) Add a bunch of tests Round TLS segment up to stack alignment so that overall stack remains correctly aligned Add aarch64 support Rebase to upstream head v8: Share NEWLIB, NEWLIB_NANO and PICOLIBC library configuration variables in a single LIBC_PARTITIONS variable instead of having separate PICOLIBC_PART and NEWLIB_PART variables. v9: Update docs to reference pending sdk-ng support for picolibc v10: Support memory protection by creating a partition for picolibc shared data and any pre-defined picolibc heap. v11: Fix formatting in arch/arm/core/aarch64/switch.S v12: Remove TLS support from this patch now that TLS is upstream Require THREAD_LOCAL_STORAGE when using PICOLIBC for architectures that support it. v13: Merge errno changes as they're only needed for picolibc. Adapt cmake changes suggested by Torsten Tejlmand Rasmussen v14: Update to picolibc 1.7 and newer (new stdin/stdout/stderr ABI) v15: Respond to comments from dcpleung: * switch kernel/errno to use CONFIG_LIBC_ERRNO instead of CONFIG_PICOLIBC * Add comment to test/lib/sprintf as to why the %n test was disabled for picolibc. Signed-off-by: Keith Packard <keithp@keithp.com>
95ef04c
to
fe48e9c
Compare
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
Picolibc is a fork of newlib designed and tested on embedded systems. It
offers a smaller memory footprint (both ROM and RAM), and native TLS
support, which uses the Zephyr TLS support.
By default, the full printf version is included in the executable, which
includes exact floating point and long long input and output. A
configuration option has been added to switch to the integer-only
version (which also omits long long support).
Here are some size comparisons using qemu-cortex-m3 and this application
(parameters passed to printf to avoid GCC optimizing it into puts):
Size data generated during build:
Signed-off-by: Keith Packard keithp@keithp.com
v2:
Include picolibc-tls.ld
v3:
Document usage in guides/c_library.rst and
getting_started/toolchain_other_x_compilers.rst
v4:
Lost the lib/libc/picolibc directory somehow!
v5:
Add PICOLIBC_ALIGNED_HEAP_SIZE configuration option.
Delete PICOLIBC_SEMIHOST option support code
v6:
Don't allocate static RAM for TLS values; TLS
values only need to be allocated for each thread.
v7:
Use arm coprocessor for TLS pointer storage where supported for
compatibility with the -mtp=cp15 compiler option (or when the
target cpu type selects this option)
v8:
Share NEWLIB, NEWLIB_NANO and PICOLIBC library configuration
variables in a single LIBC_PARTITIONS variable instead of
having separate PICOLIBC_PART and NEWLIB_PART variables.
v9:
Update docs to reference pending sdk-ng support for picolibc
v10:
Support memory protection by creating a partition for
picolibc shared data and any pre-defined picolibc heap.
v11:
Fix formatting in arch/arm/core/aarch64/switch.S
v12:
Remove TLS support from this patch now that TLS is upstream
Require THREAD_LOCAL_STORAGE when using PICOLIBC for architectures
that support it.
v13:
Merge errno changes as they're only needed for picolibc.
Adapt cmake changes suggested by Torsten Tejlmand Rasmussen
v14:
Update to picolibc 1.7 and newer (new stdin/stdout/stderr ABI)
Signed-off-by: Keith Packard keithp@keithp.com