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 04/21/04 at 16:01:48

Remove duplicate white lines.

  • Property mode set to 100644
File size: 13.5 KB
RevLine 
[33442772]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
[6128a4a]5 *  startup:
[33442772]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 *
[6128a4a]12 *  The file is a multi-section file, with sections as follows:
[33442772]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
[6ff7e2c]27 *  http://www.rtems.com/license/LICENSE.
[33442772]28 *
29 *  $Id$
[04bc5d9]30
[6128a4a]31changes:
[04bc5d9]32    SetExRegByte(ICW3S  , 0x02 ) # MUST be 0x02 according to intel
33    SetExRegByte(ICW3M  , 0x04 ) # IR2 is cascaded internally: was 0x02 => IR1 is cascaded
[6128a4a]34
[33442772]35 */
36
[cc1426bb]37#include <rtems/asm.h>
[33442772]38#include "macros.inc"
39#include "80386ex.inc"
40
[bd8c8b2a]41/*
[42c0b9ee]42 * NEW_GAS Needed for binutils 2.9.1.0.7 and higher
[6128a4a]43 */
[33442772]44
[6128a4a]45        EXTERN (boot_card)         /* exits to bspstart   */
[04bc5d9]46        EXTERN (stack_start)       /* defined in startup/linkcmds */
47        EXTERN (Clock_exit)
[33442772]48
49        PUBLIC (Interrupt_descriptor_table)
[04bc5d9]50        PUBLIC ( SYM(IDTR) )
[f70598c7]51/*      PUBLIC( SYM(_initInternalRegisters) )  */
[6128a4a]52
53BEGIN_DATA
[04bc5d9]54SYM(IDTR):      DESC3( SYM(Interrupt_descriptor_table), 0x07ff );
[6128a4a]55
[04bc5d9]56SYM(Interrupt_descriptor_table):   /* Now in data section */
57        .rept 256
58        .word 0,0,0,0
59        .endr
60
[6128a4a]61END_DATA
62
[33442772]63BEGIN_DATA
[04bc5d9]64         PUBLIC (_Global_descriptor_table)
[6128a4a]65
[33442772]66SYM(GDTR):      DESC3( GDT_TABLE, 0x1f ); # one less than the size
[6128a4a]67SYM (_Global_descriptor_table):
[33442772]68SYM(GDT_TABLE): DESC2(0,0,0,0,0,0);
[6128a4a]69SYM(GDT_ALIAS): DESC2(32,0x1000,0x0,0x93,0,0x0);
[33442772]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
[6128a4a]75
[33442772]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*/
[6128a4a]80
[f70598c7]81        .code16
[df49c60]82        .section .reset, "ax"
[6128a4a]83                PUBLIC ( SYM(reset) )
[f70598c7]84SYM(reset):
[33442772]85        nop
86        cli
[6128a4a]87#ifdef NEW_GAS
[8be7bef]88        data32 addr32 jmp     SYM(_initInternalRegisters) /* different section in this file */
89#else
[33442772]90        jmp     SYM(_initInternalRegisters) /* different section in this file */
[6128a4a]91#endif
[f70598c7]92/*      .code32                              in case this section moves     */
[33442772]93        nop                                 /* required by CHIP LAB to pad out size */
94        nop
95        nop
96        nop
97        nop
[f70598c7]98        nop
99        nop
100        nop
101        nop
102        nop
103        nop
[6128a4a]104
[df49c60]105        .section .initial, "ax"
[f70598c7]106        /* nop */               /* required for linker -- initial jump is to "label - 2"   */
[6128a4a]107        /* nop */               /* ie. _initInternalRegisters -2 ( which now == .initial ) */
[33442772]108/*
109 * Enable access to peripheral register at expanded I/O addresses
110 */
[6128a4a]111SYM(_initInternalRegisters):
[f70598c7]112
113        /* .code16 */
[6128a4a]114        movw    $0x8000 , ax
[33442772]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
[6128a4a]121 */
[33442772]122SYM(A20):
123        movw    $PORT92 , dx
[6128a4a]124
[33442772]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
[04bc5d9]130SYM(Watchdog):
131        movw    $WDTSTATUS      , dx    # address the WDT status port
132        inb     dx              , al    # get the WDT status
[6128a4a]133        orb     $0x01           , al    # set the CLKDIS bit
[04bc5d9]134        outb    al              , dx    # disable the clock to the WDT
[33442772]135
136/*
[6128a4a]137 * Initialize Refresh Control Unit for:
[33442772]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
[6128a4a]146SYM(InitRCU):
[33442772]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/*
[6128a4a]153 * Initialize clock and power mgmt unit for:
[33442772]154 *      Clock Frequency = 50 Mhz
[479c86dd]155 *      Prescaled clock output = 1 Mhz
[33442772]156 *      Normal halt instructions
157 */
[6128a4a]158
159SYM(InitClk):
[33442772]160        SetExRegByte( PWRCON, 0x0 )
[479c86dd]161        SetExRegWord( CLKPRS, 0x17)   # 0x13 for 1.19318 MHz.  0x17 for 1MHz.
[33442772]162
163/**************************************************************
164 * Initialize the Pin Configurations
165 *************************************************************/
166
167/*
[6128a4a]168 *      Initialize I/O port 1 for:
[33442772]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
[6128a4a]179SYM(InitPort1):
[33442772]180        SetExRegByte( P1LTC     , 0xff )
181        SetExRegByte( P1DIR     , 0x0  )
182        SetExRegByte( P1CFG     , 0x1f)
[6128a4a]183
[33442772]184/*
[6128a4a]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)
[33442772]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 */
[6128a4a]195
196SYM(InitPort2):
[33442772]197        SetExRegByte( P2LTC     , 0xff )
198        SetExRegByte( P2DIR     , 0x0  )
199        SetExRegByte( P2CFG     , 0xfe)
[6128a4a]200
[33442772]201/*
[6128a4a]202 *      Initialize I/O port 3 P3CFG
[33442772]203 *      PIN 0 = 1,      TMROUT0 to package pin
[6128a4a]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)
[33442772]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 */
[6128a4a]215
216SYM(InitPort3):
[33442772]217        SetExRegByte( P3LTC     , 0xff )
218        SetExRegByte( P3DIR     , 0x41 )
219        SetExRegByte( P3CFG     , 0x09 )  # can check TMROUT0
220/*
[6128a4a]221 *      Initialize Peripheral Pin Configurations:
222 *      PIN 0 = 1,      RTS1# to package pin
[33442772]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 */
[6128a4a]231
232SYM(InitPeriph):
233        SetExRegByte( PINCFG , 0x24)
234
[33442772]235/*
[6128a4a]236 *      Initialize the Asynchronous Serial Ports:
[33442772]237 *      BIT 7 = 1,      Internal SIO1 modem signals
238 *      BIT 6 = 1,      Internal SIO0 modem signals
239 *      BIT 2 = 0,      PSCLK for SSIO clock
[6128a4a]240 *      BIT 1 = 1,      SERCLK for SIO1 clock
[33442772]241 *      BIT 0 = 1,      SERCLK for SIO0 clock
242 */
243
[6128a4a]244SYM(InitSIO):
[33442772]245        SetExRegByte( SIOCFG, 0xC3 ) # SIOn clocked internally
246
247        SetExRegByte( LCR0,     0x80 )  # latch DLL0, DLH0
[f70598c7]248        SetExRegByte( DLL0, 0x51 )      # 0x51 sets to 9600 baud, 0x28=19.2k, 0x7 -> 115.2k
[33442772]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
[6128a4a]253
254        SetExRegByte( LCR1, 0x80 )  # latch DLL0, DLH0
[33442772]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
[6128a4a]261SYM(InitMCR):
[33442772]262/*
[6128a4a]263 *      Initialize Timer for:
[33442772]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
[6128a4a]270 *      BIT 1 = 0,      Vcc to Gate0
[33442772]271 *      BIT 0 = 0,      PSCLK to Gate0
272 */
273
[6128a4a]274SYM(InitTimer):
275        SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1
[33442772]276                                     # and 2 are set to Vcc
277
278        SetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSB
[479c86dd]279        SetExRegByte(TMR0   , 0x00 ) # sfa
[6128a4a]280        SetExRegByte(TMR0   , 0x00 ) # sfa
281
[33442772]282        SetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= Vcc
283        SetExRegByte(TMR1   , 0x00 ) # sfa
[6128a4a]284        SetExRegByte(TMR1   , 0x00 ) # sfa
285
[33442772]286        SetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =Vcc
[6128a4a]287        SetExRegByte(TMR2   , 0x00 ) #
288        SetExRegByte(TMR2   , 0x00 ) #
[479c86dd]289
290        SetExRegByte(TMRCFG , 0x80 ) # Enable = 0x00
[33442772]291
292/*
[6128a4a]293 *      Initialize the DMACFG register for:
[33442772]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):
[6128a4a]313
[33442772]314        cli                               # !
[f70598c7]315/*      SetExRegByte(OCW3S, 0x20)  # address the Slave status port
[6128a4a]316        movw    $OCW3S  , dx
[f70598c7]317        inb     dx      , al    # Read the IRR.
318
[6128a4a]319        SetExRegByte(OCW3M, 0x20)  # address the Master status port
320        movw    $OCW3M  , dx
[f70598c7]321        inb     dx      , al    # Read the IRR.
[6128a4a]322*/
323
[33442772]324        SetExRegByte(ICW1S  , 0x11 ) # EDGE TRIGGERED
325        SetExRegByte(ICW2S  , 0x28 ) # Slave base vector after Master
[04bc5d9]326        SetExRegByte(ICW3S  , 0x02 ) # slave cascaded to IR2 on master
[33442772]327        SetExRegByte(ICW4S  , 0x01 ) # must be 0x01
328
329        SetExRegByte(ICW1M  , 0x11 ) # edge triggered
[04bc5d9]330        SetExRegByte(ICW2M  , 0x20 ) # base vector starts at byte 32
331        SetExRegByte(ICW3M  , 0x04)  # IR2 is cascaded internally
[f70598c7]332        SetExRegByte(ICW4M  , 0x01 ) # fully nested mode
[6128a4a]333
334        SetExRegByte(OCW1M  , 0xde )    # IR0  only = 0xfe.
[f70598c7]335                                        # for IR5 and IR0 active use 0xde
336                                        # for IR0 and IR2 use 0xfa
[33442772]337        SetExRegByte(INTCFG , 0x00 )
[6128a4a]338
339SYM(SetCS4):
[33442772]340        SetExRegWord(CS4ADL , 0x702)         #Configure chip select 4
341        SetExRegWord(CS4ADH , 0x00)
[6128a4a]342        SetExRegWord(CS4MSKH, 0x03F)
343        SetExRegWord(CS4MSKL, 0xFC01)
[33442772]344
[6128a4a]345SYM(SetUCS1):
[33442772]346        SetExRegWord(UCSADL , 0x0304)      # 512K block starting at 0x80000 until 0x3f80000
347        SetExRegWord(UCSADH , 0x03F8)
[6128a4a]348        SetExRegWord(UCSMSKH, 0x03F7)
[33442772]349        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
350
[04bc5d9]351/******************************************************
352* The GDT must be in RAM since it must be writeable,
353* So, move the whole data section down.
354********************************************************/
[6128a4a]355
[04bc5d9]356        movw $ _ram_data_offset , di
[6128a4a]357        movw $ _ram_data_segment, cx
[04bc5d9]358        mov  cx                 , es
359
[6128a4a]360        movw $ _data_size       , cx
361        movw $ _rom_data_segment, ax
362        movw $ _rom_data_offset , si
[04bc5d9]363        mov  ax                 , ds
[6128a4a]364
[33442772]365        repne
366        movsb
[6128a4a]367
[33442772]368/*****************************
369 * Load the Global Descriptor
370 * Table Register
371 ****************************/
[6128a4a]372
373#ifdef NEW_GAS
[8be7bef]374        data32 addr32 lgdt SYM(GDTR) #  location of GDT
375#else
[04bc5d9]376        lgdt SYM(GDTR) #  location of GDT
[6128a4a]377#endif
378
379SYM(SetUCS):
380        SetExRegWord(UCSADL, 0x0702)      # now 512K starting at 0x3f80000.
[33442772]381        SetExRegWord(UCSADH, 0x03f8)
[6128a4a]382        SetExRegWord(UCSMSKH, 0x0007)
[33442772]383        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
[6128a4a]384
[f70598c7]385        /*
386         * SRAM chip select:     16 bit bus size,starting 16Mb, size 512k,
387         *                       4 waits
388         */
[6128a4a]389
[f70598c7]390#ifdef UT_I386EX
391
392SYM(SetCS1):
393        SetExRegWord(CS1ADL,  0x0000)
394        SetExRegWord(CS1ADH,  0x000E)
395        SetExRegWord(CS1MSKH, 0x0000)
396        SetExRegWord(CS1MSKL, 0x0001)
[33442772]397
[f70598c7]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
[6128a4a]406         *                       4 waits
[f70598c7]407         */
408SYM(SetCS3):
409        SetExRegWord(CS3ADL,  0x0504)
410        SetExRegWord(CS3ADH,  0x0108)
411        SetExRegWord(CS3MSKH, 0x0000)
412        SetExRegWord(CS3MSKL, 0x7c01)
413
414#endif
[33442772]415/***************************
416 * Switch to Protected Mode
417 ***************************/
[f70598c7]418
[bd8c8b2a]419        mov     cr0, eax
[33442772]420        orw     $0x1, ax
[bd8c8b2a]421        mov     eax, cr0
[6128a4a]422
[33442772]423/**************************
424 * Flush prefetch queue,
425 * and load CS selector
426 *********************/
427
[04bc5d9]428        ljmpl $ GDT_CODE_PTR , $  SYM(_load_segment_registers) # sets the code selector
[6128a4a]429
[33442772]430/*
[32f3e34]431 * Load the segment registers
[33442772]432 */
[6128a4a]433SYM(_load_segment_registers):
[33442772]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)
[6128a4a]440
[33442772]441/*
442 *  Set up the stack
443 */
444
[04bc5d9]445SYM(lidtr):
446        lidt    SYM(IDTR)
447
[33442772]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
[f70598c7]452
[33442772]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
[f70598c7]473
474        movw    $0xFFFB, SYM(i8259s_cache)      # ICU mask values reflect
[6128a4a]475                                                # initial ICU state
[04bc5d9]476        call SYM(boot_card)
[33442772]477        addl    $12,esp
[32f3e34]478
479        cli                              # stops interrupts from being processed after hlt!
480        hlt                              # shutdown
[33442772]481
482END
Note: See TracBrowser for help on using the repository browser.