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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [mips/] [arch/] [current/] [src/] [vectors.S] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
##=============================================================================
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 Free Software Foundation, 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
16
## version.
17
##
18
## eCos is distributed in the hope that it will be useful, but WITHOUT
19
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
## for more details.
22
##
23
## You should have received a copy of the GNU General Public License
24
## along with eCos; if not, write to the Free Software Foundation, Inc.,
25
## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
##
27
## As a special exception, if other files instantiate templates or use
28
## macros or inline functions from this file, or you compile this file
29
## and link it with other works to produce a work based on this file,
30
## this file does not by itself cause the resulting work to be covered by
31
## the GNU General Public License. However the source code for this file
32
## must still be made available in accordance with section (3) of the GNU
33
## General Public License v2.
34
##
35
## This exception does not invalidate any other reasons why a work based
36
## on this file might be covered by the GNU General Public License.
37
## -------------------------------------------
38
## ####ECOSGPLCOPYRIGHTEND####
39
##=============================================================================
40
#######DESCRIPTIONBEGIN####
41
##
42
## Author(s):   nickg
43
## Contributors:        nickg, dmoseley
44
## Date:        1998-02-04
45
## Purpose:     MIPS exception vectors
46
## Description: This file defines the code placed into the exception
47
##              vectors. It also contains the first level default VSRs
48
##              that save and restore state for both exceptions and
49
##              interrupts.
50
##
51
######DESCRIPTIONEND####
52
##
53
##=============================================================================
54
 
55
#include 
56
#include 
57
 
58
#ifdef CYGPKG_KERNEL
59
# include 
60
#endif
61
 
62
#include 
63
#include 
64
 
65
#ifdef at
66
#undef at
67
#endif
68
        .extern cyg_instrument
69
 
70
##-----------------------------------------------------------------------------
71
## Hardware supplied vectors
72
 
73
        .set    noreorder
74
 
75
        .section ".reset_vector","ax"
76
 
77
        # Reset vector at 0xBFC00000
78
 
79
FUNC_START(reset_vector)
80
 
81
#ifndef CYG_HAL_STARTUP_RAM
82
#  if defined(CYGPKG_HAL_RESET_VECTOR_FIRST_CODE)
83
        hal_reset_vector_first_code
84
#  endif
85
#  if defined(CYGPKG_HAL_EARLY_INIT)
86
        hal_early_init
87
#  endif
88
        # Decide whether this is an NMI, cold or warm boot.
89
 
90
        mfc0    k0,status               # get status reg
91
        lui     k1,0x0008               # isolate NMI bit
92
        and     k1,k1,k0
93
        beqz    k1,1f                   # skip if zero
94
        nop
95
 
96
        lar     k1,__nmi_entry          # jump to ROM nmi code
97
        jalr    k1
98
        nop
99
1:
100
        lui     k1,0x0010               # isolate soft reset bit
101
        and     k1,k1,k0
102
        beqz    k1,2f                   # skip if zero
103
        nop
104
 
105
        lar     k1,__warm_start         # jump to ROM warm_start code
106
        jr      k1
107
        nop
108
2:
109
        la      k0,INITIAL_CONFIG0      # Set up config0 register
110
        mtc0    k0,config0              # to disable cache
111
#endif
112
        lar     v0,_start               # jump to start
113
#ifdef CYGARC_START_FUNC_UNCACHED
114
        CYGARC_ADDRESS_REG_UNCACHED(v0)
115
#endif
116
 
117
        jr      v0
118
        nop                             # (delay slot)
119
 
120
FUNC_END(reset_vector)
121
 
122
        .section ".debug_vector","ax"
123
 
124
        # Debug vector at 0xBFC00200
125
 
126
FUNC_START(debug_vector)
127
        la      k0,32*4
128
        la      k1,hal_vsr_table        # Get VSR table
129
        lw      k1,32*4(k1)             # load debug vector
130
        jr      k1                      # go there
131
        nop                             # (delay slot)
132
FUNC_END(debug_vector)
133
 
134
        .section ".other_vector","ax"
135
 
