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

Subversion Repositories openrisc

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
##==========================================================================
2
##
3
##      vectors.S
4
##
5
##      SH 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):    jskov
44
## Contributors: jskov, gthomas
45
## Date:         1999-05-01
46
## Purpose:      SH 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      // CYGPKG_KERNEL_INSTRUMENT
61
#endif
62
#include CYGHWR_MEMORY_LAYOUT_H
63
 
64
#include 
65
#include 
66
#include 
67
#include 
68
 
69
#===========================================================================
70
 
71
//        .file   "vectors.S"
72
 
73
#define n__DEBUG
74
 
75
#===========================================================================
76
# Start by defining the exceptions vectors.
77
 
78
        .section ".vectors","ax"
79
# Include exception entry code since it exists in two variants,
80
# depending on the CPU model. This file also defines macros used
81
# for exception return.
82
 
83
FUNC_START(_vector_code_vma)
84
 
85
#include CYGBLD_HAL_VAR_EXCEPTION_MODEL_INC
86
 
87
#---------------------------------------------------------------------------
88
# This code handles the common part of all exception handlers.
89
# It saves the machine state onto the stack  and then calls
90
# a "C" routine to do the rest of the work. This work may result
91
# in thread switches, and changes to the saved state. When we return
92
# here the saved state is restored and execution is continued.
93
 
94
FUNC_START(cyg_hal_default_exception_vsr)
95
        hal_cpu_save_regs
96
        hal_exception_entry_extras
97
#ifdef __DEBUG
98
        mov.l   1f,r0
99
        mov.l   r0,@-r15
100
        bra     2f
101
         nop
102
        .align  2
103
1:      .long   0x77777770
104
2:
105
        # It is safe to use breakpoints below this point.
106
        .globl  _cyg_hal_default_exception_vsr_bp_safe
107
_cyg_hal_default_exception_vsr_bp_safe:
108
#endif
109
 
110
        # Make sure the saved registers structure contain
111
        # the decoded exception number
112
        hal_exception_translate
113
 
114
        # The entire CPU state is now stashed on the stack,
115
        # call into C to do something with it.
116
 
117
        mov      r15,r4                 ! R4 = register dump
118
 
119
        mov.l   $restore_state,r0       ! get return link
120
        lds     r0,pr                   ! to procedure register
121
 
122
        mov.l   $cyg_hal_exception_handler,r0
123
        jmp     @r0                     ! call C code, r4 = registers
124
         nop
125
 
126
        .align  2
127
$restore_state:
128
        .long   restore_state
129
        SYM_PTR_REF(cyg_hal_exception_handler)
130
 
131
#---------------------------------------------------------------------------
132
# Common interrupt handling code.
133
 
134
FUNC_START(cyg_hal_default_interrupt_vsr)
135
        hal_cpu_save_regs
136
        hal_interrupt_entry_extras
137
 
138
#ifdef __DEBUG
139
        mov.l   1f,r0
140
        mov.l   r0,@-r15
141
        bra     2f
142
         nop
143
        .align  2
144
1:      .long   0x77777771
145
2:
146
        # It is safe to use breakpoints below this point.
147
        .globl  _cyg_hal_default_interrupt_vsr_bp_safe
148
_cyg_hal_default_interrupt_vsr_bp_safe:
149
#endif
150
 
151
        # The entire CPU state is now stashed on the stack,
152
        # increment the scheduler lock and call the ISR
153
        # for this vector.
154
 
155
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
156
        mov.l   $cyg_scheduler_sched_lock,r0
157
        mov.l   @r0,r1
158
        add     #1,r1
159
        mov.l   r1,@r0
160
#endif
161
 
162
        mov     r15,r8                  ! R8 = register dump
163
 
164
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
165
 
166
        mov.l   $cyg_interrupt_stack_base,r0
167
        mov.l   $cyg_interrupt_stack,r1
168
        cmp/hi  r15,r0                  ! if r0 > r15 or
169
        bt      2f
