[PATCH v1 2/9] bsp/pc386: Turn start16.S into a startAP.S

Jan Sommer jan.sommer at dlr.de
Sun May 31 14:22:52 UTC 2020


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
---
 bsps/i386/pc386/start/smp-imps.c        |  14 +-
 bsps/i386/pc386/start/start16.S         | 254 --------------------------------
 bsps/i386/pc386/start/startAP.S         | 145 ++++++++++++++++++
 c/src/lib/libbsp/i386/pc386/Makefile.am |   4 +-
 4 files changed, 159 insertions(+), 258 deletions(-)
 delete mode 100644 bsps/i386/pc386/start/start16.S
 create mode 100644 bsps/i386/pc386/start/startAP.S

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 at 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 at 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  \
-- 
2.12.3



More information about the devel mailing list