136
        # Common vector at 0x80000080 or 0xBFC00180
137
 
138
FUNC_START(other_vector)
139
        mfc0    k0,cause                # K0 = exception cause
140
        nop
141
        andi    k0,k0,0x7F              # isolate exception code
142
        la      k1,hal_vsr_table        # address of VSR table
143
        add     k1,k1,k0                # offset of VSR entry
144
        lw      k1,0(k1)                # k1 = pointer to VSR
145
        jr      k1                      # go there
146
        nop                             # (delay slot)
147
FUNC_END(other_vector)
148
 
149
        .section ".utlb_vector","ax"
150
 
151
FUNC_START(utlb_vector)
152
        mfc0    k0,cause                # K0 = exception cause
153
        nop
154
        andi    k0,k0,0x7F              # isolate exception code
155
        la      k1,hal_vsr_table        # address of VSR table
156
        add     k1,k1,k0                # offset of VSR entry
157
        lw      k1,0(k1)                # k1 = pointer to VSR
158
        jr      k1                      # go there
159
        nop                             # (delay slot)
160
FUNC_END(utlb_vector)
161
 
162
##-----------------------------------------------------------------------------
163
## Startup code
164
 
165
        .text
166
 
167
FUNC_START(_start)
168
 
169
        # Initialize hardware
170
        hal_cpu_init
171
        hal_diag_init
172
        hal_mmu_init
173
        hal_fpu_init
174
        hal_memc_init
175
        hal_intc_init
176
        hal_cache_init
177
        hal_timer_init
178
 
179
#ifdef CYGARC_START_FUNC_UNCACHED
180
        # switch to cached execution address if necessary
181
        # assumption is that hal_cache_init makes this safe
182
        lar     v0,1f
183
        jr      v0
184
        nop
185
   1:
186
#endif
187
 
188
        # Load Global Pointer register.
189
        la      gp,_gp
190
 
191
        # load initial stack pointer
192
        la      a0,__interrupt_stack
193
        move    sp,a0
194
 
195
        hal_mon_init
196
 
197
#ifdef CYG_HAL_STARTUP_ROM
198
        # Copy data from ROM to RAM
199
 
200
        .extern hal_copy_data
201
        jal     hal_copy_data
202
        nop
203
 
204
#endif
205
 
206
        # Zero BSS
207
 
208
        .extern hal_zero_bss
209
        jal     hal_zero_bss
210
        nop
211
 
212
        # Call variant and platform HAL
213
        # initialization routines.
214
 
215
        .extern hal_variant_init
216
        jal     hal_variant_init
217
        nop
218
 
219
        .extern hal_platform_init
220
        jal     hal_platform_init
221
        nop
222
 
223
        # Call constructors
224
        .extern cyg_hal_invoke_constructors
225
        jal     cyg_hal_invoke_constructors
226
        nop
227
 
228
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
229
        .extern initialize_stub
230
        jal     initialize_stub
231
        nop
232
#endif
233
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT)
234
        .extern hal_ctrlc_isr_init
235
        jal     hal_ctrlc_isr_init
236
        nop
237
#endif
238
 
239
        # Call cyg_start
240
 
241
        .extern cyg_start
242
        j       cyg_start
243
        lui     ra,0
244
 
245
FUNC_END(_start )
246
 
247
 
248
##-----------------------------------------------------------------------------
249
 
250
FUNC_START(__warm_start)
251
 
252
        ## The following is debug code left in here for now in case it
253
        ## proves useful in the near future.
254
#if 0
255
        move    s0,t0
256
        move    s1,a1
257
 
258
#       hal_diag_init
259
 
260
        hal_diag_writec '$'
261
        mvafc0  a0,$30                  # get ErrorEPC
262
        lar     k0,hal_diag_ai_write_hex8
263
        jalr    k0
264
        nop
265
        hal_diag_writec '-'
266
        move    a0,s0
267
        jalr    k0
268
        nop
269
        hal_diag_writec '-'
270
        move    a0,s1
271
        jalr    k0
272
        nop
273
1:
274
        b       1b
