summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/start
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-12-01 22:06:48 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-12-01 22:06:48 +0000
commit7150f00f5be87fa8e37f7d00fbbef35645081138 (patch)
tree1cc7d3e1c4933404ddc1f742c7e37648cc783364 /c/src/lib/libbsp/i386/pc386/start
parentFixed test for RTEMS_HAS_POSIX_API so the executive POSIX API related (diff)
downloadrtems-7150f00f5be87fa8e37f7d00fbbef35645081138.tar.bz2
Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano
<pmcnr@camoes.rnl.ist.utl.pt> and Jose Rufino <ruf@asterix.ist.utl.pt> of NavIST (http://pandora.ist.utl.pt/).
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386/start')
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/Makefile.in56
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start.s416
2 files changed, 472 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/start/Makefile.in b/c/src/lib/libbsp/i386/pc386/start/Makefile.in
new file mode 100644
index 0000000000..82e228c689
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/start/Makefile.in
@@ -0,0 +1,56 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH=@srcdir@
+
+PGMS=${ARCH}/start.o
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=start
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+all: ${ARCH} $(SRCS) $(OBJS) $(PGM)
+ $(INSTALL_VARIANT) -m 555 ${PGMS} ${PROJECT_RELEASE}/lib
+
+# Install the program(s), appending _g or _p as appropriate.
+# for include files, just use $(INSTALL)
diff --git a/c/src/lib/libbsp/i386/pc386/start/start.s b/c/src/lib/libbsp/i386/pc386/start/start.s
new file mode 100644
index 0000000000..fb9019a742
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/start/start.s
@@ -0,0 +1,416 @@
+/*-------------------------------------------------------------------------+
+| 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
++--------------------------------------------------------------------------+
+| 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-1997.
+| * On-Line Applications Research Corporation (OAR).
+| * Copyright assigned to U.S. Government, 1994.
+| *
+| * The license and distribution terms for this file may be
+| * found in the file LICENSE in this distribution or at
+| * http://www.OARcorp.com/rtems/license.html.
+| **************************************************************************
+|
+| Also based on (from the Linux source tree):
+| video.S - Copyright (C) 1995, 1996 Martin Mares <mj@k332.feld.cvut.cz>
++--------------------------------------------------------------------------*/
+
+
+#include "asm.h"
+
+/*----------------------------------------------------------------------------+
+| Constants
++----------------------------------------------------------------------------*/
+
+#ifdef pc386
+
+.set PROT_CODE_SEG, 0x08 # offset of code segment descriptor into GDT
+.set CR0_PE, 1 # protected mode flag on CR0 register
+
+#endif /* pc386 */
+
+/*----------------------------------------------------------------------------+
+| A Descriptor table register has the following format:
++----------------------------------------------------------------------------*/
+
+.set DTR_LIMIT, 0 # offset of two byte limit
+.set DTR_BASE, 2 # offset of four byte base address
+.set DTR_SIZE, 6 # size of DTR register
+
+/*----------------------------------------------------------------------------+
+| CODE section
++----------------------------------------------------------------------------*/
+
+BEGIN_CODE
+
+ PUBLIC (start) # GNU default entry point
+
+ EXTERN (main)
+ EXTERN (load_segments)
+ EXTERN (exit)
+
+SYM (start):
+
+/*----------------------------------------------------------------------------+
+| 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.
++----------------------------------------------------------------------------*/
+
+#if defined(pc386) && defined(RTEMS_VIDEO_80x50)
+
+.code16
+
+ 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
+
+.code32
+
+#endif /* pc386 && RTEMS_VIDEO_80x50 */
+
+ nop
+ cli # DISABLE INTERRUPTS!!!
+
+/*----------------------------------------------------------------------------+
+| Bare PC machines boot in real mode! We have to turn protected mode on.
++----------------------------------------------------------------------------*/
+
+#ifdef pc386
+
+ data16
+ movl $ SYM(gdtptr), eax
+ data16
+ andl $0x0000ffff, eax # get offset into segment
+ addr16
+ lgdt cs:(eax) # load Global Descriptor Table
+ data16
+ movl $ SYM(idtptr), eax
+ data16
+ andl $0x0000ffff, eax # get offset into segment
+ addr16
+ lidt cs:(eax) # load Interrupt Descriptor Table
+
+ movl %cr0, eax
+ data16
+ orl $CR0_PE, eax
+ movl eax, %cr0 # turn on protected mode
+
+ data16
+ ljmp $PROT_CODE_SEG, $ SYM(next) # flush prefetch queue
+
+SYM(next):
+
+#endif /* pc386 */
+
+/*----------------------------------------------------------------------------+
+| Load the segment registers (this is done by the board's BSP) and perform any
+| other board specific initialization procedures.
+|
+| 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 $heap_size, eax # eax = end of heap
+ movl eax, stack_start # Save for brk() routine
+ addl $stack_size, eax # make room for stack
+ andl $0xffffffc0, eax # align it on 16 byte 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
+ shll ecx # size of .bss in longs
+ xorl eax, eax # value to clear out memory
+ repne # while ecx != 0
+ stosl # clear a long in the bss
+
+ /*---------------------------------------------------------------------+
+ | Copy the Global Descriptor Table to our space
+ +---------------------------------------------------------------------*/
+
+ sgdt SYM (_Original_GDTR) # save original GDT
+ movzwl SYM (_Original_GDTR)+DTR_LIMIT, ecx # size of GDT in bytes;
+ # limit is 8192 entries * 8 bytes per
+
+ /*---------------------------------------------------------------------+
+ | make ds:esi point to the original GDT
+ +---------------------------------------------------------------------*/
+
+ movl SYM (_Original_GDTR)+DTR_BASE, esi
+ push ds # save ds
+ movw gs, ax
+ movw ax, ds
+
+ /*---------------------------------------------------------------------+
+ | make es:edi point to the new (our copy) GDT
+ +---------------------------------------------------------------------*/
+
+ movl $ SYM (_Global_descriptor_table), edi
+
+ rep
+ movsb # copy the GDT (ds:esi -> es:edi)
+
+ pop ds # restore ds
+
+ /*---------------------------------------------------------------------+
+ | Build and load new contents of GDTR
+ +---------------------------------------------------------------------*/
+
+ movw SYM (_Original_GDTR)+DTR_LIMIT, ecx # set new limit
+ movw cx, SYM (_New_GDTR)+DTR_LIMIT
+
+ push $ SYM (_Global_descriptor_table)
+ push es
+ call SYM (i386_Logical_to_physical)
+ addl $6, esp
+ movl eax, SYM (_New_GDTR)+DTR_BASE # set new base
+
+ cmpb $0, SYM (_Do_Load_GDT) # Should the new GDT be loaded?
+ je SYM (no_gdt_load) # NO, then branch
+ lgdt SYM (_New_GDTR) # load the new GDT
+
+SYM (no_gdt_load):
+
+ /*---------------------------------------------------------------------+
+ | Copy the Interrupt Descriptor Table to our space
+ +---------------------------------------------------------------------*/
+
+ sidt SYM (_Original_IDTR) # save original IDT
+ movzwl SYM (_Original_IDTR)+DTR_LIMIT, ecx # size of IDT in bytes;
+ #limit is 256 entries * 8 bytes per
+
+ /*---------------------------------------------------------------------+
+ | make ds:esi point to the original IDT
+ +---------------------------------------------------------------------*/
+
+ movl SYM (_Original_IDTR)+DTR_BASE, esi
+
+ push ds # save ds
+ movw gs, ax
+ movw ax, ds
+
+ /*---------------------------------------------------------------------+
+ | make es:edi point to the new (our copy) IDT
+ +---------------------------------------------------------------------*/
+
+ movl $ SYM (Interrupt_descriptor_table), edi
+
+ rep
+ movsb # copy the IDT (ds:esi -> es:edi)
+ pop ds # restore ds
+
+ /*---------------------------------------------------------------------+
+ | Build and load new contents of IDTR
+ +---------------------------------------------------------------------*/
+
+ movw SYM (_Original_IDTR+DTR_LIMIT), ecx # set new limit
+ movw cx, SYM (_New_IDTR)+DTR_LIMIT
+
+ push $ SYM (Interrupt_descriptor_table)
+ push es
+ call SYM (i386_Logical_to_physical)
+ addl $6, esp
+ movl eax, SYM (_New_IDTR)+DTR_BASE # set new base
+
+ cmpb $0, SYM (_Do_Load_IDT) # Should the new IDT be loaded?
+ je SYM (no_idt_load) # NO, then branch
+ lidt SYM (_New_IDTR) # load the new IDT
+SYM (no_idt_load):
+
+ /*---------------------------------------------------------------------+
+ | Initialize the i387.
+ |
+ | Using the NO WAIT form of the instruction insures that if it is not
+ | present the board will not lock up or get an exception.
+ +---------------------------------------------------------------------*/
+
+ fninit # MUST USE NO-WAIT FORM
+
+ /*---------------------------------------------------------------------+
+ | Transfer control to User's Board Support Package
+ +---------------------------------------------------------------------*/
+
+ pushl $0 # environp
+ pushl $0 # argv
+ pushl $0 # argc
+ call SYM (main)
+ addl $12, esp
+
+ /*---------------------------------------------------------------------+
+ | Clean up
+ +---------------------------------------------------------------------*/
+
+ EXTERN (return_to_monitor)
+
+ PUBLIC (Bsp_cleanup)
+
+SYM (Bsp_cleanup):
+
+ cmpb $0, SYM (_Do_Load_IDT) # Was the new IDT loaded?
+ je SYM (no_idt_restore) # NO, then branch
+ lidt SYM (_Original_IDTR) # restore the new IDT
+
+SYM (no_idt_restore):
+
+ cmpb $0, SYM (_Do_Load_GDT) # Was the new GDT loaded?
+ je SYM (no_gdt_restore) # NO, then branch
+ lgdt SYM (_Original_GDTR) # restore the new GDT
+
+SYM (no_gdt_restore):
+
+ jmp SYM (_return_to_monitor)
+
+END_CODE
+
+/*----------------------------------------------------------------------------+
+| DATA section
++----------------------------------------------------------------------------*/
+
+BEGIN_DATA
+
+#ifdef pc386
+
+/**************************
+* GLOBAL DESCRIPTOR TABLE *
+**************************/
+
+ .align 4
+SYM(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
+
+/*************************************
+* INTERRUPT DESCRIPTOR TABLE POINTER *
+*************************************/
+
+ .align 4
+SYM(idtptr):
+ .word 0x07ff # limit at maximum (allows all 256 interrupts)
+ .word 0, 0 # base at 0
+
+#endif /* pc386 */
+
+ EXTERN (Do_Load_IDT) # defined in the BSP
+ EXTERN (Do_Load_GDT) # defined in the BSP
+
+ .align 2
+ PUBLIC (start_frame)
+SYM (start_frame):
+ .long 0
+
+ PUBLIC (stack_start)
+SYM (stack_start):
+ .long 0
+
+END_DATA
+
+/*----------------------------------------------------------------------------+
+| BSS section
++----------------------------------------------------------------------------*/
+
+BEGIN_BSS
+
+ PUBLIC (heap_size)
+ .set heap_size, 0x2000
+
+ PUBLIC (stack_size)
+ .set stack_size, 0x1000
+
+ PUBLIC (Interrupt_descriptor_table)
+SYM (Interrupt_descriptor_table):
+ .space (256 * 8) # reserve space for all 256 interrupts
+
+ PUBLIC (_Original_IDTR)
+SYM (_Original_IDTR):
+ .space DTR_SIZE
+
+ PUBLIC (_New_IDTR)
+SYM (_New_IDTR):
+ .space DTR_SIZE
+
+ PUBLIC (_Global_descriptor_table)
+SYM (_Global_descriptor_table):
+#ifdef pc386
+
+ .space (3 * 8) # the PC386 bsp only needs 3 segment descriptors:
+#else # NULL, CODE and DATA
+ .space (8192 * 8)
+
+#endif /* pc386 */
+
+ PUBLIC (_Original_GDTR)
+SYM (_Original_GDTR):
+ .space DTR_SIZE
+
+ PUBLIC (_New_GDTR)
+SYM (_New_GDTR):
+ .space DTR_SIZE
+
+ PUBLIC (_Physical_base_of_ds)
+SYM (_Physical_base_of_ds):
+ .space 4
+
+ PUBLIC (_Physical_base_of_cs)
+SYM (_Physical_base_of_cs):
+ .space 4
+
+END_BSS
+
+END