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

4.104.114.84.95
Last change on this file since d814e2c was 37bb9bf, checked in by Joel Sherrill <joel.sherrill@…>, on 08/14/02 at 22:43:10

2002-08-14 Joel Sherrill <joel@…>

  • start/start16.S: Per PR259, added code to test for video present before touching the adapter. Eric Norum <eric.norum@…> tested this patch.
  • Property mode set to 100644
File size: 6.4 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#include <bspopts.h>
22
23/*----------------------------------------------------------------------------+
24| Constants
25+----------------------------------------------------------------------------*/
26
27.set PROT_CODE_SEG, 0x08        # offset of code segment descriptor into GDT
28.set PROT_DATA_SEG, 0x10        # offset of code segment descriptor into GDT
29.set CR0_PE,        1           # protected mode flag on CR0 register
30.set HDRSTART,      HEADERADDR  # address of start of bin2boot header
31.set HDROFF,        0x24        # offset into bin2boot header of start32 addr
32.set STACKOFF,      0x200-0x10  # offset to load into %esp, from start of image
33
34 /* #define NEW_GAS */
35/*----------------------------------------------------------------------------+
36| CODE section
37+----------------------------------------------------------------------------*/
38
39.text
40
41        .globl _start16         # entry point
42        .globl start16
43start16:
44_start16:
45
46.code16
47
48        cli                     # DISABLE INTERRUPTS!!!
49
50        movw    %cs, %ax        #
51        movw    %ax, %ds        # set the rest of real mode registers
52        movw    %ax, %es        #
53        movw    %ax, %ss        #
54
55#if defined(RTEMS_VIDEO_80x50)
56       
57        movl    $0x0040,%eax    # use 32 bit constant to ensure 16 MSB=0
58        mov     %ax,%es
59        movw    %es:0x4a, %ax   # get 16 bit number of columns
60        cmpw    $0, %ax         # or 0 if no video adapter
61        je      1f              # if no video, skip touching it
62        /*---------------------------------------------------------------------+
63        | Switch VGA video to 80 lines x 50 columns mode. Has to be done before
64        | turning protected mode on since it uses BIOS int 10h (video) services.
65        +---------------------------------------------------------------------*/
66
67        movw    $0x0003, %ax    # forced set
68        int     $0x10
69        movw    $0x1112, %ax    # use 8x8 font
70        xorb    %bl, %bl
71        int     $0x10
72        movw    $0x1201, %ax    # turn off cursor emulation
73        movb    $0x34, %bl
74        int     $0x10
75        movb    $0x01, %ah      # define cursor (scan lines 0 to 7)
76        movw    $0x0007, %cx
77        int     $0x10
78
79+1:
80#endif /* RTEMS_VIDEO_80x50 */
81
82        /*---------------------------------------------------------------------+
83        | Bare PC machines boot in real mode! We have to turn protected mode on.
84        +---------------------------------------------------------------------*/
85
86        lgdt    gdtptr - start16        # load Global Descriptor Table
87        movl    %cr0, %eax
88        orl     $CR0_PE, %eax
89        movl    %eax, %cr0              # turn on protected mode
90       
91#ifdef NEW_GAS
92        ljmpl   $PROT_CODE_SEG, $1f     # flush prefetch queue, and reload %cs
93#else
94        ljmp    $PROT_CODE_SEG, $1f     # flush prefetch queue, and reload %cs
95#endif 
96.code32
971:
98        /*---------------------------------------------------------------------+
99        | load the other segment registers
100        +---------------------------------------------------------------------*/
101        movl    $PROT_DATA_SEG, %eax
102        movw    %ax, %ds
103        movw    %ax, %es
104        movw    %ax, %ss
105        movl    $start16 + STACKOFF, %esp       # set up stack pointer
106        addl    $start16 + STACKOFF, %ebp       # set up stack pointer
107
108        /*---------------------------------------------------------------------+
109        | we have to enable A20 in order to access memory above 1MByte
110        +---------------------------------------------------------------------*/
111        call    empty_8042
112        movb    $0xD1, %al              # command write
113        outb    %al, $0x64
114        call    empty_8042
115        movb    $0xDF, %al              # A20 on
116        outb    %al, $0x60
117        call    empty_8042
118
119        call    pc386_delay
120        call    pc386_delay
121        call    pc386_delay
122
123        movl    %cs:HDRSTART + HDROFF, %eax     #
124        pushl   %eax                            # jump to start of 32 bit code
125        ret                                     #
126
127/*----------------------------------------------------------------------------+
128| pc386_delay
129+------------------------------------------------------------------------------
130| Delay is needed after doing I/O.
131|
132| The outb version is OK on most machines BUT the loop version ...
133|
134| will delay for 1us on 1Gz machine, it will take a little bit
135| longer on slower machines, however, it does not matter because we
136| are going to call this function only a few times
137!
138| NOTE: Saving the content of the EAX register just in case. - Rosimildo.
139+----------------------------------------------------------------------------*/
140        .p2align 4
141        .globl _pc386_delay
142        .globl pc386_delay
143pc386_delay:
144_pc386_delay:
145        pushl   %eax
146#if defined(USE_OUTB_FOR_DELAY)
147        outb    %al, $0x80      # about 1uS delay on most machines
148
149#else
150
151        movl    $0x200, %eax
152pc386_delay1:
153        dec     %eax
154        jnz     pc386_delay1
155#endif
156        popl    %eax
157        ret
158
159/*----------------------------------------------------------------------------+
160| empty_8042
161+------------------------------------------------------------------------------
162| This routine checks that the keyboard command queue is empty (after emptying
163| the output buffers).
164| No timeout is used - if this hangs there is something wrong with the machine,
165| and we probably couldn't proceed anyway.
166+----------------------------------------------------------------------------*/
167        .p2align 4
168        .globl _empty_8042
169        .globl empty_8042
170empty_8042:
171_empty_8042:
172        call    pc386_delay
173        inb     $0x64, %al      # 8042 status port
174        testb   $0x01, %al      # output buffer?
175        jz      no_output
176        call    pc386_delay
177        in      $0x60, %al      # read it
178        jmp     empty_8042
179no_output:
180        test    $0x02, %al      # is input buffer full?
181        jnz     empty_8042      # yes - loop
182        ret
183       
184/*----------------------------------------------------------------------------+
185| DATA section
186+----------------------------------------------------------------------------*/
187
188/**************************
189* GLOBAL DESCRIPTOR TABLE *
190**************************/
191
192        .p2align 4
193gdtptr:
194        /* we use the NULL descriptor to store the GDT pointer - a trick quite
195           nifty due to: Robert Collins (rcollins@x86.org) */
196        .word   gdtlen - 1
197        .long   gdtptr
198        .word   0x0000
199
200        /* code segment */
201        .word   0xffff, 0
202        .byte   0, 0x9f, 0xcf, 0
203
204        /* data segment */
205        .word   0xffff, 0
206        .byte   0, 0x93, 0xcf, 0
207
208        .set    gdtlen, . - gdtptr      # length of GDT
209       
Note: See TracBrowser for help on using the repository browser.