diff options
Diffstat (limited to 'bsps/i386/pc386/start/startAP.S')
-rw-r--r-- | bsps/i386/pc386/start/startAP.S | 145 |
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 |