forked from Imagelibrary/rtems
New file from Pedro Romano
This commit is contained in:
178
c/src/lib/libbsp/i386/pc386/start/start16.s
Normal file
178
c/src/lib/libbsp/i386/pc386/start/start16.s
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
/*-------------------------------------------------------------------------+
|
||||||
|
| 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
|
||||||
Reference in New Issue
Block a user