source: rtems/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s @ 7150f00f

4.104.114.84.95
Last change on this file since 7150f00f was 7150f00f, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 1, 1997 at 10:06:48 PM

Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano
<pmcnr@…> and Jose Rufino <ruf@…>
of NavIST (http://pandora.ist.utl.pt/).

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*-------------------------------------------------------------------------+
2| ldsegs.s v1.1 - PC386 BSP - 1997/08/07
3+--------------------------------------------------------------------------+
4| This file assists the board independent startup code by loading the proper
5| segment register values. The values loaded are board dependent. In addition
6| it contains code to enable the A20 line and to reprogram the PIC to relocate
7| the IRQ interrupt vectors to 0x20 -> 0x2f.
8| NOTE: No stack has been established when this routine is invoked.
9|       It returns by jumping back to bspentry.
10+--------------------------------------------------------------------------+
11| (C) Copyright 1997 -
12| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
13|
14| http://pandora.ist.utl.pt
15|
16| Instituto Superior Tecnico * Lisboa * PORTUGAL
17+--------------------------------------------------------------------------+
18| Disclaimer:
19|
20| This file is provided "AS IS" without warranty of any kind, either
21| expressed or implied.
22+--------------------------------------------------------------------------+
23| This code is base on:
24|   ldsegs.s,v 1.4 1996/04/20 16:48:30 joel Exp - go32 BSP
25| With the following copyright notice:
26| **************************************************************************
27| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.                      *
28| * On-Line Applications Research Corporation (OAR).                       *
29| * All rights assigned to U.S. Government, 1994.                          *
30| *                                                                        *
31| * This material may be reproduced by or for the U.S. Government pursuant *
32| * to the copyright license under the clause at DFARS 252.227-7013.  This *
33| * notice must appear in all copies of this file and its derivatives.     *
34| **************************************************************************
35|
36| Also based on (from the Linux source tree):
37|   setup.S - Copyright (C) 1991, 1992 Linus Torvalds
38+--------------------------------------------------------------------------*/
39
40
41#include "asm.h"
42
43/*----------------------------------------------------------------------------+
44| Constants
45+----------------------------------------------------------------------------*/
46.set    PROT_DATA_SEG, 0x10     # offset in gdt
47.set    RESET_SS, PROT_DATA_SEG # initial value of stack segment register
48.set    RESET_DS, PROT_DATA_SEG # initial value of data segment register
49.set    RESET_ES, PROT_DATA_SEG # initial value of extra segment register
50.set    RESET_FS, PROT_DATA_SEG # initial value of "f" segment register
51.set    RESET_GS, PROT_DATA_SEG # initial value of "g" segment register
52
53
54/*----------------------------------------------------------------------------+
55| Macros
56+----------------------------------------------------------------------------*/
57#define LOAD_SEGMENTS(_value, _segment) \
58        movw    $ ## _value, ax; \
59        movw    ax, _segment
60
61/*----------------------------------------------------------------------------+
62| CODE section
63+----------------------------------------------------------------------------*/
64
65BEGIN_CODE
66
67        EXTERN (establish_stack)
68
69/*----------------------------------------------------------------------------+
70| empty_8042
71+------------------------------------------------------------------------------
72| This routine checks that the keyboard command queue is empty (after emptying
73| the output buffers).
74| No timeout is used - if this hangs there is something wrong with the machine,
75| and we probably couldn't proceed anyway.
76+----------------------------------------------------------------------------*/
77SYM(empty_8042):
78        call    delay
79        inb     $0x64, al       # 8042 status port
80        testb   $0x01, al       # output buffer?
81        jz      SYM(no_output)
82        call    SYM(delay)
83        in      $0x60, al       # read it
84        jmp     SYM(empty_8042)
85SYM(no_output):
86        test    $0x02, al       # is input buffer full?
87        jnz     SYM(empty_8042) # yes - loop
88        ret
89
90/*----------------------------------------------------------------------------+
91| delay
92+------------------------------------------------------------------------------
93| Delay is needed after doing I/O. We do it by writing to a non-existent port.
94+----------------------------------------------------------------------------*/
95SYM(delay):
96        outb    al, $0xED       # about 1uS delay
97        ret
98
99/*-------------------------------------------------------------------------+
100|         Function: _load_segments
101|      Description: Load board segment registers with apropriate values + enable
102                    A20 line + reprogram PIC.
103| Global Variables: None.
104|        Arguments: None.
105|          Returns: Nothing.
106+--------------------------------------------------------------------------*/
107        PUBLIC (_load_segments)
108SYM (_load_segments):
109       
110        LOAD_SEGMENTS(RESET_SS, ss)
111        LOAD_SEGMENTS(RESET_DS, ds)
112        LOAD_SEGMENTS(RESET_ES, es)
113        LOAD_SEGMENTS(RESET_FS, fs)
114        LOAD_SEGMENTS(RESET_GS, gs)
115
116        /*---------------------------------------------------------------------+
117        | we have to enable A20 in order to access memory above 1MByte
118        +---------------------------------------------------------------------*/
119
120        call    SYM(empty_8042)
121        movb    $0xD1, al               # command write
122        outb    al, $0x64
123        call    SYM(empty_8042)
124        movb    $0xDF, al               # A20 on
125        outb    al, $0x60
126        call    SYM(empty_8042)
127
128        /*---------------------------------------------------------------------+
129        | Now we have to reprogram the interrupts :-(. We put them right after
130        | the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
131        | won't mess up anything. Sadly IBM really messed this up with the
132        | original PC, and they haven't been able to rectify it afterwards. Thus
133        | the bios puts interrupts at 0x08-0x0f, which is used for the internal
134        | hardware interrupts as well. We just have to reprogram the 8259's, and
135        | it isn't fun.
136        +---------------------------------------------------------------------*/
137
138        movb    $0x11, al               /* initialization sequence          */
139        outb    al, $0x20               /* send it to 8259A-1               */
140        call    SYM(delay)
141        outb    al, $0xA0               /* and to 8259A-2                   */
142        call    SYM(delay)
143       
144        movb    $0x20, al               /* start of hardware int's (0x20)   */
145        outb    al, $0x21
146        call    SYM(delay)
147        movb    $0x28, al               /* start of hardware int's 2 (0x28) */
148        outb    al, $0xA1
149        call    SYM(delay)
150       
151        movb    $0x04, al               /* 8259-1 is master                 */
152        outb    al, $0x21
153        call    SYM(delay)
154        movb    $0x02, al               /* 8259-2 is slave                  */
155        outb    al, $0xA1
156        call    SYM(delay)
157       
158        movb    $0x01, al               /* 8086 mode for both               */
159        outb    al, $0x21
160        call    SYM(delay)
161        outb    al, $0xA1
162        call    SYM(delay)
163       
164        movb    $0xFF, al               /* mask off all interrupts for now  */
165        outb    al, $0xA1
166        call    SYM(delay)
167        movb    $0xFB, al               /* mask all irq's but irq2 which    */
168        outb    al, $0x21               /* is cascaded                      */
169        call    SYM(delay)
170
171        jmp     SYM (_establish_stack)  # return to the bsp entry code
172
173/*-------------------------------------------------------------------------+
174|         Function: _return_to_monitor
175|      Description: Return to board's monitor (we have none so simply restart).
176| Global Variables: None.
177|        Arguments: None.
178|          Returns: Nothing.
179+--------------------------------------------------------------------------*/
180        PUBLIC (_return_to_monitor)
181SYM (_return_to_monitor):
182
183        call    SYM (Timer_exit)
184        call    SYM (Clock_exit)
185        jmp     SYM (start)
186
187END_CODE
188
189/*----------------------------------------------------------------------------+
190| DATA section
191+----------------------------------------------------------------------------*/
192
193BEGIN_DATA
194
195        PUBLIC (_Do_Load_IDT)
196SYM (_Do_Load_IDT):
197       .byte 1  # load RTEMS own Interrupt Descriptor Table
198
199        PUBLIC (_Do_Load_GDT)
200SYM (_Do_Load_GDT):
201       .byte 0  # use the Global Descriptor Table that is already defined
202
203END_DATA
204
205END
Note: See TracBrowser for help on using the repository browser.