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 <no-reply+buildbot@haiku-os.org>
Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
This commit is contained in:
David Karoly 2022-02-24 20:58:19 +01:00 committed by Fredrik Holmqvist
parent 8a2698fe28
commit 883858e60b
2 changed files with 48 additions and 16 deletions

View File

@ -118,7 +118,7 @@ arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
status_t
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_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
arch_thread_context_switch(Thread *from, Thread *to)
{
arm_set_tls_context(to);
VMAddressSpace *oldAddressSpace = from->team->address_space;
VMTranslationMap *oldTranslationMap = oldAddressSpace->TranslationMap();
phys_addr_t oldPageDirectoryAddress =

View File

@ -1,23 +1,37 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the MIT License.
*/
/*
* Copyright 2019-2022, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2003, Axel Dörfler, axeld@pinc-software.de. 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
# define _NO_INLINE_ASM 1
#endif
#include "support/TLS.h"
#include "tls.h"
#include <runtime_loader/runtime_loader.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 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
@ -34,20 +48,27 @@ tls_allocate(void)
void *
tls_get(int32 index)
{
return gSlots[index];
return get_tls()[index];
}
void **
tls_address(int32 index)
{
return &gSlots[index];
return get_tls() + index;
}
void
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);
}