diff options
Diffstat (limited to 'bsps/i386/pc386/start/start16.S')
-rw-r--r-- | bsps/i386/pc386/start/start16.S | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/bsps/i386/pc386/start/start16.S b/bsps/i386/pc386/start/start16.S new file mode 100644 index 0000000000..3d46f40ed6 --- /dev/null +++ b/bsps/i386/pc386/start/start16.S @@ -0,0 +1,254 @@ +/*--------------------------------------------------------------------------+ + * 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 |