Skip to content
Merged
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
46 changes: 37 additions & 9 deletions arch/arm/src/common/arm_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@

#include "arm_internal.h"

/****************************************************************************
* Private Function
****************************************************************************/

/****************************************************************************
* Name: arm_read_tp
*
* Description:
* Helper function for __aeabi_read_tp.
* This allows tls_get_info() macro to expand properly.
*
****************************************************************************/

void *arm_read_tp(void)
{
return (void *)(tls_get_info() + 1);
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand All @@ -51,7 +69,7 @@ int up_tls_size(void)

return sizeof(struct tls_info_s) +
sizeof(void *) * 2 +
sizeof(uint32_t) * (_END_TBSS - _START_TDATA);
(_END_TBSS - _START_TDATA);
}

/****************************************************************************
Expand All @@ -67,15 +85,12 @@ int up_tls_size(void)

void up_tls_initialize(struct tls_info_s *info)
{
uint8_t *tls_data = (uint8_t *)(info + 1);

uint32_t tdata_len = sizeof(uint32_t) * (_END_TDATA - _START_TDATA);
uint32_t tbss_len = sizeof(uint32_t) * (_END_TBSS - _START_TBSS);

tls_data += sizeof(void *) * 2;
uint8_t *tls_data = (uint8_t *)(info + 1) + sizeof(void *) * 2;
uint32_t tdata_len = _END_TDATA - _START_TDATA;
uint32_t tbss_len = _END_TBSS - _START_TBSS;

memcpy(tls_data, _START_TDATA, tdata_len);
memset(tls_data + tdata_len, 0, tbss_len);
memset(tls_data + tdata_len + (_START_TBSS - _END_TDATA), 0, tbss_len);
}

/****************************************************************************
Expand All @@ -84,9 +99,22 @@ void up_tls_initialize(struct tls_info_s *info)
* Description:
* Read thread local storage region pointer.
*
* This function follows the ARM EABI specification for TLS helper
* functions:
* - Only r0 is modified (return value)
* - r1-r3 must be preserved for the caller
*
* The naked attribute ensures strict register usage compliance.
*
****************************************************************************/

__attribute__((naked))
void *__aeabi_read_tp(void)
{
return (void *)(tls_get_info() + 1);
__asm__ __volatile__
(
"push {r1-r3, lr}\n\t"
"bl arm_read_tp\n\t"
"pop {r1-r3, pc}\n\t"
);
}
Loading