summaryrefslogtreecommitdiff
path: root/src/thread/aarch64/__set_thread_area.c
blob: 2ec788e8ac6bb5b62002120237ea83edfc69335f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <elf.h>
#include "libc.h"

#define BITRANGE(a,b) (2*(1UL<<(b))-(1UL<<(a)))

int __set_thread_area(void *p)
{
	__asm__ __volatile__ ("msr tpidr_el0,%0" : : "r"(p) : "memory");

	/* Mask off hwcap bits for SME and unknown future features. This is
	 * necessary because SME is not safe to use without libc support for
	 * it, and we do not (yet) have such support. */
	for (size_t *v = libc.auxv; *v; v+=2) {
		if (v[0]==AT_HWCAP) {
			v[1] &= ~BITRANGE(42,63); /* 42-47 are SME */
		} else if (v[0]==AT_HWCAP2) {
			v[1] &= ~(BITRANGE(23,30)
			        | BITRANGE(37,42)
			        | BITRANGE(57,62));
		} else if (v[0]==AT_HWCAP3 || v[0]==AT_HWCAP4) {
			v[0] = AT_IGNORE;
			v[1] = 0;
		}
	}

	return 0;
}