source: rtems/c/src/lib/libbsp/i386/i386ex/start/start.S @ c01ba67

4.104.114.84.95
Last change on this file since c01ba67 was f70598c7, checked in by Joel Sherrill <joel.sherrill@…>, on 10/26/99 at 01:34:42

Patch from Erik Ivanenko <erik.ivanenko@…> to fix some
reported bugs in the start code.

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