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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [mips/] [arch/] [v2_0/] [src/] [vectors.S] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
##=============================================================================
2
##
3
##      vectors.S
4
##
5
##      MIPS exception vectors
6
##
7
##=============================================================================
8
#####ECOSGPLCOPYRIGHTBEGIN####
9
## -------------------------------------------
10
## This file is part of eCos, the Embedded Configurable Operating System.
11
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
##
13
## eCos is free software; you can redistribute it and/or modify it under
14
## the terms of the GNU General Public License as published by the Free
15
## Software Foundation; either version 2 or (at your option) any later version.
16
##
17
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
## for more details.
21
##
22
## You should have received a copy of the GNU General Public License along
23
## with eCos; if not, write to the Free Software Foundation, Inc.,
24
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
##
26
## As a special exception, if other files instantiate templates or use macros
27
## or inline functions from this file, or you compile this file and link it
28
## with other works to produce a work based on this file, this file does not
29
## by itself cause the resulting work to be covered by the GNU General Public
30
## License. However the source code for this file must still be made available
31
## in accordance with section (3) of the GNU General Public License.
32
##
33
## This exception does not invalidate any other reasons why a work based on
34
## this file might be covered by the GNU General Public License.
35
##
36
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
## at http://sources.redhat.com/ecos/ecos-license/
38
## -------------------------------------------
39
#####ECOSGPLCOPYRIGHTEND####
40
##=============================================================================
41
#######DESCRIPTIONBEGIN####
42
##
43
## Author(s):   nickg
44
## Contributors:        nickg, dmoseley
45
## Date:        1998-02-04
46
## Purpose:     MIPS exception vectors
47
## Description: This file defines the code placed into the exception
48
##              vectors. It also contains the first level default VSRs
49
##              that save and restore state for both exceptions and
50
##              interrupts.
51
##
52
######DESCRIPTIONEND####
53
##
54
##=============================================================================
55
 
56
#include 
57
#include 
58
 
59
#ifdef CYGPKG_KERNEL
60
# include 
61
#endif
62
 
63
#include 
64
#include 
65
 
66
#ifdef at
67
#undef at
68
#endif
69
        .extern cyg_instrument
70
 
71
##-----------------------------------------------------------------------------
72
## Hardware supplied vectors
73
 
74
        .set    noreorder
75
 
76
        .section ".reset_vector","ax"
77
 
78
        # Reset vector at 0xBFC00000
79
 
80
FUNC_START(reset_vector)
81
 
82
#ifndef CYG_HAL_STARTUP_RAM
83
#  if defined(CYGPKG_HAL_RESET_VECTOR_FIRST_CODE)
84
        hal_reset_vector_first_code
85
#  endif
86
#  if defined(CYGPKG_HAL_EARLY_INIT)
87
        hal_early_init
88
#  endif
89
        # Decide whether this is an NMI, cold or warm boot.
90
 
91
        mfc0    k0,status               # get status reg
92
        lui     k1,0x0008               # isolate NMI bit
93
        and     k1,k1,k0
94
        beqz    k1,1f                   # skip if zero
95
        nop
96
 
97
        lar     k1,__nmi_entry          # jump to ROM nmi code
98
        jalr    k1
99
        nop
100
1:
101
        lui     k1,0x0010               # isolate soft reset bit
102
        and     k1,k1,k0
103
        beqz    k1,2f                   # skip if zero
104
        nop
105
 
106
        lar     k1,__warm_start         # jump to ROM warm_start code
107
        jr      k1
108
        nop
109
2:
110
        la      k0,INITIAL_CONFIG0      # Set up config0 register
111
        mtc0    k0,config0              # to disable cache
112
#endif
113
        lar     v0,_start               # jump to start
114
#ifdef CYGARC_START_FUNC_UNCACHED
115
        CYGARC_ADDRESS_REG_UNCACHED(v0)
116
#endif
117
 
118
        jr      v0
119
        nop                             # (delay slot)
120
 
121
FUNC_END(reset_vector)
122
 
123
        .section ".debug_vector","ax"
124
 
125
        # Debug vector at 0xBFC00200
126
 
127
FUNC_START(debug_vector)
128
        la      k0,32*4
129
        la      k1,hal_vsr_table        # Get VSR table
130
        lw      k1,32*4(k1)             # load debug vector
131
        jr      k1                      # go there
132
        nop                             # (delay slot)
133
FUNC_END(debug_vector)
134
 
135
        .section ".other_vector","ax"
136
 
