Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/rp2040/boot_stage2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ function(pico_define_boot_stage2 NAME SOURCES)
if (PICO_C_COMPILER_IS_CLANG)
target_link_options(${NAME} PRIVATE "-nostdlib")
elseif (PICO_C_COMPILER_IS_GNU)
target_link_options(${NAME} PRIVATE "--specs=nosys.specs")
if (PICO_CLIB STREQUAL "newlib")
target_link_options(${NAME} PRIVATE "--specs=nosys.specs")
endif()
target_link_options(${NAME} PRIVATE "-nostartfiles")
endif ()

Expand Down
4 changes: 3 additions & 1 deletion src/rp2350/boot_stage2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ function(pico_define_boot_stage2 NAME SOURCES)
if (PICO_C_COMPILER_IS_CLANG)
target_link_options(${NAME} PRIVATE "-nostdlib")
elseif (PICO_C_COMPILER_IS_GNU)
target_link_options(${NAME} PRIVATE "--specs=nosys.specs")
if (PICO_CLIB STREQUAL "newlib")
target_link_options(${NAME} PRIVATE "--specs=nosys.specs")
endif()
target_link_options(${NAME} PRIVATE "-nostartfiles")
endif ()

Expand Down
66 changes: 46 additions & 20 deletions src/rp2_common/pico_clib_interface/picolibc_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <picotls.h>

#include "pico.h"
#if LIB_PICO_STDIO
Expand Down Expand Up @@ -58,6 +59,12 @@ static FILE __stdio = FDEV_SETUP_STREAM(picolibc_putc,
picolibc_flush,
_FDEV_SETUP_RW);

#ifdef __GNUCLIKE_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif

FILE *const stdin = &__stdio; __strong_reference(stdin, stdout); __strong_reference(stdin, stderr);

void __weak __assert_func(const char *file, int line, const char *func, const char *failedexpr) {
Expand Down Expand Up @@ -129,26 +136,45 @@ void runtime_init(void) {
__libc_init_array();
}

#if !PICO_RUNTIME_NO_INIT_PER_CORE_TLS_SETUP
__weak void runtime_init_pre_core_tls_setup(void) {
// for now we just set the same global area on both cores
// note: that this is superfluous with the stock picolibc it seems, since it is itself
// using a version of __aeabi_read_tp that returns the same pointer on both cores
extern char __tls_base[];
extern void _set_tls(void *tls);
_set_tls(__tls_base);
/* The size of the thread control block.
* TLS relocations are generated relative to
* a location this far *before* the first thread
* variable (!)
* NB: The actual size before tp also includes padding
* to align up to the alignment of .tdata/.tbss.
*/
extern char __arm32_tls_tcb_offset;
#define TP_OFFSET ((size_t)&__arm32_tls_tcb_offset)

static void *__tls[2];

void _set_tls(void *tls) {
tls = (uint8_t *)tls - TP_OFFSET;
__tls[get_core_num()] = tls;
}
#endif

#if !PICO_RUNTIME_SKIP_INIT_PER_CORE_TLS_SETUP
PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_pre_core_tls_setup, PICO_RUNTIME_INIT_PER_CORE_TLS_SETUP);
#endif
/* Initialized by the linker, one per core */
extern char __tls0_base[], __tls1_base[];
static void * const __tls_base[2] = { __tls0_base, __tls1_base };

void runtime_init_per_core_tls_setup(void) {
void *tls_base = __tls_base[get_core_num()];
_init_tls(tls_base);
_set_tls(tls_base);
}

//// naked as it must preserve everything except r0 and lr
//uint32_t __attribute__((naked)) WRAPPER_FUNC(__aeabi_read_tp)() {
// // note for now we are just returning a shared instance on both cores
// pico_default_asm_volatile(
// "ldr r0, =__tls_base\n"
// "bx lr\n"
// );
//}
PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_per_core_tls_setup, PICO_RUNTIME_INIT_PER_CORE_TLS_SETUP);

uint32_t __aeabi_read_tp(void);

uint32_t __attribute__((naked)) __aeabi_read_tp(void) {
pico_default_asm_volatile(
"push {r1,lr} /* Save R1 (and LR) */\n"
"ldr r1,=0xd0000000 /* Address of SIO->CPUID */\n"
"ldr r1,[r1] /* Fetch active core */\n"
"lsls r1,r1,#2 /* Multiply by 4 */\n"
"ldr r0,=%0 /* Address of __tls array */\n"
"ldr r0,[r0,r1] /* Fetch __tls[CPUID] */\n"
"pop {r1,pc} /* Restore R1 and return */\n" : : "i" (__tls)
);
}
61 changes: 43 additions & 18 deletions src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
__exidx_end
__etext
__data_start__
__bothinit_array_start
__preinit_array_start
__preinit_array_end
__init_array_start
__init_array_end
__bothinit_array_end
__fini_array_start
__fini_array_end
__data_end__
Expand Down Expand Up @@ -87,6 +89,7 @@ SECTIONS

. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__bothinit_array_start = .);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
Expand All @@ -98,6 +101,7 @@ SECTIONS
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__bothinit_array_end = .);

. = ALIGN(4);
/* finit data */
Expand Down Expand Up @@ -129,6 +133,30 @@ SECTIONS
} > FLASH
__exidx_end = .;

/* Assign TLS offsets and load TLS initialization data */
.tdata :
{
*(.tdata .tdata.* .gnu.linkonce.td.*)
PROVIDE( __tdata_end = . );
} >FLASH

.tbss (NOLOAD) : {
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
PROVIDE( __tbss_end = . );
} >FLASH

PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) );
PROVIDE( __tls_size = __tls_end - __tls_start );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __tdata_size = SIZEOF(.tdata) );
PROVIDE( __tdata_source = LOADADDR(.tdata) );
PROVIDE( __tbss_size = SIZEOF(.tbss) );
PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start );

/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
Expand Down Expand Up @@ -177,37 +205,34 @@ SECTIONS
. = ALIGN(4);
} > RAM AT> FLASH

.tdata : {
. = ALIGN(4);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* All data end */
__tdata_end = .;
} > RAM AT> FLASH
PROVIDE(__data_end__ = .);

/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);

.tbss (NOLOAD) : {
. = ALIGN(4);
__bss_start__ = .;
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)

__tls_end = .;
} > RAM

.bss (NOLOAD) : {
. = ALIGN(4);
__tbss_end = .;

__bss_start__ = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM

# Thread local storage static allocations, one per core

.tls0 (NOLOAD) : {
. = ALIGN(__tls_align);
PROVIDE(__tls0_base = .);
. = . + __tls_size_align;
} > RAM

.tls1 (NOLOAD) : {
. = ALIGN(__tls_align);
PROVIDE(__tls1_base = .);
. = . + __tls_size_align;
} > RAM

Comment on lines +222 to +235
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to put these sections between data and bss, so that bss and heap are contiguous? Otherwise, this may break compatibility with some other changes that are being worked on.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but that might break code which assumes that data and bss are contiguous?

.heap (NOLOAD):
{
__end__ = .;
Expand Down
61 changes: 43 additions & 18 deletions src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
__exidx_end
__etext
__data_start__
__bothinit_array_start
__preinit_array_start
__preinit_array_end
__init_array_start
__init_array_end
__bothinit_array_end
__fini_array_start
__fini_array_end
__data_end__
Expand Down Expand Up @@ -86,6 +88,30 @@ SECTIONS
} > FLASH
__exidx_end = .;

/* Assign TLS offsets and load TLS initialization data */
.tdata :
{
*(.tdata .tdata.* .gnu.linkonce.td.*)
PROVIDE( __tdata_end = . );
} >FLASH

.tbss (NOLOAD) : {
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
PROVIDE( __tbss_end = . );
} >FLASH

PROVIDE( __tls_start = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) );
PROVIDE( __tls_size = __tls_end - __tls_start );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = ALIGN( __tls_size, __tls_align) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __tdata_size = SIZEOF(.tdata) );
PROVIDE( __tdata_source = LOADADDR(.tdata) );
PROVIDE( __tbss_size = SIZEOF(.tbss) );
PROVIDE( __tbss_offset = ADDR(.tbss) - __tls_start );

/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
Expand Down Expand Up @@ -155,6 +181,7 @@ SECTIONS

. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__bothinit_array_start = .);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
Expand All @@ -166,6 +193,7 @@ SECTIONS
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__bothinit_array_end = .);

. = ALIGN(4);
/* finit data */
Expand All @@ -178,37 +206,34 @@ SECTIONS
. = ALIGN(4);
} > RAM AT> FLASH

.tdata : {
. = ALIGN(4);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* All data end */
__tdata_end = .;
} > RAM AT> FLASH
PROVIDE(__data_end__ = .);

/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);

.tbss (NOLOAD) : {
. = ALIGN(4);
__bss_start__ = .;
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)

__tls_end = .;
} > RAM

.bss : {
. = ALIGN(4);
__tbss_end = .;

__bss_start__ = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM

# Thread local storage static allocations, one per core

.tls0 (NOLOAD) : {
. = ALIGN(__tls_align);
PROVIDE(__tls0_base = .);
. = . + __tls_size_align;
} > RAM

.tls1 (NOLOAD) : {
. = ALIGN(__tls_align);
PROVIDE(__tls1_base = .);
. = . + __tls_size_align;
} > RAM

.heap (NOLOAD):
{
__end__ = .;
Expand Down
Loading
Loading