source: rtems/c/src/lib/libbsp/i386/i386ex/start/start.s @ 479c86dd

4.104.114.84.95
Last change on this file since 479c86dd was 479c86dd, checked in by Joel Sherrill <joel.sherrill@…>, on 09/23/98 at 13:22:43

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

Please find attached the two files that have been changed relative to
980921 . The changes here are in the handling of the counter-timer used
as the basis for the rtems executive clock. For the most part, these
are housekeeping changes.

The PSCLK frequency change in start.s... was a part of several
bug-fixes. The fix improves executive clock and timer accuracy.

changes :

start.s -- All timers are disabled by the initialization routine

-- PSCLK ( used by clock and timers ) frequency changed to 1MHz

The clock_initialize routine now assumes that the PSCLK frequency is
exactly 1 MHz.

ckinit.c

Clock_isr -- removed division by 1000. Now use 'static'
variable -- clock_intial_isr_value -- to reset Clock_isrs variable.
clock_initialize -- moved counter timer initialization here. Values
used to configure the timer are totally dependent on
BSP_configuration.microseconds_per_tick ( and the PSCLK assumption).
Initializes clock_initial_isr_value used by th Clock_isr to reset
Clock_isrs.

clock_on -- no longer configures the timer, just enables it.

Since altering the number of sections in the BSP, I decided to give it a
good "once over" . The clock handling is now cleaner.

  • Property mode set to 100644
