source: rtems/c/src/lib/libbsp/i386/pc386/start/start16.S @ 5e8bfe2

4.115
Last change on this file since 5e8bfe2 was 5e8bfe2, checked in by Jennifer Averett <Jennifer.Averett@…>, on 07/20/11 at 16:50:19

2011-07-20 Jennifer Averett <Jennifer.Averett@…>

  • start/start16.S: Removed tabs and added OAR standard copyright header in preperation for merging SMP support.
  • Property mode set to 100644
File size: 7.8 KB
Line 
1/*--------------------------------------------------------------------------+
2 * start16.s v1.0 - PC386 BSP - 1998/04/13
3 *--------------------------------------------------------------------------+
4 * This file contains the entry point for the application.
5 * The name of this entry point is compiler dependent.
6 * It jumps to the BSP which is responsible for performing all initialization.
7 *--------------------------------------------------------------------------+
8 * (C) Copyright 1997 -
9 * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
10 *
11 * http://pandora.ist.utl.pt
12 *
13 * Instituto Superior Tecnico * Lisboa * PORTUGAL
14 *--------------------------------------------------------------------------+
15 * Disclaimer:
16 *
17 * This file is provided "AS IS" without warranty of any kind, either
18 * expressed or implied.
19 *--------------------------------------------------------------------------+
20 */
21
22/*
23 *  COPYRIGHT (c) 2011.
24 *  On-Line Applications Research Corporation (OAR).
25 *
26 *  The license and distribution terms for this file may be
27 *  found in the file LICENSE in this distribution or at
28 *  http://www.rtems.com/license/LICENSE.
29 *
30 *  $Id$
31 */
32
33
34#include <bspopts.h>
35
36/*---------------------------------------------------------------------------+
37| Constants
38+----------------------------------------------------------------------------*/
39
40.set PROT_CODE_SEG, 0x0         # offset of code segment descriptor into GDT
41.set PROT_DATA_SEG, 0x10        # offset of code segment descriptor into GDT
42.set CR0_PE,        1           # protected mode flag on CR0 register
43.set HDRSTART,      HEADERADDR  # address of start of bin2boot header
44.set HDROFF,        0x24        # offset into bin2boot header of start32 addr
45.set STACKOFF,      0x200-0x10  # offset to load into %esp, from start of image
46
47 /* #define NEW_GAS */
48/*----------------------------------------------------------------------------+
49| CODE section
50+----------------------------------------------------------------------------*/
51
52.text
53
54        .globl _start16         # entry point
55        .globl start16
56start16:
57_start16:
58
59.code16
60        cli                     # DISABLE INTERRUPTS!!!
61
62        movw    %cs, %ax        #
63        movw    %ax, %ds        # set the rest of real mode registers
64        movw    %ax, %es        #
65        movw    %ax, %ss        #
66
67#if (RTEMS_VIDEO_80x50 == 1)
68
69        movl    $0x0040,%eax    # use 32 bit constant to ensure 16 MSB=0
70        mov     %ax,%es
71        movw    %es:0x4a, %ax   # get 16 bit number of columns
72        cmpw    $0, %ax         # or 0 if no video adapter
73        je      1f              # if no video, skip touching it
74        /*---------------------------------------------------------------------+
75        | Switch VGA video to 80 lines x 50 columns mode. Has to be done before
76        | turning protected mode on since it uses BIOS int 10h (video) services.
77        +---------------------------------------------------------------------*/
78
79        movw    $0x0003, %ax    # forced set
80        int     $0x10
81        movw    $0x1112, %ax    # use 8x8 font
82        xorb    %bl, %bl
83        int     $0x10
84        movw    $0x1201, %ax    # turn off cursor emulation
85        movb    $0x34, %bl
86        int     $0x10
87        movb    $0x01, %ah      # define cursor (scan lines 0 to 7)
88        movw    $0x0007, %cx
89        int     $0x10
90
911:
92#endif /* RTEMS_VIDEO_80x50 */
93
94        /*---------------------------------------------------------------------+
95        | Bare PC machines boot in real mode! We have to turn protected mode on.
96        +---------------------------------------------------------------------*/
97
98        lgdt    gdtptr - start16        # load Global Descriptor Table
99        movl    %cr0, %eax
100        orl     $CR0_PE, %eax
101        movl    %eax, %cr0              # turn on protected mode
102
103#ifdef NEW_GAS
104        ljmpl   $PROT_CODE_SEG, $1f     # flush prefetch queue, and reload %cs
105#else
106        ljmp    $PROT_CODE_SEG, $1f     # flush prefetch queue, and reload %cs
107#endif
108.code32
1091:
110        /*---------------------------------------------------------------------+
111        | load the other segment registers
112        +---------------------------------------------------------------------*/
113        movl    $PROT_DATA_SEG, %eax
114        movw    %ax, %ds
115        movw    %ax, %es
116        movw    %ax, %ss
117        movl    $start16 + STACKOFF, %esp       # set up stack pointer
118        addl    $start16 + STACKOFF, %ebp       # set up stack pointer
119
120        /*---------------------------------------------------------------------+
121        | we have to enable A20 in order to access memory above 1MByte
122        +---------------------------------------------------------------------*/
123        call    empty_8042
124        movb    $0xD1, %al                      # command write
125        outb    %al, $0x64
126        call    empty_8042
127        movb    $0xDF, %al                      # A20 on
128        outb    %al, $0x60
129        call    empty_8042
130
131        call    pc386_delay
132        call    pc386_delay
133        call    pc386_delay
134
135        movl    %cs:HDRSTART + HDROFF, %eax     #
136        pushl   %eax                            # jump to start of 32 bit code
137        ret                                     #
138
139/*----------------------------------------------------------------------------+
140| pc386_delay
141+------------------------------------------------------------------------------
142| Delay is needed after doing I/O.
143|
144| The outb version is OK on most machines BUT the loop version ...
145|
146| will delay for 1us on 1Gz machine, it will take a little bit
147| longer on slower machines, however, it does not matter because we
148| are going to call this function only a few times
149!
150| NOTE: Saving the content of the EAX register just in case. - Rosimildo.
151+----------------------------------------------------------------------------*/
152        .p2align 4
153        .globl _pc386_delay
154        .globl pc386_delay
155pc386_delay:
156_pc386_delay:
157        pushl   %eax
158#if defined(USE_OUTB_FOR_DELAY)
159        outb    %al, $0x80       # about 1uS delay on most machines
160
161#else
162
163        movl    $0x200, %eax
164pc386_delay1:
165        dec     %eax
166        jnz     pc386_delay1
167#endif
168        popl    %eax
169        ret
170
171/*----------------------------------------------------------------------------+
172| empty_8042
173+------------------------------------------------------------------------------
174| This routine checks that the keyboard command queue is empty (after emptying
175| the output buffers).
176| No timeout is used - if this hangs there is something wrong with the machine,
177| and we probably couldn't proceed anyway.
178+----------------------------------------------------------------------------*/
179        .p2align 4
180        .globl _empty_8042
181        .globl empty_8042
182empty_8042:
183_empty_8042:
184        call    pc386_delay
185        inb     $0x64, %al      # 8042 status port
186        testb   $0x01, %al      # output buffer?
187        jz      no_output
188        call    pc386_delay
189        in      $0x60, %al      # read it
190        jmp     empty_8042
191no_output:
192        test    $0x02, %al      # is input buffer full?
193        jnz     empty_8042      # yes - loop
194        ret
195
196/*----------------------------------------------------------------------------+
197| DATA section
198+----------------------------------------------------------------------------*/
199
200/**************************
201* GLOBAL DESCRIPTOR TABLE *
202**************************/
203
204        .p2align 4
205gdtptr:
206        /* we use the NULL descriptor to store the GDT pointer - a trick quite
207           nifty due to: Robert Collins (rcollins@x86.org) */
208        .word   gdtlen - 1
209        .long   gdtptr
210        .word   0x0000
211
212        /* code segment */
213        .word   0xffff, 0
214        .byte   0, 0x9f, 0xcf, 0
215
216        /* data segment */
217        .word   0xffff, 0
218        .byte   0, 0x93, 0xcf, 0
219
220        .set    gdtlen, . - gdtptr      # length of GDT
Note: See TracBrowser for help on using the repository browser.