137
        # Common vector at 0x80000080 or 0xBFC00180
138
 
139
FUNC_START(other_vector)
140
        mfc0    k0,cause                # K0 = exception cause
141
        nop
142
        andi    k0,k0,0x7F              # isolate exception code
143
        la      k1,hal_vsr_table        # address of VSR table
144
        add     k1,k1,k0                # offset of VSR entry
145
        lw      k1,0(k1)                # k1 = pointer to VSR
146
        jr      k1                      # go there
147
        nop                             # (delay slot)
148
FUNC_END(other_vector)
149
 
150
        .section ".utlb_vector","ax"
151
 
152
FUNC_START(utlb_vector)
153
        mfc0    k0,cause                # K0 = exception cause
154
        nop
155
        andi    k0,k0,0x7F              # isolate exception code
156
        la      k1,hal_vsr_table        # address of VSR table
157
        add     k1,k1,k0                # offset of VSR entry
158
        lw      k1,0(k1)                # k1 = pointer to VSR
159
        jr      k1                      # go there
160
        nop                             # (delay slot)
161
FUNC_END(utlb_vector)
162
 
163
##-----------------------------------------------------------------------------
164
## Startup code
165
 
166
        .text
167
 
168
FUNC_START(_start)
169
 
170
        # Initialize hardware
171
        hal_cpu_init
172
        hal_diag_init
173
        hal_mmu_init
174
        hal_fpu_init
175
        hal_memc_init
176
        hal_intc_init
177
        hal_cache_init
178
        hal_timer_init
179
 
180
#ifdef CYGARC_START_FUNC_UNCACHED
181
        # switch to cached execution address if necessary
182
        # assumption is that hal_cache_init makes this safe
183
        lar     v0,1f
184
        jr      v0
185
        nop
186
   1:
187
#endif
188
 
189
        # Load Global Pointer register.
190
        la      gp,_gp
191
 
192
        # load initial stack pointer
193
        la      a0,__interrupt_stack
194
        move    sp,a0
195
 
196
        hal_mon_init
197
 
198
#ifdef CYG_HAL_STARTUP_ROM
199
        # Copy data from ROM to RAM
200
 
201
        .extern hal_copy_data
202
        jal     hal_copy_data
203
        nop
204
 
205
#endif
206
 
207
        # Zero BSS
208
 
209
        .extern hal_zero_bss
210
        jal     hal_zero_bss
211
        nop
212
 
213
        # Call variant and platform HAL
214
        # initialization routines.
215
 
216
        .extern hal_variant_init
217
        jal     hal_variant_init
218
        nop
219
 
220
        .extern hal_platform_init
221
        jal     hal_platform_init
222
        nop
223
 
224
        # Call constructors
225
        .extern cyg_hal_invoke_constructors
226
        jal     cyg_hal_invoke_constructors
227
        nop
228
 
229
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
230
        .extern initialize_stub
231
        jal     initialize_stub
232
        nop
233
#endif
234
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT)
235
        .extern hal_ctrlc_isr_init
236
        jal     hal_ctrlc_isr_init
237
        nop
238
#endif
239
 
240
        # Call cyg_start
241
 
242
        .extern cyg_start
243
        j       cyg_start
244
        lui     ra,0
245
 
246
FUNC_END(_start )
247
 
248
 
249
##-----------------------------------------------------------------------------
250
 
251
FUNC_START(__warm_start)
252
 
253
        ## The following is debug code left in here for now in case it
254
        ## proves useful in the near future.
255
#if 0
256
        move    s0,t0
257
        move    s1,a1
258
 
259
#       hal_diag_init
260
 
261
        hal_diag_writec '$'
262
        mvafc0  a0,$30                  # get ErrorEPC
263
        lar     k0,hal_diag_ai_write_hex8
264
        jalr    k0
265
        nop
266
        hal_diag_writec '-'
267
        move    a0,s0
268
        jalr    k0
269
        nop
270
        hal_diag_writec '-'
271
        move    a0,s1
272
        jalr    k0
273
        nop
274
1:
275
        b       1b
276
        nop
277
#endif
278
 
279
        # Treat a warm-start either as a cold-start or an NMI
280
#if defined(CYGHWR_HAL_MIPS_WARMSTART_COLDSTART)
281
        lar     v0,_start               # jump to start
282
        jr      v0
283
        nop                             # (delay slot)
284
#else
285
        # Defaults to NMI
286
        b       __nmi_entry
287
        nop
288
#endif
289
 
