Index: c/src/lib/libbsp/i386/pc386/start/start.s
===================================================================
--- c/src/lib/libbsp/i386/pc386/start/start.s	(revision 7150f00f5be87fa8e37f7d00fbbef35645081138)
+++ c/src/lib/libbsp/i386/pc386/start/start.s	(revision 7150f00f5be87fa8e37f7d00fbbef35645081138)
@@ -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
