source: rtems/c/src/lib/libbsp/or32/orp/start/start.S @ c725258

Last change on this file since c725258 was c725258, checked in by Joel Sherrill <joel.sherrill@…>, on 09/04/03 at 18:44:58

2003-09-04 Joel Sherrill <joel@…>

  • clock/clockdrv.c, console/console.c, console/console.h, include/bsp.h, start/start.S, startup/bspclean.c, startup/bspstart.c, startup/linkcmds, startup/setvec.c, timer/timer.c, timer/timerisr.c: URL for license changed.
  • Property mode set to 100644
File size: 21.5 KB
Line 
1/* start.S -- bootup code for the Bender board using the Or1k
2 *            architecture.
3 *     
4 *  Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws
5 *
6 *  This file is distributed as part of the RTEMS package from
7 *  OAR Corporation, and follows the licensing and distribution
8 *  terms as stated for RTEMS.
9 *
10 *  COPYRIGHT (c) 1989-1999.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 */
17       
18#include "asm.h"
19
20
21/* Since we don't yet have a memory map for Bender, I am
22   assuming the following. Hopefully, this will be easily
23   modified once we get the real values.
24
25   0x00000000 - 0x00200000:    Flash/ROM (boot code / 2 MB)
26   0x01000000 - 0x010FFFFF:    Synchronous SRAM (area 2 / 1 MB)
27   0x10000000 - 0x1FFFFFFF:    External SDRAM (area 3 / 256 MB)
28   0x20000000 - 0x2FFFFFFF:    External SDRAM (area 4 / 256 MB)
29
30   0x80000000 - 0x8000001F:    4 16550 UART controllers
31   0x80010000 - 0x80017FFF:    Internal Bender RAM
32   0x80020000 - 0xFFFFFFFF:    Memory mapped Bender Peripherals
33
34   For this version, I assume that only the flash and 32 MB
35   of RAM in area 3 are populated. Everything else should
36   return a bus error when accessed.
37*/
38.file   "start.S"
39       
40.data
41        PUBLIC(Or1k_Interrupt_Vectors)
42SYM (Or1k_Interrupt_Vectors):   
43        .word   0x00000000                      # No Vector
44        .word   _start                          # Reset Vector (Ignored)
45        .word   __Internal_error_Occurred       # Bus Error
46        .word   __Internal_error_Occurred       # Data Page Fault
47        .word   __Internal_error_Occurred       # Instruction Page Fault
48        .word   __int_reenable                  # Low Priority Interrupt
49        .word   __Internal_error_Occurred       # Alignment Exception
50        .word   __Internal_error_Occurred       # Illegal Instruction Exception
51        .word   __int_reenable                  # High Priority Interrupt
52        .word   __Internal_error_Occurred       # ITBL Miss
53        .word   __Internal_error_Occurred       # DTBL Miss
54        .word   0x00000000                      # Range Exception
55        .word   0x00000000                      # System Call
56        .word   0x00000000                      # Breakpoint
57        .word   0x00000000                      # Trap
58
59/*
60        PUBLIC(BOTTOM_OF_MEMORY)
61SYM (BOTTOM_OF_MEMORY):
62        .word   0x10000000       # Assume RAM @ 0 for the sim
63
64        PUBLIC(TOP_OF_MEMORY)
65SYM (TOP_OF_MEMORY):   
66        .word   0x10800000      # Assume RAM @ 0 for the sim
67*/     
68        PUBLIC(_mem_end)
69SYM (_mem_end):
70        .word   0x10800000
71       
72        BEGIN_CODE
73        .org    0x0
74        /**************/
75        /*   _panic   */
76        /**************/
77
78        /* Place the panic vector at 0 */
79       
80.proc   __panic
81        .def    __panic
82        .val    __panic
83        .scl    2
84        .type   044
85        .endef
86        .global __panic
87__panic:
88       
89        l.jal           __exit
90        l.nop
91       
92.endproc __panic
93        .def    __panic
94        .val    .
95        .scl    -1
96        .endef
97
98        /* Exception processing...first, we will save the
99           16 non callee saved registers which could be
100           corrupted by calling a C function. We have no
101           way of knowing which of these will be used, so
102           we have to save all of them. We will then save
103           the EPCR and ESR, in case a nested exception is
104           called. Next, we call the user function. We then
105           restore all the registers to their original
106           values, and finally disable exceptions, restore
107           EPCR and ESR (EEAR is not essential to restore)
108           and then return from the interrupt. */
109           
110        /******************************************/
111        /*       Normal exception handling        */
112        /* Called with 80 bytes allocated on the  */
113        /* stack, the vector function in r11, and */
114        /* the vector number in r3. Original      */
115        /* values at 28(r1) and 0(r1).            */
116        /******************************************/
117.proc   ___standard_exception
118        .def    ___standard_exception
119        .val    ___standard_exception
120        .scl    2
121        .type   044
122        .endef
123        .global ___standard_exception
124___standard_exception:         
125        l.sfeqi r11,0                   /* Ignore it if it is zero */
126        l.bf    L2_2
127        l.sw    4(r1),r4                /* Save r4 */
128
129        /* Ignore fast context switching in this release. */
130        /* It's poorly conceived, and will probably never */
131        /* be implemented...                              */
132
133        l.sw    8(r1),r5
134        l.sw    12(r1),r6
135        l.sw    16(r1),r7
136       
137        l.mfspr r4,r0,0x20              /* Save EPCR */
138        l.mfspr r5,r0,0x30              /* Save EEAR */
139        l.mfspr r6,r0,0x40              /* Save ESR */
140       
141        l.mfspr r7,r0,17
142        l.ori   r7,r7,2
143        l.mtspr r0,r7,17                /* Reenable exceptions */
144
145        l.sw    20(r1),r8
146        l.sw    24(r1),r9
147        l.sw    32(r1),r12
148        l.sw    36(r1),r14
149        l.sw    40(r1),r16
150        l.sw    44(r1),r18
151        l.sw    48(r1),r20
152        l.sw    52(r1),r22
153        l.sw    56(r1),r24
154        l.sw    60(r1),r26
155        l.sw    64(r1),r28
156        l.sw    68(r1),r30
157        l.sw    72(r1),r4               /* Save EPCR. User could change r4 */
158
159        /* Now, call the installed handler with the arguments:
160                r3 ==> vector # (1-14)
161                r4 ==> EPCR
162                r5 ==> EEAR
163                r6 ==> ESR
164                r11 ==> User function
165        */
166
167        l.jal   ___user_function        /* Call the user routine */
168        l.sw    76(r1),r6               /* Save ESR. User could change r6 */
169                                        /* Ignore r5 (EEAR). It is not critical for state */
170
171        l.lwz   r30,68(r1)
172        l.lwz   r28,64(r1)
173        l.lwz   r26,60(r1)
174        l.lwz   r24,56(r1)
175        l.lwz   r22,52(r1)
176        l.lwz   r20,48(r1)
177        l.lwz   r18,44(r1)
178        l.lwz   r16,40(r1)
179        l.lwz   r14,36(r1)
180        l.lwz   r12,32(r1)
181        l.lwz   r9,24(r1)
182        l.lwz   r8,20(r1)
183        l.lwz   r7,16(r1)
184        l.lwz   r5,8(r1)
185
186        l.addi  r6,r0,-3                /* Set r6 to 0xFFFFFFFD */
187        l.mfspr r3,r0,17                /* Get SR value */
188        l.and   r3,r3,r6                /* Clear exception bit */
189        l.mfspr r0,r3,17                /* Disable exceptions */
190       
191        l.lwz   r6,76(r1)               /* Recover ESR */
192        l.lwz   r4,72(r1)               /* Recover EPCR */
193        l.mtspr r0,r4,0x20              /* Restore ESR */
194        l.mtspr r0,r6,0x40              /* Restore EPCR */
195        l.lwz   r6,12(r1)
196        l.lwz   r4,4(r1)
197
198L2_2:
199        l.lwz   r11,28(r1)
200        l.lwz   r3,0(r1)
201        l.addi  r1,r1,80
202        l.rfe
203        l.nop                           /* The document doesn't say this is
204                                           a delay slot instruction, but the
205                                           simulator doesn't work without this. */
206       
207.endproc ___standard_exception
208        .def    ___standard_exception
209        .val    .
210        .scl    -1
211        .endef
212
213/****************************************************************************/
214/* These constants must be in .text section in order to be                  */
215/* properly addressed in code.                                              */
216
217        PUBLIC(BOTTOM_OF_MEMORY)
218SYM (BOTTOM_OF_MEMORY):
219        .word   0x10000000       # Assume RAM @ 0 for the sim
220
221        PUBLIC(TOP_OF_MEMORY)
222SYM (TOP_OF_MEMORY):
223        .word   0x10800000      # Assume RAM @ 0 for the sim
224
225/****************************************************************************/
226
227        /** Currently, about 57 of the 64 valid address locations
228            are being used here. If you add code to the above
229            routine, make sure it isn't more than 7 instructions
230            or you will overflow into the reset vector. **/
231               
232        /****************************/
233        /* Reset vector static code */
234        /****************************/
235        .org    0x100
236.proc   ___rst
237        .global ___rst
238___rst:
239        /* Set the stack pointer */
240        l.movhi         r1,hi(_TOP_OF_MEMORY)
241        l.ori           r1,r1,lo(_TOP_OF_MEMORY)
242        l.lwz           r1,0(r1)   /* Dereference it */
243       
244        /* Set the frame pointer */
245        l.add           r2,r0,r1
246
247        l.mfspr         r3,r0,17        /* Get SR value */
248        l.ori           r3,r3,2         /* Set exception enable bit */
249        l.j             _start          /* Jump to main routine */
250        l.mtspr         r0,r3,17        /* Enable exceptions (DELAY) */
251.endproc ___rst
252
253        /***********************************************************/
254        /* Note:  right after the reset vector, we are going to    */
255        /* place a table with the necessary values to initialize   */
256        /* the memory controller. This pointer will be set and     */
257        /* passed to the _start routine in r4. The first thing the */
258        /* the _start routine will do is to initialize the memory  */
259        /* controller. The code to initialze the memory controller */
260        /* is expected to be larger than the 50 some odd           */
261        /* instructions that are remaining here before the bus     */
262        /* error vector, which is why it is left to the _start     */
263        /* routine.                                                */
264        /***********************************************************/
265       
266        /********************************/
267        /* Bus Error vector static code */
268        /********************************/
269        .org    0x200
270.proc   ___bus_error
271        .global ___bus_error
272___bus_error:
273        l.addi  r1,r1,-80
274        l.sw    0(r1),r3
275        l.sw    28(r1),r11
276        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
277        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
278        l.lwz   r11,8(r11)
279        l.j     ___standard_exception
280        l.addi  r3,r0,2
281       
282.endproc ___bus_error
283
284        /* Put _Internal_error_Occurred and _int_reenable here */
285        /* No reason to waste space...it'll be filled with 0 if */
286        /* we don't... */
287       
288        /********************************/
289        /*   _Internal_error_Occurred   */
290        /********************************/
291               
292.proc   __Internal_error_Occurred
293        .def    __Internal_error_Occurred
294        .val    __Internal_error_Occurred
295        .scl    2
296        .type   044
297        .endef
298        .global __Internal_error_Occurred
299__Internal_error_Occurred:
300       
301        l.jal           __panic
302        l.nop
303       
304.endproc __Internal_error_Occurred
305        .def    __Internal_error_Occurred
306        .val    .
307        .scl    -1
308        .endef
309
310       
311        /*********************/
312        /*   _int_reenable   */
313        /*********************/
314               
315.proc   __int_reenable
316        .def    __int_reenable
317        .val    __int_reenable
318        .scl    2
319        .type   044
320        .endef
321        .global __int_reenable
322__int_reenable:
323       
324        l.mfspr r11,r0,17
325        l.ori   r11,r11,0x04
326        l.jr    r9
327        l.mtspr r0,r11,17
328       
329.endproc __int_reenable
330        .def    __int_reenable
331        .val    .
332        .scl    -1
333        .endef
334
335        /*********************&**/
336        /*   ___user_function   */
337        /************************/
338               
339.proc   ___user_function
340        .def    ___user_function
341        .val    ___user_function
342        .scl    2
343        .type   044
344        .endef
345        .global ___user_function
346___user_function:
347
348        /* r11 contains the address to call. We can
349           modify r7, r8, r12, and r14 at will */
350       
351        l.movhi r7,hi(__Thread_Dispatch_disable_level)
352        l.ori   r7,r7,lo(__Thread_Dispatch_disable_level)
353        l.lwz   r8,0(r7)
354       
355        l.addi  r1,r1,-8        #  Stack must be DWORD aligned
356        l.sw    0(r1),r9        #  Save the return address
357
358        l.addi  r8,r8,1         # Increment __Thread_Dispatch...
359        l.jalr  r11
360        l.sw    0(r7),r8        # Disable thread dispatching
361       
362        /* Now, we need to determine if we need to
363           service the RTEMS environment. RTEMS tries
364           to draw a distinction between a RAW handler
365           (where this isn't necessary) and an RTEMS
366           handler. However, it appears almost all ISR's
367           will not be RAW under this definition, and
368           those that are will not honestly be hurt by
369           the 20 or so extra cycles it will take to do
370           the following code. If there is a very frequent
371           interrupt, then it should probably be hard
372           coded into the static routine anyway, rather
373           than suffer the hit of calling it indirectly */
374
375        /* Note:  RTEMS recommends incrementing and
376           decrementing the _ISR_Nest_Level as well.
377           We are specifically not doing this because
378           in the Or1k architecture it is impossible
379           to nest interrupts. Interrupts must run to
380           completion before reenabling. If there is a
381           significant task to be done, then it should
382           run in a bottom half handler, similar to the
383           way Linux works. In theory though, even if
384           we do allow nested interrupts, there is no
385           reason for this flag, as it seems to be for
386           the purpose of restoring the normal stack in
387           place of the interrupt stack. We don't use a
388           separate exception stack, so this should not
389           be an issue for us. */
390               
391        l.movhi r7,hi(__Thread_Dispatch_disable_level)
392        l.ori   r7,r7,lo(__Thread_Dispatch_disable_level)
393        l.lwz   r8,0(r7)
394        l.addi  r8,r8,-1        # Decrement __Thread_Dispatch...
395        l.sw    0(r7),r8        # Memory stall likely here...           
396
397        l.sfeqi r8,0            # Skip if _Thread_Dispatch != 0
398        l.bnf   L4_2
399        l.movhi r7,hi(__Context_Switch_necessary)
400       
401        l.ori   r7,r7,lo(__Context_Switch_necessary)
402        l.lwz   r8,0(r7)
403               
404        l.movhi r7,hi(__ISR_Signals_to_thread_executing)
405        l.ori   r7,r7,lo(__ISR_Signals_to_thread_executing)
406        l.lwz   r12,0(r7)
407
408        l.sfeqi r8,0            # Skip if __Context... is false
409        l.bf    L4_2
410        l.movhi r14,hi(__Thread_Dispatch)
411       
412        l.sfeqi r12,0           # Skip if __ISR... is true
413        l.bnf   L4_2
414        l.ori   r14,r14,lo(__Thread_Dispatch)
415       
416        l.jalr  r14
417        l.sw    0(r7),r0        # Set __ISR... to false
418               
419L4_2:                   
420        l.lwz   r9,0(r1)        #  Recover the return address
421        l.jr    r9
422        l.addi  r1,r1,8         #  Reset the stack
423       
424.endproc ___user_function
425        .def    ___user_function
426        .val    .
427        .scl    -1
428        .endef
429
430       
431        /* Code wasted between here and 0x300 */
432       
433        /**************************************/
434        /* Data Page Fault vector static code */
435        /**************************************/
436        .org    0x300
437.proc   ___data_page_fault
438        .global ___data_page_fault
439___data_page_fault:
440        l.addi  r1,r1,-80
441        l.sw    0(r1),r3
442        l.sw    28(r1),r11
443        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
444        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
445        l.lwz   r11,12(r11)
446        l.j     ___standard_exception
447        l.addi  r3,r0,3
448.endproc ___data_page_fault
449
450        /* Code wasted between here and 0x400 */
451               
452        /*********************************************/
453        /* Instruction Page Fault vector static code */
454        /*********************************************/
455        .org    0x400
456.proc   ___insn_page_fault
457        .global ___insn_page_fault
458___insn_page_fault:
459        l.addi  r1,r1,-80
460        l.sw    0(r1),r3
461        l.sw    28(r1),r11
462        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
463        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
464        l.lwz   r11,16(r11)
465        l.j     ___standard_exception
466        l.addi  r3,r0,4
467.endproc ___insn_page_fault
468
469        /* Code wasted between here and 0x500 */
470       
471        /**************************************/
472        /* Low Priority Interrupt static code */
473        /**************************************/
474        .org    0x500
475.proc   ___low_priority_int
476        .global ___low_priority_int
477___low_priority_int:
478        l.addi  r1,r1,-80
479        l.sw    0(r1),r3
480        l.sw    28(r1),r11
481        l.mfspr r3,r0,17                        # Get the SR
482        l.addi  r11,r0,-5                       # r11 = 0xFFFFFFFB
483        l.and   r11,r11,r3                      # Clear the EIR bit
484        l.mtspr r0,r11,17                       # Set the SR w/o INT
485        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
486        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
487        l.lwz   r11,20(r11)
488        l.j     ___standard_exception
489        l.addi  r3,r0,5
490.endproc ___low_priority_int
491
492        /* Code wasted between here and 0x600 */
493       
494        /******************************************/
495        /* Alignment Exception vector static code */
496        /******************************************/
497        .org    0x600
498.proc   ___alignment_exception
499        .global ___alignment_exception
500___alignment_exception:
501        l.addi  r1,r1,-80
502        l.sw    0(r1),r3
503        l.sw    28(r1),r11
504        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
505        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
506        l.lwz   r11,24(r11)
507        l.j     ___standard_exception
508        l.addi  r3,r0,6
509.endproc ___alignment_exception
510
511        /* Code wasted between here and 0x700 */
512       
513        /******************************************/
514        /* Illegal Instruction vector static code */
515        /******************************************/
516        .org    0x700
517.proc   ___illegal_instruction
518        .global ___illegal_instruction
519___illegal_instruction:
520        l.addi  r1,r1,-80
521        l.sw    0(r1),r3
522        l.sw    28(r1),r11
523        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
524        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
525        l.lwz   r11,28(r11)
526        l.j     ___standard_exception
527        l.addi  r3,r0,7
528.endproc ___illegal_instruction
529
530        /* Code wasted between here and 0x800 */
531       
532        /***************************************/
533        /* High Priority Interrupt static code */
534        /***************************************/
535        .org    0x800
536.proc   ___high_priority_int
537        .global ___high_priority_int
538___high_priority_int:
539        l.addi  r1,r1,-80
540        l.sw    0(r1),r3
541        l.sw    28(r1),r11
542        l.mfspr r3,r0,17                        # Get the SR
543        l.addi  r11,r0,-5                       # r11 = 0xFFFFFFFB
544        l.and   r11,r11,r3                      # Clear the EIR bit
545        l.mtspr r0,r11,17                       # Set the SR w/o INT
546        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
547        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
548        l.lwz   r11,32(r11)
549        l.j     ___standard_exception
550        l.addi  r3,r0,8
551.endproc ___high_priority_int
552
553        /* Code wasted between here and 0x900 */
554       
555        /********************************/
556        /* ITBL Miss vector static code */
557        /********************************/
558        .org    0x900
559.proc   ___ITBL_miss_exception
560        .global ___ITBL_miss_exception
561___ITBL_miss_exception:
562        l.addi  r1,r1,-80
563        l.sw    0(r1),r3
564        l.sw    28(r1),r11
565        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
566        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
567        l.lwz   r11,36(r11)
568        l.j     ___standard_exception
569        l.addi  r3,r0,9
570.endproc ___ITBL_miss_exception
571
572        /* Code wasted between here and 0xA00 */
573       
574        /********************************/
575        /* DTBL Miss vector static code */
576        /********************************/
577        .org    0xA00
578.proc   ___DTBL_miss_exception
579        .global ___DTBL_miss_exception
580___DTBL_miss_exception:
581        l.addi  r1,r1,-80
582        l.sw    0(r1),r3
583        l.sw    28(r1),r11
584        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
585        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
586        l.lwz   r11,40(r11)
587        l.j     ___standard_exception
588        l.addi  r3,r0,10
589.endproc ___DTBL_miss_exception
590
591        /* Code wasted between here and 0xB00 */
592       
593        /**************************************/
594        /* Range Exception vector static code */
595        /**************************************/
596        .org    0xB00
597.proc   ___range_exception
598        .global ___range_exception
599___range_exception:
600        l.addi  r1,r1,-80
601        l.sw    0(r1),r3
602        l.sw    28(r1),r11
603        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
604        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
605        l.lwz   r11,44(r11)
606        l.j     ___standard_exception
607        l.addi  r3,r0,11
608.endproc ___range_exception
609
610        /* Code wasted between here and 0xC00 */
611       
612        /**********************************/
613        /* System Call vector static code */
614        /**********************************/
615        .org    0xC00
616.proc   ___system_call
617        .global ___system_call
618___system_call:
619        l.addi  r1,r1,-80
620        l.sw    0(r1),r3
621        l.sw    28(r1),r11
622        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
623        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
624        l.lwz   r11,48(r11)
625        l.j     ___standard_exception
626        l.addi  r3,r0,12
627.endproc ___system_call
628
629        /* Code wasted between here and 0xD00 */
630       
631        /**********************************/
632        /* Breakpoint vector static code */
633        /**********************************/
634        .org    0xD00
635.proc   ___breakpoint
636        .global ___breakpoint
637___breakpoint:
638
639        /* In keeping with the necessary requirements for
640           gdb to work, we are limiting this vector to
641           only 2 statements, which effect an immediate
642           return. At a later date, we may insert a debug
643           monitor here that will do even more, but for
644           now, this is all we want. */
645        l.rfe
646        l.nop
647
648.endproc ___breakpoint
649
650        /* Code wasted between here and 0xE00 */
651       
652        /*************************************/
653        /* Trap Exception vector static code */
654        /*************************************/
655        .org    0xE00
656.proc   ___trap_exception
657        .global ___trap_exception
658___trap_exception:
659        l.addi  r1,r1,-80
660        l.sw    0(r1),r3
661        l.sw    28(r1),r11
662        l.movhi r11,hi(_Or1k_Interrupt_Vectors)
663        l.ori   r11,r11,lo(_Or1k_Interrupt_Vectors)
664        l.lwz   r11,56(r11)
665        l.j     ___standard_exception
666        l.addi  r3,r0,14
667.endproc ___trap_exception
668
669        /* Code wasted between here and 0x2000 */
670       
671        /* Exceptions from 0xF00 to 0x1F00 are not defined */
672        /* in the Or1k architecture. They should be filled */
673        /* in here for other implementations.              */
674
675        .org    0x2000          /* Start after exception vector table */
676               
677        /*********************/
678        /*       start       */
679        /*********************/
680
681        /* This is where we jump to right after the reset exception
682           handler. The system configuration information should
683           be passed to us in a pointer in r4. Generally, the
684           reset vector will call this routine directly, and
685           the memory configuration information will be stored
686           in the ROM/Flash image. It was decided no attempt
687           would be made to automatically determine this
688           information by probing, as the scheme would be too
689           complex and inherently unreliable. */
690
691        /* Initialize strings and structures here */   
692L_program:     
693        .ascii  "RTEMS_or1k\000"
694        .align  4
695L_argv:
696        .word   L_program
697                               
698.proc _start
699        .def    _start
700        .val    _start
701        .scl    2
702        .type   044
703        .endef
704        .global _start
705_start:
706
707        /* Initialize the memory controller here!
708           Discussions with Rudi have stated that
709           the first few bytes of the ROM image should
710           contain a RAM map as opposed to trying to
711           figure out what to do based on probing. This
712           means a separate build of the OS for every
713           possible board configuration, but there
714           doesn't seem to be a better alternative. */
715
716        /*** FIX ME! Initialize the external memory controller! ***/
717       
718        /* Move the data segment to RAM. Alternatively, we may
719           copy the text segment as well. For now, we'll assume
720           that the cache gives us sufficient performance that this
721           is not necessary. It will be very easy to add this later.
722         */     
723        l.movhi         r4,hi(_etext)
724        l.ori           r4,r4,lo(_etext)
725        l.movhi         r5,hi(_BOTTOM_OF_MEMORY)
726        l.ori           r5,r5,lo(_BOTTOM_OF_MEMORY)
727        l.lwz           r5,0(r5)            # Dereference it
728/*      l.add           r5,r5,r4            # Place it in memory above the text segment*/
729        l.movhi         r3,hi(_edata)
730        l.ori           r3,r3,lo(_edata)
731        l.movhi         r5,hi(_data_start)
732        l.ori           r5,r5,lo(_data_start)
733       
734L3_0:   
735        l.lwz           r6,0(r4)
736        l.addi          r5,r5,4
737        l.addi          r4,r4,4
738        l.sfeq          r3,r5
739        l.bnf           L3_0
740        l.sw            -4(r5),r6           # Minimize write after read stalls
741
742        /* Initialize the BSS segment */
743        l.movhi         r3,hi(__end)
744        l.ori           r3,r3,lo(__end)
745/*      l.sub           r3,r3,r4
746        l.add           r3,r3,r5*/
747        l.sfleu         r3,r5
748        l.bf            L3_2               # Check for no BSS segment!
749        l.nop
750               
751L3_1:
752        l.addi          r5,r5,4
753        l.sfeq          r5,r3
754        l.bnf           L3_1
755        l.sw            -4(r5),r0
756
757L3_2:
758        /* Tell everyone where the heap begins */
759        l.movhi         r4,hi(__mem_end)
760        l.ori           r4,r4,lo(__mem_end)
761        l.sw            0(r4),r5
762                       
763        /* Due to what I consider a bug in RTEMS, the entire
764           heap must be zeroed. I think this is the dumbest thing
765           I've ever heard, but whatever turns them on. I'd rather
766           see the code which depends on this behavior fixed. I
767           myself have never written code which assumes zeroes
768           will be returned from memory allocated from the heap.
769           Anyway, if I don't do it here, I have to set a flag in
770           the CPU structure which then will do it anyway, but
771           from less efficient C code! Zero from here to the
772           stack pointer... One day when I'm old and gray maybe
773           I'll set this to random values instead and fix
774           whatever breaks. */
775       
776        l.sw            0(r5),r0
777        l.sfeq          r5,r1
778        l.bnf           L3_3
779        l.addi          r5,r5,4
780       
781L3_3:
782        l.addi          r3,r0,1         /* Set argc to 1 */
783        l.movhi         r4,hi(L_argv)   /* Initialize argv */
784        l.ori           r4,r4,lo(L_argv)
785        l.addi          r5,r5,0         /* Set envp to NULL */
786               
787        l.mfspr         r11,r0,17       /* Get SR value */
788        l.ori           r11,r11,0x4     /* Set interrupt enable bit */
789        l.jal           _boot_card      /* Boot up the card...run the OS */
790        l.mtspr         r0,r11,17       /* Enable exceptions (DELAY) */
791       
792        /* We're done. We exited normally. Shut down. */
793        l.jal           __exit
794        l.nop
795       
796.endproc _start
797        .def    _start
798        .val    .
799        .scl    -1
800        .endef
801       
802        END_CODE
803
Note: See TracBrowser for help on using the repository browser.