summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/start/start16.s
blob: 0e715368bac90bf1963a1f8bceb88177d618fc37 (plain) (tree)

















































































































































































                                                                                                                                                      
/*-------------------------------------------------------------------------+
| start16hi.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.
+--------------------------------------------------------------------------+
| This code is partly based on (from the Linux source tree):
|   video.S - Copyright (C) 1995, 1996 Martin Mares <mj@k332.feld.cvut.cz>
+--------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------+
| Constants
+----------------------------------------------------------------------------*/

.set PROT_CODE_SEG, 0x08	# offset of code segment descriptor into GDT
.set CR0_PE,        1		# protected mode flag on CR0 register
.set START32,       START32ADDR # address of protected mode code

/*----------------------------------------------------------------------------+
| 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
+----------------------------------------------------------------------------*/

.text

	.globl _start16		# entry point
	.globl start16
start16:
_start16:

.code16

#if defined(RTEMS_VIDEO_80x50)
	
	/*---------------------------------------------------------------------+
	| 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

#endif /* RTEMS_VIDEO_80x50 */

        cli			# DISABLE INTERRUPTS!!!

	/*---------------------------------------------------------------------+
	| Bare PC machines boot in real mode! We have to turn protected mode on.
	+---------------------------------------------------------------------*/

	movl	$gdtptr, %eax
	andl	$0x0000ffff, %eax	# get offset into segment
	lgdt	%cs:(%eax)		# load Global Descriptor Table
	movl	$idtptr, %eax
	andl	$0x0000ffff, %eax	# get offset into segment
	lidt	%cs:(%eax)		# load Interrupt Descriptor Table
	
	movl	%cr0, %eax
	orl	$CR0_PE, %eax
	movl	%eax, %cr0		# turn on protected mode

	ljmp	$PROT_CODE_SEG, $1f	# flush prefetch queue
1:

.code32

        /*---------------------------------------------------------------------+        | 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

	ljmp	$PROT_CODE_SEG, $START32	# jump to start of 32 bit code

/*----------------------------------------------------------------------------+
| delay
+------------------------------------------------------------------------------
| Delay is needed after doing I/O. We do it by writing to a non-existent port.
+----------------------------------------------------------------------------*/
	.globl _delay
	.globl delay
delay:
_delay:
	outb	%al, $0xED	# about 1uS delay
	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.
+----------------------------------------------------------------------------*/
	.globl _empty_8042
	.globl empty_8042
empty_8042:
_empty_8042:
	call	delay
	inb	$0x64, %al	# 8042 status port
	testb	$0x01, %al	# output buffer?
	jz	no_output
	call	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 *
**************************/

	.align	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
	
/*************************************
* INTERRUPT DESCRIPTOR TABLE POINTER *
*************************************/

	.align	4
idtptr:
	.word	0x07ff	# limit at maximum (allows all 256 interrupts)
	.word	0, 0	# base at 0