275
        nop
276
#endif
277
 
278
        # Treat a warm-start either as a cold-start or an NMI
279
#if defined(CYGHWR_HAL_MIPS_WARMSTART_COLDSTART)
280
        lar     v0,_start               # jump to start
281
        jr      v0
282
        nop                             # (delay slot)
283
#else
284
        # Defaults to NMI
285
        b       __nmi_entry
286
        nop
287
#endif
288
 
289
FUNC_END(__warm_start)
290
 
291
##-----------------------------------------------------------------------------
292
 
293
FUNC_START(__nmi_entry)
294
 
295
        # Clear exception state
296
        hal_cpu_except_enable
297
 
298
        # Move the ErrorEPC register to the EPC register so that the
299
        # default exception handler saves the right PC value.
300
        mvafc0  k0,$30
301
        nop; nop; nop;
302
        mvatc0  k0,epc
303
        nop; nop; nop;
304
 
305
#if (INITIAL_SR & 0x00400000) == 0
306
        # Taking this exception will have set the BEV bit to 1.
307
        # If we normally run with it zero, we must clear it here.
308
        mfc0    k0,status
309
        la      k1,0xFFBFFFFF
310
        and     k0,k0,k1
311
        mtc0    k0,status
312
#endif
313
 
314
        la      k0,34*4
315
        la      k1,hal_vsr_table        # Get VSR table
316
        lw      k1,34*4(k1)             # load NMI vector
317
        jr      k1                      # go there
318
        nop                             # (delay slot)
319
 
320
FUNC_END(__nmi_entry)
321
 
322
##-----------------------------------------------------------------------------
323
## Default exception VSR.
324
## Saves machine state and calls external handling code.
325
 
326
FUNC_START(__default_exception_vsr)
327
 
328
        # We enter here with all of the CPU state still
329
        # in its registers except:
330
        # K0 = vector index
331
        # K1 = address of this function
332
 
333
        move    k1,sp                   # K1 = original SP
334
 
335
        addi    sp,sp,-mips_exception_decrement
336
                                # space for registers + safety margin
337
 
338
        sw      k0,mipsreg_vector(sp)   # store vector
339
 
340
        # store GPRs
341
        .set    noat
342
        sgpr    0,sp
343
        sgpr    1,sp
344
        sgpr    2,sp
345
        sgpr    3,sp
346
        sgpr    4,sp
347
        sgpr    5,sp
348
        sgpr    6,sp
349
        sgpr    7,sp
350
        sgpr    8,sp
351
        sgpr    9,sp
352
        sgpr    10,sp
353
        sgpr    11,sp
354
        sgpr    12,sp
355
        sgpr    13,sp
356
        sgpr    14,sp
357
        sgpr    15,sp
358
        sgpr    16,sp
359
        sgpr    17,sp
360
        sgpr    18,sp
361
        sgpr    19,sp
362
        sgpr    20,sp
363
        sgpr    21,sp
364
        sgpr    22,sp
365
        sgpr    23,sp
366
        sgpr    24,sp
367
        sgpr    25,sp
368
#       sgpr    26,sp   # == K0
369
#       sgpr    27,sp   # == K1
370
        sgpr    28,sp   # == GP
371
#       sgpr    29,sp   # == SP
372
        sgpr    30,sp   # == FP
373
        sgpr    31,sp   # == RA
374
        .set    at
375
 
376
        mfhi    a0
377
        mflo    a1
378
        shi     a0,sp
379
        slo     a1,sp
380
 
381
        # K1 contains original SP
382
        ssp     k1,sp                   # store in reg dump
383
 
384
        # save remaining machine state registers
385
        mfc0    t0,cause
386
        mfc0    t1,status
387
        mfc0    t2,cachectrl
388
        mvafc0  t3,badvr
389
        mfc0    t4,config
390
        mfc0    t5,prid
391
        mvafc0  t6,epc
392
 
393
        sw      t0,mipsreg_cause(sp)
394
        sw      t1,mipsreg_sr(sp)
395
        sw      t2,mipsreg_cachectrl(sp)
396
        sva     t3,mipsreg_badvr(sp)
397
        sw      t4,mipsreg_config(sp)
398
        sw      t5,mipsreg_prid(sp)
399
        sva     t6,mipsreg_pc(sp)
400
 
401
        hal_fpu_save sp
402
 
403
        # The machine state is now all saved on the stack.
404
 
405
        hal_diag_excpt_start
406
 
407
        # Load Global Pointer register.
408
        la      gp,_gp
409
 
410
        move    s0,sp                           # save pointer to saved state
411
 
412
#if defined(CYGSEM_HAL_ROM_MONITOR) && \
413
    defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
414
 
415
        la      a0,__interrupt_stack            # a0 = stack top
416
        la      a1,__interrupt_stack_base       # a1 = stack base
417
        sub     a3,sp,a1                        # a3 = sp - base
418
        bltz    a3,1f                           # not on istack if < 0
419
        nop                                     # delay slot
420
        sub     t0,a0,sp                        # t0 = top - sp
421
        bgtz    t0,8f                           # already on istack if > 0
422
        nop                                     # delay slot
423
1:
424
        move    sp,a0                           # switch to istack
425
8:
426
        addi    sp,sp,-8                        # space for old SP
427
                                                # (8 to keep dword alignment!)
428
        sw      s0,0(sp)                        # save old SP on stack
429
 
430
#endif
431
        addi    sp,sp,-mips_stack_frame_size    # make a null frame
432
 
433
        # Need to set up back pointers etc. ???
434
 
435
        hal_cpu_except_enable                   # reenable exceptions
436
 
437
        .extern cyg_hal_exception_handler
438
        jal     cyg_hal_exception_handler       # call C code
439
        move    a0,s0                           # arg0 = register dump (delay slot)
440
 
441
#if defined(CYGSEM_HAL_ROM_MONITOR) && \
442
    defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
443
 
444
        # If we are returning from the last nested exception, move back
445
        # to the thread stack.
446
        # Since we have arranged for the top of stack location to
447
        # contain the sp we need to go back to here, just pop it off
448
        # and put it in SP.
449
 
450
        lw      sp,mips_stack_frame_size(sp)    # sp = *sp
451
        subu    sp,sp,mips_stack_frame_size     # make a null frame
452
#endif
453
 
454
        j       restore_state
455
        nop
456
 
457
FUNC_END(__default_exception_vsr)
458
 
459
##------------------------------------------------------------------------------
460
## Default interrupt VSR.
461
## Saves machine state and calls appropriate ISR. When done, calls
462
## interrupt_end() to finish up and possibly reschedule.
463
 
464
FUNC_START(__default_interrupt_vsr)
465
 
466
 
467
        # We enter here with all of the CPU state still
468
        # in its registers except:
469
        # K0 = vector index
470
        # K1 = address of this function
471
 
472
        move    k1,sp                   # K1 = original SP
473
 
474
        addi    sp,sp,-mips_exception_decrement
475
                                # space for registers + safety margin
476
 
477
        sw      k0,mipsreg_vector(sp)   # store vector
478
 
479
        # store GPRs
480
        .set    noat
481
        sgpr    0,sp
482
        sgpr    1,sp
483
        sgpr    2,sp
484
        sgpr    3,sp
485
        sgpr    4,sp
486
        sgpr    5,sp
487
        sgpr    6,sp
488
        sgpr    7,sp
489
        sgpr    8,sp
490
        sgpr    9,sp
491
        sgpr    10,sp
492
        sgpr    11,sp
493
        sgpr    12,sp
494
        sgpr    13,sp
495
        sgpr    14,sp
496
        sgpr    15,sp
497
        sgpr    16,sp
498
        sgpr    17,sp
499
        sgpr    18,sp
500
        sgpr    19,sp
501
        sgpr    20,sp
502
        sgpr    21,sp
503
        sgpr    22,sp
504
        sgpr    23,sp
505
        sgpr    24,sp
506
        sgpr    25,sp