170
        cmp/hi  r1,r15                  ! if r15 > r1
171
        bf      1f
172
2:      mov     r1,r15                  ! change to supervisor stack
173
1:      mov.l   r8,@-r15                ! save old stack pointer
174
 
175
#endif
176
 
177
#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
178
        mov.l   $n0301,r4               ! arg0 = type = INTR,RAISE
179
        mov     r7,r5                   ! arg1 = vector number
180
        mov.l   $cyg_instrument,r0
181
        mov     #0,r6                   ! arg2 = 0
182
        jsr      @r0                    ! call instrument function
183
         nop
184
        bra     1f
185
         nop
186
 
187
        .align  2
188
$n0301:
189
        .long   0x0301
190
        SYM_PTR_REF(cyg_instrument)
191
1:
192
#endif
193
 
194
        # Decode the interrupt vector, and find ISR index
195
        mov     #CYGARC_SHREG_EVENT,r0
196
        mov.l   @(r0,r8),r4             ! load existing vector number
197
        hal_intc_decode r1,r4
198
        mov.l   r4,@(r0,r8)             ! store decoded vector number back
199
                                        ! to saved state.
200
        hal_intc_translate r4,r9
201
 
202
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
203
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
204
        # If we are supporting Ctrl-C interrupts from GDB, we must squirrel
205
        # away a pointer to the save interrupt state here so that we can
206
        # plant a breakpoint at some later time.
207
 
208
        mov.l   $hal_saved_interrupt_state,r1
209
        mov.l   r8,@r1
210
#endif
211
 
212
#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
213
 
214
#if defined(CYGARC_SH_SOFTWARE_IP_UPDATE)
215
        # The interrupt mask bits in the SR are not updated by the
216
        # CPU. Proper nested operation requires the level to be
217
        # found and put in the SR.
218
 
219
        # R4 contains the vector number:
220
        # CYGNUM_HAL_INTERRUPT_NMI:
221
        #  Ix = 15
222
        # CYGNUM_HAL_INTERRUPT_LVL0-CYGNUM_HAL_INTERRUPT_LVL14:
223
        #  Ix = 15-(CYGNUM_HAL_INTERRUPT_LVL0-R4)
224
        # IRA sources:
225
        #  Get level from IRA
226
        # IRB sources:
227
        #  Get level from IRB
228
 
229
        # However, doing mutiple checks and branches here is not smart.
230
        # Instead rely on alternative implementation where all programmed
231
        # priorities are also kept in a table.
232
 
233
        mov.l   $cyg_hal_ILVL_table,r0
234
        mov.b   @(r0,r4),r0
235
        shll2   r0
236
        shll2   r0
237
        mov.l   $unmasked_SR,r1
238
        or      r0,r1
239
        ldc     r1,sr
240
#endif
241
 
242
#endif
243
 
244
        mov     r9,r0
245
        mov.l   $hal_interrupt_handlers,r1 ! get interrupt handler
246
        mov.l   @(r0,r1),r1
247
 
248
        mov.l   $hal_interrupt_data,r5 ! get interrupt data
249
        mov.l   @(r0,r5),r5
250
 
251
        jsr     @r1                     ! r4=vector, r5=data
252
         nop
253
 
254
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
255
 
256
        # If we are returning from the last nested interrupt, move back
257
        # to the thread stack. interrupt_end() must be called on the
258
        # thread stack since it potentially causes a context switch.
259
        # Since we have arranged for the top of stack location to
260
        # contain the sp we need to go back to here, just pop it off
261
        # and put it in SP.
262
 
263
        mov.l   @r15,r15
264
#endif
265
 
266
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
267
 
268
        # We only need to call _interrupt_end() when there is a kernel
269
        # present to do any tidying up.
270
 
271
        # on return r0 bit 1 will indicate whether a DSR is
272
        # to be posted. Pass this together with a pointer to
273
        # the interrupt object we have just used to the
274
        # interrupt tidy up routine.
275
        mov     r0,r4                   ! arg1 = isr_ret
