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

4.104.114.84.95
Last change on this file since 1d4048b2 was 26eff5c, checked in by Joel Sherrill <joel.sherrill@…>, on 08/02/99 at 20:26:57

Fix By Joel based on suggestion from Ian Lance Taylor <ian@…>
to fix problem reported by Ralf Corsepius <corsepiu@…>.

Date: Fri, 30 Jul 1999 14:53:20 -0500 (CDT)
From: <joel@…>

it is used like this in i386ex/start/start.S

/* set up same values in cache */

start.S: movw $0xFFFB, SYM(i8259s_cache)

I am heading out the door. Any other ideas what could have tripped this?

This instruction appears in a .code16 section. In a .code16 section,
current versions of gas assume that all addresses are 16 bits unless
told otherwise.

If you change the line to

addr32 movw $0xFFFB, SYM(i8259s_cache)

then you will get a 32 bit address reference.

You may want to use addr32 only when NEW_GAS is defined.

  • Property mode set to 100644
File size: 12.7 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        /*
328         *  The addr32 override should ensure that the address for
329         *  i8259s_cache is put in 32-bit address space.
330         */
331
332#if defined(NEW_GAS)
333        addr32 movw $0xFFFB, SYM(i8259s_cache) # set up same values in cache
334#else
335        movw    $0xFFFB, SYM(i8259s_cache)     # set up same values in cache
336#endif
337       
338SYM(SetCS4):   
339        SetExRegWord(CS4ADL , 0x702)         #Configure chip select 4
340        SetExRegWord(CS4ADH , 0x00)
341        SetExRegWord(CS4MSKH, 0x03F)     
342        SetExRegWord(CS4MSKL, 0xFC01) 
343
344SYM(SetUCS1):           
345        SetExRegWord(UCSADL , 0x0304)      # 512K block starting at 0x80000 until 0x3f80000
346        SetExRegWord(UCSADH , 0x03F8)
347        SetExRegWord(UCSMSKH, 0x03F7)   
348        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
349
350/******************************************************
351* The GDT must be in RAM since it must be writeable,
352* So, move the whole data section down.
353********************************************************/
354
355        movw $ _ram_data_offset , di
356        movw $ _ram_data_segment, cx
357        mov  cx                 , es
358
359        movw $ _data_size       , cx
360        movw $ _rom_data_segment, ax
361        movw $ _rom_data_offset , si
362        mov  ax                 , ds
363       
364        repne
365        movsb
366       
367/*****************************
368 * Load the Global Descriptor
369 * Table Register
370 ****************************/
371       
372#ifdef NEW_GAS 
373        data32
374        addr32
375#endif 
376        lgdt SYM(GDTR) #  location of GDT
377
378       
379SYM(SetUCS):           
380        SetExRegWord(UCSADL, 0x0702)      # now 512K starting at 0x3f80000.     
381        SetExRegWord(UCSADH, 0x03f8)
382        SetExRegWord(UCSMSKH, 0x0007)   
383        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
384
385/***************************
386 * Switch to Protected Mode
387 ***************************/
388        mov     cr0, eax
389        orw     $0x1, ax
390        mov     eax, cr0
391       
392/**************************
393 * Flush prefetch queue,
394 * and load CS selector
395 *********************/
396
397        ljmpl $ GDT_CODE_PTR , $  SYM(_load_segment_registers) # sets the code selector
398       
399/*
400 * Load the segment registers
401 */
402SYM(_load_segment_registers):   
403        .code32
404        pLOAD_SEGMENT( GDT_DATA_PTR, fs)
405        pLOAD_SEGMENT( GDT_DATA_PTR, gs)
406        pLOAD_SEGMENT( GDT_DATA_PTR, ss)
407        pLOAD_SEGMENT( GDT_DATA_PTR, ds)
408        pLOAD_SEGMENT( GDT_DATA_PTR, es)
409       
410/*
411 *  Set up the stack
412 */
413
414SYM(lidtr):
415        lidt    SYM(IDTR)
416
417SYM (_establish_stack):
418        movl    $end, eax               # stack starts right after bss
419        movl    $stack_origin, esp      # this is the high starting address
420        movl    $stack_origin, ebp
421/*
422 *  Zero out the BSS segment
423 */
424SYM (zero_bss):
425        cld                             # make direction flag count up
426        movl    $ SYM (end),ecx        # find end of .bss
427        movl    $ SYM (_bss_start),edi # edi = beginning of .bss
428        subl    edi,ecx               # ecx = size of .bss in bytes
429        shrl    ecx                    # size of .bss in longs
430        shrl    ecx
431        xorl    eax,eax               # value to clear out memory
432        repne                           # while ecx != 0
433        stosl                           #   clear a long in the bss
434
435/*
436 *  Transfer control to User's Board Support Package
437 */
438        pushl   $0                       # environp
439        pushl   $0                       # argv
440        pushl   $0                       # argc
441        call SYM(boot_card)
442        addl    $12,esp
443
444        cli                              # stops interrupts from being processed after hlt!
445        hlt                              # shutdown
446
447END
448
Note: See TracBrowser for help on using the repository browser.