1 |
30 |
unneback |
/*
|
2 |
|
|
* This file is the main boot and configuration file for the i386ex. It is
|
3 |
|
|
* solely responsible for initializing the internal register set to reflect
|
4 |
|
|
* the proper board configuration. This version is the "generic" i386ex
|
5 |
|
|
* startup:
|
6 |
|
|
*
|
7 |
|
|
* 1) 512K flask ROM @3f80000
|
8 |
|
|
* 2) 1 Mb RAM @ 0x0
|
9 |
|
|
* 3) Timer0 used as RTEMS clock ticker, 1 msec tick rate.
|
10 |
|
|
* 4) READY# is generated by CPU
|
11 |
|
|
*
|
12 |
|
|
* The file is a multi-section file, with sections as follows:
|
13 |
|
|
* 1) interrupt gates, in section "ints"
|
14 |
|
|
* 2) interrupt descriptor table, in section "idt"
|
15 |
|
|
* 3) global descriptor table, in section "gdt"
|
16 |
|
|
* 4) reset in section "reset"
|
17 |
|
|
* 5) and initial boot code in section " initial"
|
18 |
|
|
*
|
19 |
|
|
* Submitted by:
|
20 |
|
|
*
|
21 |
|
|
* Erik Ivanenko
|
22 |
|
|
* University of Toronto
|
23 |
|
|
* erik.ivanenko@utoronto.ca
|
24 |
|
|
*
|
25 |
|
|
* The license and distribution terms for this file may be
|
26 |
|
|
* found in the file LICENSE in this distribution or at
|
27 |
|
|
* http://www.OARcorp.com/rtems/license.html.
|
28 |
|
|
*
|
29 |
|
|
* $Id: start.S,v 1.2 2001-09-27 11:59:46 chris Exp $
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
changes:
|
33 |
|
|
SetExRegByte(ICW3S , 0x02 ) # MUST be 0x02 according to intel
|
34 |
|
|
SetExRegByte(ICW3M , 0x04 ) # IR2 is cascaded internally: was 0x02 => IR1 is cascaded
|
35 |
|
|
|
36 |
|
|
*/
|
37 |
|
|
|
38 |
|
|
|
39 |
|
|
#include "asm.h"
|
40 |
|
|
#include "macros.inc"
|
41 |
|
|
#include "80386ex.inc"
|
42 |
|
|
|
43 |
|
|
|
44 |
|
|
/*
|
45 |
|
|
* NEW_GAS Needed for binutils 2.9.1.0.7 and higher
|
46 |
|
|
*/
|
47 |
|
|
|
48 |
|
|
EXTERN (boot_card) /* exits to bspstart */
|
49 |
|
|
EXTERN (stack_start) /* defined in startup/linkcmds */
|
50 |
|
|
EXTERN (Clock_exit)
|
51 |
|
|
|
52 |
|
|
PUBLIC (Interrupt_descriptor_table)
|
53 |
|
|
PUBLIC ( SYM(IDTR) )
|
54 |
|
|
/* PUBLIC( SYM(_initInternalRegisters) ) */
|
55 |
|
|
|
56 |
|
|
BEGIN_DATA
|
57 |
|
|
SYM(IDTR): DESC3( SYM(Interrupt_descriptor_table), 0x07ff );
|
58 |
|
|
|
59 |
|
|
SYM(Interrupt_descriptor_table): /* Now in data section */
|
60 |
|
|
.rept 256
|
61 |
|
|
.word 0,0,0,0
|
62 |
|
|
.endr
|
63 |
|
|
|
64 |
|
|
END_DATA
|
65 |
|
|
|
66 |
|
|
BEGIN_DATA
|
67 |
|
|
PUBLIC (_Global_descriptor_table)
|
68 |
|
|
|
69 |
|
|
SYM(GDTR): DESC3( GDT_TABLE, 0x1f ); # one less than the size
|
70 |
|
|
SYM (_Global_descriptor_table):
|
71 |
|
|
SYM(GDT_TABLE): DESC2(0,0,0,0,0,0);
|
72 |
|
|
SYM(GDT_ALIAS): DESC2(32,0x1000,0x0,0x93,0,0x0);
|
73 |
|
|
SYM(GDT_CODE): DESC2(0xffff,0,0x0,0x9B,0xDF,0x00);
|
74 |
|
|
SYM(GDT_DATA): DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF
|
75 |
|
|
SYM(GDT_END):
|
76 |
|
|
|
77 |
|
|
END_DATA
|
78 |
|
|
|
79 |
|
|
|
80 |
|
|
/* This section is the section that is used by the interrupt
|
81 |
|
|
descriptor table. It is used to provide the IDT with the
|
82 |
|
|
correct vector offsets. It is for symbol definition only.
|
83 |
|
|
*/
|
84 |
|
|
|
85 |
|
|
.code16
|
86 |
|
|
.section .reset, "ax"
|
87 |
|
|
PUBLIC ( SYM(reset) )
|
88 |
|
|
SYM(reset):
|
89 |
|
|
nop
|
90 |
|
|
cli
|
91 |
|
|
#ifdef NEW_GAS
|
92 |
|
|
data32 addr32 jmp SYM(_initInternalRegisters) /* different section in this file */
|
93 |
|
|
#else
|
94 |
|
|
jmp SYM(_initInternalRegisters) /* different section in this file */
|
95 |
|
|
#endif
|
96 |
|
|
/* .code32 in case this section moves */
|
97 |
|
|
nop /* required by CHIP LAB to pad out size */
|
98 |
|
|
nop
|
99 |
|
|
nop
|
100 |
|
|
nop
|
101 |
|
|
nop
|
102 |
|
|
nop
|
103 |
|
|
nop
|
104 |
|
|
nop
|
105 |
|
|
nop
|
106 |
|
|
nop
|
107 |
|
|
nop
|
108 |
|
|
|
109 |
|
|
.section .initial, "ax"
|
110 |
|
|
/* nop */ /* required for linker -- initial jump is to "label - 2" */
|
111 |
|
|
/* nop */ /* ie. _initInternalRegisters -2 ( which now == .initial ) */
|
112 |
|
|
/*
|
113 |
|
|
* Enable access to peripheral register at expanded I/O addresses
|
114 |
|
|
*/
|
115 |
|
|
SYM(_initInternalRegisters):
|
116 |
|
|
|
117 |
|
|
/* .code16 */
|
118 |
|
|
movw $0x8000 , ax
|
119 |
|
|
outb al , $REMAPCFGH
|
120 |
|
|
xchg al , ah
|
121 |
|
|
outb al,$REMAPCFGL
|
122 |
|
|
outw ax, $REMAPCFG ;
|
123 |
|
|
/*
|
124 |
|
|
* Configure operation of the A20 Address Line
|
125 |
|
|
*/
|
126 |
|
|
SYM(A20):
|
127 |
|
|
movw $PORT92 , dx
|
128 |
|
|
|
129 |
|
|
inb dx , al # clear A20 port reset
|
130 |
|
|
andb $0xfe , al # b0 Fast Reset(0)=disabled,(1)=reset triggered
|
131 |
|
|
orb $0x02 , al # Bit 1 Fast A20 = 0 (always 0) else enabled.
|
132 |
|
|
outb al , dx
|
133 |
|
|
|
134 |
|
|
|
135 |
|
|
SYM(Watchdog):
|
136 |
|
|
movw $WDTSTATUS , dx # address the WDT status port
|
137 |
|
|
inb dx , al # get the WDT status
|
138 |
|
|
orb $0x01 , al # set the CLKDIS bit
|
139 |
|
|
outb al , dx # disable the clock to the WDT
|
140 |
|
|
|
141 |
|
|
/*
|
142 |
|
|
* Initialize Refresh Control Unit for:
|
143 |
|
|
* Refresh Address = 0x0000
|
144 |
|
|
|
145 |
|
|
* Refresh gate between rows is 15.6 uSec
|
146 |
|
|
* Using a CLK2 frequency of 50Mhz ( 25Mhz CPU )
|
147 |
|
|
* The refresh unit is enabled
|
148 |
|
|
* The refresh pin is not used.
|
149 |
|
|
*/
|
150 |
|
|
|
151 |
|
|
SYM(InitRCU):
|
152 |
|
|
SetExRegWord( RFSCIR , 390) # refresh interval was 390, tried 312
|
153 |
|
|
SetExRegWord( RFSBAD , 0x0) # base address
|
154 |
|
|
SetExRegWord( RFSADD , 0x0) # address register
|
155 |
|
|
SetExRegWord( RFSCON , 0x8000) # enable bit
|
156 |
|
|
|
157 |
|
|
/*
|
158 |
|
|
* Initialize clock and power mgmt unit for:
|
159 |
|
|
* Clock Frequency = 50 Mhz
|
160 |
|
|
* Prescaled clock output = 1 Mhz
|
161 |
|
|
* Normal halt instructions
|
162 |
|
|
*/
|
163 |
|
|
|
164 |
|
|
SYM(InitClk):
|
165 |
|
|
SetExRegByte( PWRCON, 0x0 )
|
166 |
|
|
SetExRegWord( CLKPRS, 0x17) # 0x13 for 1.19318 MHz. 0x17 for 1MHz.
|
167 |
|
|
|
168 |
|
|
/**************************************************************
|
169 |
|
|
* Initialize the Pin Configurations
|
170 |
|
|
*************************************************************/
|
171 |
|
|
|
172 |
|
|
/*
|
173 |
|
|
* Initialize I/O port 1 for:
|
174 |
|
|
* PIN 0 = 1, DCD0# to package pin
|
175 |
|
|
* PIN 1 = 1, RTS0# to package pin
|
176 |
|
|
* PIN 2 = 1, DTR0# to package pin
|
177 |
|
|
* PIN 3 = 1, DSR0# to package pin
|
178 |
|
|
* PIN 4 = 1, RI0# to package pin
|
179 |
|
|
* PIN 5 = 0, Outport (FLASH Vpp Enable, 0=Enable 1=Disable)
|
180 |
|
|
* PIN 6 = 0, Outport (P16_HOLD to 386ex option header JP7 pin 5)
|
181 |
|
|
* PIN 7 = 0, Outport (P17_HOLD to 386ex option header JP7 pin 3)
|
182 |
|
|
*/
|
183 |
|
|
|
184 |
|
|
SYM(InitPort1):
|
185 |
|
|
SetExRegByte( P1LTC , 0xff )
|
186 |
|
|
SetExRegByte( P1DIR , 0x0 )
|
187 |
|
|
SetExRegByte( P1CFG , 0x1f)
|
188 |
|
|
|
189 |
|
|
/*
|
190 |
|
|
* Initialize I/O port 2 for:
|
191 |
|
|
* PIN 0 = 0, Outport (P20_CS0# to 386ex option header JP7 pin 11)
|
192 |
|
|
* PIN 1 = 0, Outport (P21_CS1# to 386ex option header JP7 pin 9)
|
193 |
|
|
* PIN 2 = 1, CS2# (SMRAM) If not using CS2 can be configured as.?
|
194 |
|
|
* PIN 3 = 0, Outport ( no connect )
|
195 |
|
|
* PIN 4 = 1, CS#4 (DRAM)
|
196 |
|
|
* PIN 5 = 1, RXD0 input. See not for I/0 port 1 pins 1-4
|
197 |
|
|
* PIN 6 = 1, TXD0 output.
|
198 |
|
|
* PIN 7 = 1, CTS0# input.
|
199 |
|
|
*/
|
200 |
|
|
|
201 |
|
|
SYM(InitPort2):
|
202 |
|
|
SetExRegByte( P2LTC , 0xff )
|
203 |
|
|
SetExRegByte( P2DIR , 0x0 )
|
204 |
|
|
SetExRegByte( P2CFG , 0xfe)
|
205 |
|
|
|
206 |
|
|
/*
|
207 |
|
|
* Initialize I/O port 3 P3CFG
|
208 |
|
|
* PIN 0 = 1, TMROUT0 to package pin
|
209 |
|
|
* PIN 1 = 0, (TMROUT1 to 386ex option header JP7 pin 23)
|
210 |
|
|
* PIN 2 = 0, INT0 (IR1) disabled, (P3.2 out to JP7 pin 21)
|
211 |
|
|
* PIN 3 = 0, INT1 (IR5) disbled (P3.3 to option header JP7 pin 19)
|
212 |
|
|
* PIN 4 = 0, INT2 (IR6) disbled (P3.4 to option header JP7 pin 17)
|
213 |
|
|
* PIN 5 = 0, INT2 (IR7) disabled (P3.5 to 386ex header JP7 pin 15)
|
214 |
|
|
* PIN 6 = 0, Inport (Debugger Break P3.6/PWRD to package pin )
|
215 |
|
|
* P3.6 selected
|
216 |
|
|
* PIN 7 = 0, COMCLK output disabled, 1.8432 Mhz OSC1 oscillator.
|
217 |
|
|
* ( Debbugger uses COMCLK as the clocking source )
|
218 |
|
|
* P3.7 connected to package pin.
|
219 |
|
|
*/
|
220 |
|
|
|
221 |
|
|
SYM(InitPort3):
|
222 |
|
|
SetExRegByte( P3LTC , 0xff )
|
223 |
|
|
SetExRegByte( P3DIR , 0x41 )
|
224 |
|
|
SetExRegByte( P3CFG , 0x09 ) # can check TMROUT0
|
225 |
|
|
/*
|
226 |
|
|
* Initialize Peripheral Pin Configurations:
|
227 |
|
|
* PIN 0 = 1, RTS1# to package pin
|
228 |
|
|
* PIN 1 = 1, DTR1# to package pin
|
229 |
|
|
* PIN 2 = 1, TXD1 out to package pin
|
230 |
|
|
* PIN 3 = 0, EOP#/TC
|
231 |
|
|
* PIN 4 = 0, DACK0#
|
232 |
|
|
* PIN 5 = 1, Timer2
|
233 |
|
|
* PIN 6 = 0, 0 => CS6# connected to package pin
|
234 |
|
|
* PIN 7 = 0, Don't care
|
235 |
|
|
*/
|
236 |
|
|
|
237 |
|
|
SYM(InitPeriph):
|
238 |
|
|
SetExRegByte( PINCFG , 0x24)
|
239 |
|
|
|
240 |
|
|
/*
|
241 |
|
|
* Initialize the Asynchronous Serial Ports:
|
242 |
|
|
* BIT 7 = 1, Internal SIO1 modem signals
|
243 |
|
|
* BIT 6 = 1, Internal SIO0 modem signals
|
244 |
|
|
* BIT 2 = 0, PSCLK for SSIO clock
|
245 |
|
|
* BIT 1 = 1, SERCLK for SIO1 clock
|
246 |
|
|
* BIT 0 = 1, SERCLK for SIO0 clock
|
247 |
|
|
*/
|
248 |
|
|
|
249 |
|
|
SYM(InitSIO):
|
250 |
|
|
SetExRegByte( SIOCFG, 0xC3 ) # SIOn clocked internally
|
251 |
|
|
|
252 |
|
|
SetExRegByte( LCR0, 0x80 ) # latch DLL0, DLH0
|
253 |
|
|
SetExRegByte( DLL0, 0x51 ) # 0x51 sets to 9600 baud, 0x28=19.2k, 0x7 -> 115.2k
|
254 |
|
|
SetExRegByte( DLH0, 0x00 ) # 0x145 is 2400 baud
|
255 |
|
|
SetExRegByte( LCR0, 0x03 ) # enable r/w buffers, IER0 accessible
|
256 |
|
|
# mode 8-n-1
|
257 |
|
|
SetExRegByte( IER0, 0x00 ) # was 0x0f All interrupts detected
|
258 |
|
|
|
259 |
|
|
SetExRegByte( LCR1, 0x80 ) # latch DLL0, DLH0
|
260 |
|
|
SetExRegByte( DLL1, 0x51 ) # 0x51 set to 9600 baud, 0x7 = 115200
|
261 |
|
|
SetExRegByte( DLH1, 0x00 ) # 0x145 is 2400 baud
|
262 |
|
|
SetExRegByte( LCR1, 0x03 ) # enable r/w buffers, IER1 accessible
|
263 |
|
|
# reg 8-n-1
|
264 |
|
|
SetExRegByte( IER1, 0x00 ) # was 0x0f - All interrupts detected
|
265 |
|
|
|
266 |
|
|
SYM(InitMCR):
|
267 |
|
|
/*
|
268 |
|
|
* Initialize Timer for:
|
269 |
|
|
* BIT 7 = 1, Timer clocks disabled
|
270 |
|
|
* BIT 6 = 0, Reserved
|
271 |
|
|
* BIT 5 = 1, TMRCLK2 instead of Vcc to Gate2
|
272 |
|
|
* BIT 4 = 0, PSCLK to CLK2
|
273 |
|
|
* BIT 3 = 1, TMRCLK1 instead of Vcc to Gate1
|
274 |
|
|
* BIT 2 = 0, PSCLK to Gate1
|
275 |
|
|
* BIT 1 = 0, Vcc to Gate0
|
276 |
|
|
* BIT 0 = 0, PSCLK to Gate0
|
277 |
|
|
*/
|
278 |
|
|
|
279 |
|
|
SYM(InitTimer):
|
280 |
|
|
SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1
|
281 |
|
|
# and 2 are set to Vcc
|
282 |
|
|
|
283 |
|
|
SetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSB
|
284 |
|
|
SetExRegByte(TMR0 , 0x00 ) # sfa
|
285 |
|
|
SetExRegByte(TMR0 , 0x00 ) # sfa
|
286 |
|
|
|
287 |
|
|
|
288 |
|
|
SetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= Vcc
|
289 |
|
|
SetExRegByte(TMR1 , 0x00 ) # sfa
|
290 |
|
|
SetExRegByte(TMR1 , 0x00 ) # sfa
|
291 |
|
|
|
292 |
|
|
SetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =Vcc
|
293 |
|
|
SetExRegByte(TMR2 , 0x00 ) #
|
294 |
|
|
SetExRegByte(TMR2 , 0x00 ) #
|
295 |
|
|
|
296 |
|
|
SetExRegByte(TMRCFG , 0x80 ) # Enable = 0x00
|
297 |
|
|
|
298 |
|
|
/*
|
299 |
|
|
* Initialize the DMACFG register for:
|
300 |
|
|
* BIT 7 = 1 , Disable DACK#1
|
301 |
|
|
* BITs 6:4 = 100, TMROUT2 connected to DRQ1
|
302 |
|
|
* BIT 3 = 1 , Disable DACK0#
|
303 |
|
|
* BIT 2:0 = 000, Pin is connected to DRQ0
|
304 |
|
|
*/
|
305 |
|
|
|
306 |
|
|
SetExRegByte(DMACFG , 0xC0 )
|
307 |
|
|
SetExRegByte(DMACMD1, 0x00 ) # disable both DMA channels
|
308 |
|
|
SetExRegByte(DMAMOD1, 0x40 )
|
309 |
|
|
/*
|
310 |
|
|
* Initialize the INTCFG register for:
|
311 |
|
|
* BIT 7 = 0, 8259 cascade disabled
|
312 |
|
|
* BIT 3 = 0, SLAVE IR6 connected to Vss
|
313 |
|
|
* BIT 2 = 0, SLAVE IR5 connected to Vss
|
314 |
|
|
* BIT 1 = 0, SLAVE IR1 connected to SSIOINT
|
315 |
|
|
* BIT 0 = 0, SLAVE IR0 connected to Vss
|
316 |
|
|
*/
|
317 |
|
|
|
318 |
|
|
SYM(InitInt):
|
319 |
|
|
|
320 |
|
|
cli # !
|
321 |
|
|
/* SetExRegByte(OCW3S, 0x20) # address the Slave status port
|
322 |
|
|
movw $OCW3S , dx
|
323 |
|
|
inb dx , al # Read the IRR.
|
324 |
|
|
|
325 |
|
|
SetExRegByte(OCW3M, 0x20) # address the Master status port
|
326 |
|
|
movw $OCW3M , dx
|
327 |
|
|
inb dx , al # Read the IRR.
|
328 |
|
|
*/
|
329 |
|
|
|
330 |
|
|
SetExRegByte(ICW1S , 0x11 ) # EDGE TRIGGERED
|
331 |
|
|
SetExRegByte(ICW2S , 0x28 ) # Slave base vector after Master
|
332 |
|
|
SetExRegByte(ICW3S , 0x02 ) # slave cascaded to IR2 on master
|
333 |
|
|
SetExRegByte(ICW4S , 0x01 ) # must be 0x01
|
334 |
|
|
|
335 |
|
|
SetExRegByte(ICW1M , 0x11 ) # edge triggered
|
336 |
|
|
SetExRegByte(ICW2M , 0x20 ) # base vector starts at byte 32
|
337 |
|
|
SetExRegByte(ICW3M , 0x04) # IR2 is cascaded internally
|
338 |
|
|
SetExRegByte(ICW4M , 0x01 ) # fully nested mode
|
339 |
|
|
|
340 |
|
|
SetExRegByte(OCW1M , 0xde ) # IR0 only = 0xfe.
|
341 |
|
|
# for IR5 and IR0 active use 0xde
|
342 |
|
|
# for IR0 and IR2 use 0xfa
|
343 |
|
|
SetExRegByte(INTCFG , 0x00 )
|
344 |
|
|
|
345 |
|
|
|
346 |
|
|
SYM(SetCS4):
|
347 |
|
|
SetExRegWord(CS4ADL , 0x702) #Configure chip select 4
|
348 |
|
|
SetExRegWord(CS4ADH , 0x00)
|
349 |
|
|
SetExRegWord(CS4MSKH, 0x03F)
|
350 |
|
|
SetExRegWord(CS4MSKL, 0xFC01)
|
351 |
|
|
|
352 |
|
|
SYM(SetUCS1):
|
353 |
|
|
SetExRegWord(UCSADL , 0x0304) # 512K block starting at 0x80000 until 0x3f80000
|
354 |
|
|
SetExRegWord(UCSADH , 0x03F8)
|
355 |
|
|
SetExRegWord(UCSMSKH, 0x03F7)
|
356 |
|
|
SetExRegWord(UCSMSKL, 0xFC01) # configure upper chip select
|
357 |
|
|
|
358 |
|
|
/******************************************************
|
359 |
|
|
* The GDT must be in RAM since it must be writeable,
|
360 |
|
|
* So, move the whole data section down.
|
361 |
|
|
********************************************************/
|
362 |
|
|
|
363 |
|
|
movw $ _ram_data_offset , di
|
364 |
|
|
movw $ _ram_data_segment, cx
|
365 |
|
|
mov cx , es
|
366 |
|
|
|
367 |
|
|
movw $ _data_size , cx
|
368 |
|
|
movw $ _rom_data_segment, ax
|
369 |
|
|
movw $ _rom_data_offset , si
|
370 |
|
|
mov ax , ds
|
371 |
|
|
|
372 |
|
|
repne
|
373 |
|
|
movsb
|
374 |
|
|
|
375 |
|
|
/*****************************
|
376 |
|
|
* Load the Global Descriptor
|
377 |
|
|
* Table Register
|
378 |
|
|
****************************/
|
379 |
|
|
|
380 |
|
|
#ifdef NEW_GAS
|
381 |
|
|
data32 addr32 lgdt SYM(GDTR) # location of GDT
|
382 |
|
|
#else
|
383 |
|
|
lgdt SYM(GDTR) # location of GDT
|
384 |
|
|
#endif
|
385 |
|
|
|
386 |
|
|
|
387 |
|
|
SYM(SetUCS):
|
388 |
|
|
SetExRegWord(UCSADL, 0x0702) # now 512K starting at 0x3f80000.
|
389 |
|
|
SetExRegWord(UCSADH, 0x03f8)
|
390 |
|
|
SetExRegWord(UCSMSKH, 0x0007)
|
391 |
|
|
SetExRegWord(UCSMSKL, 0xFC01) # configure upper chip select
|
392 |
|
|
|
393 |
|
|
/*
|
394 |
|
|
* SRAM chip select: 16 bit bus size,starting 16Mb, size 512k,
|
395 |
|
|
* 4 waits
|
396 |
|
|
*/
|
397 |
|
|
|
398 |
|
|
#ifdef UT_I386EX
|
399 |
|
|
|
400 |
|
|
SYM(SetCS1):
|
401 |
|
|
SetExRegWord(CS1ADL, 0x0000)
|
402 |
|
|
SetExRegWord(CS1ADH, 0x000E)
|
403 |
|
|
SetExRegWord(CS1MSKH, 0x0000)
|
404 |
|
|
SetExRegWord(CS1MSKL, 0x0001)
|
405 |
|
|
|
406 |
|
|
SYM(SetCS2):
|
407 |
|
|
SetExRegWord(CS2ADL, 0x0704)
|
408 |
|
|
SetExRegWord(CS2ADH, 0x0100)
|
409 |
|
|
SetExRegWord(CS2MSKH, 0x0003)
|
410 |
|
|
SetExRegWord(CS2MSKL, 0xfc01)
|
411 |
|
|
|
412 |
|
|
/*
|
413 |
|
|
* Real-time clock: 8 bit bus size, starting@16Mb+512K, size 32k
|
414 |
|
|
* 4 waits
|
415 |
|
|
*/
|
416 |
|
|
SYM(SetCS3):
|
417 |
|
|
SetExRegWord(CS3ADL, 0x0504)
|
418 |
|
|
SetExRegWord(CS3ADH, 0x0108)
|
419 |
|
|
SetExRegWord(CS3MSKH, 0x0000)
|
420 |
|
|
SetExRegWord(CS3MSKL, 0x7c01)
|
421 |
|
|
|
422 |
|
|
#endif
|
423 |
|
|
/***************************
|
424 |
|
|
* Switch to Protected Mode
|
425 |
|
|
***************************/
|
426 |
|
|
|
427 |
|
|
mov cr0, eax
|
428 |
|
|
orw $0x1, ax
|
429 |
|
|
mov eax, cr0
|
430 |
|
|
|
431 |
|
|
/**************************
|
432 |
|
|
* Flush prefetch queue,
|
433 |
|
|
* and load CS selector
|
434 |
|
|
*********************/
|
435 |
|
|
|
436 |
|
|
ljmpl $ GDT_CODE_PTR , $ SYM(_load_segment_registers) # sets the code selector
|
437 |
|
|
|
438 |
|
|
/*
|
439 |
|
|
* Load the segment registers
|
440 |
|
|
*/
|
441 |
|
|
SYM(_load_segment_registers):
|
442 |
|
|
.code32
|
443 |
|
|
pLOAD_SEGMENT( GDT_DATA_PTR, fs)
|
444 |
|
|
pLOAD_SEGMENT( GDT_DATA_PTR, gs)
|
445 |
|
|
pLOAD_SEGMENT( GDT_DATA_PTR, ss)
|
446 |
|
|
pLOAD_SEGMENT( GDT_DATA_PTR, ds)
|
447 |
|
|
pLOAD_SEGMENT( GDT_DATA_PTR, es)
|
448 |
|
|
|
449 |
|
|
/*
|
450 |
|
|
* Set up the stack
|
451 |
|
|
*/
|
452 |
|
|
|
453 |
|
|
SYM(lidtr):
|
454 |
|
|
lidt SYM(IDTR)
|
455 |
|
|
|
456 |
|
|
SYM (_establish_stack):
|
457 |
|
|
movl $end, eax # stack starts right after bss
|
458 |
|
|
movl $stack_origin, esp # this is the high starting address
|
459 |
|
|
movl $stack_origin, ebp
|
460 |
|
|
|
461 |
|
|
/*
|
462 |
|
|
* Zero out the BSS segment
|
463 |
|
|
*/
|
464 |
|
|
SYM (zero_bss):
|
465 |
|
|
cld # make direction flag count up
|
466 |
|
|
movl $ SYM (end),ecx # find end of .bss
|
467 |
|
|
movl $ SYM (_bss_start),edi # edi = beginning of .bss
|
468 |
|
|
subl edi,ecx # ecx = size of .bss in bytes
|
469 |
|
|
shrl ecx # size of .bss in longs
|
470 |
|
|
shrl ecx
|
471 |
|
|
xorl eax,eax # value to clear out memory
|
472 |
|
|
repne # while ecx != 0
|
473 |
|
|
stosl # clear a long in the bss
|
474 |
|
|
|
475 |
|
|
|
476 |
|
|
/*
|
477 |
|
|
* Transfer control to User's Board Support Package
|
478 |
|
|
*/
|
479 |
|
|
pushl $0 # environp
|
480 |
|
|
pushl $0 # argv
|
481 |
|
|
pushl $0 # argc
|
482 |
|
|
|
483 |
|
|
movw $0xFFFB, SYM(i8259s_cache) # ICU mask values reflect
|
484 |
|
|
# initial ICU state
|
485 |
|
|
call SYM(boot_card)
|
486 |
|
|
addl $12,esp
|
487 |
|
|
|
488 |
|
|
cli # stops interrupts from being processed after hlt!
|
489 |
|
|
hlt # shutdown
|
490 |
|
|
|
491 |
|
|
END
|
492 |
|
|
|