276
 
277
        # Note that r8 and r9 are defined to be preserved across
278
        # calls by the calling convention, so they still contain
279
        # the register dump and the vector table index respectively.
280
 
281
        mov.l   $hal_interrupt_objects,r0  ! get interrupt object table
282
        mov.l   @(r0,r9),r5             ! arg2 = interrupt object
283
        mov.l   $interrupt_end,r0
284
        mov     r8,r6                   ! arg3 = saved register dump
285
        jsr     @r0                     ! call into C to finish off
286
         nop
287
#endif
288
 
289
restore_state:
290
        # All done, restore CPU state and continue
291
#ifdef __DEBUG
292
        # skip past debug marker
293
        add     #4,sp
294
#endif
295
 
296
        hal_cpu_restore_regs_return
297
 
298
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
299
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
300
##-----------------------------------------------------------------------------
301
## Execute pending DSRs on the interrupt stack with interrupts enabled.
302
## Note: this can only be called from code running on a thread stack
303
FUNC_START(hal_interrupt_stack_call_pending_DSRs)
304
        # Change to interrupt stack
305
        mov     r15,r2
306
        mov.l   $cyg_interrupt_stack,r15
307
 
308
        mov.l   r2,@-r15                ! save old stack pointer
309
        sts.l   pr,@-r15                ! save pr on stack
310
        stc     sr,r3
311
        mov.l   r3,@-r15                ! save sr on stack
312
 
313
        # enable interrupts
314
        hal_cpu_int_enable r0,r1
315
 
316
        # Call into kernel which will execute DSRs
317
        mov.l   $cyg_interrupt_call_pending_DSRs,r0
318
        jsr     @r0
319
         nop
320
 
321
        # Get old sr, pr, and stack values
322
        mov.l   @r15+,r3                ! get old sr
323
        lds.l   @r15+,pr                ! get old pr
324
        mov.l   @r15+,r15               ! get old stack pointer
325
 
326
        # Restore SR interrupt state
327
        hal_cpu_int_merge r3,r0,r1
328
        rts
329
         nop
330
 
331
#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
332
#endif // CYGFUN_HAL_COMMON_KERNEL_SUPPORT
333
 
334
        .align  2
335
 
336
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
337
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
338
        SYM_PTR_REF(hal_saved_interrupt_state)
339
#endif
340
 
341
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
342
        SYM_PTR_REF(cyg_interrupt_stack_base)
343
        SYM_PTR_REF(cyg_interrupt_stack)
344
#endif
345
        SYM_PTR_REF(hal_interrupt_handlers)
346
        SYM_PTR_REF(hal_interrupt_data)
347
        SYM_PTR_REF(hal_interrupt_objects)
348
 
349
#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
350
        SYM_PTR_REF(cyg_hal_ILVL_table)
351
$unmasked_SR:
352
        .long   (CYG_SR & ~CYGARC_REG_SR_IMASK)
353
#endif // CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
354
 
355
 
356
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
357
        SYM_PTR_REF(cyg_interrupt_call_pending_DSRs)
358
        SYM_PTR_REF(interrupt_end)
359
        SYM_PTR_REF(cyg_scheduler_sched_lock)
360
#endif
361
 
362
#---------------------------------------------------------------------------
363
# Platform initialization (reset)
364
FUNC_START(_reset_platform)
365
        hal_post_reset_init
366
 
367
#ifdef __DEBUG
368
        mov     #0,r0
369
        mov     #1,r1
370
        mov     #2,r2
371
        mov     #3,r3
372
        mov     #4,r4
373
        mov     #5,r5
374
        mov     #6,r6
375
        mov     #7,r7
376
        mov     #8,r8
377
        mov     #9,r9
378
        mov     #10,r10
379
        mov     #11,r11
380
        mov     #12,r12
381
        mov     #13,r13
382
        mov     #14,r14
383
#endif
384
 
385
        # Call platform specific hardware initialization
386
        # This may include memory controller initialization. It is not
