OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [ts_386ex/] [start/] [start.S] - Blame information for rev 773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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: start.S,v 1.2 2001-09-27 11:59:50 chris Exp $
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, "ax"
54
 
55
/*
56
 * Enable access to peripheral register at expanded I/O addresses
57
 */
58
SYM(_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
 */
77
SYM(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
*/
88
SYM(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
/*
111
SYM(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
 
131
SYM(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
 
154
SYM(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
 
174
SYM(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
 
194
SYM(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
 
214
SYM(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
 
229
SYM(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
*/
249
SYM(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
*/
268
SYM(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
 
317
SYM(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
 
349
SYM(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
#if 0
373
        lgdt     (eax)                    #  location of GDT in segment
374
#endif
375
        lgdt SYM(GDTR) #  location of GDT
376
 
377
/*
378
        NOTE: not sure about this either so comment out for now...
379
SYM(SetUCS):
380
        SetExRegWord(UCSADL, 0xC503)      # values taken from TS-1325 memory
381
        SetExRegWord(UCSADH, 0x000D)
382
        SetExRegWord(UCSMSKH, 0x0000)
383
        SetExRegWord(UCSMSKL, 0x3C01)     # configure upper chip select
384
*/
385
/*
386
        LED_OFF
387
        WAIT_BUTTON
388
*/
389
/***************************
390
 * Switch to Protected Mode
391
 ***************************/
392
        mov     cr0, eax
393
        orw     $0x1, ax
394
        mov     eax, cr0
395
 
396
/**************************
397
 * Flush prefetch queue,
398
 * and load CS selector
399
 *********************/
400
/*
401
        LED_YELLOW
402
        WAIT_BUTTON
403
*/
404
        ljmpl $ GDT_CODE_PTR , $  SYM(_load_segment_registers) # sets the code selector
405
 
406
/*
407
 * Load the segment registers
408
 */
409
SYM(_load_segment_registers):
410
        .code32
411
/*
412
        LED_GREEN
413
        WAIT_BUTTON
414
*/
415
        pLOAD_SEGMENT( GDT_DATA_PTR, fs)
416
        pLOAD_SEGMENT( GDT_DATA_PTR, gs)
417
        pLOAD_SEGMENT( GDT_DATA_PTR, ss)
418
        pLOAD_SEGMENT( GDT_DATA_PTR, ds)
419
        pLOAD_SEGMENT( GDT_DATA_PTR, es)
420
 
421
/*
422
 *  Set up the stack
423
 */
424
/*
425
        LED_OFF
426
        WAIT_BUTTON
427
*/
428
SYM(lidtr):
429
        lidt    SYM(IDTR)
430
/*
431
        LED_YELLOW
432
        WAIT_BUTTON
433
*/
434
SYM (_establish_stack):
435
        movl    $_ebss, eax             # stack starts right after bss
436
        movl    $stack_origin, esp      # this is the high starting address
437
        movl    $stack_origin, ebp
438
/*
439
        LED_GREEN
440
        WAIT_BUTTON
441
*/
442
/*
443
 *  Zero out the BSS segment
444
 */
445
SYM (zero_bss):
446
        cld                             # make direction flag count up
447
        movl    $ SYM (_ebss),ecx       # find end of .bss
448
        movl    $ SYM (_bss_start),edi  # edi = beginning of .bss
449
        subl    edi,ecx                 # ecx = size of .bss in bytes
450
        shrl    ecx                     # size of .bss in longs
451
        shrl    ecx
452
        xorl    eax,eax                 # value to clear out memory
453
        repne                           # while ecx != 0
454
        stosl                           # clear a long in the bss
455
/*
456
 *  Now we can initialize the IRQ mask in i8259s_cache
457
 */
458
        movw    $0xFFFB, SYM(i8259s_cache)
459
/*
460
        LED_YELLOW                      # Indicate ready to run
461
        WAIT_BUTTON
462
*/
463
        LED_GREEN                       # Indicate RTEMS running!
464
 
465
/*
466
 *  Transfer control to User's Board Support Package
467
 */
468
        pushl   $0                       # environp
469
        pushl   $0                       # argv
470
        pushl   $0                       # argc
471
        call SYM(boot_card)
472
        addl    $12,esp
473
 
474
        LED_RED                          # Indicate RTEMS exited
475
/*
476
        WAIT_BUTTON
477
*/
478
        cli                              # stops interrupts after hlt!
479
        hlt                              # shutdown
480
 
481
 
482
        .balign 4                        # align tables to 4 byte boundary
483
 
484
SYM(IDTR):      DESC3( SYM(Interrupt_descriptor_table), 0x07ff );
485
 
486
SYM(Interrupt_descriptor_table):   /* Now in data section */
487
        .rept 256
488
        .word 0,0,0,0
489
        .endr
490
 
491
 
492
/*
493
 *  Use the first (null) entry in the the GDT as a self-pointer for the GDTR.
494
 *  (looks like a common trick)
495
 */
496
 
497
SYM (_Global_descriptor_table):
498
SYM(GDTR):      DESC3( GDTR, 0x17 );      # one less than the size
499
                .word 0                   # padding to DESC2 size
500
SYM(GDT_CODE):  DESC2(0xffff,0,0x0,0x9B,0xDF,0x00);
501
SYM(GDT_DATA):  DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF
502
SYM(GDT_END):
503
 
504
END

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.