/*-------------------------------------------------------------------------+ | start.s v1.1 - PC386 BSP - 1997/08/07 +--------------------------------------------------------------------------+ | 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 +--------------------------------------------------------------------------+ | Modified the 20/05/1998 by valette@crf.canon.fr in order to give a working | example of eraly stage debugging via the DEBUG_EARLY_START define. +--------------------------------------------------------------------------+ | Disclaimer: | | This file is provided "AS IS" without warranty of any kind, either | expressed or implied. +--------------------------------------------------------------------------+ | This code is based on an earlier generation RTEMS i386 start.s and the | following copyright applies: | | ************************************************************************** | * COPYRIGHT (c) 1989-1999. | * 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.com/license/LICENSE. | ************************************************************************** | | $Id$ +--------------------------------------------------------------------------*/ /* * The most trivial start.s possible. It does not know anything * about system it is running on, so it will jump to appropriate * place in BSP specific place to do things it knows nothing about */ #include #include /*----------------------------------------------------------------------------+ | Size of heap and stack: +----------------------------------------------------------------------------*/ #ifndef CPU_STACK_ALIGNMENT #error "Missing header ? CPU_STACK_ALIGNMENT NOT DEFINED" #endif .set STACK_SIZE, 0x1000 /*----------------------------------------------------------------------------+ | CODE section +----------------------------------------------------------------------------*/ BEGIN_CODE PUBLIC (start) # GNU default entry point EXTERN (boot_card) EXTERN (_load_segments) EXTERN (_return_to_monitor) EXTERN (_IBMPC_initVideo) EXTERN (debugPollingGetChar) EXTERN (checkCPUtypeSetCr0) EXTERN (BSP_console_select) EXTERN (printk) #ifdef __SSE__ EXTERN (x86_capability) #ifdef __SSE3__ EXTERN (x86_capability_x) #endif #endif /* * In case this crashes on your machine and this is not due * to video mode set by the loader, you may try to define * the following variable: */ /* #define DEBUG_EARLY_START */ SYM (start): /* * When things are really, REALLY!, bad -- turn on the speaker and * lock up. This shows whether or not we make it to a certain * location. */ #if 0 inb $0x61, al orb $0x03, al outb al, $0x61 # enable the speaker speakl: jmp speakl # and SPIN!!! #endif nop cli # DISABLE INTERRUPTS!!! cld /* Save multiboot info if we detect a multiboot loader */ cmp $0x2badb002,eax jne 2f /* We have multiboot info; let's hope DS and ES are OK... */ movl ebx, SYM(_boot_multiboot_info_p) /* Check for memory size info and save */ movl ebx, esi movl (esi), eax movl eax, ebx movl $SYM(_boot_multiboot_info), edi /* save flags, always present */ movsd /* flag 1 is memory */ and $1, eax je 1f movl $2, ecx rep movsd /* flag 2 is the command line */ 1: movl ebx, eax and $4, eax je 3f movl (_boot_multiboot_info_p), eax movl 16(eax), esi movl $255, ecx 2: movzbl (esi), eax test al, al je 3f movb al, (edi) inc edi inc esi dec ecx je 3f jmp 2b 3: xor al, al movb al, (edi) #ifdef DEBUG_EARLY_START /* * Must get video attribute to have a working printk. * Note that the following code assume we already have * valid segments and a stack. It should be true for * any loader starting RTEMS in protected mode (or * at least I hope so : -)). */ call _IBMPC_initVideo /* * try printk and a getchar in polling mode ASAP */ movl $welcome_msg, 0(esp) call printk addl $4, esp /* call debugPollingGetChar */ #endif /*----------------------------------------------------------------------------+ | Load the segment registers (this is done by the board's BSP) and perform any | other board specific initialization procedures, this piece of code | does not know anything about | | NOTE: Upon return, gs will contain the segment descriptor for a segment which | maps directly to all of physical memory. +----------------------------------------------------------------------------*/ jmp SYM (_load_segments) # load board dependent segments /*----------------------------------------------------------------------------+ | Set up the stack +----------------------------------------------------------------------------*/ PUBLIC (_establish_stack) SYM (_establish_stack): movl $_end, eax # eax = end of bss/start of heap addl $STACK_SIZE, eax # make room for stack subl $4, eax # reserve room for arg to 'boot_card' andl $ - CPU_STACK_ALIGNMENT, eax # align SP on CPU_STACK_ALIGNMENT boundary movl eax, esp # set stack pointer movl eax, ebp # set base pointer /*----------------------------------------------------------------------------+ | Zero out the BSS segment +----------------------------------------------------------------------------*/ SYM (zero_bss): cld # make direction flag count up movl $ SYM (_end), ecx # find end of .bss movl $ SYM (__bss_start), edi # edi = beginning of .bss subl edi, ecx # ecx = size of .bss in bytes shrl ecx # size of .bss in longs shrl ecx xorl eax, eax # value to clear out memory repne # while ecx != 0 stosl # clear a long in the bss /*-------------------------------------------------------------------+ | Initialize the video because zero_bss has cleared initVideo parameters | if it was called earlier | So from now we can use printk +-------------------------------------------------------------------*/ call _IBMPC_initVideo /*---------------------------------------------------------------------+ | Check CPU type. Enable Cache and init coprocessor if needed. +---------------------------------------------------------------------*/ call checkCPUtypeSetCr0 #ifdef __SSE__ call SYM(enable_sse) #endif /*---------------------------------------------------------------------+ | Transfer control to User's Board Support Package | Note: at the top we reserved space for the argument | so that | initial_esp = ( TOS - 4 ) & ~(CPU_STACK_ALIGNMENT-1) | this ensures that | 1) esp is now aligned | 2) there is space for the cmdline pointer which we just | may store at *(esp) +---------------------------------------------------------------------*/ movl $SYM(_boot_multiboot_cmdline), (esp) call SYM (boot_card) cli # stops interrupts from being processed after hlt! hlt # shutdown #ifdef __SSE__ /*--------------------------------------------------------------------+ | Enable SSE; we really only care about fxsave/fxrstor and leave | The only feature *we* (as an OS) use is fxsave/fxrstor. | But as a courtesy we make sure we don't execute on hardware | that doesn't support features possibly used by the compiler. +---------------------------------------------------------------------*/ PUBLIC (enable_sse) SYM(enable_sse): movl SYM (x86_capability), eax testl $0x01000000, eax jne 1f movl $SYM (no_fxsave_msg), 0(esp) jmp SYM(_sse_panic) 1: testl $0x02000000, eax jne 1f movl $SYM (no_sse_msg), 0(esp) jmp SYM(_sse_panic) 1: #ifdef __SSE2__ testl $0x04000000, eax jne 1f movl $SYM (no_sse2_msg), 0(esp) jmp SYM(_sse_panic) 1: #endif #ifdef __SSE3__ movl SYM (x86_capability_x), eax testl $1, eax jne 1f movl $SYM (no_sse3_msg), 0(esp) jmp SYM(_sse_panic) 1: #endif mov cr4, eax # OK to enable now or $0x600, eax mov eax, cr4 ret SYM(_sse_panic): call SYM(printk) 1: hlt jmp 1b #endif END_CODE BEGIN_DATA PUBLIC(_boot_multiboot_info_p) SYM(_boot_multiboot_info_p): .long 0 PUBLIC(_boot_multiboot_info) PUBLIC(_boot_multiboot_flags) PUBLIC(_boot_multiboot_memory) PUBLIC(_boot_multiboot_cmdline) SYM(_boot_multiboot_info): SYM(_boot_multiboot_flags): .long 0 /* flags */ SYM(_boot_multiboot_memory): .long 0 /* mem_lower */ .long 0 /* mem_upper */ SYM(_boot_multiboot_cmdline): .rept 256 /* cmd line */ .byte 0 .endr PUBLIC(_stack_size) SYM(_stack_size): .long STACK_SIZE #ifdef DEBUG_EARLY_START PUBLIC (welcome_msg) SYM (welcome_msg) : .string "Ready to debug RTEMS ?\nEnter \n" PUBLIC (hex_msg) SYM (hex_msg) : .string "0x%x\n" PUBLIC (made_it_msg) SYM (made_it_msg) : .string "made it to %d\n" #endif #ifdef __SSE__ SYM (no_fxsave_msg) : .string "PANIC: compiled for SSE but CPU seems to have no FXSAVE/FXRSTOR support (which I need)\n" SYM (no_sse_msg) : .string "PANIC: compiled for SSE but your CPU seems to have no SSE support\n" #ifdef __SSE2__ SYM (no_sse2_msg) : .string "PANIC: compiled for SSE2 but your CPU seems to have no SSE2 support\n" #endif #ifdef __SSE3__ SYM (no_sse3_msg) : .string "PANIC: compiled for SSE3 but your CPU seems to have no SSE3 support\n" #endif #endif END_DATA END