summaryrefslogtreecommitdiffstats
path: root/bsps/i386
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 10:19:28 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:08:36 +0200
commitfbcd7c8fa65eb695e96a62ea1c1ac7a024fa9dfc (patch)
treea17e285cf22cd49cd42e8b3ad562febc3987d566 /bsps/i386
parentbsps: Move console drivers to bsps (diff)
downloadrtems-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.S345
-rw-r--r--bsps/i386/pc386/start/start16.S254
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