diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/thread/arm/__aeabi_read_tp.s | 8 | ||||
| -rw-r--r-- | src/thread/arm/__aeabi_read_tp_c.c | 8 | ||||
| -rw-r--r-- | src/thread/arm/__set_thread_area.c | 34 | ||||
| -rw-r--r-- | src/thread/arm/atomics.s | 75 | 
4 files changed, 69 insertions, 56 deletions
| diff --git a/src/thread/arm/__aeabi_read_tp.s b/src/thread/arm/__aeabi_read_tp.s new file mode 100644 index 00000000..9d0cd311 --- /dev/null +++ b/src/thread/arm/__aeabi_read_tp.s @@ -0,0 +1,8 @@ +.syntax unified +.global __aeabi_read_tp +.type __aeabi_read_tp,%function +__aeabi_read_tp: +	push {r1,r2,r3,lr} +	bl __aeabi_read_tp_c +	pop {r1,r2,r3,lr} +	bx lr diff --git a/src/thread/arm/__aeabi_read_tp_c.c b/src/thread/arm/__aeabi_read_tp_c.c new file mode 100644 index 00000000..654bdc57 --- /dev/null +++ b/src/thread/arm/__aeabi_read_tp_c.c @@ -0,0 +1,8 @@ +#include "pthread_impl.h" +#include <stdint.h> + +__attribute__((__visibility__("hidden"))) +void *__aeabi_read_tp_c(void) +{ +	return (void *)((uintptr_t)__pthread_self()-8+sizeof(struct pthread)); +} diff --git a/src/thread/arm/__set_thread_area.c b/src/thread/arm/__set_thread_area.c index 61d02827..daf496c2 100644 --- a/src/thread/arm/__set_thread_area.c +++ b/src/thread/arm/__set_thread_area.c @@ -6,43 +6,47 @@  #define HWCAP_TLS (1 << 15)  extern const unsigned char __attribute__((__visibility__("hidden"))) -	__a_barrier_dummy[], __a_barrier_oldkuser[], -	__a_barrier_v6[], __a_barrier_v7[], -	__a_cas_dummy[], __a_cas_v6[], __a_cas_v7[], -	__a_gettp_dummy[]; +	__a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[], +	__a_cas_v6[], __a_cas_v7[], +	__a_gettp_cp15[];  #define __a_barrier_kuser 0xffff0fa0 +#define __a_barrier_oldkuser (uintptr_t)__a_barrier_oldkuser +#define __a_barrier_v6 (uintptr_t)__a_barrier_v6 +#define __a_barrier_v7 (uintptr_t)__a_barrier_v7 +  #define __a_cas_kuser 0xffff0fc0 +#define __a_cas_v6 (uintptr_t)__a_cas_v6 +#define __a_cas_v7 (uintptr_t)__a_cas_v7 +  #define __a_gettp_kuser 0xffff0fe0 +#define __a_gettp_cp15 (uintptr_t)__a_gettp_cp15  extern uintptr_t __attribute__((__visibility__("hidden")))  	__a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr; -#define SET(op,ver) (__a_##op##_ptr = \ -	(uintptr_t)__a_##op##_##ver - (uintptr_t)__a_##op##_dummy) -  int __set_thread_area(void *p)  {  #if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7  	if (__hwcap & HWCAP_TLS) {  		size_t *aux; -		SET(cas, v7); -		SET(barrier, v7); +		__a_cas_ptr = __a_cas_v7; +		__a_barrier_ptr = __a_barrier_v7;  		for (aux=libc.auxv; *aux; aux+=2) {  			if (*aux != AT_PLATFORM) continue;  			const char *s = (void *)aux[1];  			if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break; -			SET(cas, v6); -			SET(barrier, v6); +			__a_cas_ptr = __a_cas_v6; +			__a_barrier_ptr = __a_barrier_v6;  			break;  		}  	} else {  		int ver = *(int *)0xffff0ffc; -		SET(gettp, kuser); -		SET(cas, kuser); -		SET(barrier, kuser); +		__a_gettp_ptr = __a_gettp_kuser; +		__a_cas_ptr = __a_cas_kuser; +		__a_barrier_ptr = __a_barrier_kuser;  		if (ver < 2) a_crash(); -		if (ver < 3) SET(barrier, oldkuser); +		if (ver < 3) __a_barrier_ptr = __a_barrier_oldkuser;  	}  #endif  	return __syscall(0xf0005, p); diff --git a/src/thread/arm/atomics.s b/src/thread/arm/atomics.s index 673fc03b..202faa4a 100644 --- a/src/thread/arm/atomics.s +++ b/src/thread/arm/atomics.s @@ -1,20 +1,15 @@  .syntax unified  .text -.global __a_barrier -.hidden __a_barrier -.type __a_barrier,%function -__a_barrier: -	ldr ip,1f -	ldr ip,[pc,ip] -	add pc,pc,ip -1:	.word __a_barrier_ptr-1b  .global __a_barrier_dummy  .hidden __a_barrier_dummy +.type __a_barrier_dummy,%function  __a_barrier_dummy:  	bx lr +  .global __a_barrier_oldkuser  .hidden __a_barrier_oldkuser +.type __a_barrier_oldkuser,%function  __a_barrier_oldkuser:  	push {r0,r1,r2,r3,ip,lr}  	mov r1,r0 @@ -24,90 +19,88 @@ __a_barrier_oldkuser:  	mov pc,ip  	pop {r0,r1,r2,r3,ip,lr}  	bx lr +  .global __a_barrier_v6  .hidden __a_barrier_v6 +.type __a_barrier_v6,%function  __a_barrier_v6: +	.arch armv6t2  	mcr p15,0,r0,c7,c10,5  	bx lr +  .global __a_barrier_v7  .hidden __a_barrier_v7 +.type __a_barrier_v7,%function  __a_barrier_v7: -	.word 0xf57ff05b        /* dmb ish */ +	.arch armv7-a +	dmb ish  	bx lr -.global __a_cas -.hidden __a_cas -.type __a_cas,%function -__a_cas: -	ldr ip,1f -	ldr ip,[pc,ip] -	add pc,pc,ip -1:	.word __a_cas_ptr-1b  .global __a_cas_dummy  .hidden __a_cas_dummy +.type __a_cas_dummy,%function  __a_cas_dummy:  	mov r3,r0  	ldr r0,[r2]  	subs r0,r3,r0  	streq r1,[r2]  	bx lr +  .global __a_cas_v6  .hidden __a_cas_v6 +.type __a_cas_v6,%function  __a_cas_v6: +	.arch armv6t2  	mov r3,r0  	mcr p15,0,r0,c7,c10,5 -1:	.word 0xe1920f9f        /* ldrex r0,[r2] */ +1:	ldrex r0,[r2]  	subs r0,r3,r0 -	.word 0x01820f91        /* strexeq r0,r1,[r2] */ +	strexeq r0,r1,[r2]  	teqeq r0,#1  	beq 1b  	mcr p15,0,r0,c7,c10,5  	bx lr +  .global __a_cas_v7  .hidden __a_cas_v7 +.type __a_cas_v7,%function  __a_cas_v7: +	.arch armv7-a  	mov r3,r0 -	.word 0xf57ff05b        /* dmb ish */ -1:	.word 0xe1920f9f        /* ldrex r0,[r2] */ +	dmb ish +1:	ldrex r0,[r2]  	subs r0,r3,r0 -	.word 0x01820f91        /* strexeq r0,r1,[r2] */ +	strexeq r0,r1,[r2]  	teqeq r0,#1  	beq 1b -	.word 0xf57ff05b        /* dmb ish */ +	dmb ish  	bx lr -.global __aeabi_read_tp -.type __aeabi_read_tp,%function -__aeabi_read_tp: - -.global __a_gettp -.hidden __a_gettp -.type __a_gettp,%function -__a_gettp: -	ldr r0,1f -	ldr r0,[pc,r0] -	add pc,pc,r0 -1:	.word __a_gettp_ptr-1b -.global __a_gettp_dummy -.hidden __a_gettp_dummy -__a_gettp_dummy: +.global __a_gettp_cp15 +.hidden __a_gettp_cp15 +.type __a_gettp_cp15,%function +__a_gettp_cp15:  	mrc p15,0,r0,c13,c0,3  	bx lr +/* Tag this file with minimum ISA level so as not to affect linking. */ +.arch armv4t +.eabi_attribute 6,2 +  .data  .align 2  .global __a_barrier_ptr  .hidden __a_barrier_ptr  __a_barrier_ptr: -	.word 0 +	.word __a_barrier_dummy  .global __a_cas_ptr  .hidden __a_cas_ptr  __a_cas_ptr: -	.word 0 +	.word __a_cas_dummy  .global __a_gettp_ptr  .hidden __a_gettp_ptr  __a_gettp_ptr: -	.word 0 +	.word __a_gettp_cp15 | 
