diff options
-rw-r--r-- | bsps/i386/pc386/include/bsp/tblsizes.h | 8 | ||||
-rw-r--r-- | bsps/i386/pc386/start/getcpuid.c | 2 | ||||
-rw-r--r-- | bsps/i386/pc386/start/ldsegs.S | 4 | ||||
-rw-r--r-- | bsps/i386/pc386/start/smp-imps.c | 15 | ||||
-rw-r--r-- | bsps/i386/pc386/start/startAP.S | 39 | ||||
-rw-r--r-- | cpukit/score/cpu/i386/cpu_asm.S | 11 | ||||
-rw-r--r-- | cpukit/score/cpu/i386/include/rtems/asm.h | 26 |
7 files changed, 59 insertions, 46 deletions
diff --git a/bsps/i386/pc386/include/bsp/tblsizes.h b/bsps/i386/pc386/include/bsp/tblsizes.h index 13429dc85f..978cde2b3e 100644 --- a/bsps/i386/pc386/include/bsp/tblsizes.h +++ b/bsps/i386/pc386/include/bsp/tblsizes.h @@ -20,5 +20,11 @@ #include <bspopts.h> #define IDT_SIZE (256) -#define NUM_SYSTEM_GDT_DESCRIPTORS 4 +/* We have 3 fixed segments (NULL, text, data) + a GS segment for TLS */ +#ifdef RTEMS_SMP +/* Need one GS segment for each processor (x86 can have up to 256 processors) */ +#define NUM_SYSTEM_GDT_DESCRIPTORS 3+256 +#else +#define NUM_SYSTEM_GDT_DESCRIPTORS 3+1 +#endif #define GDT_SIZE (NUM_SYSTEM_GDT_DESCRIPTORS + NUM_APP_DRV_GDT_DESCRIPTORS) diff --git a/bsps/i386/pc386/start/getcpuid.c b/bsps/i386/pc386/start/getcpuid.c index c5284d0069..4918a2a970 100644 --- a/bsps/i386/pc386/start/getcpuid.c +++ b/bsps/i386/pc386/start/getcpuid.c @@ -17,6 +17,6 @@ unsigned imps_lapic_addr = ((unsigned)(&lapic_dummy)) - LAPIC_ID; uint32_t _CPU_SMP_Get_current_processor( void ) { - return APIC_ID(IMPS_LAPIC_READ(LAPIC_ID)); + return imps_apic_cpu_map[APIC_ID(IMPS_LAPIC_READ(LAPIC_ID))]; } diff --git a/bsps/i386/pc386/start/ldsegs.S b/bsps/i386/pc386/start/ldsegs.S index b56bf836f0..9ed66ef1a3 100644 --- a/bsps/i386/pc386/start/ldsegs.S +++ b/bsps/i386/pc386/start/ldsegs.S @@ -191,9 +191,11 @@ SYM (_Global_descriptor_table): .word 0xffff, 0 .byte 0, 0x92, 0xcf, 0 - /* gs segment */ + /* gs segment(s) */ + .rept (NUM_SYSTEM_GDT_DESCRIPTORS - 3) .word 0xffff, 0 .byte 0, 0x92, 0xcf, 0 + .endr /* allocated space for user segments */ .rept (GDT_SIZE - NUM_SYSTEM_GDT_DESCRIPTORS) diff --git a/bsps/i386/pc386/start/smp-imps.c b/bsps/i386/pc386/start/smp-imps.c index 58d9178f90..6480c0d25e 100644 --- a/bsps/i386/pc386/start/smp-imps.c +++ b/bsps/i386/pc386/start/smp-imps.c @@ -83,6 +83,7 @@ #include <assert.h> extern void _pc386_delay(void); +extern uint32_t* gdtdesc; /* #define KERNEL_PRINT(_format) printk(_format) */ @@ -258,10 +259,10 @@ boot_cpu(imps_processor *proc) * under the 1MB boundary. */ - uint32_t *reset; + volatile uint32_t *reset; bootaddr = (512-64)*1024; - reset= (uint32_t *)bootaddr; + reset= (volatile uint32_t *)bootaddr; memcpy( (char *) bootaddr, @@ -269,9 +270,14 @@ boot_cpu(imps_processor *proc) (size_t)_binary_appstart_bin_size ); + /* Pass start function, stack region and gdtdescr to AP + * see startAP.S for location */ reset[1] = (uint32_t)secondary_cpu_initialize; reset[2] = (uint32_t)_Per_CPU_Get_by_index(apicid)->interrupt_stack_high; - + memcpy( + (char*) &reset[3], + &gdtdesc, + 6); /* * Generic CPU startup sequence starts here. */ @@ -325,8 +331,6 @@ boot_cpu(imps_processor *proc) CMOS_WRITE_BYTE(CMOS_RESET_CODE, 0); *((volatile unsigned *) bios_reset_vector) = 0; - printk("\n"); - return success; } @@ -359,6 +363,7 @@ add_processor(imps_processor *proc) /* AP booted successfully, increase number of available cores */ imps_num_cpus++; + printk("#%d Application Processor (AP)\n", imps_apic_cpu_map[apicid]); } } diff --git a/bsps/i386/pc386/start/startAP.S b/bsps/i386/pc386/start/startAP.S index 0f81c03144..024c1f70fb 100644 --- a/bsps/i386/pc386/start/startAP.S +++ b/bsps/i386/pc386/start/startAP.S @@ -73,9 +73,12 @@ app_processor_start: */ .align 4 app_cpu_start: - .long 0 + .long 0 app_cpu_stack: - .long 0 + .long 0 +app_gdt_descr: + .word 0 /* GDT size */ + .long 0 /* GDT location */ setup_processor: movw %cs, %ax # Initialize the rest of @@ -87,7 +90,7 @@ setup_processor: | Bare PC machines boot in real mode! We have to turn protected mode on. +---------------------------------------------------------------------*/ - lgdt gdtptr - app_processor_start # load Global Descriptor Table + lgdt app_gdt_descr - app_processor_start # load Global Descriptor Table movl %cr0, %eax orl $CR0_PE, %eax @@ -113,33 +116,3 @@ start_32bit: movl $0, app_cpu_stack /* Switch to the higher level initialization routines */ ret - -/*----------------------------------------------------------------------------+ -| DATA section -+----------------------------------------------------------------------------*/ - -/************************** -* GLOBAL DESCRIPTOR TABLE * -**************************/ - - .p2align 4 -gdtptr: - /* we use the NULL descriptor to store the GDT pointer - a trick quite - nifty due to: Robert Collins (rcollins@x86.org) */ - .word gdtlen - 1 - .long gdtptr - .word 0x0000 - - /* code segment */ - .word 0xffff, 0 - .byte 0, 0x9f, 0xcf, 0 - - /* data segment */ - .word 0xffff, 0 - .byte 0, 0x93, 0xcf, 0 - - /* gs segment */ - .word 0xffff, 0 - .byte 0, 0x92, 0xcf, 0 - - .set gdtlen, . - gdtptr # length of GDT diff --git a/cpukit/score/cpu/i386/cpu_asm.S b/cpukit/score/cpu/i386/cpu_asm.S index 6b609ab4ce..9e1e848bbd 100644 --- a/cpukit/score/cpu/i386/cpu_asm.S +++ b/cpukit/score/cpu/i386/cpu_asm.S @@ -85,12 +85,13 @@ 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 */ + GET_CPU_ID ecx + movl REG_GS_0(eax), edx /* restore gs segment */ + movl edx, _Global_descriptor_table+24(,ecx,8) movl REG_GS_1(eax), edx - movl ecx, _Global_descriptor_table + 24 - movl edx, _Global_descriptor_table + 28 - movl $24, ecx - mov ecx, gs + movl edx, _Global_descriptor_table+28(,ecx,8) + leal 24(,ecx,8), edx + movl edx, gs ret /* diff --git a/cpukit/score/cpu/i386/include/rtems/asm.h b/cpukit/score/cpu/i386/include/rtems/asm.h index 5db402c930..5856f724de 100644 --- a/cpukit/score/cpu/i386/include/rtems/asm.h +++ b/cpukit/score/cpu/i386/include/rtems/asm.h @@ -38,6 +38,7 @@ #endif #include <rtems/score/cpuopts.h> #include <rtems/score/i386.h> +#include <rtems/score/percpu.h> /** * @defgroup RTEMSScoreCPUi386ASM i386 Assembler Support @@ -146,6 +147,31 @@ #define PUBLIC(sym) .globl SYM (sym) #define EXTERN(sym) .globl SYM (sym) +#ifdef RTEMS_SMP +.macro GET_CPU_ID REG + .set LAPIC_ID, 0x20 + .set LAPIC_ID_SHIFT, 0x18L + movl imps_lapic_addr,\REG + movl LAPIC_ID(\REG),\REG + shrl $LAPIC_ID_SHIFT,\REG /* LAPIC_ID in REG */ + movb imps_apic_cpu_map(\REG),\REG /* CPU ID in REG */ +.endm + +.macro GET_SELF_CPU_CONTROL REG + GET_CPU_ID \REG + shll $PER_CPU_CONTROL_SIZE_LOG2,\REG /* Calculate offset for CPU structure */ + leal _Per_CPU_Information(\REG),\REG /* Address of info for current CPU in REG */ +.endm +#else +.macro GET_CPU_ID REG + movl $0,\REG +.endm + +.macro GET_SELF_CPU_CONTROL REG + leal _Per_CPU_Information, \REG +.endm +#endif + /**@}**/ #endif |