387
        # safe to access RAM until after this point.
388
        # Note that caches must not be enabled until after this point,
389
        # since we may be fiddling the FRQCR which cannot be safely done
390
        # by code in burst/cachable memory (errata SH7-184e).
391
        hal_hardware_init
392
 
393
        # Now copy necessary bits to RAM and jump to the VMA base
394
 
395
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_SUBSETROMRAM)
396
 
397
        # Copy data from ROM to ram
398
        mov.l   $_rom_data_start,r3    ! r3 = rom start
399
        mov.l   $_ram_data_start,r4    ! r4 = ram start
400
        mov.l   $_ram_data_end,r5      ! r5 = ram end
401
 
402
        cmp/eq  r4,r5                   ! skip if no data
403
        bt      2f
404
1:      mov.l   @r3+,r0                 ! get word from ROM
405
        mov.l   r0,@r4                  ! store in RAM
406
        add     #4,r4
407
        cmp/eq  r4,r5                   ! compare
408
        bf      1b                      ! loop if not yet done
409
2:
410
 
411
 
412
        # Jump to the proper VMA base of the code.
413
        mov.l   $complete_setup,r0
414
        jmp     @r0
415
         nop
416
        .align 2
417
 
418
        SYM_PTR_REF(_rom_data_start)
419
        SYM_PTR_REF(_ram_data_start)
420
        SYM_PTR_REF(_ram_data_end)
421
        SYM_PTR_REF(complete_setup)
422
 
423
 
424
#elif defined(CYG_HAL_STARTUP_ROMRAM)
425
 
426
        # Copy everything to the proper VMA base and jump to it.
427
        mov.l   $_vector_code_lma,r0
428
        mov.l   $_vector_code_vma,r1
429
        mov.l   $end,r2
430
1:      mov.l   @r0+,r3                 ! get word from ROM
431
        mov.l   r3,@r1                  ! store in RAM
432
        add     #4,r1
433
        cmp/eq  r1,r2                   ! compare
434
        bf      1b                      ! loop if not yet done
435
        mov.l   $complete_setup,r0
436
        jmp     @r0
437
         nop
438
        .align  2
439
 
440
        SYM_PTR_REF(_vector_code_lma)
441
        SYM_PTR_REF(_vector_code_vma)
442
        SYM_PTR_REF(end)
443
        SYM_PTR_REF(complete_setup)
444
 
445
#else
446
 
447
        # Jump to remaining setup code. Relative branch is OK since VMA=LMA.
448
        bra   CYG_LABEL_DEFN(complete_setup)
449
         nop
450
 
451
#endif
452
 
453
#-----------------------------------------------------------------------------
454
# Complete target initialization and setup.
455
# After this point we can use absolute addressing modes and access all the
456
# memory in the system.
457
 
458
        .align  2
459
FUNC_START(complete_setup)
460
 
461
        # Set up monitor related stuff (vectors primarily)
462
        hal_mon_init
463
 
464
        # set up stack
465
        mov.l    $startup_stack,r15
466
 
467
        # clear BSS
468
        mov.l   $_bss_start,r3         ! r3 = start
469
        mov.l   $_bss_end,r4           ! r4 = end
470
        mov     #0,r0                   ! r0 = 0
471
1:      cmp/eq  r3,r4                   ! skip if no bss
472
        bt      2f
473
        mov.l   r0,@r3                  ! store zero
474
        add     #4,r3
475
        bra     1b                      ! loop
476
         nop
477
2:
478
 
479
        # It is now safe to call C functions which may rely on initialized
480
        # data.
481
 
482
#        # Initialize MMU.
483
#        .extern hal_MMU_init
484
#        jsr      hal_MMU_init
485
#         nop
486
 
487
        # Enable caches
488
        mov.l    $cyg_var_enable_caches,r1
489
        jsr      @r1
490
         nop
491
 
492
        # Variant HALs may need to do something special before we continue
493
        mov.l    $hal_variant_init,r1
494
        jsr      @r1
