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

4.104.114.84.95
Last change on this file since ddd22e5 was ddd22e5, checked in by Joel Sherrill <joel.sherrill@…>, on 05/11/99 at 15:15:03

Patch from Erik Ivanenko <erik.ivanenko@…> to correct 32 bit
jmp relative offset from .reset section.

  • Property mode set to 100644
File size: 12.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#include "asm.h"
39#include "macros.inc"
40#include "80386ex.inc"
41
42/*
43 * NEW_GAS Needed for binutils 2.9.1.0.7 and higher
44 */                     
45
46        EXTERN (boot_card)         /* exits to bspstart   */
47        EXTERN (stack_start)       /* defined in startup/linkcmds */
48        EXTERN (Clock_exit)
49
50        PUBLIC (Interrupt_descriptor_table)
51        PUBLIC ( SYM(IDTR) )
52        PUBLIC( SYM(_initInternalRegisters) )
53       
54BEGIN_DATA
55SYM(IDTR):      DESC3( SYM(Interrupt_descriptor_table), 0x07ff );
56       
57SYM(Interrupt_descriptor_table):   /* Now in data section */
58        .rept 256
59        .word 0,0,0,0
60        .endr
61
62END_DATA       
63       
64BEGIN_DATA
65         PUBLIC (_Global_descriptor_table)
66                       
67SYM(GDTR):      DESC3( GDT_TABLE, 0x1f ); # one less than the size
68SYM (_Global_descriptor_table):
69SYM(GDT_TABLE): DESC2(0,0,0,0,0,0);
70SYM(GDT_ALIAS): DESC2(32,0x1000,0x0,0x93,0,0x0);
71SYM(GDT_CODE):  DESC2(0xffff,0,0x0,0x9B,0xDF,0x00);
72SYM(GDT_DATA):  DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF
73SYM(GDT_END):
74
75END_DATA
76       
77
78/* This section is the section that is used by the interrupt
79   descriptor table.  It is used to provide the IDT with the
80   correct vector offsets.  It is for symbol definition only.
81*/
82       
83
84        .section .reset                       
85
86                PUBLIC ( SYM(reset) )
87SYM(reset):     
88        nop
89        cli
90        jmp     SYM(_initInternalRegisters) /* different section in this file */
91        .code32                             /* in case this section moves     */
92        nop                                 /* required by CHIP LAB to pad out size */
93        nop
94        nop
95        nop
96        nop
97
98       
99       
100        .section .initial
101        nop     /* nops required to correct 32 bit jmp relative */
102        nop     /*    offset from .reset section */
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 Mhz
153 *      Normal halt instructions
154 */
155       
156SYM(InitClk):   
157        SetExRegByte( PWRCON, 0x0 )
158        SetExRegWord( CLKPRS, 0x17)   # 0x13 for 1.19318 MHz.  0x17 for 1MHz.
159
160/**************************************************************
161 * Initialize the Pin Configurations
162 *************************************************************/
163
164/*
165 *      Initialize I/O port 1 for:     
166 *      PIN 0 = 1,      DCD0# to package pin
167 *      PIN 1 = 1,      RTS0# to package pin
168 *      PIN 2 = 1,      DTR0# to package pin
169 *      PIN 3 = 1,      DSR0# to package pin
170 *      PIN 4 = 1,      RI0# to package pin
171 *      PIN 5 = 0,      Outport (FLASH Vpp Enable, 0=Enable 1=Disable)
172 *      PIN 6 = 0,      Outport (P16_HOLD to 386ex option header JP7 pin 5)
173 *      PIN 7 = 0,      Outport (P17_HOLD to 386ex option header JP7 pin 3)
174 */
175
176SYM(InitPort1):         
177        SetExRegByte( P1LTC     , 0xff )
178        SetExRegByte( P1DIR     , 0x0  )
179        SetExRegByte( P1CFG     , 0x1f)
180       
181/*
182 *      Initialize I/O port 2 for:     
183 *      PIN 0 = 0,      Outport (P20_CS0# to 386ex option header JP7 pin 11)
184 *      PIN 1 = 0,      Outport (P21_CS1# to 386ex option header JP7 pin 9)
185 *      PIN 2 = 1,      CS2# (SMRAM) If not using CS2 can be configured as.?
186 *      PIN 3 = 0,      Outport ( no connect )
187 *      PIN 4 = 1,      CS#4 (DRAM)
188 *      PIN 5 = 1,      RXD0 input. See not for I/0 port 1 pins 1-4
189 *      PIN 6 = 1,      TXD0 output.
190 *      PIN 7 = 1,      CTS0# input.
191 */
192       
193SYM(InitPort2):
194        SetExRegByte( P2LTC     , 0xff )
195        SetExRegByte( P2DIR     , 0x0  )
196        SetExRegByte( P2CFG     , 0xfe)
197       
198/*
199 *      Initialize I/O port 3 P3CFG     
200 *      PIN 0 = 1,      TMROUT0 to package pin
201 *      PIN 1 = 0,      (TMROUT1 to 386ex option header JP7 pin 23)
202 *      PIN 2 = 0,      INT0 (IR1) disabled, (P3.2 out to JP7 pin 21)
203 *      PIN 3 = 0,      INT1 (IR5) disbled (P3.3  to option header JP7 pin 19)
204 *      PIN 4 = 0,      INT2 (IR6) disbled (P3.4 to option header JP7 pin 17)
205 *      PIN 5 = 0,      INT2 (IR7) disabled (P3.5 to 386ex header JP7 pin 15)
206 *      PIN 6 = 0,      Inport (Debugger Break P3.6/PWRD to package pin )
207 *                      P3.6 selected
208 *      PIN 7 = 0,      COMCLK output disabled, 1.8432 Mhz OSC1 oscillator.
209 *                      ( Debbugger uses COMCLK as the clocking source )
210 *                      P3.7 connected to package pin.
211 */
212       
213SYM(InitPort3):         
214        SetExRegByte( P3LTC     , 0xff )
215        SetExRegByte( P3DIR     , 0x41 )
216        SetExRegByte( P3CFG     , 0x09 )  # can check TMROUT0
217/*
218 *      Initialize Peripheral Pin Configurations:       
219 *      PIN 0 = 1,      RTS1# to package pin   
220 *      PIN 1 = 1,      DTR1# to package pin
221 *      PIN 2 = 1,      TXD1 out to package pin
222 *      PIN 3 = 0,      EOP#/TC
223 *      PIN 4 = 0,      DACK0#
224 *      PIN 5 = 1,      Timer2
225 *      PIN 6 = 0,      0 => CS6# connected to package pin
226 *      PIN 7 = 0,      Don't care
227 */
228       
229SYM(InitPeriph):       
230        SetExRegByte( PINCFG , 0x24)
231       
232/*
233 *      Initialize the Asynchronous Serial Ports:       
234 *      BIT 7 = 1,      Internal SIO1 modem signals
235 *      BIT 6 = 1,      Internal SIO0 modem signals
236 *      BIT 2 = 0,      PSCLK for SSIO clock
237 *      BIT 1 = 1,      SERCLK for SIO1 clock
238 *      BIT 0 = 1,      SERCLK for SIO0 clock
239 */
240
241SYM(InitSIO):   
242        SetExRegByte( SIOCFG, 0xC3 ) # SIOn clocked internally
243
244        SetExRegByte( LCR0,     0x80 )  # latch DLL0, DLH0
245        SetExRegByte( DLL0, 0x51 )      # 0x51 sets to 9600 baud 0x7 -> 115,200
246        SetExRegByte( DLH0, 0x00 )  # 0x145 is 2400 baud
247        SetExRegByte( LCR0, 0x03 )  # enable r/w buffers, IER0 accessible
248                                    # mode 8-n-1
249        SetExRegByte( IER0, 0x00 )  # was 0x0f All interrupts detected
250       
251        SetExRegByte( LCR1, 0x80 )  # latch DLL0, DLH0
252        SetExRegByte( DLL1, 0x51 )  # 0x51 set to 9600 baud, 0x7 = 115200
253        SetExRegByte( DLH1, 0x00 )  # 0x145 is 2400 baud
254        SetExRegByte( LCR1, 0x03 )  # enable r/w buffers, IER1 accessible
255                                        # reg 8-n-1
256        SetExRegByte( IER1, 0x00 )  # was 0x0f - All interrupts detected
257
258SYM(InitMCR):   
259/*
260 *      Initialize Timer for:   
261 *      BIT 7 = 1,      Timer clocks disabled
262 *      BIT 6 = 0,      Reserved
263 *      BIT 5 = 1,      TMRCLK2 instead of Vcc to Gate2
264 *      BIT 4 = 0,      PSCLK to CLK2
265 *      BIT 3 = 1,      TMRCLK1 instead of Vcc to Gate1
266 *      BIT 2 = 0,      PSCLK to Gate1
267 *      BIT 1 = 0,      Vcc to Gate0   
268 *      BIT 0 = 0,      PSCLK to Gate0
269 */
270
271SYM(InitTimer):
272        SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1
273                                     # and 2 are set to Vcc
274
275        SetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSB
276        SetExRegByte(TMR0   , 0x00 ) # sfa
277        SetExRegByte(TMR0   , 0x00 ) # sfa
278
279                       
280        SetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= Vcc
281        SetExRegByte(TMR1   , 0x00 ) # sfa
282        SetExRegByte(TMR1   , 0x00 ) # sfa
283       
284        SetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =Vcc
285        SetExRegByte(TMR2   , 0x00 ) # 
286        SetExRegByte(TMR2   , 0x00 ) # 
287
288        SetExRegByte(TMRCFG , 0x80 ) # Enable = 0x00
289
290/*
291 *      Initialize the DMACFG register for:     
292 *      BIT 7    = 1  , Disable DACK#1
293 *      BITs 6:4 = 100, TMROUT2 connected to DRQ1
294 *      BIT 3    = 1  , Disable DACK0#
295 *      BIT 2:0  = 000, Pin is connected to DRQ0
296 */
297
298        SetExRegByte(DMACFG , 0xC0  )
299        SetExRegByte(DMACMD1, 0x00 ) # disable both DMA channels
300        SetExRegByte(DMAMOD1, 0x40 )
301/*
302 *      Initialize the INTCFG register for:
303 *      BIT 7 = 0,      8259 cascade disabled
304 *      BIT 3 = 0,      SLAVE IR6 connected to Vss
305 *      BIT 2 = 0,      SLAVE IR5 connected to Vss
306 *      BIT 1 = 0,      SLAVE IR1 connected to SSIOINT
307 *      BIT 0 = 0,      SLAVE IR0 connected to Vss
308 */
309
310SYM(InitInt):
311       
312        cli                               # !
313       
314        SetExRegByte(ICW1S  , 0x11 ) # EDGE TRIGGERED
315        SetExRegByte(ICW2S  , 0x28 ) # Slave base vector after Master
316        SetExRegByte(ICW3S  , 0x02 ) # slave cascaded to IR2 on master
317        SetExRegByte(ICW4S  , 0x01 ) # must be 0x01
318
319        SetExRegByte(ICW1M  , 0x11 ) # edge triggered
320        SetExRegByte(ICW2M  , 0x20 ) # base vector starts at byte 32
321        SetExRegByte(ICW3M  , 0x04)  # IR2 is cascaded internally
322        SetExRegByte(ICW4M  , 0x01 ) # idem
323       
324        SetExRegByte(OCW1M  , 0xde ) # IR0  only = 0xfe.  for IR5 and IR0 active use 0xde
325        SetExRegByte(INTCFG , 0x00 )
326       
327        movw    $0xFFFB, SYM(i8259s_cache) /* set up same values in cache */
328       
329SYM(SetCS4):   
330        SetExRegWord(CS4ADL , 0x702)         #Configure chip select 4
331        SetExRegWord(CS4ADH , 0x00)
332        SetExRegWord(CS4MSKH, 0x03F)     
333        SetExRegWord(CS4MSKL, 0xFC01) 
334
335SYM(SetUCS1):           
336        SetExRegWord(UCSADL , 0x0304)      # 512K block starting at 0x80000 until 0x3f80000
337        SetExRegWord(UCSADH , 0x03F8)
338        SetExRegWord(UCSMSKH, 0x03F7)   
339        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
340
341/******************************************************
342* The GDT must be in RAM since it must be writeable,
343* So, move the whole data section down.
344********************************************************/
345
346        movw $ _ram_data_offset , di
347        movw $ _ram_data_segment, cx
348        mov  cx                 , es
349
350        movw $ _data_size       , cx
351        movw $ _rom_data_segment, ax
352        movw $ _rom_data_offset , si
353        mov  ax                 , ds
354       
355        repne
356        movsb
357       
358/*****************************
359 * Load the Global Descriptor
360 * Table Register
361 ****************************/
362       
363#ifdef NEW_GAS 
364        data32
365        addr32
366#endif 
367        lgdt SYM(GDTR) #  location of GDT
368
369       
370SYM(SetUCS):           
371        SetExRegWord(UCSADL, 0x0702)      # now 512K starting at 0x3f80000.     
372        SetExRegWord(UCSADH, 0x03f8)
373        SetExRegWord(UCSMSKH, 0x0007)   
374        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
375
376/***************************
377 * Switch to Protected Mode
378 ***************************/
379        mov     cr0, eax
380        orw     $0x1, ax
381        mov     eax, cr0
382       
383/**************************
384 * Flush prefetch queue,
385 * and load CS selector
386 *********************/
387
388        ljmpl $ GDT_CODE_PTR , $  SYM(_load_segment_registers) # sets the code selector
389       
390/*
391 * Load the segment registers
392 */
393SYM(_load_segment_registers):   
394        .code32
395        pLOAD_SEGMENT( GDT_DATA_PTR, fs)
396        pLOAD_SEGMENT( GDT_DATA_PTR, gs)
397        pLOAD_SEGMENT( GDT_DATA_PTR, ss)
398        pLOAD_SEGMENT( GDT_DATA_PTR, ds)
399        pLOAD_SEGMENT( GDT_DATA_PTR, es)
400       
401/*
402 *  Set up the stack
403 */
404
405SYM(lidtr):
406        lidt    SYM(IDTR)
407
408SYM (_establish_stack):
409        movl    $end, eax               # stack starts right after bss
410        movl    $stack_origin, esp      # this is the high starting address
411        movl    $stack_origin, ebp
412/*
413 *  Zero out the BSS segment
414 */
415SYM (zero_bss):
416        cld                             # make direction flag count up
417        movl    $ SYM (end),ecx        # find end of .bss
418        movl    $ SYM (_bss_start),edi # edi = beginning of .bss
419        subl    edi,ecx               # ecx = size of .bss in bytes
420        shrl    ecx                    # size of .bss in longs
421        shrl    ecx
422        xorl    eax,eax               # value to clear out memory
423        repne                           # while ecx != 0
424        stosl                           #   clear a long in the bss
425
426/*
427 *  Transfer control to User's Board Support Package
428 */
429        pushl   $0                       # environp
430        pushl   $0                       # argv
431        pushl   $0                       # argc
432        call SYM(boot_card)
433        addl    $12,esp
434
435        cli                              # stops interrupts from being processed after hlt!
436        hlt                              # shutdown
437
438END
439
Note: See TracBrowser for help on using the repository browser.