290
FUNC_END(__warm_start)
291
 
292
##-----------------------------------------------------------------------------
293
 
294
FUNC_START(__nmi_entry)
295
 
296
        # Clear exception state
297
        hal_cpu_except_enable
298
 
299
        # Move the ErrorEPC register to the EPC register so that the
300
        # default exception handler saves the right PC value.
301
        mvafc0  k0,$30
302
        nop; nop; nop;
303
        mvatc0  k0,epc
304
        nop; nop; nop;
305
 
306
#if (INITIAL_SR & 0x00400000) == 0
307
        # Taking this exception will have set the BEV bit to 1.
308
        # If we normally run with it zero, we must clear it here.
309
        mfc0    k0,status
310
        la      k1,0xFFBFFFFF
311
        and     k0,k0,k1
312
        mtc0    k0,status
313
#endif
314
 
315
        la      k0,34*4
316
        la      k1,hal_vsr_table        # Get VSR table
317
        lw      k1,34*4(k1)             # load NMI vector
318
        jr      k1                      # go there
319
        nop                             # (delay slot)
320
 
321
FUNC_END(__nmi_entry)
322
 
323
##-----------------------------------------------------------------------------
324
## Default exception VSR.
325
## Saves machine state and calls external handling code.
326
 
327
FUNC_START(__default_exception_vsr)
328
 
329
        # We enter here with all of the CPU state still
330
        # in its registers except:
331
        # K0 = vector index
332
        # K1 = address of this function
333
 
334
        move    k1,sp                   # K1 = original SP
335
 
336
        addi    sp,sp,-mips_exception_decrement
337
                                # space for registers + safety margin
338
 
339
        sw      k0,mipsreg_vector(sp)   # store vector
340
 
341
        # store GPRs
342
        .set    noat
343
        sgpr    0,sp
344
        sgpr    1,sp
345
        sgpr    2,sp
346
        sgpr    3,sp
347
        sgpr    4,sp
348
        sgpr    5,sp
349
        sgpr    6,sp
350
        sgpr    7,sp
351
        sgpr    8,sp
352
        sgpr    9,sp
353
        sgpr    10,sp
354
        sgpr    11,sp
355
        sgpr    12,sp
356
        sgpr    13,sp
357
        sgpr    14,sp
358
        sgpr    15,sp
359
        sgpr    16,sp
360
        sgpr    17,sp
361
        sgpr    18,sp
362
        sgpr    19,sp
363
        sgpr    20,sp
364
        sgpr    21,sp
365
        sgpr    22,sp
366
        sgpr    23,sp
367
        sgpr    24,sp
368
        sgpr    25,sp
369
#       sgpr    26,sp   # == K0
370
#       sgpr    27,sp   # == K1
371
        sgpr    28,sp   # == GP
372
#       sgpr    29,sp   # == SP
373
        sgpr    30,sp   # == FP
374
        sgpr    31,sp   # == RA
375
        .set    at
376
 
377
        mfhi    a0
378
        mflo    a1
379
        shi     a0,sp
380
        slo     a1,sp
381
 
382
        # K1 contains original SP
383
        ssp     k1,sp                   # store in reg dump
384
 
385
        # save remaining machine state registers
386
        mfc0    t0,cause
387
        mfc0    t1,status
388
        mfc0    t2,cachectrl
389
        mvafc0  t3,badvr
390
        mfc0    t4,config
391
        mfc0    t5,prid
392
        mvafc0  t6,epc
393
 
394
        sw      t0,mipsreg_cause(sp)
395
        sw      t1,mipsreg_sr(sp)
396
        sw      t2,mipsreg_cachectrl(sp)
397
        sva     t3,mipsreg_badvr(sp)
398
        sw      t4,mipsreg_config(sp)
399
        sw      t5,mipsreg_prid(sp)
400
        sva     t6,mipsreg_pc(sp)
401
 
402
        hal_fpu_save sp
403
 
404
        # The machine state is now all saved on the stack.
405
 
406
        hal_diag_excpt_start
407
 
408
        # Load Global Pointer register.
409
        la      gp,_gp
410
 
411
        move    s0,sp                           # save pointer to saved state
412
 
413
#if defined(CYGSEM_HAL_ROM_MONITOR) && \
414
    defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
415
 
416
        la      a0,__interrupt_stack            # a0 = stack top
417
        la      a1,__interrupt_stack_base       # a1 = stack base
418
        sub     a3,sp,a1                        # a3 = sp - base
