157c324a7SJerome Duval /*
2*883858e6SDavid Karoly * Copyright 2019-2022, Haiku, Inc. All Rights Reserved.
3*883858e6SDavid Karoly * Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
4*883858e6SDavid Karoly * Distributed under the terms of the MIT License.
557c324a7SJerome Duval */
657c324a7SJerome Duval
7*883858e6SDavid Karoly #include <runtime_loader/runtime_loader.h>
8*883858e6SDavid Karoly
9*883858e6SDavid Karoly #include <support/TLS.h>
10*883858e6SDavid Karoly #include <tls.h>
11*883858e6SDavid Karoly
12*883858e6SDavid Karoly
13*883858e6SDavid Karoly struct tls_index {
14*883858e6SDavid Karoly unsigned long ti_module;
15*883858e6SDavid Karoly unsigned long ti_offset;
16*883858e6SDavid Karoly };
1757c324a7SJerome Duval
1857c324a7SJerome Duval
1957c324a7SJerome Duval static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
20*883858e6SDavid Karoly
21*883858e6SDavid Karoly
22*883858e6SDavid Karoly static inline void**
get_tls()23*883858e6SDavid Karoly get_tls()
24*883858e6SDavid Karoly {
25*883858e6SDavid Karoly void **tls;
26*883858e6SDavid Karoly asm volatile("MRC p15, 0, %0, c13, c0, 3" : "=r" (tls));
27*883858e6SDavid Karoly return tls;
28*883858e6SDavid Karoly }
2957c324a7SJerome Duval
3057c324a7SJerome Duval
3157c324a7SJerome Duval int32
tls_allocate(void)3257c324a7SJerome Duval tls_allocate(void)
3357c324a7SJerome Duval {
3457c324a7SJerome Duval int32 next = atomic_add(&gNextSlot, 1);
3557c324a7SJerome Duval if (next >= TLS_MAX_KEYS)
3657c324a7SJerome Duval return B_NO_MEMORY;
3757c324a7SJerome Duval
3857c324a7SJerome Duval return next;
3957c324a7SJerome Duval }
4057c324a7SJerome Duval
4157c324a7SJerome Duval
4257c324a7SJerome Duval void *
tls_get(int32 index)4357c324a7SJerome Duval tls_get(int32 index)
4457c324a7SJerome Duval {
45*883858e6SDavid Karoly return get_tls()[index];
4657c324a7SJerome Duval }
4757c324a7SJerome Duval
4857c324a7SJerome Duval
4957c324a7SJerome Duval void **
tls_address(int32 index)5057c324a7SJerome Duval tls_address(int32 index)
5157c324a7SJerome Duval {
52*883858e6SDavid Karoly return get_tls() + index;
5357c324a7SJerome Duval }
5457c324a7SJerome Duval
5557c324a7SJerome Duval
5657c324a7SJerome Duval void
tls_set(int32 index,void * value)5757c324a7SJerome Duval tls_set(int32 index, void *value)
5857c324a7SJerome Duval {
59*883858e6SDavid Karoly get_tls()[index] = value;
60*883858e6SDavid Karoly }
61*883858e6SDavid Karoly
62*883858e6SDavid Karoly
63*883858e6SDavid Karoly void *
__tls_get_addr(struct tls_index * ti)64*883858e6SDavid Karoly __tls_get_addr(struct tls_index *ti)
65*883858e6SDavid Karoly {
66*883858e6SDavid Karoly return __gRuntimeLoader->get_tls_address(ti->ti_module, ti->ti_offset);
6757c324a7SJerome Duval }
68