summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Sommer <jan.sommer@dlr.de>2020-05-31 16:22:52 +0200
committerChris Johns <chrisj@rtems.org>2020-06-11 13:28:46 +1000
commitf99b1f02b0a9a3457336949e086b863561d0fb76 (patch)
tree94127c6b6cda3cc349177268c9d0bb2cc67cdad9
parentbsp/pc386: Fix Makefile for building with SMP (diff)
downloadrtems-f99b1f02b0a9a3457336949e086b863561d0fb76.tar.bz2
bsp/pc386: Turn start16.S into a startAP.S
start16.S is now only used for SMP configurations to start the application processors. This commit removes all unnecessary parts for this job, i.e. video conssole initalisation, A20 gate activation and all non-AP related code. Update #3335
-rw-r--r--bsps/i386/pc386/start/smp-imps.c14
-rw-r--r--bsps/i386/pc386/start/start16.S254
-rw-r--r--bsps/i386/pc386/start/startAP.S145
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.am4
4 files changed, 159 insertions, 258 deletions
diff --git a/bsps/i386/pc386/start/smp-imps.c b/bsps/i386/pc386/start/smp-imps.c
index 0543b17ec5..58d9178f90 100644
--- a/bsps/i386/pc386/start/smp-imps.c
+++ b/bsps/i386/pc386/start/smp-imps.c
@@ -309,6 +309,11 @@ boot_cpu(imps_processor *proc)
}
/*
+ * Wait until AP is in protected mode before starting the next AP
+ */
+ while (reset[2] != 0);
+
+ /*
* Generic CPU startup sequence ends here, the rest is cleanup.
*/
@@ -342,12 +347,17 @@ add_processor(imps_processor *proc)
printk("#0 BootStrap Processor (BSP)\n");
return;
}
+ /* Setup the apic/cpu maps before booting the APs
+ * otherwise calls to _Get_current_processor can deliver
+ * wrong values if the BSP gets interrupted
+ */
+ imps_cpu_apic_map[imps_num_cpus] = apicid;
+ imps_apic_cpu_map[apicid] = imps_num_cpus;
if (boot_cpu(proc)) {
/* XXXXX add OS-specific setup for secondary CPUs here */
- imps_cpu_apic_map[imps_num_cpus] = apicid;
- imps_apic_cpu_map[apicid] = imps_num_cpus;
+ /* AP booted successfully, increase number of available cores */
imps_num_cpus++;
}
}
diff --git a/bsps/i386/pc386/start/start16.S b/bsps/i386/pc386/start/start16.S
deleted file mode 100644
index 3d46f40ed6..0000000000
--- a/bsps/i386/pc386/start/start16.S
+++ /dev/null
@@ -1,254 +0,0 @@
-/*--------------------------------------------------------------------------+
- * start16.s v1.0 - PC386 BSP - 1998/04/13
- *--------------------------------------------------------------------------+
- * This file contains the entry point for the application.
- * The name of this entry point is compiler dependent.
- * It jumps to the BSP which is responsible for performing all initialization.
- *--------------------------------------------------------------------------+
- * (C) Copyright 1997 -
- * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
- *
- * http://pandora.ist.utl.pt
- *
- * Instituto Superior Tecnico * Lisboa * PORTUGAL
- *--------------------------------------------------------------------------+
- * Disclaimer:
- *
- * This file is provided "AS IS" without warranty of any kind, either
- * expressed or implied.
- *--------------------------------------------------------------------------+
- */
-
-/*
- * COPYRIGHT (c) 2011.
- * On-Line Applications Research Corporation (OAR).
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-
-#include <bspopts.h>
-
-/*---------------------------------------------------------------------------+
-| Constants
-+----------------------------------------------------------------------------*/
-
-#if defined(SMP_SECONDARY_CORE)
-.set PROT_CODE_SEG, 0x08 # offset of code segment descriptor into GDT
-#else
-.set PROT_CODE_SEG, 0x0 # offset of code segment descriptor into GDT
-#endif
-
-.set PROT_DATA_SEG, 0x10 # offset of code segment descriptor into GDT
-.set CR0_PE, 1 # protected mode flag on CR0 register
-.set HDRSTART, HEADERADDR # address of start of bin2boot header
-.set HDROFF, 0x24 # offset into bin2boot header of start32 addr
-.set STACKOFF, 0x200-0x10 # offset to load into %esp, from start of image
-
-/* #define NEW_GAS */
-#ifdef NEW_GAS
- #define LJMPL ljmpl
-#else
- #define LJMPL ljmp
-#endif
-
-/*----------------------------------------------------------------------------+
-| CODE section
-+----------------------------------------------------------------------------*/
-
-.text
-#if defined(SMP_SECONDARY_CORE)
- .globl app_processor_start # entry point
-app_processor_start:
-#else
- .globl _start16 # entry point
- .globl start16
-start16:
-_start16:
-#endif
-
-.code16
- cli # DISABLE INTERRUPTS!!!
-#if defined(SMP_SECONDARY_CORE)
- jmp 1f
- .align 4
-app_cpu_start:
- .long 0
-app_cpu_stack:
- .long 0
-1:
-#endif
- movw %cs, %ax # Initialize the rest of
- movw %ax, %ds # segment registers
- movw %ax, %es
- movw %ax, %ss
-
-#if !defined(SMP_SECONDARY_CODE) && (RTEMS_VIDEO_80x50 == 1)
- movl $0x0040,%eax # use 32 bit constant to ensure 16 MSB=0
- mov %ax,%es
- movw %es:0x4a, %ax # get 16 bit number of columns
- cmpw $0, %ax # or 0 if no video adapter
- je 1f # if no video, skip touching it
- /*---------------------------------------------------------------------+
- | Switch VGA video to 80 lines x 50 columns mode. Has to be done before
- | turning protected mode on since it uses BIOS int 10h (video) services.
- +---------------------------------------------------------------------*/
-
- movw $0x0003, %ax # forced set
- int $0x10
- movw $0x1112, %ax # use 8x8 font
- xorb %bl, %bl
- int $0x10
- movw $0x1201, %ax # turn off cursor emulation
- movb $0x34, %bl
- int $0x10
- movb $0x01, %ah # define cursor (scan lines 0 to 7)
- movw $0x0007, %cx
- int $0x10
-1:
-#endif /* !SMP_SECONDARY_CODE and RTEMS_VIDEO_80x50 */
-
- /*---------------------------------------------------------------------+
- | Bare PC machines boot in real mode! We have to turn protected mode on.
- +---------------------------------------------------------------------*/
-
-#if defined(SMP_SECONDARY_CORE)
- lgdt gdtptr - app_processor_start # load Global Descriptor Table
-#else
- lgdt gdtptr - start16 # load Global Descriptor Table
-#endif /* SMP_SECONDARY_CORE */
-
- movl %cr0, %eax
- orl $CR0_PE, %eax
- movl %eax, %cr0 # turn on protected mode
-#if defined(SMP_SECONDARY_CORE)
- LJMPL $PROT_CODE_SEG, $2f # flush prefetch queue, and reload %cs
-#else
- LJMPL $PROT_CODE_SEG, $2f # flush prefetch queue, and reload %cs
-#endif
-.code32
-2:
-
- /*---------------------------------------------------------------------+
- | load the other segment registers
- +---------------------------------------------------------------------*/
- movl $PROT_DATA_SEG, %eax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %ss
-#if defined(SMP_SECONDARY_CORE)
- movl app_cpu_stack, %esp # stack pointer
- movl app_cpu_stack, %ebp # base pointer
- #else
- movl $start16 + STACKOFF, %esp # set up stack pointer
- addl $start16 + STACKOFF, %ebp # set up stack pointer
-#endif /* SMP_SECONDARY_CORE */
-
- /*---------------------------------------------------------------------+
- | we have to enable A20 in order to access memory above 1MByte
- +---------------------------------------------------------------------*/
- call empty_8042
- movb $0xD1, %al # command write
- outb %al, $0x64
- call empty_8042
- movb $0xDF, %al # A20 on
- outb %al, $0x60
- call empty_8042
-
- call pc386_delay
- call pc386_delay
- call pc386_delay
-
-#if defined(SMP_SECONDARY_CORE)
- movl app_cpu_start, %eax # jump to app CPU start
-#else
- movl %cs:HDRSTART + HDROFF, %eax # jump to start of 32 bit code
-#endif /* SMP_SECONDARY_CORE */
- pushl %eax
- ret
-
-
-/*----------------------------------------------------------------------------+
-| pc386_delay
-+------------------------------------------------------------------------------
-| Delay is needed after doing I/O.
-|
-| The outb version is OK on most machines BUT the loop version ...
-|
-| will delay for 1us on 1Gz machine, it will take a little bit
-| longer on slower machines, however, it does not matter because we
-| are going to call this function only a few times
-!
-| NOTE: Saving the content of the EAX register just in case. - Rosimildo.
-+----------------------------------------------------------------------------*/
- .p2align 4
- .globl _pc386_delay
- .globl pc386_delay
-pc386_delay:
-_pc386_delay:
- pushl %eax
-#if defined(USE_OUTB_FOR_DELAY)
- outb %al, $0x80 # about 1uS delay on most machines
-
-#else
-
- movl $0x200, %eax
-pc386_delay1:
- dec %eax
- jnz pc386_delay1
-#endif
- popl %eax
- ret
-
-/*----------------------------------------------------------------------------+
-| empty_8042
-+------------------------------------------------------------------------------
-| This routine checks that the keyboard command queue is empty (after emptying
-| the output buffers).
-| No timeout is used - if this hangs there is something wrong with the machine,
-| and we probably couldn't proceed anyway.
-+----------------------------------------------------------------------------*/
- .p2align 4
- .globl _empty_8042
- .globl empty_8042
-empty_8042:
-_empty_8042:
- call pc386_delay
- inb $0x64, %al # 8042 status port
- testb $0x01, %al # output buffer?
- jz no_output
- call pc386_delay
- in $0x60, %al # read it
- jmp empty_8042
-no_output:
- test $0x02, %al # is input buffer full?
- jnz empty_8042 # yes - loop
- 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
-
- .set gdtlen, . - gdtptr # length of GDT
diff --git a/bsps/i386/pc386/start/startAP.S b/bsps/i386/pc386/start/startAP.S
new file mode 100644
index 0000000000..0f81c03144
--- /dev/null
+++ b/bsps/i386/pc386/start/startAP.S
@@ -0,0 +1,145 @@
+/*--------------------------------------------------------------------------+
+ * start16.s v1.0 - PC386 BSP - 1998/04/13
+ * startAP.s 05/2019
+ *--------------------------------------------------------------------------+
+ * This file contains the initialization code for application processors (AP)
+ * for i386 based board support packages in SMP configuration.
+ * The APs start in 16 bit real mode. The goal is to:
+ * 1. Initialize the CPU registers
+ * 2. Load the global descriptor table
+ * 3. Switch to protected mode
+ * 4. Setup the stack pointers
+ * 5. Switch to the higher level initialization routine
+ *
+ *--------------------------------------------------------------------------+
+ * (C) Copyright 1997 -
+ * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+ *
+ * http://pandora.ist.utl.pt
+ *
+ * Instituto Superior Tecnico * Lisboa * PORTUGAL
+ *--------------------------------------------------------------------------+
+ * Disclaimer:
+ *
+ * This file is provided "AS IS" without warranty of any kind, either
+ * expressed or implied.
+ *--------------------------------------------------------------------------+
+ */
+
+/*
+ * COPYRIGHT (c) 2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#include <bspopts.h>
+
+/*---------------------------------------------------------------------------+
+| Constants
++----------------------------------------------------------------------------*/
+
+.set PROT_CODE_SEG, 0x08 # offset of code segment descriptor into GDT
+.set PROT_DATA_SEG, 0x10 # offset of code segment descriptor into GDT
+.set CR0_PE, 1 # protected mode flag on CR0 register
+.set HDRSTART, HEADERADDR # address of start of bin2boot header
+.set HDROFF, 0x24 # offset into bin2boot header of start32 addr
+.set STACKOFF, 0x200-0x10 # offset to load into %esp, from start of image
+
+/* #define NEW_GAS */
+#ifdef NEW_GAS
+ #define LJMPL ljmpl
+#else
+ #define LJMPL ljmp
+#endif
+
+/*----------------------------------------------------------------------------+
+| CODE section
++----------------------------------------------------------------------------*/
+
+.text
+ .globl app_processor_start # entry point
+app_processor_start:
+
+.code16
+ cli # DISABLE INTERRUPTS!!!
+ jmp setup_processor
+/*
+ * Placeholder to copy information from boot_cpu()
+ * Do NOT move or add asm instruction before
+ */
+.align 4
+app_cpu_start:
+ .long 0
+app_cpu_stack:
+ .long 0
+
+setup_processor:
+ movw %cs, %ax # Initialize the rest of
+ movw %ax, %ds # segment registers
+ movw %ax, %es
+ movw %ax, %ss
+
+ /*---------------------------------------------------------------------+
+ | Bare PC machines boot in real mode! We have to turn protected mode on.
+ +---------------------------------------------------------------------*/
+
+ lgdt gdtptr - app_processor_start # load Global Descriptor Table
+
+ movl %cr0, %eax
+ orl $CR0_PE, %eax
+ movl %eax, %cr0 # turn on protected mode
+ LJMPL $PROT_CODE_SEG, $start_32bit # flush prefetch queue, and reload %cs
+
+.code32
+start_32bit:
+
+ /*---------------------------------------------------------------------+
+ | load the other segment registers
+ +---------------------------------------------------------------------*/
+ movl $PROT_DATA_SEG, %eax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss
+ /* Prepare stack pointers */
+ movl app_cpu_stack, %esp # stack pointer
+ movl app_cpu_stack, %ebp # base pointer
+ movl app_cpu_start, %eax # jump to app CPU start
+ pushl %eax
+ /* Clear stack pointer to signal that the we jump to the kernel */
+ 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/c/src/lib/libbsp/i386/pc386/Makefile.am b/c/src/lib/libbsp/i386/pc386/Makefile.am
index 218e6bc065..c71f672063 100644
--- a/c/src/lib/libbsp/i386/pc386/Makefile.am
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.am
@@ -114,8 +114,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/start/getcpuid.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/start/smp-imps.c
project_lib_DATA += appstart.$(OBJEXT)
-appcpustart.$(OBJEXT): ../../../../../../bsps/i386/pc386/start/start16.S
- $(CPPASCOMPILE) $(AM_CPPFLAGS) -DSMP_SECONDARY_CORE -o $@ -c $<
+appcpustart.$(OBJEXT): ../../../../../../bsps/i386/pc386/start/startAP.S
+ $(CPPASCOMPILE) $(AM_CPPFLAGS) -o $@ -c $<
appstart.$(OBJEXT): appcpustart.$(OBJEXT)
$(LD) -N \