419
        bltz    a3,1f                           # not on istack if < 0
420
        nop                                     # delay slot
421
        sub     t0,a0,sp                        # t0 = top - sp
422
        bgtz    t0,8f                           # already on istack if > 0
423
        nop                                     # delay slot
424
1:
425
        move    sp,a0                           # switch to istack
426
8:
427
        addi    sp,sp,-8                        # space for old SP
428
                                                # (8 to keep dword alignment!)
429
        sw      s0,0(sp)                        # save old SP on stack
430
 
431
#endif
432
        addi    sp,sp,-mips_stack_frame_size    # make a null frame
433
 
434
        # Need to set up back pointers etc. ???
435
 
436
        hal_cpu_except_enable                   # reenable exceptions
437
 
438
        .extern cyg_hal_exception_handler
439
        jal     cyg_hal_exception_handler       # call C code
440
        move    a0,s0                           # arg0 = register dump (delay slot)
441
 
442
#if defined(CYGSEM_HAL_ROM_MONITOR) && \
443
    defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
444
 
445
        # If we are returning from the last nested exception, move back
446
        # to the thread stack.
447
        # Since we have arranged for the top of stack location to
448
        # contain the sp we need to go back to here, just pop it off
449
        # and put it in SP.
450
 
451
        lw      sp,mips_stack_frame_size(sp)    # sp = *sp
452
        subu    sp,sp,mips_stack_frame_size     # make a null frame
453
#endif
454
 
455
        j       restore_state
456
        nop
457
 
458
FUNC_END(__default_exception_vsr)
459
 
460
##------------------------------------------------------------------------------
461
## Default interrupt VSR.
462
## Saves machine state and calls appropriate ISR. When done, calls
463
## interrupt_end() to finish up and possibly reschedule.
464
 
465
FUNC_START(__default_interrupt_vsr)
466
 
467
 
468
        # We enter here with all of the CPU state still
469
        # in its registers except:
470
        # K0 = vector index
471
        # K1 = address of this function
472
 
473
        move    k1,sp                   # K1 = original SP
474
 
475
        addi    sp,sp,-mips_exception_decrement
476
                                # space for registers + safety margin
477
 
478
        sw      k0,mipsreg_vector(sp)   # store vector
479
 
480
        # store GPRs
481
        .set    noat
482
        sgpr    0,sp
483
        sgpr    1,sp
484
        sgpr    2,sp
485
        sgpr    3,sp
486
        sgpr    4,sp
487
        sgpr    5,sp
488
        sgpr    6,sp
489
        sgpr    7,sp
490
        sgpr    8,sp
491
        sgpr    9,sp
492
        sgpr    10,sp
493
        sgpr    11,sp
494
        sgpr    12,sp
495
        sgpr    13,sp
496
        sgpr    14,sp
497
        sgpr    15,sp
498
        sgpr    16,sp
499
        sgpr    17,sp
500
        sgpr    18,sp
501
        sgpr    19,sp
502
        sgpr    20,sp
503
        sgpr    21,sp
504
        sgpr    22,sp
505
        sgpr    23,sp
506
        sgpr    24,sp
507
        sgpr    25,sp
508
#       sgpr    26,sp   # == K0
509
#       sgpr    27,sp   # == K1
510
        sgpr    28,sp   # == GP
511
#       sgpr    29,sp   # == SP
512
        sgpr    30,sp   # == FP
513
        sgpr    31,sp   # == RA
514
        .set    at
515
 
516
        mfhi    a0
517
        mflo    a1
518
        shi     a0,sp
519
        slo     a1,sp
520
 
521
        # K1 contains original SP
522
        ssp     k1,sp                   # store in reg dump
523
 
524
        mfc0    t1,status
525
        mfc0    t2,cachectrl
526
        mvafc0  t3,epc
527
 
528
        sw      t1,mipsreg_sr(sp)
529
        sw      t2,mipsreg_cachectrl(sp)
530
        sva     t3,mipsreg_pc(sp)
531
 
532
        hal_fpu_save sp
533
 
534
        # The machine state is now all saved on the stack.
535
 
536
        # Load Global Pointer register.
537
        la      gp,_gp
538
 
539
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
540
        .extern cyg_scheduler_sched_lock
541
        la      v0,cyg_scheduler_sched_lock
542
        lw      a0,0(v0)
543
        addi    a0,a0,1
544
        sw      a0,0(v0)
545
#endif
546
 
547
        move    s0,sp                           # save pointer to saved state
548
 
549
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
550
 