495
         nop
496
 
497
        # Platform initialization
498
        mov.l    $hal_platform_init,r1
499
        jsr      @r1
500
         nop
501
 
502
        # call c++ constructors
503
        mov.l    $cyg_hal_invoke_constructors,r1
504
        jsr      @r1
505
         nop
506
 
507
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
508
        mov.l    $initialize_stub,r1
509
        jsr      @r1
510
         nop
511
#endif
512
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
513
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
514
        mov.l    $hal_ctrlc_isr_init,r1
515
        jsr      @r1
516
         nop
517
#endif
518
 
519
        mov.l    $cyg_start,r1
520
        jsr      @r1
521
         nop
522
9:
523
        bra      9b                     ! if we return, loop
524
         nop
525
 
526
        .align  2
527
        SYM_PTR_REF(_bss_start)
528
        SYM_PTR_REF(_bss_end)
529
        SYM_PTR_REF(startup_stack)
530
        SYM_PTR_REF(cyg_hal_invoke_constructors)
531
        SYM_PTR_REF(cyg_var_enable_caches)
532
        SYM_PTR_REF(hal_variant_init)
533
        SYM_PTR_REF(hal_platform_init)
534
        SYM_PTR_REF(cyg_start)
535
 
536
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
537
        SYM_PTR_REF(initialize_stub)
538
#endif
539
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
540
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
541
        SYM_PTR_REF(hal_ctrlc_isr_init)
542
#endif
543
 
544
#---------------------------------------------------------------------------
545
# Interrupt vector tables.
546
# These tables contain the isr, data and object pointers used to deliver
547
# interrupts to user code.
548
 
549
        .data
550
 
551
        .extern CYG_LABEL_DEFN(hal_default_isr)
552
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
553
#define CYG_ISR_TABLE_SIZE    1
554
#else
555
#define CYG_ISR_TABLE_SIZE    CYGNUM_HAL_ISR_COUNT
556
#endif
557
 
558
SYM_DEF(hal_interrupt_handlers)
559
        .rept   CYG_ISR_TABLE_SIZE
560
        .long   CYG_LABEL_DEFN(hal_default_isr)
561
        .endr
562
 
563
SYM_DEF(hal_interrupt_data)
564
        .rept   CYG_ISR_TABLE_SIZE
565
        .long   0
566
        .endr
567
 
568
SYM_DEF(hal_interrupt_objects)
569
        .rept   CYG_ISR_TABLE_SIZE
570
        .long   0
571
        .endr
572
 
573
#---------------------------------------------------------------------------
574
## Temporary interrupt stack
575
 
576
        .section ".bss"
577
 
578
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
579
        .balign 16
580
SYM_DEF(cyg_interrupt_stack_base)
581
        .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
582
        .byte 0
583
        .endr
584
        .balign 16
585
        .global _cyg_interrupt_stack
586
SYM_DEF(cyg_interrupt_stack)
587
 
588
        .long   0,0,0,0
589
#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
590
 
591
 
592
#ifdef CYGSEM_HAL_ROM_MONITOR
593
  // Enough space for stub to handle downloads. If using thread capabilities
594
  // it will be using the RAM application's stack.
595
# define STARTUP_STACK_SIZE 1024
596
#else
597
# ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
598
   // Enough space to run constructors.
599
   // FIXME: 512 is enough for all tests. doc/examples/twothreads
600
   // calls printf on this stack though, and so requires more space.
601
#  define STARTUP_STACK_SIZE 1024
602
# else
603
#  define STARTUP_STACK_SIZE CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
604
# endif
605
#endif
606
 
607
        .balign 16
608
SYM_DEF(startup_stack_base)
609
        .rept   STARTUP_STACK_SIZE
610
        .byte 0
611
        .endr
612
        .balign 16
613
SYM_DEF(startup_stack)
614
        .long   0,0,0,0
615
 
616
#---------------------------------------------------------------------------
617
# end of vectors.S

powered by: WebSVN 2.1.0

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