1#include "pthread_impl.h"
2#include "libc.h"
3#include <elf.h>
4
5/* Also perform sh-specific init */
6
7#define CPU_HAS_LLSC 0x0040
8#define CPU_HAS_CAS_L 0x0400
9
10__attribute__((__visibility__("hidden")))
11extern const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
12
13__attribute__((__visibility__("hidden")))
14const void *__sh_cas_ptr;
15
16__attribute__((__visibility__("hidden")))
17unsigned __sh_nommu;
18
19int __set_thread_area(void *p)
20{
21	size_t *aux;
22	__asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
23#ifndef __SH4A__
24	__sh_cas_ptr = __sh_cas_gusa;
25#if !defined(__SH3__) && !defined(__SH4__)
26	for (aux=libc.auxv; *aux; aux+=2) {
27		if (*aux != AT_PLATFORM) continue;
28		const char *s = (void *)aux[1];
29		if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
30		__sh_cas_ptr = __sh_cas_imask;
31		__sh_nommu = 1;
32	}
33#endif
34	if (__hwcap & CPU_HAS_CAS_L)
35		__sh_cas_ptr = __sh_cas_cas_l;
36	else if (__hwcap & CPU_HAS_LLSC)
37		__sh_cas_ptr = __sh_cas_llsc;
38#endif
39	return 0;
40}
41