31,17 → 31,39 |
#ifndef __LIBC__mips32THREAD_H__ |
#define __LIBC__mips32THREAD_H__ |
|
static inline void __tls_set(void *tls) |
/* I did not find any specification (neither MIPS nor PowerPC), but |
* as I found it |
* - it uses Variant II |
* - TCB is at Address(First TLS Block)+0x7000. |
* - DTV is at Address(First TLS Block)+0x8000 |
* - What would happen if the TLS data was larger then 0x7000? |
* - The linker never accesses DTV directly, has the second definition any |
* sense? |
* We will make it this way: |
* - TCB is at TP-0x7000-sizeof(tcb) |
* - No assumption about DTV etc., but it will not have a fixed address |
*/ |
#define MIPS_TP_OFFSET 0x7000 |
|
typedef struct { |
void *pst_data; |
} tcb_t; |
|
static inline void __tcb_set(tcb_t *tcb) |
{ |
__asm__ volatile ("add $27, %0, $0" : : "r"(tls)); /* Move tls to K1 */ |
void *tp = tcb; |
tp += MIPS_TP_OFFSET + sizeof(tcb_t); |
|
__asm__ volatile ("add $27, %0, $0" : : "r"(tp)); /* Move tls to K1 */ |
} |
|
static inline void * __tls_get(void) |
static inline tcb_t * __tcb_get(void) |
{ |
void * retval; |
|
__asm__ volatile("add %0, $27, $0" : "=r"(retval)); |
return retval; |
|
return (tcb_t *)(retval - MIPS_TP_OFFSET - sizeof(tcb_t)); |
} |
|
#endif |