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

4.104.114.84.95
Last change on this file since 5c7f274 was f05b2ac, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 21, 2004 at 4:01:48 PM

Remove duplicate white lines.

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