source: rtems/c/src/lib/libbsp/mips/genmongoosev/start/start.S @ 7de58239

4.104.114.84.95
Last change on this file since 7de58239 was 7de58239, checked in by Joel Sherrill <joel.sherrill@…>, on 02/01/02 at 16:45:18

2001-02-01 Greg Menke <gregory.menke@…>

  • Update of BSP to address problems restarting, provide more information during boot, and better handle ROM vs RAM images.
  • README, include/bsp.h, start/regs.S, start/start.S, startup/bspstart.c, startup/linkcmds, timer/timer.c: Updated
  • Property mode set to 100644
File size: 18.0 KB
Line 
1/*
2** start.S -- startup file for Mongoose V BSP based upon crt0.S from
3** newlib-1.8.2/libgloss/mips and adapted for RTEMS.
4**
5** crt0.S -- startup file for MIPS.
6**
7** Copyright (c) 1995, 1996, 1997 Cygnus Support
8**
9** The authors hereby grant permission to use, copy, modify, distribute,
10** and license this software and its documentation for any purpose, provided
11** that existing copyright notices are retained in all copies and that this
12** notice is included verbatim in any distributions. No written agreement,
13** license, or royalty fee is required for any of the authorized uses.
14** Modifications to this software may be copyrighted by their authors
15** and need not follow the licensing terms described here, provided that
16** the new terms are clearly indicated on the first page of each file where
17** they apply.
18**
19**
20** Modification History:
21**        01/XX/01  Joel Sherrill, OAR Corp,
22**           Modified for Mongoose V BSP for NASA/GSFC Code 582.
23**
24**        06/XX/01  Greg Menke, Raytheon, Code 582
25**           Debug modifications. Removed R4000 dependencies.
26**           Added HACKED_PMON defines to facilitate startup.
27**           Added DEFAULT_EXIT_RETURN_TO_MONITOR option.
28**
29**        11/14/01  A.Ferrer, NASA/GSFC, Code 582
30**           Cleanup for ST5 mission.
31**
32**        11/27/01  A.Ferrer, NASA/GSFC, Code 582
33**           Added cache flush routines.
34*/
35
36#define LANGUAGE_ASSEMBLY
37
38
39#include <asm.h>
40#include "regs.S"
41#include "mg5.h"
42
43
44       
45#ifdef __mips16
46   /* This file contains 32 bit assembly code.  */
47   .set nomips16
48#endif
49
50
51#ifdef HACKED_PMON
52   #define PMON_UTIL_ROUTINES      0xbfc00200
53   #define UTIL_WARMSTART_VECTOR   21*4
54   #define UTIL_CPUINIT_VECTOR     22*4
55   #define UTIL_CONFIGUART_VECTOR  23*4
56   #define UTIL_PUTCHROM_VECTOR    24*4
57#endif
58
59
60/*
61** defined by linkcmds, pointing to the start of the relocation target
62** memory, referenced in this way so we can avoid defining it
63** multiply
64*/
65   .bss
66   .word 0
67   .text
68   .align 2
69
70
71/**********************************************************************
72**
73** Function: _start
74*/
75
76   /* Without the following nop, GDB thinks _start is a data variable.
77   ** This is probably a bug in GDB in handling a symbol that is at the
78   ** start of the .text section.
79   */
80    nop
81   .globl  _start
82   .ent    _start
83
84   .globl putch_rom
85_start:
86   .set    noreorder
87   move    k1,ra       /* save ra so we can optionally return to caller */
88   $LF1 = . + 8
89
90   /*
91   ** Get the address of start into $5 in a position independent fashion.
92   ** This lets us know whether we have been relocated or not.
93   */
94
95   bal     $LF1
96   nop
97_branch:
98   move    a1, ra      /* save return address from the jump above */
99
100   /* ensure we're sane before doing anything */
101
102   li      t0, SR_CU0|SR_PE
103   mtc0    t0, C0_SR
104   nop
105   li      t0, 0
106   mtc0    t0, C0_DCIC
107   nop
108   mtc0    t0, C0_CAUSE
109   nop
110
111
112   /*
113   ** Call cpuinit. Masking used to call EEPROM address of _cpuinit.  Label is RAM label.
114   */
115   move   t2,a1
116   and    t2,0xffff0000
117   la     t0,_cpuinit
118   and    t0,0x0000ffff
119   or     t0,t2
120   jal    t0
121   nop
122
123   /*
124   ** Configure UART
125   */
126   move   t2,a1
127   and    t2,0xffff0000
128   la     t0,config_uart
129   and    t0,0x0000ffff
130   or     t0,t2
131   jal    t0
132   nop
133
134   /*
135   ** Call IcacheFlush. Masking used to call EEPROM address of IcacheFlush.  Label is RAM label.
136   */
137   move   t2,a1
138   and    t2,0xffff0000
139   la     t0,IcacheFlush
140   and    t0,0x0000ffff
141   or     t0,t2
142   jal    t0
143   nop
144
145
146   /*
147   ** Print 'I'.  Show that we flushed I cache.
148   */
149   move   t2,a1
150   and    t2,0xffff0000
151   li     a0,'I'
152   la     t0,putch_rom
153   and    t0,0x0000ffff
154   or     t0,t2
155   jal    t0
156   nop
157
158
159   /*
160   ** Call DcacheFlush. Masking used to call EEPROM address of DcacheFlush.  Label is RAM label.
161   */
162   move   t2,a1
163   and    t2,0xffff0000
164   la     t0,DcacheFlush
165   and    t0,0x0000ffff
166   or     t0,t2
167   jal    t0
168   nop
169
170
171   /*
172   ** Print 'D'.  Show that we flushed D cache.
173   */
174   move   t2,a1
175   and    t2,0xffff0000
176   li     a0,'D'
177   la     t0,putch_rom
178   and    t0,0x0000ffff
179   or     t0,t2
180   jal    t0
181   nop
182
183
184   /*
185   ** Print ' RTEMS  b'.  Show that we are booting.
186   */
187   move   t2,a1
188   and    t2,0xffff0000
189   li     a0,' '
190   la     t0,putch_rom
191   and    t0,0x0000ffff
192   or     t0,t2
193   jal    t0
194   nop
195
196   move   t2,a1
197   and    t2,0xffff0000
198   li     a0,'R'
199   la     t0,putch_rom
200   and    t0,0x0000ffff
201   or     t0,t2
202   jal    t0
203   nop
204
205   move   t2,a1
206   and    t2,0xffff0000
207   li     a0,'T'
208   la     t0,putch_rom
209   and    t0,0x0000ffff
210   or     t0,t2
211   jal    t0
212   nop
213
214   move   t2,a1
215   and    t2,0xffff0000
216   li     a0,'E'
217   la     t0,putch_rom
218   and    t0,0x0000ffff
219   or     t0,t2
220   jal    t0
221   nop
222
223   move   t2,a1
224   and    t2,0xffff0000
225   li     a0,'M'
226   la     t0,putch_rom
227   and    t0,0x0000ffff
228   or     t0,t2
229   jal    t0
230   nop
231
232   move   t2,a1
233   and    t2,0xffff0000
234   li     a0,'S'
235   la     t0,putch_rom
236   and    t0,0x0000ffff
237   or     t0,t2
238   jal    t0
239   nop
240
241   move   t2,a1
242   and    t2,0xffff0000
243   li     a0,' '
244   la     t0,putch_rom
245   and    t0,0x0000ffff
246   or     t0,t2
247   jal    t0
248   nop
249
250   move   t2,a1
251   and    t2,0xffff0000
252   li     a0,'b'
253   la     t0,putch_rom
254   and    t0,0x0000ffff
255   or     t0,t2
256   jal    t0
257   nop
258
259
260   /*
261   ** get the address of the _branch label above as it would appear in
262   ** the relocated code
263   */
264
265   la  a2, _branch                 /* relocation destination */
266   beq a1, a2, _start_in_ram       /* skip relocating if we're already there */
267   nop
268
269   /* relocate the code from EEPROM to RAM */
270
271   /*
272   ** Print 'r'
273   */
274   move   t2,a1
275   and    t2,0xffff0000
276   li     a0,'r'
277   la     t0,putch_rom
278   and    t0,0x0000ffff
279   or     t0,t2
280   jal    t0
281   nop
282
283   la  a3, _edata
284relocate:
285   lw  t0, (a1)            /* load from EEPROM */
286   addu    a1, 4
287   sw      t0, (a2)        /* store to RAM */
288   addu    a2, 4
289   bne a2, a3, relocate    /* copied all the way to edata? */
290   nop
291
292   /*
293   ** Print 'R'
294   */
295   li     a0,'R'
296   la     t0,putch_rom
297   and    t0,0x0000ffff
298   or     t0,t2
299   jal    t0
300   nop
301
302   la  a2, _start_in_ram
303   jr  a2
304   nop
305   .end _start
306
307
308/**********************************************************************
309**
310** Function: _start_in_ram
311*/
312
313   .globl  _start_in_ram
314   .ent _start_in_ram
315_start_in_ram:
316
317   /*
318   ** Print 'S'.  Already in RAM no need to reference EEPROM address.
319   */
320   li a0,'S'
321   jal putch_rom
322   nop
323
324   la  gp, _gp         /* set the global data pointer */
325   .end _start_in_ram
326
327
328/**********************************************************************
329**
330** Function: zerobss
331*/
332   .globl  __memsize
333   .globl  zerobss
334   .ent    zerobss
335zerobss:
336
337   /*
338   ** Print 'z'.  Starting to zero out bss.
339   */
340   li a0,'z'
341   jal putch_rom
342   nop
343
344   la v0, _fbss
345   la v1, _end
3463:
347   sw zero,0(v0)
348   bltu v0,v1,3b
349   addiu v0,v0,4               /* executed in delay slot */
350
351   la  t0, _stack_init         /* initialize stack so we */
352
353   /*
354   ** We must subtract 24 bytes for the 3 8 byte arguments to main, in
355   ** case main wants to write them back to the stack.  The caller is
356   ** supposed to allocate stack space for parameters in registers in
357   ** the old MIPS ABIs.  We must do this even though we aren't passing
358   ** arguments, because main might be declared to have them.
359   **
360   ** Some ports need a larger alignment for the stack, so we subtract
361   ** 32, which satisifes the stack for the arguments and keeps the
362   ** stack pointer better aligned.
363   */
364   subu    t0,t0,32
365   move    sp,t0               /* set stack pointer */
366   nop
367
368   /*
369   ** Print 'Z'.  Finished zeroing bss.
370   */
371   li a0,'Z'
372   jal putch_rom
373   nop
374
375   .end    zerobss
376
377
378/**********************************************************************
379**
380** Function: _init
381*/
382   .globl  exit .text
383   .globl  _init
384   .ent    _init
385_init:
386
387   /*
388   ** Print 'i'.  Starting to initialize RTEMS.
389   */
390   li a0, 'i'
391   jal putch_rom
392   nop
393
394   move    a0,zero         /* set argc to 0 */
395   jal boot_card           /* call the program start function */
396   nop
397
398   /*
399   ** fall through to the "exit" routine
400   */
401   jal _sys_exit
402   nop
403   .end _init
404
405
406/**********************************************************************
407**
408** Function: _sys_exit
409**
410** Exit from the application by jumping to PMON address in EEPROM.
411*/
412   .globl  _sys_exit
413   .ent _sys_exit
414_sys_exit:
415   la  t0, PMON_ADDRESS
416   jal t0
417   .end _sys_exit
418
419
420
421/**********************************************************************
422**
423** function: putch
424** input   : ASCII character in A0
425** registers used: ra, a0, t0, t1
426**
427*/
428   .globl putch_rom
429   .ent   putch_rom
430putch_rom:
431
432   /*
433   ** Delay for UART
434   */
435   li   t0, 1000
436   move t1, zero
4372:
438   beq  t0, t1, 3f
439   addu t1, 1
440   b    2b
441   nop
442
4433:
444   /*
445   ** Print a character out from a0
446   */
447
448   li   t0, MG5_INT_STATUS_REG      /* load uart register base address */
449   lw   t1, 0(t0)                   /* Read status */
450   nop
451   and  t1, t1, UART_0_TX_READY_BIT /* see if the transmitter is ready */
452   beq  t1 , zero , 1f              /* skip uart output if not ready */
453   nop
454   la   t0, MG5_UART_0_TX_REG
455   sw   a0, 0(t0)
456   nop
457
4581: /*
459   ** if jumped to here, UART was not ready...forget it
460   */
461   j    ra
462  .end putch_rom
463
464
465/**********************************************************************
466**
467** function: config_uart
468** registers used: ra, t0, t1
469**
470*/
471
472   .globl config_uart
473   .ent   config_uart
474config_uart:
475
476   /*
477   **  Configure UART 0
478   */
479
480   /* First, reset the uart */
481   la   t0, MG5_COMMAND_REG
482   li   t1, UART_RESET_BIT
483   sw   t1, 0(t0)
484
485   /* Next, set the baud rate register for 19200 with a clock speed of 12 Mhz*/
486   la   t0, MG5_UART_0_BAUD_REG
487   li   t1, 0x02700270
488   sw   t1, 0(t0)
489
490   /* Now, clear the reset bit & set the tx enable bit */
491   la   t0, MG5_COMMAND_REG
492   li   t1, UART_0_TX_ENABLE_BIT
493   sw   t1, 0(t0)
494
495   /*
496   ** return
497   */
498   j    ra
499.end config_uart
500
501
502/*************************************************************
503* CpuInit:
504*   Perform CPU-specific initialization
505*   This routine is only callable from assembly because it
506*   clobbers s7. It should be called from your ROM-based startup
507*   code. It returns:
508*       s0 = address of cache flush routine
509*/
510
511   .globl  _cpuinit
512   .ent _cpuinit
513_cpuinit:
514
515   #
516   # BIU/Cache config register setup
517   #
518   # RES    = 0: 31 -> 18 : Reserved
519   # RES    = 1: 17       : Reserved must be set to 1 (Synova Manual)
520   # RES    = 0: 16       : Reserved must be set to 0 (Synova Manual)
521   # BGNT   = 0: 15       : Disable Bus Grant (set to 0)
522   # NOPAD  = 1: 14       : No padding of waitstates between transactions
523   # RDPRI  = 1: 13       : Loads have priority over stores
524   # INTP   = 1: 12       : Interrupts are active high
525   # IS1    = 1: 11       : Enable I-Cache
526   # IS0    = 0: 10       : Hardwired to zero
527   # IBLKSZ =10:  9 ->  8 : I-Cache refill size = 8 words
528   # DS     = 1:  7       : Enable D-Cache
529   # RES    = 0:  6       : Hardwared to zero
530   # DBLKSZ =10:  5 ->  4 : D-Cache refill block size 8 words
531   # RAM    = 0:  3       : No Scratchpad RAM
532   # TAG    = 0:  2       : Disable tag test
533   # INV    = 0:  1       : Disable invalidate mode
534   # LOCK   = 0:  0       : Disable cache lock
535   #
536   li  t0,0x00027AA0
537   sw  t0,M_BIU
538
539   #
540   # Refresh register setup
541   #
542   # set 94 clock cycles at 12Mhz
543   #
544   li  t1,M_RTIC
545   li  t0,0x5E
546   sw  t0,(t1)
547
548   #
549   # DRAM register setup
550   #
551   #
552   # RESERVED=0: 31 -> 29 : Reserved
553   # SYNC  = 0 : 27       : No Syncronous DRAM
554   # SCFG  = 0 : 26       : No Syncronous DRAM
555   # DMARDY =1 : 25       : Internal DRDY for DMA
556   # DMABLK =0 : 24 -> 22 : 2 word blk size for DMA transfers
557   # DPTH = 0  : 21 -> 20 : No interleaved or syncronous memory
558   # RDYW = 0  : 19       : No interleaved or syncronous memory
559   # PGSZ = 110: 18 -> 16 : Page size = 1K
560   # PGMW = 0  : 15       : Disable page mode write
561   # RFWE = 0  : 14 -> 13 : Allow BIU to do non-DRAM work during refresh
562   # RFEN = 1  : 12       : Enable Refresh generator
563   # RDYEN = 1 : 11       : Internal DRDY
564   # BFD =   1 : 10       : Block fetch disable
565   # PE =    0 : 9        : No parity checking
566   # RPC =   0 : 8 -> 7   : RAS Precharge = 2 SYSCLK cycles
567   # RCD =   1 : 6 -> 5   : RAS-to-CAS delay = 3 cycles
568   # CS  =   0 : 4        : CAS shortened by 1/2 cycle
569   # CL  =   1 : 3 -> 1   : 2.5 cycle CAS pulse width
570   # DCE =   1 : 0        : Enable DRAM controller
571   li  s0,0x02061C23
572   sw  s0,M_DRAM
573
574   #
575   # SRAM setup
576   # Dont Care about this, we are not using SRAM
577   # Power on default of 0x0 is ok
578   #
579   li  t0,0
580   sw  t0,M_SRAM
581
582   #
583   # SPEC0 setup
584   #
585   # SPEC0 contains the BCRT registers, BCRT Shared RAM and EEPROM
586   # This area is configured to use an external waitstate generator
587   # and Data Ready signal.
588   # Also, I see no need to cache this data. It could confuse the
589   # BCRT.
590   #
591   # - 9/29/99 - APC - set NOSNOOP to 1 and EXTGNT to 1
592   #  Bit 23 = 1 : EXTGNT External data ready = 1
593   #  Bit 19 = 1 : NOSNOOP No Snoop = 1
594   li  t0,0x00880000         # use external waitstates
595   sw  t0,M_SPEC0
596
597   #
598   # SPEC1 setup
599   #
600   # This is where most of the SDB I/O is.
601   #
602   #  Important fields:
603   #
604   #  Bit 19 =1 : NOSNOOP = 1
605   #  Bit 6 = 1 : Enable DAWG
606   #  Bit 5 -> 0  = 1 : 1 Wait state
607   #
608   li  t0,0x00880000      /* Bit23 EXTGNT set to 1, Bit19 NOSNOOP set to 1 */
609   sw  t0,M_SPEC1
610
611   #
612   # SPEC2 setup
613   #
614   # SPEC2 is not currently used on the SDB.
615   # Bit 19 = 1 : NOSNOOP = 1
616   #
617   #li t0, 0x00080000
618   #sw t0,M_SPEC2
619   #
620   li  t0, 0x0
621   sw  t0,M_SPEC2
622
623
624   #
625   # SPEC3 Setup
626   # SPEC3 will be used for the SONIC ethernet controller.
627   # Use the same # of waitstates that the turborocket board uses.
628   # Bit 19 = 1 : NOSNOOP = 1
629   #
630   #li t0, (SPC_CACHED | SPC_WAITENA | (16<<SPC_WAITSHFT))
631   #sw t0,M_SPEC3
632   #
633   li  t0, 0x0
634   sw  t0,M_SPEC3
635
636   #
637   # Finally, delay to allow RAM to stabilize
638   #
639   li  t0,2000
6401: subu    t0,1
641   bne t0,zero,1b
642   nop
643
644   #
645   # Init Mongoose V registers.
646   #
647
648   /*
649   ** Mongoose V Control Register Setup
650   ** For now just setup UART defaults, turn edac off.
651   ** May not even need to put anything in here...
652   */
653   li  t0,0
654   sw  t0,MG5_COMMAND_REG
655
656   /*
657   ** Setup Mongoose V extended interrupt mask
658   */
659   li  t0,0
660   sw  t0,MG5_INT_MASK_REG
661
662   /*
663   ** Clear Mongoose V extended interrupts
664   ** Clear all of the pulse interrupts that may be pending.
665   */
666   li  t0,( EDAC_SERR_BIT | EDAC_MERR_BIT | UART_0_RX_OVERRUN_BIT | UART_0_FRAME_ERR_BIT | UART_1_RX_OVERRUN_BIT | UART_1_FRAME_ERR_BIT | MAVN_WRITE_ACC_BIT | MAVN_READ_ACC_BIT )
667   sw  t0,MG5_INT_STATUS_REG
668
669   /*
670   ** Setup MAVN Access Priv Register
671   */
672   li  t0,0x7FFFFFFF  /* Default reset value */
673   sw  t0,MG5_MAVN_PRIVLEGE_REG
674
675   /*
676   ** Mavn Range Register 0 -- 0 and 1 cover EEPROM
677   ** 0xbfc00000 -> 0xbfe00000
678   */
679   li  t0,( 0xBFC00000 | 0x15 )
680   sw  t0,MG5_MAVN_RANGE_0_REG
681
682   /*
683   ** Mavn Range Register 1
684   ** 0xbfe00000 -> 0xc0000000
685   */
686   li  t0,( 0xBFE00000 | 0x15 )
687   sw  t0,MG5_MAVN_RANGE_1_REG
688
689   /*
690   ** Mavn Range Register 2 -- 2 and 3 cover the first RAM
691   ** 0x80000000 -> 0x80200000
692   */
693   li  t0,( 0x80000000 | 0x15 )
694   sw  t0,MG5_MAVN_RANGE_2_REG
695
696   /*
697   ** Mavn Range Register 3
698   ** 0x80200000 -> 0x80400000
699   */
700   li  t0, ( 0x80200000 | 0x15 )
701   sw  t0, MG5_MAVN_RANGE_3_REG
702
703   /*
704   ** Mavn Range Register 4 -- IO Space 1
705   ** 0xBE00000 -> 0xBe0000200
706   */
707   li  t0, ( 0xBe000000 | 0x09 )
708   sw  t0, MG5_MAVN_RANGE_4_REG
709
710   /*
711   ** Mavn Range Register 5 -- IO Space 2
712   ** 0xBe200000 -> 0xbe400000
713   */
714   li  t0, ( 0xBE200000 | 0x15 )
715   sw  t0, MG5_MAVN_RANGE_5_REG
716
717   /*
718   ** MAVN Error Address Register ( Unstick )
719   */
720   la      t0, MG5_MAVN_VIOLATION_REG
721   lw      t1, 0(t0)
722
723   /*
724   ** Read EDAC Error Register to unstick it
725   */
726   la      t0, MG5_EDAC_ADDR_REG
727   lw      t1, 0(t0)
728
729   /*
730   ** Enable Mongoose V EDAC
731   */
732   la      t0, MG5_COMMAND_REG
733   li      t1, EDAC_ENABLE_BIT
734   sw      t1, 0(t0)
735   nop
736
737   /*
738   ** Program Watchdog to 10 seconds - If PMON will
739   ** run, it will be set to MAX later.
740   */
741   la      t0, 0xBE000000
742   li      t1, 0xA0
743   sw      t1, 0(t0)
744
7453: nop
746
747   j ra
748   .end _cpuinit
749
750
751/*******************************************************************************
752** Function Name:   IcacheFlush
753** Description:     This functions flushes the on chip icache.
754*/
755
756     .globl IcacheFlush
757     .ent IcacheFlush
758IcacheFlush:
759
7601:
761     # Assume I cache is already enabled in BIU/Cache setup
762     # Get contents of M_BIU register and save in t1
763     li        t0, M_BIU
764     lw        t1, 0(t0)
765
766     .set noreorder
767
768     # Isolate I cache
769     mfc0      t3, C0_SR        /* Read Status Register */
770     nop
771     or        t0, t3, SR_ISC   /* Isolate Cache so we don't propagate operations */
772     mtc0      t0, C0_SR        /* Write it back to Status Register */
773     nop
774
775     # Setup for cache flush
776     li        t8, 0            /* Store zero */
777     li        t9, LR33300_IC_SIZE
778
779icache_write:
780     sw        zero, 0(t8)          /* Store zero to memory addres in t8 */
781     addu      t8, 4                /* Increment t8 addres by 4 */
782     bltu      t8, t9, icache_write /* check to see if we are done */
783     nop
784
785
786     # De-isolate I cache
787     mtc0      t3, C0_SR        /* Load unchanged t3 to Status Register */
788     nop
789
790     jal       ra
791     nop
792     .set reorder
793     .end IcacheFlush
794
795
796/********************************************************
797** Function Name:   DcacheFlush
798** Description:     This functions flushes the on chip dcache.
799*/
800
801     .globl DcacheFlush
802     .ent DcacheFlush
803DcacheFlush:
804
805     # isolate icache
806     .set noreorder
807     mfc0      t3,C0_SR
808     nop
809     or        t0, t3, SR_ISC
810     mtc0      t0, C0_SR
811     nop
812
813     # Setup up for cache flush
814     li        t8, 0
815     li        t9, LR33300_DC_SIZE
816
817dcache_write:
818     sw        zero, 0(t8)
819     addu      t8, 4
820     bltu      t8, t9, dcache_write /* check to see if we are done */
821     nop
822
823     # De-isolate cache
824     mtc0      t3, C0_SR
825     nop
826
827     jal       ra
828     nop
829     .set reorder
830     .end DcacheFlush
831
832
833/* EOF start.S */
Note: See TracBrowser for help on using the repository browser.