551
        la      a0,__interrupt_stack            # a0 = stack top
552
        la      a1,__interrupt_stack_base       # a1 = stack base
553
        sub     a3,sp,a1                        # a3 = sp - base
554
        bltz    a3,1f                           # not on istack if < 0
555
        nop                                     # delay slot
556
        sub     t0,a0,sp                        # t0 = top - sp
557
        bgtz    t0,8f                           # already on istack if > 0
558
        nop                                     # delay slot
559
1:
560
        move    sp,a0                           # switch to istack
561
8:
562
        addi    sp,sp,-8                        # space for old SP
563
                                                # (8 to keep dword alignment!)
564
        sw      s0,0(sp)                        # save old SP on stack
565
 
566
#endif
567
 
568
        subu    sp,sp,mips_stack_frame_size     # make a null frame
569
 
570
        # Need to set up back pointers etc. ???
571
 
572
        # Decode external interrupt via interrupt controller
573
 
574
        hal_intc_decode s2
575
 
576
        # Here, s2 contains the number of the interrupt being serviced,
577
        # we need to derive from that the vector number to call in the ISR
578
        # table.
579
 
580
        hal_intc_translate s2,s1
581
 
582
        # Here s1 is the number of the vector to be called and s2 is
583
        # the number of the interrupt being serviced.
584
 
585
        hal_diag_intr_start
586
 
587
#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
588
 
589
        # Call cyg_instrument to record that this interrupt is being raised.
590
 
591
        li      a0,0x0301                       # a0 = type = INTR,RAISE
592
        move    a1,s1                           # a1 = vector number
593
        jal     cyg_instrument                  # call instrument function
594
         move   a2,s2                           # a2 = interrupt number
595
#endif
596
 
597
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT)
598
        # If we are supporting Ctrl-C interrupts from GDB, we must squirrel
599
        # away a pointer to the save interrupt state here so that we can
600
        # plant a breakpoint at some later time.
601
 
602
        .extern hal_saved_interrupt_state
603
        la      v0,hal_saved_interrupt_state
604
        sw      s0,0(v0)
605
 
606
#endif
607
 
608
        sll     s1,s1,2                         # s1 = byte offset of vector
609
 
610
        hal_cpu_except_enable                   # reenable exceptions
611
 
612
        la      t2,hal_interrupt_handlers       # handler table
613
        add     t2,t2,s1                        # address of ISR ptr
614
        lw      t2,0(t2)                        # ISR pointer
615
 
616
        la      a1,hal_interrupt_data           # data table
617
        add     a1,a1,s1                        # address of data ptr
618
        lw      a1,0(a1)                        # Data pointer
619
 
620
        move    a0,s2                           # pass interrupt number
621
 
622
        jalr    t2                              # call ISR via t2
623
        nop                                     # (delay slot)
624
 
625
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
626
 
627
        # If we are returning from the last nested interrupt, move back
628
        # to the thread stack. interrupt_end() must be called on the
629
        # thread stack since it potentially causes a context switch.
630
        # Since we have arranged for the top of stack location to
631
        # contain the sp we need to go back to here, just pop it off
632
        # and put it in SP.
633
 
634
 
635
        lw      sp,mips_stack_frame_size(sp)    # sp = *sp
636
        subu    sp,sp,mips_stack_frame_size     # make a null frame
637
#endif
638
 
639
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
640
 
641
        # We only need to call _interrupt_end() when there is a kernel
642
        # present to do any tidying up.
643
 
644
        # On return v0 bit 1 will indicate whether a DSR is
645
        # to be posted. Pass this together with a pointer to
646
        # the interrupt object we have just used to the
647
        # interrupt tidy up routine.
648
 
649
        # Note that s0, s1 and s2 are defined to be preserved across
650
        # calls by the calling convention, so they still contain
651
        # the register dump, the vector offset and the interrupt number
652
        # respectively.
653
 
654
        move    s2,v0
655
 
656
        la      a1,hal_interrupt_objects        # interrupt object table
657
        add     a1,a1,s1                        # address of object ptr
658
        lw      a1,0(a1)                        # a1 = object ptr
659
 
660
        move    a2,s0                           # arg3 = saved register dump
661
 
662
        .extern interrupt_end
663
        jal     interrupt_end                   # call into C to finish off
664
         move   a0,v0                           # put ISR result in arg0
665
 
666
        move    v0,s2                           # return value from isr
667
#endif
668
 
669
restore_state:
670
#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)
671
        move    k0,v0
