diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 10:19:28 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 13:08:36 +0200 |
commit | fbcd7c8fa65eb695e96a62ea1c1ac7a024fa9dfc (patch) | |
tree | a17e285cf22cd49cd42e8b3ad562febc3987d566 /bsps/i386 | |
parent | bsps: Move console drivers to bsps (diff) | |
download | rtems-fbcd7c8fa65eb695e96a62ea1c1ac7a024fa9dfc.tar.bz2 |
bsps: Move start files to bsps
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'bsps/i386')
-rw-r--r-- | bsps/i386/pc386/start/start.S | 345 | ||||
-rw-r--r-- | bsps/i386/pc386/start/start16.S | 254 |
2 files changed, 599 insertions, 0 deletions
diff --git a/bsps/i386/pc386/start/start.S b/bsps/i386/pc386/start/start.S new file mode 100644 index 0000000000..51cd4711f0 --- /dev/null +++ b/bsps/i386/pc386/start/start.S @@ -0,0 +1,345 @@ +/*-------------------------------------------------------------------------+ +| 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-2012. +| * 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. +| ************************************************************************** ++--------------------------------------------------------------------------*/ + +/* + * 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 <rtems/asm.h> +#include <rtems/score/cpu.h> +#include <bspopts.h> + +/*----------------------------------------------------------------------------+ +| 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) +#if USE_VBE_RM + EXTERN (vesa_realmode_bootup_init) +#endif + EXTERN (_load_segments) + EXTERN (_return_to_monitor) + EXTERN (_IBMPC_initVideo) + EXTERN (debugPollingGetChar) + EXTERN (checkCPUtypeSetCr0) + 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 + +#if BSP_ENABLE_VGA +/*-------------------------------------------------------------------+ +| 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 + +#if USE_VBE_RM + call vesa_realmode_bootup_init +#endif +#endif + +/*---------------------------------------------------------------------+ +| 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 <CR>\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 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 |