summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bsps/i386/pc386/include/bsp/tblsizes.h8
-rw-r--r--bsps/i386/pc386/start/getcpuid.c2
-rw-r--r--bsps/i386/pc386/start/ldsegs.S4
-rw-r--r--bsps/i386/pc386/start/smp-imps.c15
-rw-r--r--bsps/i386/pc386/start/startAP.S39
-rw-r--r--cpukit/score/cpu/i386/cpu_asm.S11
-rw-r--r--cpukit/score/cpu/i386/include/rtems/asm.h26
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