Close #2468. --- c/src/lib/libbsp/i386/pc386/include/tblsizes.h | 3 ++- c/src/lib/libbsp/i386/pc386/startup/ldsegs.S | 10 +++++++--- c/src/lib/libbsp/i386/shared/irq/idt.c | 3 ++- cpukit/score/cpu/i386/cpu.c | 6 ++++++ cpukit/score/cpu/i386/cpu_asm.S | 10 ++++++++++ cpukit/score/cpu/i386/rtems/score/cpu.h | 4 +++- cpukit/score/include/rtems/score/tls.h | 23 +++++++++++++++++++---- 7 files changed, 49 insertions(+), 10 deletions(-)
diff --git a/c/src/lib/libbsp/i386/pc386/include/tblsizes.h b/c/src/lib/libbsp/i386/pc386/include/tblsizes.h index bd4e9896bf..cea8619c8f 100644 --- a/c/src/lib/libbsp/i386/pc386/include/tblsizes.h +++ b/c/src/lib/libbsp/i386/pc386/include/tblsizes.h @@ -20,4 +20,5 @@ #include <bspopts.h> #define IDT_SIZE (256) -#define GDT_SIZE (3 + NUM_APP_DRV_GDT_DESCRIPTORS) +#define NUM_SYSTEM_GDT_DESCRIPTORS 4 +#define GDT_SIZE (NUM_SYSTEM_GDT_DESCRIPTORS + NUM_APP_DRV_GDT_DESCRIPTORS) diff --git a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S index ea41874a1b..626d5a02d4 100644 --- a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S +++ b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S @@ -171,8 +171,8 @@ next_step: /*---------------------------------------------------------------------------+ | GDT itself +--------------------------------------------------------------------------*/ -#if GDT_SIZE < 3 -#error "GDT_SIZE must be at least 3" +#if GDT_SIZE < NUM_SYSTEM_GDT_DESCRIPTORS +#error "GDT_SIZE must be at least NUM_SYSTEM_GDT_DESCRIPTORS" #endif BEGIN_DATA @@ -193,8 +193,12 @@ SYM (_Global_descriptor_table): .word 0xffff, 0 .byte 0, 0x92, 0xcf, 0 + /* gs segment */ + .word 0xffff, 0 + .byte 0, 0x92, 0xcf, 0 + /* allocated space for user segments */ - .rept (GDT_SIZE - 3) + .rept (GDT_SIZE - NUM_SYSTEM_GDT_DESCRIPTORS) .word 0,0,0,0 .endr diff --git a/c/src/lib/libbsp/i386/shared/irq/idt.c b/c/src/lib/libbsp/i386/shared/irq/idt.c index ac79a97004..d3adbc4f05 100644 --- a/c/src/lib/libbsp/i386/shared/irq/idt.c +++ b/c/src/lib/libbsp/i386/shared/irq/idt.c @@ -18,6 +18,7 @@ #include <rtems/score/cpu.h> #include <bsp/irq.h> +#include <bsp/tblsizes.h> /* * This locking is not enough if IDT is changed at runtime @@ -331,7 +332,7 @@ uint16_t i386_next_empty_gdt_entry () uint16_t gdt_limit; segment_descriptors* gdt_entry_tbl; /* initial amount of filled descriptors */ - static uint16_t segment_selector_index = 2; + static uint16_t segment_selector_index = NUM_SYSTEM_GDT_DESCRIPTORS - 1; segment_selector_index += 1; i386_get_info_from_GDTR (&gdt_entry_tbl, &gdt_limit); diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c index 804afb1647..a9e12d9c75 100644 --- a/cpukit/score/cpu/i386/cpu.c +++ b/cpukit/score/cpu/i386/cpu.c @@ -24,6 +24,7 @@ #include <rtems/score/types.h> #include <rtems/score/isr.h> #include <rtems/score/idtr.h> +#include <rtems/score/tls.h> #include <rtems/bspIo.h> #include <rtems/score/percpu.h> @@ -42,6 +43,7 @@ I386_ASSERT_OFFSET(ebp, EBP); I386_ASSERT_OFFSET(ebx, EBX); I386_ASSERT_OFFSET(esi, ESI); I386_ASSERT_OFFSET(edi, EDI); +I386_ASSERT_OFFSET(gs, GS); #ifdef RTEMS_SMP I386_ASSERT_OFFSET(is_executing, IS_EXECUTING); @@ -168,6 +170,10 @@ void _CPU_Context_Initialize( *((proc_ptr *)(_stack)) = (_entry_point); the_context->ebp = (void *) 0; the_context->esp = (void *) _stack; + + if ( tls_area != NULL ) { + the_context->gs = _TLS_TCB_after_TLS_block_initialize( tls_area ); + } } 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..f4eb38b8bd 100644 --- a/cpukit/score/cpu/i386/cpu_asm.S +++ b/cpukit/score/cpu/i386/cpu_asm.S @@ -32,6 +32,7 @@ .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, I386_CONTEXT_CONTROL_GS_OFFSET BEGIN_CODE @@ -83,6 +84,15 @@ 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(eax), ecx + movw cx, _Global_descriptor_table + 26 + movl ecx, edx + shrl $16, edx + movb dl, _Global_descriptor_table + 28 + shrl $24, ecx + movb cl, _Global_descriptor_table + 31 + 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..4aea2e1669 100644 --- a/cpukit/score/cpu/i386/rtems/score/cpu.h +++ b/cpukit/score/cpu/i386/rtems/score/cpu.h @@ -122,9 +122,10 @@ 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_OFFSET 24 #ifdef RTEMS_SMP - #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 24 + #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 28 #endif /* structures */ @@ -142,6 +143,7 @@ typedef struct { uint32_t ebx; /* extended bx register */ uint32_t esi; /* extended source index register */ uint32_t edi; /* extended destination index flags register */ + void *gs; /* thread pointer */ #ifdef RTEMS_SMP volatile bool is_executing; #endif diff --git a/cpukit/score/include/rtems/score/tls.h b/cpukit/score/include/rtems/score/tls.h index 51398a0a35..644e54e6f7 100644 --- a/cpukit/score/include/rtems/score/tls.h +++ b/cpukit/score/include/rtems/score/tls.h @@ -70,9 +70,13 @@ typedef struct { void *tls_blocks[1]; } TLS_Dynamic_thread_vector; -typedef struct { +typedef struct TLS_Thread_control_block { +#ifdef __i386__ + struct TLS_Thread_control_block *tcb; +#else TLS_Dynamic_thread_vector *dtv; uintptr_t reserved; +#endif } TLS_Thread_control_block; typedef struct { @@ -109,10 +113,16 @@ static inline uintptr_t _TLS_Get_allocation_size( uintptr_t alignment ) { - uintptr_t aligned_size = _TLS_Heap_align_up( size ); + uintptr_t allocation_size = 0; + + allocation_size += _TLS_Heap_align_up( size ); + allocation_size += _TLS_Get_thread_control_block_area_size( alignment ); + +#ifndef __i386__ + allocation_size += sizeof(TLS_Dynamic_thread_vector); +#endif - return _TLS_Get_thread_control_block_area_size( alignment ) - + aligned_size + sizeof(TLS_Dynamic_thread_vector); + return allocation_size; } static inline void *_TLS_Copy_and_clear( void *tls_area ) @@ -140,9 +150,14 @@ static inline void *_TLS_Initialize( TLS_Dynamic_thread_vector *dtv ) { +#ifdef __i386__ + (void) dtv; + tcb->tcb = tcb; +#else tcb->dtv = dtv; dtv->generation_number = 1; dtv->tls_blocks[0] = tls_block; +#endif return _TLS_Copy_and_clear( tls_block ); } -- 2.12.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel