Changeset 7b0c74ff in rtems


Ignore:
Timestamp:
Jun 9, 2017, 1:42:36 PM (2 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
86c1004
Parents:
cb0d9a0
git-author:
Sebastian Huber <sebastian.huber@…> (06/09/17 13:42:36)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/12/17 06:01:58)
Message:

i386: Support thread-local storage (TLS)

Update #2468.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/pc386/include/tblsizes.h

    rcb0d9a0 r7b0c74ff  
    2121
    2222#define IDT_SIZE (256)
    23 #define GDT_SIZE (3 + NUM_APP_DRV_GDT_DESCRIPTORS)
     23#define NUM_SYSTEM_GDT_DESCRIPTORS 4
     24#define GDT_SIZE (NUM_SYSTEM_GDT_DESCRIPTORS + NUM_APP_DRV_GDT_DESCRIPTORS)
  • c/src/lib/libbsp/i386/pc386/startup/ldsegs.S

    rcb0d9a0 r7b0c74ff  
    172172| GDT itself
    173173+--------------------------------------------------------------------------*/
    174 #if GDT_SIZE < 3
    175 #error "GDT_SIZE must be at least 3"
     174#if GDT_SIZE < NUM_SYSTEM_GDT_DESCRIPTORS
     175#error "GDT_SIZE must be at least NUM_SYSTEM_GDT_DESCRIPTORS"
    176176#endif
    177177
     
    194194        .byte 0, 0x92, 0xcf, 0
    195195
     196        /* gs segment */
     197        .word 0xffff, 0
     198        .byte 0, 0x92, 0xcf, 0
     199
    196200        /* allocated space for user segments */
    197         .rept (GDT_SIZE - 3)
     201        .rept (GDT_SIZE - NUM_SYSTEM_GDT_DESCRIPTORS)
    198202        .word 0,0,0,0
    199203        .endr
  • c/src/lib/libbsp/i386/shared/irq/idt.c

    rcb0d9a0 r7b0c74ff  
    1919#include <rtems/score/cpu.h>
    2020#include <bsp/irq.h>
     21#include <bsp/tblsizes.h>
    2122
    2223/*
     
    332333    segment_descriptors*    gdt_entry_tbl;
    333334    /* initial amount of filled descriptors */
    334     static uint16_t         segment_selector_index = 2;
     335    static uint16_t         segment_selector_index = NUM_SYSTEM_GDT_DESCRIPTORS - 1;
    335336
    336337    segment_selector_index += 1;
  • cpukit/score/cpu/i386/cpu.c

    rcb0d9a0 r7b0c74ff  
    2525#include <rtems/score/isr.h>
    2626#include <rtems/score/idtr.h>
     27#include <rtems/score/tls.h>
    2728
    2829#include <rtems/bspIo.h>
     
    4344I386_ASSERT_OFFSET(esi, ESI);
    4445I386_ASSERT_OFFSET(edi, EDI);
     46
     47RTEMS_STATIC_ASSERT(
     48  offsetof(Context_Control, gs)
     49    == I386_CONTEXT_CONTROL_GS_0_OFFSET,
     50  Context_Control_gs_0
     51);
    4552
    4653#ifdef RTEMS_SMP
     
    154161{
    155162  uint32_t _stack;
     163  uint32_t tcb;
    156164
    157165  (void) is_fp; /* avoid warning for being unused */
     
    169177  the_context->ebp     = (void *) 0;
    170178  the_context->esp     = (void *) _stack;
     179
     180  if ( tls_area != NULL ) {
     181    tcb = (uint32_t) _TLS_TCB_after_TLS_block_initialize( tls_area );
     182  } else {
     183    tcb = 0;
     184  }
     185
     186  the_context->gs.limit_15_0 = 0xffff;
     187  the_context->gs.base_address_15_0 = (tcb >> 0) & 0xffff;
     188  the_context->gs.type = 0x2;
     189  the_context->gs.descriptor_type = 0x1;
     190  the_context->gs.limit_19_16 = 0xf;
     191  the_context->gs.present = 0x1;
     192  the_context->gs.operation_size = 0x1;
     193  the_context->gs.granularity = 0x1;
     194  the_context->gs.base_address_23_16 = (tcb >> 16) & 0xff;
     195  the_context->gs.base_address_31_24 = (tcb >> 24) & 0xff;
    171196}
    172197
  • cpukit/score/cpu/i386/cpu_asm.S

    rcb0d9a0 r7b0c74ff  
    3333.set REG_ESI,     I386_CONTEXT_CONTROL_ESI_OFFSET
    3434.set REG_EDI,     I386_CONTEXT_CONTROL_EDI_OFFSET
     35.set REG_GS_0,    I386_CONTEXT_CONTROL_GS_0_OFFSET
     36.set REG_GS_1,    I386_CONTEXT_CONTROL_GS_1_OFFSET
    3537
    3638        BEGIN_CODE
     
    8486        movl      REG_ESI(eax),esi         /* restore source register */
    8587        movl      REG_EDI(eax),edi         /* restore destination register */
     88        movl      REG_GS_0(eax), ecx       /* restore gs segment */
     89        movl      REG_GS_1(eax), edx
     90        movl      ecx, _Global_descriptor_table + 24
     91        movl      edx, _Global_descriptor_table + 28
     92        movl      $24, ecx
     93        mov       ecx, gs
    8694        ret
    8795
  • cpukit/score/cpu/i386/rtems/score/cpu.h

    rcb0d9a0 r7b0c74ff  
    123123#define I386_CONTEXT_CONTROL_ESI_OFFSET 16
    124124#define I386_CONTEXT_CONTROL_EDI_OFFSET 20
     125#define I386_CONTEXT_CONTROL_GS_0_OFFSET 24
     126#define I386_CONTEXT_CONTROL_GS_1_OFFSET 28
    125127
    126128#ifdef RTEMS_SMP
    127   #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 24
     129  #define I386_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 32
    128130#endif
    129131
     
    137139
    138140typedef struct {
    139   uint32_t    eflags;   /* extended flags register                   */
    140   void       *esp;      /* extended stack pointer register           */
    141   void       *ebp;      /* extended base pointer register            */
    142   uint32_t    ebx;      /* extended bx register                      */
    143   uint32_t    esi;      /* extended source index register            */
    144   uint32_t    edi;      /* extended destination index flags register */
     141  uint32_t    eflags;     /* extended flags register                   */
     142  void       *esp;        /* extended stack pointer register           */
     143  void       *ebp;        /* extended base pointer register            */
     144  uint32_t    ebx;        /* extended bx register                      */
     145  uint32_t    esi;        /* extended source index register            */
     146  uint32_t    edi;        /* extended destination index flags register */
     147  segment_descriptors gs; /* gs segment descriptor                     */
    145148#ifdef RTEMS_SMP
    146149  volatile bool is_executing;
  • cpukit/score/include/rtems/score/tls.h

    rcb0d9a0 r7b0c74ff  
    7171} TLS_Dynamic_thread_vector;
    7272
    73 typedef struct {
     73typedef struct TLS_Thread_control_block {
     74#ifdef __i386__
     75  struct TLS_Thread_control_block *tcb;
     76#else
    7477  TLS_Dynamic_thread_vector *dtv;
    7578  uintptr_t reserved;
     79#endif
    7680} TLS_Thread_control_block;
    7781
     
    110114)
    111115{
    112   uintptr_t aligned_size = _TLS_Heap_align_up( size );
    113 
    114   return _TLS_Get_thread_control_block_area_size( alignment )
    115     + aligned_size + sizeof(TLS_Dynamic_thread_vector);
     116  uintptr_t allocation_size = 0;
     117
     118  allocation_size += _TLS_Heap_align_up( size );
     119  allocation_size += _TLS_Get_thread_control_block_area_size( alignment );
     120
     121#ifndef __i386__
     122  allocation_size += sizeof(TLS_Dynamic_thread_vector);
     123#endif
     124
     125  return allocation_size;
    116126}
    117127
     
    141151)
    142152{
     153#ifdef __i386__
     154  (void) dtv;
     155  tcb->tcb = tcb;
     156#else
    143157  tcb->dtv = dtv;
    144158  dtv->generation_number = 1;
    145159  dtv->tls_blocks[0] = tls_block;
     160#endif
    146161
    147162  return _TLS_Copy_and_clear( tls_block );
Note: See TracChangeset for help on using the changeset viewer.