672
#endif
673
 
674
        # All done, restore CPU state and continue
675
 
676
        addi    sp,sp,mips_stack_frame_size     # retrieve CPU state ptr
677
 
678
        # Disable interrupts again while we restore state.
679
        hal_cpu_int_disable
680
 
681
        hal_diag_restore
682
 
683
        hal_fpu_load sp
684
 
685
        lw      t0,mipsreg_cachectrl(sp)
686
        lhi     t1,sp
687
        llo     t2,sp
688
 
689
        mtc0    t0,cachectrl
690
        mthi    t1
691
        mtlo    t2
692
 
693
        # load GPRs
694
        .set    noat
695
#       lgpr    0,sp
696
        lgpr    1,sp
697
        lgpr    2,sp
698
        lgpr    3,sp
699
        lgpr    4,sp
700
        lgpr    5,sp
701
        lgpr    6,sp
702
        lgpr    7,sp
703
        lgpr    8,sp
704
        lgpr    9,sp
705
        lgpr    10,sp
706
        lgpr    11,sp
707
        lgpr    12,sp
708
        lgpr    13,sp
709
        lgpr    14,sp
710
        lgpr    15,sp
711
        lgpr    16,sp
712
        lgpr    17,sp
713
        lgpr    18,sp
714
        lgpr    19,sp
715
        lgpr    20,sp
716
        lgpr    21,sp
717
        lgpr    22,sp
718
        lgpr    23,sp
719
        lgpr    24,sp
720
        lgpr    25,sp
721
#       lgpr    26,sp   # == K0
722
#       lgpr    27,sp   # == K1
723
        lgpr    28,sp   # == GP
724
#       lgpr    29,sp   # == SP
725
        lgpr    30,sp   # == FP
726
        lgpr    31,sp   # == RA
727
        .set    at
728
 
729
#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)
730
 
731
        # If we have a Cygmon that wants to listen to network interrupts, then
732
        # the return code from the earlier call to hal_default_isr() will
733
        # have been negative to indicate this. So we jump into Cygmon here
734
        # because Cygmon requires the processor state to be the same as when
735
        # the interrupt was taken, but with k0 as the exception number.
736
 
737
        bgez    k0,1f
738
        nop
739
        # Check for new cygmon
740
        sw      k0,(mipsreg_regs+26*4)(sp)      # save k0
741
        la      k1,0x80000100 + 41*4            # New cygmon "magic" id
742
        lw      k1,0(k1)
743
        lui     k0,0x55aa
744
        ori     k0,0x4321
745
        bne     k0,k1,1f
746
 
747
        # Need to let cygmon handle this
748
        la      k1,0x80000100 + 39*4            # stub entry vector
749
        lw      k0,(mipsreg_regs+26*4)(sp)      # restore k0
750
        lw      k1,0(k1)
751
        lw      sp,(mipsreg_regs+29*4)(sp)      # restore SP
752
        sll     k0,1                            # clear bit 31.
753
        jr      k1
754
        srl     k0,1
755
    1:
756
#endif
757
 
758
        lw      k1,mipsreg_sr(sp)               # K1 = saved SR
759
 
760
#if 0 < CYGINT_HAL_MIPS_INTERRUPT_RETURN_KEEP_SR_IM
761
        # Keep the current settings of the IM[7:0] bits within the status
762
        # register.  These may be used as interrupt masks, so if an ISR or
763
        # DSR masks interrupts they must be preserved.
764
        # If they are not used, then this does no harm.
765
        ori     k0,zero,0xff00
766
        nor     k0,k0,k0                        # 0xffff00ff
767
        and     k1,k1,k0                        # all interrupts disabled
768
 
769
        mfc0    k0,status                       # V0 = current SR
770
        nop
771
        nop
772
        andi    k0,k0,0xff00                    # preserve interrupt set
773
        or      k1,k1,k0                        # insert into "saved SR"
774
#endif // 0 < CYGINT_HAL_MIPS_INTERRUPT_RETURN_KEEP_SR_IM
775
        lva     k0,mipsreg_pc(sp)               # K0 = return PC
776
        lsp     sp,sp                           # load SP
777
 
778
        # Invoke CPU specific mechanism for returning from this
779
        # exception
780
 
781
        hal_cpu_eret k0,k1
782
 
783
FUNC_END(__default_interrupt_vsr)
784
 
785
        hal_intc_decode_data
786
 
787
##-----------------------------------------------------------------------------
788
## Execute pending DSRs on the interrupt stack with interrupts enabled.
789
## Note: this can only be called from code running on a thread stack
790
 
