summaryrefslogtreecommitdiffstats
path: root/bsps/i386/pc386/start/startAP.S
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/i386/pc386/start/startAP.S')
-rw-r--r--bsps/i386/pc386/start/startAP.S145
1 files changed, 145 insertions, 0 deletions
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