From 7b0c74ffb085656d67554102857224223ee03f88 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 9 Jun 2017 15:42:36 +0200 Subject: i386: Support thread-local storage (TLS) Update #2468. --- cpukit/score/cpu/i386/cpu.c | 25 +++++++++++++++++++++++++ cpukit/score/cpu/i386/cpu_asm.S | 8 ++++++++ cpukit/score/cpu/i386/rtems/score/cpu.h | 17 ++++++++++------- 3 files changed, 43 insertions(+), 7 deletions(-) (limited to 'cpukit/score/cpu/i386') diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c index 804afb1647..c9434f7c86 100644 --- a/cpukit/score/cpu/i386/cpu.c +++ b/cpukit/score/cpu/i386/cpu.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,12 @@ I386_ASSERT_OFFSET(ebx, EBX); I386_ASSERT_OFFSET(esi, ESI); I386_ASSERT_OFFSET(edi, EDI); +RTEMS_STATIC_ASSERT( + offsetof(Context_Control, gs) + == I386_CONTEXT_CONTROL_GS_0_OFFSET, + Context_Control_gs_0 +); + #ifdef RTEMS_SMP I386_ASSERT_OFFSET(is_executing, IS_EXECUTING); #endif @@ -153,6 +160,7 @@ void _CPU_Context_Initialize( ) { uint32_t _stack; + uint32_t tcb; (void) is_fp; /* avoid warning for being unused */ @@ -168,6 +176,23 @@ void _CPU_Context_Initialize( *((proc_ptr *)(_stack)) = (_entry_point); the_context->ebp = (void *) 0; the_context->esp = (void *) _stack; + + if ( tls_area != NULL ) { + tcb = (uint32_t) _TLS_TCB_after_TLS_block_initialize( tls_area ); + } else { + tcb = 0; + } + + the_context->gs.limit_15_0 = 0xffff; + the_context->gs.base_address_15_0 = (tcb >> 0) & 0xffff; + the_context->gs.type = 0x2; + the_context->gs.descriptor_type = 0x1; + the_context->gs.limit_19_16 = 0xf; + the_context->gs.present = 0x1; + the_context->gs.operation_size = 0x1; + the_context->gs.granularity = 0x1; + the_context->gs.base_address_23_16 = (tcb >> 16) & 0xff; + the_context->gs.base_address_31_24 = (tcb >> 24) & 0xff; } uint32_t _CPU_ISR_Get_level( void ) diff --git a/cpukit/score/cpu/i386/cpu_asm.S b/cpukit/score/cpu/i386/cpu_asm.S index 45079a65b8..6b609ab4ce 100644 --- a/cpukit/score/cpu/i386/cpu_asm.S +++ b/cpukit/score/cpu/i386/cpu_asm.S @@ -32,6 +32,8 @@ .set REG_EBX, I386_CONTEXT_CONTROL_EBX_OFFSET .set REG_ESI, I386_CONTEXT_CONTROL_ESI_OFFSET .set REG_EDI, I386_CONTEXT_CONTROL_EDI_OFFSET +.set REG_GS_0, I386_CONTEXT_CONTROL_GS_0_OFFSET +.set REG_GS_1, I386_CONTEXT_CONTROL_GS_1_OFFSET BEGIN_CODE @@ -83,6 +85,12 @@ restore: movl REG_EBX(eax),ebx /* restore ebx */ movl REG_ESI(eax),esi /* restore source register */ movl REG_EDI(eax),edi /* restore destination register */ + movl REG_GS_0(eax), ecx /* restore gs segment */ + movl REG_GS_1(eax), edx + movl ecx, _Global_descriptor_table + 24 + movl edx, _Global_descriptor_table + 28 + movl $24, ecx + mov ecx, gs ret /* diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h index 64f049ed0b..f78149c24b 100644 --- a/cpukit/score/cpu/i386/rtems/score/cpu.h +++ b/cpukit/score/cpu/i386/rtems/score/cpu.h @@ -122,9 +122,11 @@ extern "C" { #define I386_CONTEXT_CONTROL_EBX_OFFSET 12 #define I386_CONTEXT_CONTROL_ESI_OFFSET 16 #define I386_CONTEXT_CONTROL_EDI_OFFSET 20 +#define I386_CONTEXT_CONTROL_GS_0_OFFSET 24 +#define I386_CONTEXT_CONTROL_GS_1_OFFSET 28 #ifdef RTEMS_SMP - #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 24 + #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 32 #endif /* structures */ @@ -136,12 +138,13 @@ extern "C" { */ typedef struct { - uint32_t eflags; /* extended flags register */ - void *esp; /* extended stack pointer register */ - void *ebp; /* extended base pointer register */ - uint32_t ebx; /* extended bx register */ - uint32_t esi; /* extended source index register */ - uint32_t edi; /* extended destination index flags register */ + uint32_t eflags; /* extended flags register */ + void *esp; /* extended stack pointer register */ + void *ebp; /* extended base pointer register */ + uint32_t ebx; /* extended bx register */ + uint32_t esi; /* extended source index register */ + uint32_t edi; /* extended destination index flags register */ + segment_descriptors gs; /* gs segment descriptor */ #ifdef RTEMS_SMP volatile bool is_executing; #endif -- cgit v1.2.3