507
#       sgpr    26,sp   # == K0
508
#       sgpr    27,sp   # == K1
509
        sgpr    28,sp   # == GP
510
#       sgpr    29,sp   # == SP
511
        sgpr    30,sp   # == FP
512
        sgpr    31,sp   # == RA
513
        .set    at
514
 
515
        mfhi    a0
516
        mflo    a1
517
        shi     a0,sp
518
        slo     a1,sp
519
 
520
        # K1 contains original SP
521
        ssp     k1,sp                   # store in reg dump
522
 
523
        mfc0    t1,status
524
        mfc0    t2,cachectrl
525
        mvafc0  t3,epc
526
 
527
        sw      t1,mipsreg_sr(sp)
528
        sw      t2,mipsreg_cachectrl(sp)
529
        sva     t3,mipsreg_pc(sp)
530
 
531
        hal_fpu_save sp
532
 
533
        # The machine state is now all saved on the stack.
534
 
535
        # Load Global Pointer register.
536
        la      gp,_gp
537
 
538
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
539
        .extern cyg_scheduler_sched_lock
540
        la      v0,cyg_scheduler_sched_lock
541
        lw      a0,0(v0)
542
        addi    a0,a0,1
543
        sw      a0,0(v0)
544
#endif
545
 
546
        move    s0,sp                           # save pointer to saved state
547
 
548
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
549
 
550
        la      a0,__interrupt_stack            # a0 = stack top
551
        la      a1,__interrupt_stack_base       # a1 = stack base
552
        sub     a3,sp,a1                        # a3 = sp - base
553
        bltz    a3,1f                           # not on istack if < 0
554
        nop                                     # delay slot
555
        sub     t0,a0,sp                        # t0 = top - sp
556
        bgtz    t0,8f                           # already on istack if > 0
557
        nop                                     # delay slot
558
1:
559
        move    sp,a0                           # switch to istack
560
8:
561
        addi    sp,sp,-8                        # space for old SP
562
                                                # (8 to keep dword alignment!)
563
        sw      s0,0(sp)                        # save old SP on stack
564
 
565
#endif
566
 
567
        subu    sp,sp,mips_stack_frame_size     # make a null frame
568
 
569
        # Need to set up back pointers etc. ???
570
 
571
        # Decode external interrupt via interrupt controller
572
 
573
        hal_intc_decode s2
574
 
575
        # Here, s2 contains the number of the interrupt being serviced,
576
        # we need to derive from that the vector number to call in the ISR
577
        # table.
578
 
579
        hal_intc_translate s2,s1
580
 
581
        # Here s1 is the number of the vector to be called and s2 is
582
        # the number of the interrupt being serviced.
583
 
584
        hal_diag_intr_start
585
 
586
#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
587
 
588
        # Call cyg_instrument to record that this interrupt is being raised.
589
 
590
        li      a0,0x0301                       # a0 = type = INTR,RAISE
591
        move    a1,s1                           # a1 = vector number
592
        jal     cyg_instrument                  # call instrument function
593
         move   a2,s2                           # a2 = interrupt number
594
#endif
595
 
596
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT)
597
        # If we are supporting Ctrl-C interrupts from GDB, we must squirrel
598
        # away a pointer to the save interrupt state here so that we can
599
        # plant a breakpoint at some later time.
600
 
601
        .extern hal_saved_interrupt_state
602
        la      v0,hal_saved_interrupt_state
603
        sw      s0,0(v0)
604
 
605
#endif
606
 
607
        sll     s1,s1,2                         # s1 = byte offset of vector
608
 
609
        hal_cpu_except_enable                   # reenable exceptions
610
 
611
        la      t2,hal_interrupt_handlers       # handler table
612
        add     t2,t2,s1                        # address of ISR ptr
613
        lw      t2,0(t2)                        # ISR pointer
614
 
615
        la      a1,hal_interrupt_data           # data table
616
        add     a1,a1,s1                        # address of data ptr
617
        lw      a1,0(a1)                        # Data pointer
618
 
619
        move    a0,s2                           # pass interrupt number
620
        move    a2,s0                           # pass saved interrupt state
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.