File size: 12.9 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/*      .section        .gdt */
69         PUBLIC (_Global_descriptor_table)
70                       
71SYM(GDTR):      DESC3( GDT_TABLE, 0x1f ); # one less than the size
72SYM (_Global_descriptor_table):
73SYM(GDT_TABLE): DESC2(0,0,0,0,0,0);
74SYM(GDT_ALIAS): DESC2(32,0x1000,0x0,0x93,0,0x0);
75SYM(GDT_CODE):  DESC2(0xffff,0,0x0,0x9B,0xDF,0x00);
76SYM(GDT_DATA):  DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF
77SYM(GDT_END):
78
79END_DATA
80       
81
82/* This section is the section that is used by the interrupt
83   descriptor table.  It is used to provide the IDT with the
84   correct vector offsets.  It is for symbol definition only.
85*/
86       
87
88        .section .reset                       
89
90                PUBLIC ( SYM(reset) )
91SYM(reset):     
92        nop
93        cli
94        jmp     SYM(_initInternalRegisters) /* different section in this file */
95        .code32                             /* in case this section moves     */
96        nop                                 /* required by CHIP LAB to pad out size */
97        nop
98        nop
99        nop
100        nop
101
102       
103       
104        .section .initial
105       
106/*
107 * Enable access to peripheral register at expanded I/O addresses
108 */
109SYM(_initInternalRegisters):   
110        .code16
111        movw    $0x8000 , ax           
112        outb    al      , $REMAPCFGH
113        xchg    al      , ah
114        outb    al,$REMAPCFGL
115        outw    ax,      $REMAPCFG ;
116       
117
118/*
119 * Configure operation of the A20 Address Line
120 */     
121SYM(A20):
122        movw    $PORT92 , dx
123       
124        inb     dx      , al   # clear A20 port reset
125        andb    $0xfe   , al   # b0 Fast Reset(0)=disabled,(1)=reset triggered
126        orb     $0x02   , al   # Bit 1 Fast A20 = 0 (always 0) else enabled.
127        outb    al      , dx
128
129SYM(Watchdog):
130        movw    $WDTSTATUS      , dx    # address the WDT status port
131        inb     dx              , al    # get the WDT status
132        orb     $0x01           , al    # set the CLKDIS bit
133        outb    al              , dx    # disable the clock to the WDT
134
135/*
136 * Initialize Refresh Control Unit for:
137 *      Refresh Address = 0x0000
138
139 *      Refresh gate between rows is 15.6 uSec
140 *      Using a CLK2 frequency of 50Mhz ( 25Mhz CPU )
141 *      The refresh unit is enabled
142 *      The refresh pin is not used.
143 */
144
145SYM(InitRCU):           
146        SetExRegWord( RFSCIR , 390)     # refresh interval was 390, tried 312
147        SetExRegWord( RFSBAD , 0x0)     # base address
148        SetExRegWord( RFSADD , 0x0)     # address register
149        SetExRegWord( RFSCON , 0x8000)  # enable bit
150
151/*
152 * Initialize clock and power mgmt unit for:   
153 *      Clock Frequency = 50 Mhz
154 *      Prescaled clock output = 1 Mhz
155 *      Normal halt instructions
156 */
157       
158SYM(InitClk):   
159        SetExRegByte( PWRCON, 0x0 )
160        SetExRegWord( CLKPRS, 0x17)   # 0x13 for 1.19318 MHz.  0x17 for 1MHz.
161
162/**************************************************************
163 * Initialize the Pin Configurations
164 *************************************************************/
165
166/*
167 *      Initialize I/O port 1 for:     
168 *      PIN 0 = 1,      DCD0# to package pin
169 *      PIN 1 = 1,      RTS0# to package pin
170 *      PIN 2 = 1,      DTR0# to package pin
171 *      PIN 3 = 1,      DSR0# to package pin
172 *      PIN 4 = 1,      RI0# to package pin
173 *      PIN 5 = 0,      Outport (FLASH Vpp Enable, 0=Enable 1=Disable)
174 *      PIN 6 = 0,      Outport (P16_HOLD to 386ex option header JP7 pin 5)
175 *      PIN 7 = 0,      Outport (P17_HOLD to 386ex option header JP7 pin 3)
176 */
177
178SYM(InitPort1):         
179        SetExRegByte( P1LTC     , 0xff )
180        SetExRegByte( P1DIR     , 0x0  )
181        SetExRegByte( P1CFG     , 0x1f)
182       
183/*
184 *      Initialize I/O port 2 for:     
185 *      PIN 0 = 0,      Outport (P20_CS0# to 386ex option header JP7 pin 11)
186 *      PIN 1 = 0,      Outport (P21_CS1# to 386ex option header JP7 pin 9)
187 *      PIN 2 = 1,      CS2# (SMRAM) If not using CS2 can be configured as.?
188 *      PIN 3 = 0,      Outport ( no connect )
189 *      PIN 4 = 1,      CS#4 (DRAM)
190 *      PIN 5 = 1,      RXD0 input. See not for I/0 port 1 pins 1-4
191 *      PIN 6 = 1,      TXD0 output.
192 *      PIN 7 = 1,      CTS0# input.
193 */
194       
195SYM(InitPort2):
196        SetExRegByte( P2LTC     , 0xff )
197        SetExRegByte( P2DIR     , 0x0  )
198        SetExRegByte( P2CFG     , 0xfe)
199       
200/*
201 *      Initialize I/O port 3 P3CFG     
202 *      PIN 0 = 1,      TMROUT0 to package pin
203 *      PIN 1 = 0,      (TMROUT1 to 386ex option header JP7 pin 23)
204 *      PIN 2 = 0,      INT0 (IR1) disabled, (P3.2 out to JP7 pin 21)
205 *      PIN 3 = 0,      INT1 (IR5) disbled (P3.3  to option header JP7 pin 19)
206 *      PIN 4 = 0,      INT2 (IR6) disbled (P3.4 to option header JP7 pin 17)
207 *      PIN 5 = 0,      INT2 (IR7) disabled (P3.5 to 386ex header JP7 pin 15)
208 *      PIN 6 = 0,      Inport (Debugger Break P3.6/PWRD to package pin )
209 *                      P3.6 selected
210 *      PIN 7 = 0,      COMCLK output disabled, 1.8432 Mhz OSC1 oscillator.
211 *                      ( Debbugger uses COMCLK as the clocking source )
212 *                      P3.7 connected to package pin.
213 */
214       
215SYM(InitPort3):         
216        SetExRegByte( P3LTC     , 0xff )
217        SetExRegByte( P3DIR     , 0x41 )
218        SetExRegByte( P3CFG     , 0x09 )  # can check TMROUT0
219/*
220 *      Initialize Peripheral Pin Configurations:       
221 *      PIN 0 = 1,      RTS1# to package pin   
222 *      PIN 1 = 1,      DTR1# to package pin
223 *      PIN 2 = 1,      TXD1 out to package pin
224 *      PIN 3 = 0,      EOP#/TC
225 *      PIN 4 = 0,      DACK0#
226 *      PIN 5 = 1,      Timer2
227 *      PIN 6 = 0,      0 => CS6# connected to package pin
228 *      PIN 7 = 0,      Don't care
229 */
230       
231SYM(InitPeriph):       
232        SetExRegByte( PINCFG , 0x24)
233       
234/*
235 *      Initialize the Asynchronous Serial Ports:       
236 *      BIT 7 = 1,      Internal SIO1 modem signals
237 *      BIT 6 = 1,      Internal SIO0 modem signals
238 *      BIT 2 = 0,      PSCLK for SSIO clock
239 *      BIT 1 = 1,      SERCLK for SIO1 clock
240 *      BIT 0 = 1,      SERCLK for SIO0 clock
241 */
242
243SYM(InitSIO):   
244        SetExRegByte( SIOCFG, 0xC3 ) # SIOn clocked internally
245
246        SetExRegByte( LCR0,     0x80 )  # latch DLL0, DLH0
247        SetExRegByte( DLL0, 0x51 )      # 0x51 sets to 9600 baud 0x7 -> 115,200
248        SetExRegByte( DLH0, 0x00 )  # 0x145 is 2400 baud
249        SetExRegByte( LCR0, 0x03 )  # enable r/w buffers, IER0 accessible
250                                    # mode 8-n-1
251        SetExRegByte( IER0, 0x00 )  # was 0x0f All interrupts detected
252       
253        SetExRegByte( LCR1, 0x80 )  # latch DLL0, DLH0
254        SetExRegByte( DLL1, 0x51 )  # 0x51 set to 9600 baud, 0x7 = 115200
255        SetExRegByte( DLH1, 0x00 )  # 0x145 is 2400 baud
256        SetExRegByte( LCR1, 0x03 )  # enable r/w buffers, IER1 accessible
257                                        # reg 8-n-1
258        SetExRegByte( IER1, 0x00 )  # was 0x0f - All interrupts detected
259
260SYM(InitMCR):   
261/*
262 *      Initialize Timer for:   
263 *      BIT 7 = 1,      Timer clocks disabled
264 *      BIT 6 = 0,      Reserved
265 *      BIT 5 = 1,      TMRCLK2 instead of Vcc to Gate2
266 *      BIT 4 = 0,      PSCLK to CLK2
267 *      BIT 3 = 1,      TMRCLK1 instead of Vcc to Gate1
268 *      BIT 2 = 0,      PSCLK to Gate1
269 *      BIT 1 = 0,      Vcc to Gate0   
270 *      BIT 0 = 0,      PSCLK to Gate0
271 */
272
273SYM(InitTimer):
274        SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1
275                                     # and 2 are set to Vcc
276
277        SetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSB
278        SetExRegByte(TMR0   , 0x00 ) # sfa
279        SetExRegByte(TMR0   , 0x00 ) # sfa
280
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       
316        SetExRegByte(ICW1S  , 0x11 ) # EDGE TRIGGERED
317        SetExRegByte(ICW2S  , 0x28 ) # Slave base vector after Master
318        SetExRegByte(ICW3S  , 0x02 ) # slave cascaded to IR2 on master
319        SetExRegByte(ICW4S  , 0x01 ) # must be 0x01
320
321        SetExRegByte(ICW1M  , 0x11 ) # edge triggered
322        SetExRegByte(ICW2M  , 0x20 ) # base vector starts at byte 32
323        SetExRegByte(ICW3M  , 0x04)  # IR2 is cascaded internally
324        SetExRegByte(ICW4M  , 0x01 ) # idem
325       
326        SetExRegByte(OCW1M  , 0xde ) # IR0  only = 0xfe.  for IR5 and IR0 active use 0xde
327        SetExRegByte(INTCFG , 0x00 )
328       
329        movw    $0xFFFB, SYM(i8259s_cache) /* set up same values in cache */
330       
331SYM(SetCS4):   
332        SetExRegWord(CS4ADL , 0x702)         #Configure chip select 4
333        SetExRegWord(CS4ADH , 0x00)
334        SetExRegWord(CS4MSKH, 0x03F)     
335        SetExRegWord(CS4MSKL, 0xFC01) 
336
337SYM(SetUCS1):           
338        SetExRegWord(UCSADL , 0x0304)      # 512K block starting at 0x80000 until 0x3f80000
339        SetExRegWord(UCSADH , 0x03F8)
340        SetExRegWord(UCSMSKH, 0x03F7)   
341        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
342
343/******************************************************
344* The GDT must be in RAM since it must be writeable,
345* So, move the whole data section down.
346********************************************************/
347               
348/* SYM(xfer_gdt):               
349        movw $ _ram_gdt_offset  , di
350        movw $ _ram_gdt_segment , cx
351        mov  cx                 , es
352
353        movw $ _gdt_size        , cx
354        movw $ _rom_gdt_segment , ax
355        movw $ _rom_gdt_offset  , si
356        mov  ax                 , ds
357       
358        repne
359        movsb
360*/
361
362        movw $ _ram_data_offset , di
363        movw $ _ram_data_segment, cx
364        mov  cx                 , es
365
366        movw $ _data_size       , cx
367        movw $ _rom_data_segment, ax
368        movw $ _rom_data_offset , si
369        mov  ax                 , ds
370       
371        repne
372        movsb
373       
374/*****************************
375 * Load the Global Descriptor
376 * Table Register
377 ****************************/
378       
379/*      movw $ _ram_gdt_segment, ax */
380
381#ifdef NEXT_GAS
382        data32
383        addr32
384#endif 
385/*        lgdt  _ram_gdt_offset     #  location of GDT */
386
387        lgdt SYM(GDTR) #  location of GDT
388
389       
390SYM(SetUCS):           
391        SetExRegWord(UCSADL, 0x0702)      # now 512K starting at 0x3f80000.     
392        SetExRegWord(UCSADH, 0x03f8)
393        SetExRegWord(UCSMSKH, 0x0007)   
394        SetExRegWord(UCSMSKL, 0xFC01)     # configure upper chip select
395
396/***************************
397 * Switch to Protected Mode
398 ***************************/
399        mov     cr0, eax
400        orw     $0x1, ax
401        mov     eax, cr0
402       
403/**************************
404 * Flush prefetch queue,
405 * and load CS selector
406 *********************/
407
408/*      ljmpl $ GDT_CODE_PTR , $  SYM(_copy_data) # sets the code selector*/
409        ljmpl $ GDT_CODE_PTR , $  SYM(_load_segment_registers) # sets the code selector
410       
411/*
412 * Copy the data section down to RAM
413 */
414/*SYM(_copy_data): */
415SYM(_load_segment_registers):   
416        .code32
417        pLOAD_SEGMENT( GDT_DATA_PTR, fs)
418        pLOAD_SEGMENT( GDT_DATA_PTR, gs)
419        pLOAD_SEGMENT( GDT_DATA_PTR, ss)
420        pLOAD_SEGMENT( GDT_DATA_PTR, ds)
421        pLOAD_SEGMENT( GDT_DATA_PTR, es)
422       
423/*      movl            $ SYM(_data_start)      , edi # ram destination
424        movl            $ SYM(_rom_data_start)  , esi # rom data source
425        movl            $ SYM(_data_size)       , ecx # amount to move
426        repne                                         # while ecx != 0
427        movsb                                         #   move a byte   
428*/
429/*
430 *  Set up the stack
431 */
432
433SYM(lidtr):
434        lidt    SYM(IDTR)
435
436SYM (_establish_stack):
437        movl    $end, eax               # stack starts right after bss
438        movl    $stack_origin, esp      # this is the high starting address
439        movl    $stack_origin, ebp
440/*
441 *  Zero out the BSS segment
442 */
443SYM (zero_bss):
444        cld                             # make direction flag count up
445        movl    $ SYM (end),ecx        # find end of .bss
446        movl    $ SYM (_bss_start),edi # edi = beginning of .bss
447        subl    edi,ecx               # ecx = size of .bss in bytes
448        shrl    ecx                    # size of .bss in longs
449        shrl    ecx
450        xorl    eax,eax               # value to clear out memory
451        repne                           # while ecx != 0
452        stosl                           #   clear a long in the bss
453
454/*
455 *  Transfer control to User's Board Support Package
456 */
457        pushl   $0                       # environp
458        pushl   $0                       # argv
459        pushl   $0                       # argc
460        call SYM(boot_card)
461        addl    $12,esp
462       
463        hlt
464
465END
466
Note: See TracBrowser for help on using the repository browser.