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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [or1k/] [bender/] [start/] [start.S] - Blame information for rev 173

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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