source: rtems/c/src/lib/libbsp/i386/ts_386ex/start/start.S @ 16a384cf

4.104.114.84.95
Last change on this file since 16a384cf was 16a384cf, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 23, 1999 at 4:35:11 PM

New BSP from Tony R. Ambardar <tonya@…> from the
University of British Columbia. The BSP is for:

Yes, this is the "entry model" of a series of boards from Technologic
Systems. Costs <$200 I believe. They have a WWW page at www.t-systems.com.
I am letting them know about the availability of this BSP too.

  • Property mode set to 100644
File size: 12.4 KB
Line 
1/*
2 *  This file is the main boot and configuration file for the TS-1325. It is
3 *  solely responsible for initializing the internal register set to reflect
4 *  the proper board configuration.  This version is modified from the i386ex
5 *  BSP startup:       
6 *
7 *    1) 1 MB RAM @ 0x0100000
8 *    2) 1 MB RAM @ 0x0 but with standard DOS memory usage.
9 *    3) Timer0 used as RTEMS clock ticker, 1 msec tick rate.
10 *    4) READY# is generated by CPU
11 *
12 *  The file describes the ".initial" section, which contains: 
13 *     1) device configuration code
14 *     2) interrupt descriptor table
15 *     3) global descriptor table
16 *     4) and initial boot code
17 *
18 *  Modified by:
19 *
20 *    Tony Ambardar
21 *    University of British Columbia
22 *    tonya@ece.ubc.ca
23 *
24 *  The license and distribution terms for this file may be
25 *  found in the file LICENSE in this distribution or at
26 *  http://www.OARcorp.com/rtems/license.html.
27 *
28 *  $Id$
29 */
30
31#include "asm.h"
32#include "macros.inc"
33#include "80386ex.inc"
34
35#include "ts_1325.inc"             /* controls for LED and button */
36       
37/*
38 * NEW_GAS Needed for binutils 2.9.1.0.7 and higher
39 */                     
40
41        EXTERN (boot_card)         /* exits to bspstart   */
42        EXTERN (_DOS_seg_base)     /* defined in startup/linkcmds */
43        EXTERN (Clock_exit)
44
45        PUBLIC (Interrupt_descriptor_table)
46        PUBLIC ( SYM(IDTR) )
47        PUBLIC (_Global_descriptor_table)
48        PUBLIC ( SYM(GDTR) )
49
50        PUBLIC( SYM(_init_i386ex) )
51
52       
53        .section .initial
54
55/*
56 * Enable access to peripheral register at expanded I/O addresses
57 */
58SYM(_init_i386ex):     
59        .code16
60/*
61        LED_GREEN
62        WAIT_BUTTON
63*/
64#       cli                    Move this up for now for debug.
65        movw    $0x8000 , ax           
66        outb    al , $REMAPCFGH
67        xchg    al , ah
68        outb    al , $REMAPCFGL
69        outw    ax , $REMAPCFG ;
70/*     
71        LED_OFF
72        WAIT_BUTTON
73*/
74/*
75 * Configure operation of the A20 Address Line
76 */     
77SYM(A20):
78        movw    $PORT92 , dx
79       
80        inb     dx      , al   # clear A20 port reset
81        andb    $0xfe   , al   # b0 Fast Reset(0)=disabled,(1)=reset triggered
82        orb     $0x02   , al   # Bit 1 Fast A20 = 0 (always 0) else enabled.
83        outb    al      , dx
84/*
85        LED_YELLOW
86        WAIT_BUTTON
87*/
88SYM(Watchdog):
89        movw    $WDTSTATUS      , dx    # address the WDT status port
90        inb     dx              , al    # get the WDT status
91        orb     $0x01           , al    # set the CLKDIS bit
92        outb    al              , dx    # disable the clock to the WDT
93/*
94        LED_GREEN
95        WAIT_BUTTON
96*/
97/*
98 * Initialize Refresh Control Unit for:
99 *      Refresh Address = 0x0000
100
101 *      Refresh gate between rows is 20.0 (???) uSec
102 *      Using a CLK2 frequency of 50Mhz ( 25Mhz CPU )
103 *      The refresh unit is enabled
104 *      The refresh pin is not used.
105 *
106 *      Different TS units might have different refresh intervals, so
107 *      comment out. Will be set up anyway after booting to DOS.
108 */
109
110/*
111SYM(InitRCU):           
112        SetExRegWord( RFSCIR , 0x1F4)   # refresh interval 500
113        SetExRegWord( RFSBAD , 0x0)     # base address
114        SetExRegWord( RFSADD , 0x0)     # address register
115        SetExRegWord( RFSCON , 0x8000)  # enable bit
116*/
117
118/*
119        LED_OFF
120        WAIT_BUTTON
121*/
122/*
123 * Initialize clock and power mgmt unit for:   
124 *      Clock Frequency = 50 Mhz
125 *      Prescaled clock output = 1 Mhz
126 *      Normal halt instructions
127 *
128 *      NOTE: Hope this doesn't change the COMCLK frequency
129 */
130       
131SYM(InitClk):   
132        SetExRegByte( PWRCON, 0x0 )
133        SetExRegWord( CLKPRS, 0x17)     # 0x13 for 1.19318 MHz.  0x17 for 1MHz.
134
135/**************************************************************
136 * Initialize the Pin Configurations
137 *************************************************************/
138/*
139        LED_YELLOW
140        WAIT_BUTTON
141*/
142/*
143 *      Initialize I/O port 1 for:     
144 *      PIN 0 = 0,      Inport for external push-button switch
145 *      PIN 1 = 1,      RTS0# to package pin
146 *      PIN 2 = 1,      DTR0# to package pin
147 *      PIN 3 = 1,      DSR0# to package pin
148 *      PIN 4 = 0,      Inport ???
149 *      PIN 5 = 0,      Outport (Green LED, 1 = ON)
150 *      PIN 6 = 0,      Outport (Red LED, 1 = OFF)
151 *      PIN 7 = 0,      Inport ???
152 */
153
154SYM(InitPort1):         
155        SetExRegByte( P1LTC     , 0xd1 )
156        SetExRegByte( P1DIR     , 0x91)
157        SetExRegByte( P1CFG     , 0x0e)
158/*
159        LED_GREEN
160        WAIT_BUTTON
161*/
162/*
163 *      Initialize I/O port 2 for:     
164 *      PIN 0 = 0,      Outport ???
165 *      PIN 1 = 0,      Outport ???
166 *      PIN 2 = 0,      Outport ???
167 *      PIN 3 = 0,      Outport ???
168 *      PIN 4 = 0,      Outport ???
169 *      PIN 5 = 1,      Int. periph, RXD0
170 *      PIN 6 = 1,      Int. periph, TXD0
171 *      PIN 7 = 0,      Outport ???
172 */
173       
174SYM(InitPort2):
175        SetExRegByte( P2LTC     , 0x1f )
176        SetExRegByte( P2DIR     , 0x00  )
177        SetExRegByte( P2CFG     , 0x60)
178/*
179        LED_OFF
180        WAIT_BUTTON
181*/
182/*
183 *      Initialize I/O port 3 P3CFG     
184 *      PIN 0 = 1,      Int. periph, TMROUT0
185 *      PIN 1 = 1,      Int. periph, TMROUT1
186 *      PIN 2 = 1,      Int. periph, INT0 (IR1)
187 *      PIN 3 = 1,      Int. periph, INT1 (IR5)
188 *      PIN 4 = 1,      Int. periph, INT2 (IR6)
189 *      PIN 5 = 1,      Int. periph, INT2 (IR7)
190 *      PIN 6 = 0,      Outport ???
191 *      PIN 7 = 1,      Int. periph, COMCLK used for serial I/O
192 */
193       
194SYM(InitPort3):         
195        SetExRegByte( P3LTC     , 0x00 )
196        SetExRegByte( P3DIR     , 0xbf )
197        SetExRegByte( P3CFG     , 0xbf )  # can check TMROUT0
198/*
199        LED_YELLOW
200        WAIT_BUTTON
201*/
202/*
203 *      Initialize Peripheral Pin Configurations:       
204 *      PIN 0 = 1,      Select RTS1#
205 *      PIN 1 = 1,      Select DTR1#
206 *      PIN 2 = 1,      Select TXD1#
207 *      PIN 3 = 1,      Select CTS1#
208 *      PIN 4 = 1,      CS5
209 *      PIN 5 = 1,      Timer2 pins enabled
210 *      PIN 6 = 0,      Select CS6#
211 *      PIN 7 = 0,      Don't care
212 */
213       
214SYM(InitPeriph):       
215        SetExRegByte( PINCFG , 0x3f)
216/*
217        LED_GREEN
218        WAIT_BUTTON
219*/
220/*
221 *      Initialize the Asynchronous Serial Ports:       
222 *      BIT 7 = 1,      Internal SIO1 modem signals
223 *      BIT 6 = 1,      Internal SIO0 modem signals
224 *      BIT 2 = 0,      PSCLK for SSIO clock
225 *      BIT 1 = 1,      SERCLK for SIO1 clock
226 *      BIT 0 = 1,      SERCLK for SIO0 clock
227 */
228
229SYM(InitSIO):   
230        SetExRegByte( SIOCFG, 0x00 ) # COMCLK -> baud-rate generator
231                                     # modem signals -> package pins
232        SetExRegByte( LCR0, 0x80 )  # latch DLL0, DLH0
233        SetExRegByte( DLL0, 0x01 )  # 0x0C sets to 9600 baud 0x6 = 19.2K
234        SetExRegByte( DLH0, 0x00 )  # 0x4 is 28.8K baud, 0x1 is 115K baud
235        SetExRegByte( LCR0, 0x03 )  # enable r/w buffers, IER0 accessible
236                                    # mode 8-n-1
237        SetExRegByte( IER0, 0x00 )  # no generated interrupts
238       
239        SetExRegByte( LCR1, 0x80 )  # latch DLL0, DLH0
240        SetExRegByte( DLL1, 0x01 )  # 0x0C set to 9600 baud, 0x6 = 19.2K
241        SetExRegByte( DLH1, 0x00 )  # 0x4 is 28.8K baud
242        SetExRegByte( LCR1, 0x03 )  # enable r/w buffers, IER1 accessible
243                                        # reg 8-n-1
244        SetExRegByte( IER1, 0x00 )  # no generated intrrupts
245/*
246        LED_OFF
247        WAIT_BUTTON
248*/
249SYM(InitMCR):
250        SetExRegByte( MCR0, 0x03 )  # standard mode, RTS,DTR activated
251        SetExRegByte( MCR1, 0x03 )  # standard mode, RTS,DTR activated
252
253/*
254 *      Initialize Timer for:   
255 *      BIT 7 = 1,      Timer clocks disabled
256 *      BIT 6 = 0,      Reserved
257 *      BIT 5 = 1,      TMRCLK2 instead of Vcc to Gate2
258 *      BIT 4 = 0,      PSCLK to CLK2
259 *      BIT 3 = 1,      TMRCLK1 instead of Vcc to Gate1
260 *      BIT 2 = 0,      PSCLK to Gate1
261 *      BIT 1 = 0,      Vcc to Gate0   
262 *      BIT 0 = 0,      PSCLK to Gate0
263 */
264/*
265        LED_YELLOW
266        WAIT_BUTTON
267*/
268SYM(InitTimer):
269        SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1
270                                     # and 2 are set to Vcc
271
272        SetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSB
273        SetExRegByte(TMR0   , 0x00 ) # sfa
274        SetExRegByte(TMR0   , 0x00 ) # sfa
275
276                       
277        SetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= Vcc
278        SetExRegByte(TMR1   , 0x00 ) # sfa
279        SetExRegByte(TMR1   , 0x00 ) # sfa
280       
281        SetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =Vcc
282        SetExRegByte(TMR2   , 0x00 ) # 
283        SetExRegByte(TMR2   , 0x00 ) # 
284
285/*
286        LED_GREEN
287        WAIT_BUTTON
288*/
289/*
290 *      Initialize the DMACFG register for:     
291 *      BIT 7    = 1  , Disable DACK#1
292 *      BITs 6:4 = 100, TMROUT2 connected to DRQ1
293 *      BIT 3    = 1  , Disable DACK0#
294 *      BIT 2:0  = 000, Pin is connected to DRQ0
295 *
296 *      NOTE: not 100% sure of this...
297 */
298
299        SetExRegByte(DMACFG , 0xC0  )
300        SetExRegByte(DMACMD1, 0x00 ) # disable both DMA channels
301        SetExRegByte(DMAMOD1, 0x40 ) # DMA0 single transer mode
302/*
303        LED_OFF
304        WAIT_BUTTON
305*/
306/*
307 *      Initialize the INTCFG register for:
308 *      BIT 7 = 0,      8259 cascade disabled
309 *      BIT 3 = 0,      SLAVE IR6 connected to Vss
310 *      BIT 2 = 0,      SLAVE IR5 connected to Vss
311 *      BIT 1 = 0,      SLAVE IR1 connected to SSIOINT
312 *      BIT 0 = 0,      SLAVE IR0 connected to Vss
313 *
314 *      NOTE: not 100% sure of this either... Why IR5 active?
315 */
316
317SYM(InitInt):
318       
319        cli                               # !
320/*
321        LED_YELLOW
322        WAIT_BUTTON
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 ) # fully nested mode, no EOI
328
329        SetExRegByte(ICW1M  , 0x11 ) # edge triggered
330        SetExRegByte(ICW2M  , 0x20 ) # base vector starts at byte 32
331        SetExRegByte(ICW3M  , 0x04)  # internal slave cascaded from master IR2
332        SetExRegByte(ICW4M  , 0x01 ) # idem
333       
334        SetExRegByte(OCW1M  , 0xfb ) # mask master IRQs, but not IR2 (cascade)
335        SetExRegByte(OCW1S  , 0xff ) # mask all slave IRQs
336        SetExRegByte(INTCFG , 0x00 ) # slave IRs -> Vss or SSIOINT
337
338/*      The i8259s_cache (IRQ mask) location is in BSS, which is zeroed later!
339 *      So to initialize the cache we should do the following command after
340 *      the BSS is zeroed, and in 32-bit protected mode.
341 *
342 *      movw    $0xFFFB, SYM(i8259s_cache)
343 *
344 */
345
346/*
347        NOTE: not sure about this so comment out...
348
349SYM(SetCS4):   
350        SetExRegWord(CS4ADL , 0x702)         #Configure chip select 4
351        SetExRegWord(CS4ADH , 0x00)
352        SetExRegWord(CS4MSKH, 0x03F)     
353        SetExRegWord(CS4MSKL, 0xFC01) 
354*/
355/*
356        LED_GREEN
357        WAIT_BUTTON
358*/
359/*****************************
360 * Load the Global Descriptor
361 * Table Register
362 ****************************/
363
364        movl    $SYM(GDTR), eax
365        andl    $0xFFFF, eax
366
367#ifdef NEW_GAS 
368        addr32
369        data32
370#endif 
371
372        lgdt     (eax)                    #  location of GDT in segment
373
374/*
375        NOTE: not sure about this either so comment out for now...     
376SYM(SetUCS):           
377        SetExRegWord(UCSADL, 0xC503)      # values taken from TS-1325 memory
378        SetExRegWord(UCSADH, 0x000D)
379        SetExRegWord(UCSMSKH, 0x0000)   
380        SetExRegWord(UCSMSKL, 0x3C01)     # configure upper chip select
381*/
382/*
383        LED_OFF
384        WAIT_BUTTON
385*/
386/***************************
387 * Switch to Protected Mode
388 ***************************/
389        mov     cr0, eax
390        orw     $0x1, ax
391        mov     eax, cr0
392       
393/**************************
394 * Flush prefetch queue,
395 * and load CS selector
396 *********************/
397/*
398        LED_YELLOW
399        WAIT_BUTTON
400*/
401        ljmpl $ GDT_CODE_PTR , $  SYM(_load_segment_registers) # sets the code selector
402
403/*
404 * Load the segment registers
405 */
406SYM(_load_segment_registers):   
407        .code32
408/*
409        LED_GREEN
410        WAIT_BUTTON
411*/
412        pLOAD_SEGMENT( GDT_DATA_PTR, fs)
413        pLOAD_SEGMENT( GDT_DATA_PTR, gs)
414        pLOAD_SEGMENT( GDT_DATA_PTR, ss)
415        pLOAD_SEGMENT( GDT_DATA_PTR, ds)
416        pLOAD_SEGMENT( GDT_DATA_PTR, es)
417       
418/*
419 *  Set up the stack
420 */
421/*
422        LED_OFF
423        WAIT_BUTTON
424*/
425SYM(lidtr):
426        lidt    SYM(IDTR)
427/*
428        LED_YELLOW
429        WAIT_BUTTON
430*/
431SYM (_establish_stack):
432        movl    $_ebss, eax             # stack starts right after bss
433        movl    $stack_origin, esp      # this is the high starting address
434        movl    $stack_origin, ebp
435/*
436        LED_GREEN
437        WAIT_BUTTON
438*/
439/*
440 *  Zero out the BSS segment
441 */
442SYM (zero_bss):
443        cld                             # make direction flag count up
444        movl    $ SYM (_ebss),ecx       # find end of .bss
445        movl    $ SYM (_bss_start),edi  # edi = beginning of .bss
446        subl    edi,ecx                 # ecx = size of .bss in bytes
447        shrl    ecx                     # size of .bss in longs
448        shrl    ecx
449        xorl    eax,eax                 # value to clear out memory
450        repne                           # while ecx != 0
451        stosl                           # clear a long in the bss
452/*
453 *  Now we can initialize the IRQ mask in i8259s_cache
454 */
455        movw    $0xFFFB, SYM(i8259s_cache)
456/*
457        LED_YELLOW                      # Indicate ready to run
458        WAIT_BUTTON
459*/
460        LED_GREEN                       # Indicate RTEMS running!
461
462/*
463 *  Transfer control to User's Board Support Package
464 */
465        pushl   $0                       # environp
466        pushl   $0                       # argv
467        pushl   $0                       # argc
468        call SYM(boot_card)
469        addl    $12,esp
470
471        LED_RED                          # Indicate RTEMS exited
472/*
473        WAIT_BUTTON
474*/
475        cli                              # stops interrupts after hlt!
476        hlt                              # shutdown
477
478
479        .balign 4                        # align tables to 4 byte boundary
480
481SYM(IDTR):      DESC3( SYM(Interrupt_descriptor_table), 0x07ff );
482       
483SYM(Interrupt_descriptor_table):   /* Now in data section */
484        .rept 256
485        .word 0,0,0,0
486        .endr
487
488
489/*
490 *  Use the first (null) entry in the the GDT as a self-pointer for the GDTR.
491 *  (looks like a common trick)
492 */
493                       
494SYM (_Global_descriptor_table):
495SYM(GDTR):      DESC3( GDTR, 0x17 );      # one less than the size
496                .word 0                   # padding to DESC2 size
497SYM(GDT_CODE):  DESC2(0xffff,0,0x0,0x9B,0xDF,0x00);
498SYM(GDT_DATA):  DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF
499SYM(GDT_END):
500
501END
Note: See TracBrowser for help on using the repository browser.