xref: /haiku/src/system/libroot/os/arch/arm64/tls.c (revision 9a31a305285d61b364164b24d45860dcecc1bdf2)
1cbdb30f4SJaroslaw Pelczar /*
2*9a31a305SDavid Karoly  * Copyright 2019-2022, Haiku, Inc. All Rights Reserved.
3cbdb30f4SJaroslaw Pelczar  * Distributed under the terms of the MIT License.
4cbdb30f4SJaroslaw Pelczar  */
5cbdb30f4SJaroslaw Pelczar 
6cbdb30f4SJaroslaw Pelczar #include <runtime_loader/runtime_loader.h>
7cbdb30f4SJaroslaw Pelczar 
8*9a31a305SDavid Karoly #include <support/TLS.h>
9*9a31a305SDavid Karoly #include <tls.h>
10*9a31a305SDavid Karoly 
11cbdb30f4SJaroslaw Pelczar 
12cbdb30f4SJaroslaw Pelczar struct tls_index {
13cbdb30f4SJaroslaw Pelczar 	unsigned long ti_module;
14cbdb30f4SJaroslaw Pelczar 	unsigned long ti_offset;
15cbdb30f4SJaroslaw Pelczar };
16cbdb30f4SJaroslaw Pelczar 
17cbdb30f4SJaroslaw Pelczar 
18cbdb30f4SJaroslaw Pelczar static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
19cbdb30f4SJaroslaw Pelczar 
20*9a31a305SDavid Karoly void* __tls_get_addr(struct tls_index* ti);
21*9a31a305SDavid Karoly 
22*9a31a305SDavid Karoly 
23*9a31a305SDavid Karoly static inline void**
24*9a31a305SDavid Karoly get_tls()
25*9a31a305SDavid Karoly {
26*9a31a305SDavid Karoly 	void **tls;
27*9a31a305SDavid Karoly 	asm volatile("MRS %0, tpidrro_el0" : "=r" (tls));
28*9a31a305SDavid Karoly 	return tls;
29*9a31a305SDavid Karoly }
30*9a31a305SDavid Karoly 
31cbdb30f4SJaroslaw Pelczar 
32cbdb30f4SJaroslaw Pelczar int32
33cbdb30f4SJaroslaw Pelczar tls_allocate(void)
34cbdb30f4SJaroslaw Pelczar {
35cbdb30f4SJaroslaw Pelczar 	int32 next = atomic_add(&gNextSlot, 1);
36cbdb30f4SJaroslaw Pelczar 	if (next >= TLS_MAX_KEYS)
37cbdb30f4SJaroslaw Pelczar 		return B_NO_MEMORY;
38cbdb30f4SJaroslaw Pelczar 
39cbdb30f4SJaroslaw Pelczar 	return next;
40cbdb30f4SJaroslaw Pelczar }
41cbdb30f4SJaroslaw Pelczar 
42cbdb30f4SJaroslaw Pelczar 
43cbdb30f4SJaroslaw Pelczar void *
44cbdb30f4SJaroslaw Pelczar tls_get(int32 index)
45cbdb30f4SJaroslaw Pelczar {
46*9a31a305SDavid Karoly 	return get_tls()[index];
47cbdb30f4SJaroslaw Pelczar }
48cbdb30f4SJaroslaw Pelczar 
49cbdb30f4SJaroslaw Pelczar 
50cbdb30f4SJaroslaw Pelczar void **
51cbdb30f4SJaroslaw Pelczar tls_address(int32 index)
52cbdb30f4SJaroslaw Pelczar {
53*9a31a305SDavid Karoly 	return get_tls() + index;
54cbdb30f4SJaroslaw Pelczar }
55cbdb30f4SJaroslaw Pelczar 
56cbdb30f4SJaroslaw Pelczar 
57cbdb30f4SJaroslaw Pelczar void
58cbdb30f4SJaroslaw Pelczar tls_set(int32 index, void *value)
59cbdb30f4SJaroslaw Pelczar {
60*9a31a305SDavid Karoly 	get_tls()[index] = value;
61cbdb30f4SJaroslaw Pelczar }
62cbdb30f4SJaroslaw Pelczar 
63cbdb30f4SJaroslaw Pelczar 
64cbdb30f4SJaroslaw Pelczar void*
65cbdb30f4SJaroslaw Pelczar __tls_get_addr(struct tls_index* ti)
66cbdb30f4SJaroslaw Pelczar {
67cbdb30f4SJaroslaw Pelczar 	return __gRuntimeLoader->get_tls_address(ti->ti_module, ti->ti_offset);
68cbdb30f4SJaroslaw Pelczar }
69