From 7150f00f5be87fa8e37f7d00fbbef35645081138 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 1 Dec 1997 22:06:48 +0000 Subject: Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano and Jose Rufino of NavIST (http://pandora.ist.utl.pt/). --- c/src/lib/libbsp/i386/pc386/start/Makefile.in | 56 ++++ c/src/lib/libbsp/i386/pc386/start/start.s | 416 ++++++++++++++++++++++++++ 2 files changed, 472 insertions(+) create mode 100644 c/src/lib/libbsp/i386/pc386/start/Makefile.in create mode 100644 c/src/lib/libbsp/i386/pc386/start/start.s (limited to 'c/src/lib/libbsp/i386/pc386/start') 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 ++--------------------------------------------------------------------------*/ + + +#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 -- cgit v1.2.3