791
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
792
        .extern cyg_interrupt_call_pending_DSRs
793
 
794
FUNC_START(hal_interrupt_stack_call_pending_DSRs)
795
        mfc0    t0,status                       # get status register value
796
        la      v0,__interrupt_stack            # v0 = interrupt stack
797
        move    v1,sp                           # v1 = original stack ptr
798
        move    sp,v0                           # sp = interrupt stack
799
        addi    sp,sp,-32                       # make a null frame
800
        sw      v1,16(sp)                       # save old sp
801
        sw      ra,20(sp)                       # save old ra
802
        sw      t0,24(sp)                       # save old sr
803
 
804
        hal_cpu_int_enable
805
 
806
        jal     cyg_interrupt_call_pending_DSRs # call back to kernel
807
        nop
808
 
809
        lw      a0,24(sp)                       # get status reg
810
 
811
        hal_cpu_int_merge a0                    # merge with current SR
812
 
813
        lw      ra,20(sp)                       # restore ra
814
        lw      sp,16(sp)                       # restore sp
815
 
816
        jr      ra                              # go back
817
        nop                                     # delay slot
818
 
819
FUNC_END(hal_interrupt_stack_call_pending_DSRs)
820
#endif
821
 
822
##-----------------------------------------------------------------------------
823
## Short circuit in case any code tries to use "__gccmain()"
824
 
825
FUNC_START(__gccmain)
826
        jr      ra
827
        nop
828
FUNC_END(__gccmain)
829
 
830
##-----------------------------------------------------------------------------
831
## Switch to a new stack.
832
## This is used in RedBoot to allow code to execute in a different
833
## stack context.
834
 
835
FUNC_START(hal_program_new_stack)
836
        # Arguments are:
837
        # a0 = function to call
838
        # a1 = stack pointer to use
839
 
840
        move    v1,sp                           # v1 = original stack ptr
841
        move    sp,a1                           # sp = new stack
842
        addi    sp,sp,-32                       # make a null frame
843
        sva     v1,8(sp)                        # save old sp
844
        sva     ra,16(sp)                       # save old ra
845
 
846
        jalr    a0                              # call function
847
         nop
848
 
849
        lva     ra,16(sp)                       # restore ra
850
        lva     sp,8(sp)                        # restore sp
851
 
852
        jr      ra                              # go back
853
         nop                                    # delay slot
854
 
855
FUNC_END(hal_program_new_stack)
856
 
857
##-----------------------------------------------------------------------------
858
## hal_zero_bss
859
## Zero bss. Done in assembler to be optimal rather than using memset,
860
## which would risk zeroing bss while using it.
861
 
862
FUNC_START(hal_zero_bss)
863
#ifdef CYGHWR_HAL_MIPS_64BIT
864
#define STORE_OP        sd
865
#define BLOCK_SHIFT     6
866
#else
867
#define STORE_OP        sw
868
#define BLOCK_SHIFT     5
869
#endif
870
        la      a0,__bss_start          # start of bss
871
        la      a1,__bss_end            # end of bss
872
        andi    a2,a0,mips_regsize-1    # is bss aligned?
873
        bne     a2,zero,1f              # skip word copy
874
        nop
875
 
876
        # loop with 8 stores per loop
877
        subu            a3,a1,a0                # get length
878
        srl             a3,a3,BLOCK_SHIFT       # get number of blocks
879
        sll             a3,a3,BLOCK_SHIFT       # get length of blocks
880
        addu            a3,a0,a3                # get end addr of blocks
881
2:      STORE_OP        zero,(mips_regsize*0)(a0)
882
        STORE_OP        zero,(mips_regsize*1)(a0)
883
        STORE_OP        zero,(mips_regsize*2)(a0)
884
        STORE_OP        zero,(mips_regsize*3)(a0)
885
        STORE_OP        zero,(mips_regsize*4)(a0)
886
        STORE_OP        zero,(mips_regsize*5)(a0)
887
        STORE_OP        zero,(mips_regsize*6)(a0)
888
        STORE_OP        zero,(mips_regsize*7)(a0)
889
        addu            a0,a0,mips_regsize*8    # next addr
890
        bne             a3,a0,2b                # to next store
891
        nop
892
 
893
        # If length is a multiple of block size then we
894
        # are done and need to skip the byte loop
895
        beq             a1,a0,3f
896
        nop
897
 
898
        # finish 1 byte at a time
