implement TLS for arm
Use the User Read-only Thread ID Register aka TPIDRURO to store TLS pointer. The User Read-only Thread ID Register is read-only in User mode, and read/write in privileged modes. see: ARMv7 Architecture Reference Manual, section B3.12.46 CP15 c13 Software Thread ID registers Change-Id: I7bff2fd66f41d7bf1a8a247151bcd02b32733c1b Reviewed-on: https://review.haiku-os.org/c/haiku/+/4994 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Fredrik Holmqvist <[email protected]>
This commit is contained in:
committed by
Fredrik Holmqvist
parent
8a2698fe28
commit
883858e60b
@@ -118,7 +118,7 @@ arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
|
|||||||
status_t
|
status_t
|
||||||
arch_thread_init_tls(Thread *thread)
|
arch_thread_init_tls(Thread *thread)
|
||||||
{
|
{
|
||||||
uint32 tls[TLS_USER_THREAD_SLOT + 1];
|
uint32 tls[TLS_FIRST_FREE_SLOT];
|
||||||
|
|
||||||
thread->user_local_storage = thread->user_stack_base
|
thread->user_local_storage = thread->user_stack_base
|
||||||
+ thread->user_stack_size;
|
+ thread->user_stack_size;
|
||||||
@@ -149,9 +149,20 @@ arm_swap_pgdir(uint32_t pageDirectoryAddress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
arm_set_tls_context(Thread *thread)
|
||||||
|
{
|
||||||
|
// Set TPIDRURO to point to TLS base
|
||||||
|
asm volatile("MCR p15, 0, %0, c13, c0, 3"
|
||||||
|
: : "r" (thread->user_local_storage));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_thread_context_switch(Thread *from, Thread *to)
|
arch_thread_context_switch(Thread *from, Thread *to)
|
||||||
{
|
{
|
||||||
|
arm_set_tls_context(to);
|
||||||
|
|
||||||
VMAddressSpace *oldAddressSpace = from->team->address_space;
|
VMAddressSpace *oldAddressSpace = from->team->address_space;
|
||||||
VMTranslationMap *oldTranslationMap = oldAddressSpace->TranslationMap();
|
VMTranslationMap *oldTranslationMap = oldAddressSpace->TranslationMap();
|
||||||
phys_addr_t oldPageDirectoryAddress =
|
phys_addr_t oldPageDirectoryAddress =
|
||||||
|
|||||||
@@ -1,23 +1,37 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2019-2022, Haiku, Inc. All Rights Reserved.
|
||||||
** Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*
|
||||||
|
* Copyright 2003, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
// ToDo: this is a dummy implementation - I've not yet gained enough knowledge
|
|
||||||
// to decide how this should be done, so it's just broken now (okay for single
|
|
||||||
// threaded apps, though).
|
|
||||||
|
|
||||||
// we don't want to have the inline assembly included here
|
|
||||||
#ifndef _NO_INLINE_ASM
|
#ifndef _NO_INLINE_ASM
|
||||||
# define _NO_INLINE_ASM 1
|
# define _NO_INLINE_ASM 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "support/TLS.h"
|
#include <runtime_loader/runtime_loader.h>
|
||||||
#include "tls.h"
|
|
||||||
|
#include <support/TLS.h>
|
||||||
|
#include <tls.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct tls_index {
|
||||||
|
unsigned long ti_module;
|
||||||
|
unsigned long ti_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
|
static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
|
||||||
static void *gSlots[TLS_MAX_KEYS];
|
|
||||||
|
|
||||||
|
static inline void**
|
||||||
|
get_tls()
|
||||||
|
{
|
||||||
|
void **tls;
|
||||||
|
asm volatile("MRC p15, 0, %0, c13, c0, 3" : "=r" (tls));
|
||||||
|
return tls;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
@@ -34,20 +48,27 @@ tls_allocate(void)
|
|||||||
void *
|
void *
|
||||||
tls_get(int32 index)
|
tls_get(int32 index)
|
||||||
{
|
{
|
||||||
return gSlots[index];
|
return get_tls()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void **
|
void **
|
||||||
tls_address(int32 index)
|
tls_address(int32 index)
|
||||||
{
|
{
|
||||||
return &gSlots[index];
|
return get_tls() + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
tls_set(int32 index, void *value)
|
tls_set(int32 index, void *value)
|
||||||
{
|
{
|
||||||
gSlots[index] = value;
|
get_tls()[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *
|
||||||
|
__tls_get_addr(struct tls_index *ti)
|
||||||
|
{
|
||||||
|
return __gRuntimeLoader->get_tls_address(ti->ti_module, ti->ti_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user