source: rtems/c/src/lib/libbsp/i386/i386ex/start/start.s @ 32f3e34

4.104.114.84.95
Last change on this file since 32f3e34 was 32f3e34, checked in by Joel Sherrill <joel.sherrill@…>, on 09/24/98 at 13:55:18

Patch from Erik Ivanenko <erik.ivanenko@…>:

Please find attached a start.s that includes a cli prior to the hlt
instruction. This ensures that external interrupts cannot restart
the system after returning to the startup code. ( According to the hlt
docs, they will! )

Also find a new timer.c. ( I forgot to update the countdowm value
in the timer when I changed the PSCLK frequency in start.s) . This
improves timer accuracy.

The raw_idt_notify messages are no longer infinite, I tested sp11 and
sp05, both which were bad, and I have seen the message print once in
one test. I think it's ok if it prints out once. In fact, I don't
think you can effectively stop it!

  • Property mode set to 100644
File size: 12.4 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#define NEXT_GAS
48       
49        EXTERN (boot_card)         /* exits to bspstart   */
50        EXTERN (stack_start)       /* defined in startup/linkcmds */
51        EXTERN (Clock_exit)
52
53        PUBLIC (Interrupt_descriptor_table)
54        PUBLIC ( SYM(IDTR) )
55        PUBLIC( SYM(_initInternalRegisters) )
56       
57BEGIN_DATA
58SYM(IDTR):      DESC3( SYM(Interrupt_descriptor_table), 0x07ff );
59       
60SYM(Interrupt_descriptor_table):   /* Now in data section */
61        .rept 256
62        .word 0,0,0,0
63        .endr
64
65END_DATA       
66       
67BEGIN_DATA
68         PUBLIC (_Global_descriptor_table)
69                       
70SYM(GDTR):      DESC3( GDT_TABLE, 0x1f ); # one less than the size
71SYM (_Global_descriptor_table):
72SYM(GDT_TABLE): DESC2(0,0,0,0,0,0);
73SYM(GDT_ALIAS): DESC2(32,0x1000,0x0,0x93,0,0x0);
74SYM(GDT_CODE):  DESC2(0xffff,0,0x0,0x9B,0xDF,0x00);
75SYM(GDT_DATA):  DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF
76SYM(GDT_END):
77
78END_DATA
79       
80
81/* This section is the section that is used by the interrupt
82   descriptor table.  It is used to provide the IDT with the
83   correct vector offsets.  It is for symbol definition only.
84*/
85       
86
87        .section .reset                       
88
89                PUBLIC ( SYM(reset) )
90SYM(reset):     
91        nop
92        cli
93        jmp     SYM(_initInternalRegisters) /* different section in this file */
94        .code32                             /* in case this section moves     */
95        nop                                 /* required by CHIP LAB to pad out size */
96        nop
97        nop
98        nop
99        nop
100
101       
102       
103        .section .initial
104       
105/*
106 * Enable access to peripheral register at expanded I/O addresses
107 */
108SYM(_initInternalRegisters):   
109        .code16
110        movw    $0x8000 , ax           
111        outb    al      , $REMAPCFGH
112        xchg    al      , ah
113        outb    al,$REMAPCFGL
114        outw    ax,      $REMAPCFG ;
115       
116
117/*
118 * Configure operation of the A20 Address Line
119 */     
120SYM(A20):
121        movw    $PORT92 , dx
122       
123        inb     dx      , al   # clear A20 port reset
124        andb    $0xfe   , al   # b0 Fast Reset(0)=disabled,(1)=reset triggered
125        orb     $0x02   , al   # Bit 1 Fast A20 = 0 (always 0) else enabled.
126        outb    al      , dx
127
128SYM(Watchdog):
129        movw    $WDTSTATUS      , dx    # address the WDT status port
130        inb     dx              , al    # get the WDT status
131        orb     $0x01           , al    # set the CLKDIS bit
132        outb    al              , dx    # disable the clock to the WDT
133
134/*
135 * Initialize Refresh Control Unit for:
136 *      Refresh Address = 0x0000
137
138 *      Refresh gate between rows is 15.6 uSec
139 *      Using a CLK2 frequency of 50Mhz ( 25Mhz CPU )
140 *      The refresh unit is enabled
141 *      The refresh pin is not used.
142 */
143
144SYM(InitRCU):           
145        SetExRegWord( RFSCIR , 390)     # refresh interval was 390, tried 312
146        SetExRegWord( RFSBAD , 0x0)     # base address
147        SetExRegWord( RFSADD , 0x0)     # address register
148        SetExRegWord( RFSCON , 0x8000)  # enable bit
149
150/*
151 * Initialize clock and power mgmt unit for:   
152 *      Clock Frequency = 50 Mhz
153 *      Prescaled clock output = 1 Mhz
154 *      Normal halt instructions
155 */
156       
157SYM(InitClk):   
158        SetExRegByte( PWRCON, 0x0 )
159        SetExRegWord( CLKPRS, 0x17)   # 0x13 for 1.19318 MHz.  0x17 for 1MHz.
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   , 0x00 ) # sfa
278        SetExRegByte(TMR0   , 0x00 ) # sfa
279
280                       
281        SetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= Vcc
282        SetExRegByte(TMR1   , 0x00 ) # sfa
283        SetExRegByte(TMR1   , 0x00 ) # sfa
284       
285        SetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =Vcc
286        SetExRegByte(TMR2   , 0x00 ) # 
287        SetExRegByte(TMR2   , 0x00 ) # 
288
289        SetExRegByte(TMRCFG , 0x80 ) # Enable = 0x00
290
291/*
292 *      Initialize the DMACFG register for:     
293 *      BIT 7    = 1  , Disable DACK#1
294 *      BITs 6:4 = 100, TMROUT2 connected to DRQ1
295 *      BIT 3    = 1  , Disable DACK0#
296 *      BIT 2:0  = 000, Pin is connected to DRQ0
297 */
298
299        SetExRegByte(DMACFG , 0xC0  )
300        SetExRegByte(DMACMD1, 0x00 ) # disable both DMA channels
301        SetExRegByte(DMAMOD1, 0x40 )
302/*
303 *      Initialize the INTCFG register for:
304 *      BIT 7 = 0,      8259 cascade disabled
305 *      BIT 3 = 0,      SLAVE IR6 connected to Vss
306 *      BIT 2 = 0,      SLAVE IR5 connected to Vss
307 *      BIT 1 = 0,      SLAVE IR1 connected to SSIOINT
308 *      BIT 0 = 0,      SLAVE IR0 connected to Vss
309 */
310
311SYM(InitInt):
312       
313        cli                               # !
314       
315        SetExRegByte(ICW1S  , 0x11 ) # EDGE TRIGGERED
316        SetExRegByte(ICW2S  , 0x28 ) # Slave base vector after Master
317        SetExRegByte(ICW3S  , 0x02 ) # slave cascaded to IR2 on master
318        SetExRegByte(ICW4S  , 0x01 ) # must be 0x01
319
320        SetExRegByte(ICW1M  , 0x11 ) # edge triggered
321        SetExRegByte(ICW2M  , 0x20 ) # base vector starts at byte 32
322        SetExRegByte(ICW3M  , 0x04)  # IR2 is cascaded internally
323        SetExRegByte(ICW4M  , 0x01 ) # idem
324       
325        SetExRegByte(OCW1M  , 0xde ) # IR0  only = 0xfe.  for IR5 and IR0 active use 0xde
326        SetExRegByte(INTCFG , 0x00 )
327       
328        movw    $0xFFFB, SYM(i8259s_cache) /* set up same values in cache */
329       
330SYM(SetCS4):   
331        SetExRegWord(CS4ADL , 0x702)         #Configure chip select 4
332        SetExRegWord(CS4ADH , 0x00)
333        SetExRegWord(CS4MSKH, 0x03F)     
334        SetExRegWord(CS4MSKL, 0xFC01) 
335
336SYM(SetUCS1):           
337        SetExRegWord(UCSADL , 0x0304)      # 512K block starting at 0x80000 until 0x3f80000
338        SetExRegWord(UCSADH , 0x03F8)
339        SetExRegWord(UCSMSKH, 0x03F7)   
340        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
341
342/******************************************************
343* The GDT must be in RAM since it must be writeable,
344* So, move the whole data section down.
345********************************************************/
346
347        movw $ _ram_data_offset , di
348        movw $ _ram_data_segment, cx
349        mov  cx                 , es
350
351        movw $ _data_size       , cx
352        movw $ _rom_data_segment, ax
353        movw $ _rom_data_offset , si
354        mov  ax                 , ds
355       
356        repne
357        movsb
358       
359/*****************************
360 * Load the Global Descriptor
361 * Table Register
362 ****************************/
363       
364#ifdef NEXT_GAS
365        data32
366        addr32
367#endif 
368        lgdt SYM(GDTR) #  location of GDT
369
370       
371SYM(SetUCS):           
372        SetExRegWord(UCSADL, 0x0702)      # now 512K starting at 0x3f80000.     
373        SetExRegWord(UCSADH, 0x03f8)
374        SetExRegWord(UCSMSKH, 0x0007)   
375        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
376
377/***************************
378 * Switch to Protected Mode
379 ***************************/
380        mov     cr0, eax
381        orw     $0x1, ax
382        mov     eax, cr0
383       
384/**************************
385 * Flush prefetch queue,
386 * and load CS selector
387 *********************/
388
389        ljmpl $ GDT_CODE_PTR , $  SYM(_load_segment_registers) # sets the code selector
390       
391/*
392 * Load the segment registers
393 */
394SYM(_load_segment_registers):   
395        .code32
396        pLOAD_SEGMENT( GDT_DATA_PTR, fs)
397        pLOAD_SEGMENT( GDT_DATA_PTR, gs)
398        pLOAD_SEGMENT( GDT_DATA_PTR, ss)
399        pLOAD_SEGMENT( GDT_DATA_PTR, ds)
400        pLOAD_SEGMENT( GDT_DATA_PTR, es)
401       
402/*
403 *  Set up the stack
404 */
405
406SYM(lidtr):
407        lidt    SYM(IDTR)
408
409SYM (_establish_stack):
410        movl    $end, eax               # stack starts right after bss
411        movl    $stack_origin, esp      # this is the high starting address
412        movl    $stack_origin, ebp
413/*
414 *  Zero out the BSS segment
415 */
416SYM (zero_bss):
417        cld                             # make direction flag count up
418        movl    $ SYM (end),ecx        # find end of .bss
419        movl    $ SYM (_bss_start),edi # edi = beginning of .bss
420        subl    edi,ecx               # ecx = size of .bss in bytes
421        shrl    ecx                    # size of .bss in longs
422        shrl    ecx
423        xorl    eax,eax               # value to clear out memory
424        repne                           # while ecx != 0
425        stosl                           #   clear a long in the bss
426
427/*
428 *  Transfer control to User's Board Support Package
429 */
430        pushl   $0                       # environp
431        pushl   $0                       # argv
432        pushl   $0                       # argc
433        call SYM(boot_card)
434        addl    $12,esp
435
436        cli                              # stops interrupts from being processed after hlt!
437        hlt                              # shutdown
438
439END
440
Note: See TracBrowser for help on using the repository browser.