899
1:      sb      zero,0(a0)              # zero memory
900
        addiu   a0,a0,1                 # next addr
901
        bne     a0,a1,1b                # to next store
902
        nop
903
3:      jr      ra
904
        nop
905
FUNC_END(hal_zero_bss)
906
 
907
 
908
##-----------------------------------------------------------------------------
909
## VSR springboard for break instruction exceptions
910
## Both GCC and GDB use break instructions. GCC for division-by-zero
911
## notification and GDB for program-flow breakpoints. This springboard
912
## looks for the d-b-z kind and directs them to another vector so libc
913
## can handle these without affecting the debugger.
914
 
915
FUNC_START(__break_vsr_springboard)
916
        mvafc0  k0,epc
917
        mfc0    k1,cause
918
        bltzl   k1,1f
919
        addi    k0,k0,4                 # delay slot (only executed if BD set)
920
1:      lw      k1,0(k0)                # get break instruction
921
        la      k0,0x0007000d           # break 0x7 used by GCC for d-b-z
922
        bne     k0,k1,2f
923
        nop
924
        ori     k0,$0,14*4              # CYGNUM_HAL_VECTOR_DIV_BY_ZERO
925
        la      k1,hal_vsr_table        # address of VSR table
926
        add     k1,k1,k0                # offset of VSR entry
927
        lw      k1,0(k1)                # k1 = pointer to VSR
928
        jr      k1                      # go there
929
        nop                             # (delay slot)
930
2:      ori     k0,$0,9*4               # CYGNUM_HAL_VECTOR_BREAKPOINT
931
        j       __default_exception_vsr
932
        nop                             # (delay slot)
933
FUNC_END(__break_vsr_springboard)
934
 
935
 
936
##-----------------------------------------------------------------------------
937
## Interrupt Stack.
938
## Used during intialization and for executing ISRs.
939
 
940
        .bss
941
 
942
        .balign 16
943
        .global cyg_interrupt_stack_base
944
cyg_interrupt_stack_base:
945
__interrupt_stack_base:
946
        .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
947
        .byte 0
948
        .endr
949
        .balign 16
950
        .global cyg_interrupt_stack
951
cyg_interrupt_stack:
952
__interrupt_stack:
953
 
954
        .long   0,0,0,0,0,0,0,0
955
 
956
##-----------------------------------------------------------------------------
957
## VSR table.
958
## The main interrupt code indirects through here to find the VSR
959
## to execute for each architecture defined interrupt.
960
## This is only used for simulated targets, on real targets a fixed location VSR
961
## table is now allocated at 0x80000100.
962
 
963
#ifndef CYG_HAL_MIPS_VSR_TABLE_DEFINED
964
 
965
##      .section ".vsr_table","a"
966
 
967
        .data
968
 
969
        .globl  hal_vsr_table
970
 
971
hal_vsr_table:
972
        .long   __default_interrupt_vsr
973
        .rept   63
974
        .long   __default_exception_vsr
975
        .endr
976
 
977
#endif
978
 
979
#------------------------------------------------------------------------------
980
# Interrupt vector tables.
981
# These tables contain the isr, data and object pointers used to deliver
982
# interrupts to user code.
983
# hal_interrupt_level contains the interrupt level set by
984
# HAL_INTERRUPT_CONFIGURE().
985
# This is a default set that provide support only for the 6 external
986
# interrupts in the status/cause registers. Platforms or boards are expected
987
# to define their own versions of these if they have their own interrupt mappings.
988
 
989
#ifndef CYG_HAL_MIPS_ISR_TABLES_DEFINED
990
 
991
        .extern hal_default_isr
992
 
993
        .data
994
 
995
        .globl  hal_interrupt_handlers
996
hal_interrupt_handlers:
997
        .long   hal_default_isr
998
        .long   hal_default_isr
999
        .long   hal_default_isr
1000
        .long   hal_default_isr
1001
        .long   hal_default_isr
1002
        .long   hal_default_isr
1003
 
1004
 
1005
        .globl  hal_interrupt_data
1006
hal_interrupt_data:
1007
        .rept   6
1008
        .long   0
1009
        .endr
1010
 
1011
        .globl  hal_interrupt_objects
1012
hal_interrupt_objects:
1013
        .rept   6
1014
        .long   0
1015
        .endr
1016
 
1017
#endif
1018
 
1019
##-----------------------------------------------------------------------------
1020
## end of vectors.S
1021
 
1022
 

powered by: WebSVN 2.1.0

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