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