source: rtems/c/src/lib/libbsp/i386/i386ex/start/start.s @ 362b88e

4.104.114.84.95
Last change on this file since 362b88e was 362b88e, checked in by Joel Sherrill <joel.sherrill@…>, on 09/23/98 at 13:17:23

Switched "NEW_GAS" flag.

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