source: rtems/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S @ 0089173

4.115
Last change on this file since 0089173 was 0089173, checked in by Joel Sherrill <joel.sherrill@…>, on 05/02/12 at 19:22:46

pc386 - Remove odd $Id$

  • Property mode set to 100644
File size: 7.1 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-1999.
28| *  On-Line Applications Research Corporation (OAR).
29| *
30| *  The license and distribution terms for this file may be
31| *  found in the file LICENSE in this distribution or at
32| *  http://www.rtems.com/license/LICENSE.
33| **************************************************************************
34+--------------------------------------------------------------------------*/
35
36#include <rtems/asm.h>
37
38/*----------------------------------------------------------------------------+
39| CODE section
40+----------------------------------------------------------------------------*/
41EXTERN (rtems_i8259_masks)
42
43BEGIN_CODE
44
45        EXTERN (_establish_stack)
46        EXTERN (Timer_exit)
47        EXTERN (clockOff)
48
49/*----------------------------------------------------------------------------+
50| pc386_delay
51+------------------------------------------------------------------------------
52| Delay is needed after doing I/O.
53|
54| The outb version is OK on most machines BUT the loop version ...
55|
56| will delay for 1us on 1Gz machine, it will take a little bit
57| longer on slower machines, however, it does not matter because we
58| are going to call this function only a few times
59
60+----------------------------------------------------------------------------*/
61#define DELAY_USE_OUTB
62
63        .p2align 4
64        .globl _pc386_delay
65        .globl pc386_delay
66pc386_delay:
67_pc386_delay:
68#ifdef  DELAY_USE_OUTB
69        outb    al, $0x80       # about 1uS delay on most machines
70#else
71        movl    $0x200, eax
72pc386_delay1:
73        dec     eax
74        jnz     pc386_delay1
75#endif
76        ret
77
78/*-------------------------------------------------------------------------+
79|         Function: _load_segments
80|      Description: Current environment is standard PC booted by grub.
81|                   So, there is no value in saving current GDT and IDT
82|                   settings we have to set it up ourseves. (Naturally
83|                   it will be not so in case we are booted by some
84|                   boot monitor, however, then it will be different
85|                   BSP). After that we have to load board segment registers
86|                   with apropriate values +  reprogram PIC.
87| Global Variables: None.
88|        Arguments: None.
89|          Returns: Nothing.
90+--------------------------------------------------------------------------*/
91        .p2align 4
92
93        PUBLIC (_load_segments)
94SYM (_load_segments):
95
96        lgdt SYM(gdtdesc)
97        lidt SYM(IDT_Descriptor)
98
99        /* Load CS, flush prefetched queue */
100        ljmp $0x8, $next_step
101
102next_step:
103        /* Load segment registers */
104        movw $0x10, ax
105        movw ax, ss
106        movw ax, ds
107        movw ax, es
108        movw ax, fs
109        movw ax, gs
110
111/*---------------------------------------------------------------------+
112| Now we have to reprogram the interrupts :-(. We put them right after
113| the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
114| won't mess up anything. Sadly IBM really messed this up with the
115| original PC, and they haven't been able to rectify it afterwards. Thus
116| the bios puts interrupts at 0x08-0x0f, which is used for the internal
117| hardware interrupts as well. We just have to reprogram the 8259's, and
118| it isn't fun.
119+---------------------------------------------------------------------*/
120
121        movb    $0x11, al               /* initialization sequence          */
122        outb    al, $0x20               /* send it to 8259A-1               */
123        call    SYM(pc386_delay)
124        outb    al, $0xA0               /* and to 8259A-2                   */
125        call    SYM(pc386_delay)
126
127        movb    $0x20, al               /* start of hardware int's (0x20)   */
128        outb    al, $0x21
129        call    SYM(pc386_delay)
130        movb    $0x28, al               /* start of hardware int's 2 (0x28) */
131        outb    al, $0xA1
132        call    SYM(pc386_delay)
133
134        movb    $0x04, al               /* 8259-1 is master                 */
135        outb    al, $0x21
136        call    SYM(pc386_delay)
137        movb    $0x02, al               /* 8259-2 is slave                  */
138        outb    al, $0xA1
139        call    SYM(pc386_delay)
140
141        movb    $0x01, al               /* 8086 mode for both               */
142        outb    al, $0x21
143        call    SYM(pc386_delay)
144        outb    al, $0xA1
145        call    SYM(pc386_delay)
146
147        movb    $0xFF, al               /* mask off all interrupts for now  */
148        outb    al, $0xA1
149        call    SYM(pc386_delay)
150        movb    $0xFB, al               /* mask all irq's but irq2 which    */
151        outb    al, $0x21               /* is cascaded                      */
152        call    SYM(pc386_delay)
153
154        movw    $0xFFFB, SYM(i8259s_cache) /* set up same values in cache */
155
156        jmp     SYM (_establish_stack)  # return to the bsp entry code
157
158/*-------------------------------------------------------------------------+
159|         Function: _default_int_handler
160|      Description: default interrupt handler
161| Global Variables: None.
162|        Arguments: None.
163|          Returns: Nothing.
164+--------------------------------------------------------------------------*/
165        .p2align 4
166
167/*---------------------------------------------------------------------------+
168| GDT itself
169+--------------------------------------------------------------------------*/
170
171BEGIN_DATA
172        .p2align 4
173
174        PUBLIC (_Global_descriptor_table)
175SYM (_Global_descriptor_table):
176
177        /* NULL segment */
178        .word 0, 0
179        .byte 0, 0, 0, 0
180
181        /* code segment */
182        .word 0xffff, 0
183        .byte 0, 0x9e, 0xcf, 0
184
185        /* data segment */
186        .word 0xffff, 0
187        .byte 0, 0x92, 0xcf, 0
188
189/*---------------------------------------------------------------------------+
190| Descriptor of GDT
191+--------------------------------------------------------------------------*/
192SYM (gdtdesc):
193        .word (3*8 - 1)
194        .long SYM (_Global_descriptor_table)
195
196/*---------------------------------------------------------------------------+
197| IDT itself
198+---------------------------------------------------------------------------*/
199        .p2align 4
200
201        PUBLIC(Interrupt_descriptor_table)
202SYM(Interrupt_descriptor_table):
203        .rept 256
204        .word 0,0,0,0
205        .endr
206
207/*---------------------------------------------------------------------------+
208| Descriptor of IDT
209+--------------------------------------------------------------------------*/
210
211        .p2align 4
212        PUBLIC(IDT_Descriptor)
213SYM(IDT_Descriptor):
214        .word  (256*8 - 1)
215        .long  SYM (Interrupt_descriptor_table)
216
217END_DATA
218
219    .section .m_hdr
220        .long 0x1BADB002
221        .long 0
222        .long 0xE4524FFE
223END
Note: See TracBrowser for help on using the repository browser.