1 ##==========================================================================
5 ## PowerPC exception vectors
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 ## Copyright (C) 2002 Gary Thomas
14 ## eCos is free software; you can redistribute it and/or modify it under
15 ## the terms of the GNU General Public License as published by the Free
16 ## Software Foundation; either version 2 or (at your option) any later version.
18 ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 ## WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 ## You should have received a copy of the GNU General Public License along
24 ## with eCos; if not, write to the Free Software Foundation, Inc.,
25 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 ## As a special exception, if other files instantiate templates or use macros
28 ## or inline functions from this file, or you compile this file and link it
29 ## with other works to produce a work based on this file, this file does not
30 ## by itself cause the resulting work to be covered by the GNU General Public
31 ## License. However the source code for this file must still be made available
32 ## in accordance with section (3) of the GNU General Public License.
34 ## This exception does not invalidate any other reasons why a work based on
35 ## this file might be covered by the GNU General Public License.
37 ## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 ## at http://sources.redhat.com/ecos/ecos-license/
39 ## -------------------------------------------
40 #####ECOSGPLCOPYRIGHTEND####
41 ##==========================================================================
42 #######DESCRIPTIONBEGIN####
44 ## Author(s): nickg, jskov
45 ## Contributors: nickg, jskov
47 ## Purpose: PowerPC exception vectors
48 ## Description: This file defines the code placed into the exception
49 ## vectors. It also contains the first level default VSRs
50 ## that save and restore state for both exceptions and
53 ######DESCRIPTIONEND####
55 ##==========================================================================
57 #===========================================================================
59 # The PowerPC exception handling has changed as of version 1.3.1.
60 # The primary motivation for rewriting the code was to bring it more
61 # in line with the other HALs, in particular to allow a RAM application
62 # to cleanly take over only a subset of vectors from a running ROM
65 # GDB stubs (and CygMon, should it be ported to PPC) copies
66 # exception vector entry handler code to address 0. These vector entry
67 # handlers (defined by the exception_vector macro below) compute
68 # a vector index into the hal_vsr_table, fetch the pointer, and
69 # jump to the HAL vector service routine (VSR).
71 # The hal_vsr_table is located immediately after the vector
72 # handlers (at address 0x3000), allowing RAM applications to
73 # change VSRs as necessary, while still keeping desired ROM
74 # monitor functionality available for debugging.
76 # ROM applications can still be configured to leave the vector entry
77 # handlers at 0xff000000, but there is at the moment no
78 # provision for reclaiming the reserved vector space in RAM to
81 # RAM applications can also be configured to provide exception
82 # handlers which are copied to address 0 on startup, thus taking
83 # full control of the target.
86 # Default configuration is for RAM applications to rely on an
87 # existing ROM monitor to provide debugging functionality, and
88 # for ROM applications to copy vectors to address 0.
91 # Unfortunately the new exception scheme is not compatible with the
92 # old scheme. Stubs and applications must be compiled using the same
93 # scheme (i.e., old binaries will not run with new stubs, and new
94 # binaries will not run with old stubs).
96 #===========================================================================
98 #include <pkgconf/hal.h>
101 #include <pkgconf/kernel.h> // CYGPKG_KERNEL_INSTRUMENT
104 #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
105 #include <cyg/hal/ppc_regs.h>
107 #===========================================================================
111 .extern hal_interrupt_data
112 .extern hal_interrupt_handlers
113 .extern hal_interrupt_objects
114 .extern hal_vsr_table
116 .extern cyg_hal_invoke_constructors
117 .extern cyg_instrument
121 .extern hal_enable_caches
122 .extern hal_hardware_init
123 .extern initialize_stub
130 #===========================================================================
131 # MSR initialization value
132 # zero all bits except:
133 # FP = floating point available
134 # ME = machine check enabled
135 # IP = vectors at 0xFFFxxxxx (ROM startup only)
136 # IR = instruction address translation
137 # DR = data address translation
138 # RI = recoverable interrupt
140 #define CYG_MSR_COMMON (MSR_FP | MSR_ME | MSR_RI)
142 #if (CYGHWR_HAL_POWERPC_VECTOR_BASE == 0xfff00000)
143 # define IP_BIT MSR_IP
148 #ifdef CYGHWR_HAL_POWERPC_ENABLE_MMU
149 # define IR_DR_BITS (MSR_IR | MSR_DR)
151 # define IR_DR_BITS 0
154 #define CYG_MSR (CYG_MSR_COMMON | IP_BIT | IR_DR_BITS)
156 # Include variant macros after MSR definition.
157 #include <cyg/hal/arch.inc>
158 #include <cyg/hal/ppc_offsets.inc>
161 #===========================================================================
162 # If the following option is enabled, we only save registers up to R12.
163 # The PowerPC ABI defines registers 13..31 as callee saved and thus we do
164 # not need to save them when calling C functions.
166 #ifdef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
167 # define MAX_SAVE_REG 12
169 # define MAX_SAVE_REG 31
173 #if defined(CYGHWR_HAL_POWERPC_NEED_VECTORS)
175 #===========================================================================
176 # Start by defining the exceptions vectors that must be placed at
177 # locations 0xFFF00000 or 0x00000000. The following code will normally
178 # be located at 0xFFF00000 in the ROM. It may optionally be copied out
179 # to 0x00000000 if we want to use the RAM vectors. For this reason this code
180 # MUST BE POSITION INDEPENDENT.
182 .section ".vectors","ax"
184 #---------------------------------------------------------------------------
185 # Macros for generating an exception vector service routine
189 .macro reset_vector name
191 .globl __exception_\name
193 #ifdef CYGSEM_HAL_POWERPC_RESET_USES_JUMP
203 # Generic vector macro
205 .macro exception_vector name
207 .globl __exception_\name
209 mtspr SPRG1,r3 # stash some work registers away
213 li r5,__exception_\name-rom_vectors # load low half of vector addr
214 srwi r5,r5,6 # shift right by 6
215 lwi r3,hal_vsr_table # table base
216 lwzx r3,r3,r5 # address of vsr
217 mflr r5 # save link register
218 mtlr r3 # put vsr address into it
219 li r3,__exception_\name-rom_vectors # reload low half of vector addr
220 blr # go to common code
223 #---------------------------------------------------------------------------
224 # Define the exception vectors.
226 // Some platforms won't let us put the vector code just where we want
227 // This macro introduces some lattitude in vector placement
229 #ifdef CYG_HAL_FUDGE_VECTOR_ALIGNMENT
230 hal_fudge_vector_alignment
234 # These are the architecture defined vectors that
235 # are always present.
236 #ifdef CYG_HAL_RESERVED_VECTOR_00000
237 hal_reserved_vector_00000
239 exception_vector reserved_00000
242 exception_vector machine_check
243 exception_vector data_storage
244 exception_vector instruction_storage
245 exception_vector external
246 exception_vector alignment
247 exception_vector program
248 exception_vector floatingpoint_unavailable
249 exception_vector decrementer
250 exception_vector reserved_00a00
251 exception_vector reserved_00b00
252 exception_vector system_call
253 exception_vector trace
254 exception_vector floatingpoint_assist
255 exception_vector reserved_00f00
257 # Variants may define extra vectors.
262 #else // CYGHWR_HAL_POWERPC_NEED_VECTORS
264 # When vectors are not included this is the primary entry point.
265 .globl __exception_reset
271 #endif // CYGHWR_HAL_POWERPC_NEED_VECTORS
275 #===========================================================================
276 # Real startup code. We jump here from the various reset vectors to set up
282 # Initialize CPU to a post-reset state, ensuring the ground doesn''t
283 # shift under us while we try to set things up.
286 # Set up global offset table
287 lwi r2,_GLOBAL_OFFSET_TABLE_
289 # set up time base register to zero
295 # Call platform specific hardware initialization
296 # This may include memory controller initialization. It is not
297 # safe to access RAM until after this point.
298 bl hal_hardware_init # this is platform dependent
299 .globl _hal_hardware_init_done
300 _hal_hardware_init_done:
302 #if !defined(CYG_HAL_STARTUP_ROM) && defined(CYGSEM_HAL_POWERPC_COPY_VECTORS)
304 lwi r4,((CYGHWR_HAL_POWERPC_VECTOR_BASE)-4)
305 lwi r5,rom_vectors_end-4
306 sub r5,r5,r3 # compute number of words to copy
315 lwi sp,__interrupt_stack
316 mtspr SPRG0,sp # save in sprg0 for later use
318 # Set up exception handlers and VSR table, taking care not to
319 # step on any ROM monitor''s toes.
322 #if defined(CYG_HAL_STARTUP_ROM)
323 # Copy data from ROM to ram
324 lwi r3,__rom_data_start # r3 = rom start
325 lwi r4,__ram_data_start # r4 = ram start
326 lwi r5,__ram_data_end # r5 = ram end
328 cmplw r4,r5 # skip if no data
330 sub r5,r5,r4 # compute number of words to copy
335 1: lwzu r0,4(r3) # get word from ROM
336 stwu r0,4(r4) # store in RAM
342 lwi r3,__bss_start # r3 = start
343 lwi r4,__bss_end # r4 = end
345 cmplw r3,r4 # skip if no bss
347 sub r4,r4,r3 # compute number of words to clear
352 1: stwu r0,4(r3) # store zero & increment pointer
357 lwi r3,__sbss_start # r3 = start
358 lwi r4,__sbss_end # r4 = end
359 cmplw r3,r4 # skip if no sbss
361 sub r4,r4,r3 # compute number of words to clear
366 1: stwu r0,4(r3) # store zero & increment pointer
370 # It is now safe to call C functions which may rely on initialized
373 # Set up stack for calls to C code.
374 subi sp,sp,12 # make space on stack
376 stw r0,0(sp) # clear back chain
377 stw r0,8(sp) # zero return pc
378 stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame
380 # Variant HALs may need to do something special before we continue
383 # Platform initialization
386 # MMU and cache are controlled by the same option since caching
387 # on the PPC [typically] does not make sense without the MMU to mark
388 # regions which should not be cached.
389 #ifdef CYGHWR_HAL_POWERPC_ENABLE_MMU
393 # Enable MMU (if desired) so we can safely enable caches.
394 lwi r3,CYG_MSR # interrupts enabled later
401 #endif // CYGHWR_HAL_POWERPC_ENABLE_MMU
403 # set up platform specific interrupt environment
406 # call c++ constructors
407 bl cyg_hal_invoke_constructors
409 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
412 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
413 || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
414 .extern hal_ctrlc_isr_init
415 bl hal_ctrlc_isr_init
418 bl cyg_start # call cyg_start
420 b 9b # if we return, loop
422 #---------------------------------------------------------------------------
423 # This code handles the common part of all exception handlers.
424 # It saves the machine state onto the stack and then calls
425 # a "C" routine to do the rest of the work. This work may result
426 # in thread switches, and changes to the saved state. When we return
427 # here the saved state is restored and execution is continued.
431 .globl cyg_hal_default_exception_vsr
432 cyg_hal_default_exception_vsr:
434 # We come here with all register containing their
435 # pre-exception values except:
436 # R3 = ls 16 bits of vector address
444 # SRR1 = old MSR and the exception cause (the POW state is lost!)
446 subi sp,sp,CYGARC_PPC_EXCEPTION_DECREMENT
447 # leave space for registers and
449 #ifdef CYGPKG_HAL_POWERPC_PPC40x
450 // The caches on this processor are always enabled when the MMU is on
451 // (and disabled when off). Thus we need to be careful about cache
452 // polution and staleness when changing the MMU state.
453 // At this point, the MMU is off due to the exception. We need to
454 // flush the part of the cache which may be touched before the MMU
455 // is reenabled so that memory will be consistent when that happens.
456 // Of course, this is complicated by the fact that there are no "free"
457 // registers at this point in the code.
458 dcbf 0,sp // Flushes first line
459 stw r3,0(sp) // This is now safe
460 li r3,CYGARC_PPCREG_VECTOR // Flush lines which will be changed
462 li r3,CYGARC_PPCREG_CR
464 li r3,CYGARC_PPCREG_LR
466 lwz r3,0(sp) // Restore register
469 # First, save away some registers
470 stw r3,CYGARC_PPCREG_VECTOR(sp) # stash vector
471 stw r4,CYGARC_PPCREG_CR(sp) # stash CR
472 stw r5,CYGARC_PPCREG_LR(sp) # stash LR
474 #ifdef CYGDBG_HAL_POWERPC_FRAME_WALLS
475 # Mark this fram as an Exception frame
477 stw r3,CYGARC_PPCREG_WALL_HEAD(sp)
479 stw r3,CYGARC_PPCREG_WALL_TAIL(sp)
482 # Enable MMU & interrupt/FPU environment (as configured)
488 mfspr r3,SPRG1 # save original R3
489 stw r3,CYGARC_PPCREG_REGS+3*4(sp)
490 mfspr r4,SPRG2 # save original R4
491 stw r4,CYGARC_PPCREG_REGS+4*4(sp)
492 mfspr r5,SPRG3 # save original R5
493 stw r5,CYGARC_PPCREG_REGS+5*4(sp)
495 stw r0,CYGARC_PPCREG_REGS+0*4(sp) # save R0
496 stw r2,CYGARC_PPCREG_REGS+2*4(sp) # save R2
498 mr r3,sp # recreate original SP
499 addi r3,r3,CYGARC_PPC_EXCEPTION_DECREMENT
500 stw r3,CYGARC_PPCREG_REGS+1*4(sp) # and save it in state
502 # Save registers r6..r12/r31
504 .rept MAX_SAVE_REG+1-6
505 stw _reg,(CYGARC_PPCREG_REGS+_reg*4)(sp)
509 # Save registers used in vsr (r14+r15)
510 stw r14,(CYGARC_PPCREG_REGS+14*4)(sp)
511 stw r15,(CYGARC_PPCREG_REGS+15*4)(sp)
513 # get remaining family CPU registers
519 stw r3,CYGARC_PPCREG_XER(sp)
520 stw r4,CYGARC_PPCREG_CTR(sp)
521 stw r5,CYGARC_PPCREG_PC(sp)
522 stw r6,CYGARC_PPCREG_MSR(sp)
524 # Save variant registers
530 # The entire CPU state is now stashed on the stack,
531 # call into C to do something with it.
533 mr r3,sp # R3 = register dump
535 subi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE # make a null frame
538 stw r0,0(sp) # backchain = 0
539 stw r0,8(sp) # return pc = 0
541 stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame
542 # where C code can save LR
544 lwi r5,restore_state # get return link
545 mtlr r5 # to link register
547 .extern cyg_hal_exception_handler
548 b cyg_hal_exception_handler # call C code, r3 = registers
550 # When the call returns it will go to restore_state below.
553 ##--------------------------------------------------------------------------
554 ## The following macros are defined depending on whether the Interrupt
555 ## system is using isr tables or chaining, and depending on the interrupt
556 ## controller in the system.
558 #ifndef CYGPKG_HAL_POWERPC_INTC_DEFINED
560 ## This is the simple version. No interrupt controller, CYGARC_PPCREG_VECTOR
561 ## is updated with the decoded interrupt vector. Isr tables/chaining
562 ## use same interrupt decoder.
563 ## Bit 21 biffers between decrementer (0) and external (1).
565 # decode the interrupt
566 .macro hal_intc_decode dreg,state
567 lwz \dreg,CYGARC_PPCREG_VECTOR(\state) # retrieve vector number,
568 rlwinm \dreg,\dreg,22,31,31 # isolate bit 21 and update
569 stw \dreg,CYGARC_PPCREG_VECTOR(\state) # vector in state frame.
570 slwi \dreg,\dreg,2 # convert to word offset.
573 #endif // CYGPKG_HAL_POWERPC_INTC_DEFINED
575 #---------------------------------------------------------------------------
576 # Common interrupt handling code.
578 .globl cyg_hal_default_interrupt_vsr
579 cyg_hal_default_interrupt_vsr:
581 # We come here with all register containing their
582 # pre-exception values except:
583 # R3 = ls 16 bits of vector address
594 subi sp,sp,CYGARC_PPC_EXCEPTION_DECREMENT
595 # leave space for registers and
597 #ifdef CYGPKG_HAL_POWERPC_PPC40x
598 // The caches on this processor are always enabled when the MMU is on
599 // (and disabled when off). Thus we need to be careful about cache
600 // polution and staleness when changing the MMU state.
601 // At this point, the MMU is off due to the exception. We need to
602 // flush the part of the cache which may be touched before the MMU
603 // is reenabled so that memory will be consistent when that happens.
604 // Of course, this is complicated by the fact that there are no "free"
605 // registers at this point in the code.
606 dcbf 0,sp // Flushes first line
607 stw r3,0(sp) // This is now safe
608 li r3,CYGARC_PPCREG_VECTOR // Flush lines which will be changed
610 li r3,CYGARC_PPCREG_CR
612 li r3,CYGARC_PPCREG_LR
614 lwz r3,0(sp) // Restore register
617 stw r3,CYGARC_PPCREG_VECTOR(sp) # stash vector
618 stw r4,CYGARC_PPCREG_CR(sp) # stash CR
619 stw r5,CYGARC_PPCREG_LR(sp) # stash LR
621 #ifdef CYGDBG_HAL_POWERPC_FRAME_WALLS
622 # Mark this fram as an 1nterrupt frame
624 stw r3,CYGARC_PPCREG_WALL_HEAD(sp)
626 stw r3,CYGARC_PPCREG_WALL_TAIL(sp)
629 # Enable MMU & interrupt/FPU environment as configured
635 mfspr r3,SPRG1 # save original R3
636 stw r3,CYGARC_PPCREG_REGS+3*4(sp)
637 mfspr r4,SPRG2 # save original R4
638 stw r4,CYGARC_PPCREG_REGS+4*4(sp)
639 mfspr r5,SPRG3 # save original R5
640 stw r5,CYGARC_PPCREG_REGS+5*4(sp)
642 stw r0,CYGARC_PPCREG_REGS+0*4(sp) # save R0
643 stw r2,CYGARC_PPCREG_REGS+2*4(sp) # save R2
645 mr r3,sp # recreate original SP
646 addi r3,r3,CYGARC_PPC_EXCEPTION_DECREMENT
647 stw r3,CYGARC_PPCREG_REGS+1*4(sp) # and save it in state
649 # Save registers r6..r12/r31
651 .rept MAX_SAVE_REG+1-6
652 stw _reg,(CYGARC_PPCREG_REGS+_reg*4)(sp)
656 # Save registers used in vsr (r14+r15)
657 stw r14,CYGARC_PPCREG_REGS+14*4(sp)
658 stw r15,CYGARC_PPCREG_REGS+15*4(sp)
660 # get remaining family CPU registers
667 stw r3,CYGARC_PPCREG_XER(sp)
668 stw r4,CYGARC_PPCREG_CTR(sp)
669 stw r5,CYGARC_PPCREG_PC(sp)
670 stw r6,CYGARC_PPCREG_MSR(sp)
672 # Save variant registers
678 # The entire CPU state is now stashed on the stack,
679 # increment the scheduler lock and call the ISR
682 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
683 .extern cyg_scheduler_sched_lock
684 lwi r3,cyg_scheduler_sched_lock
690 mr r14,sp # r14 = register dump
692 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
693 lwi r3,__interrupt_stack # stack top
694 lwi r4,__interrupt_stack_base # stack base
695 sub. r5,sp,r4 # sp - base
696 blt 1f # if < 0 - not on istack
697 sub. r5,r3,sp # top - sp
698 bgt 2f # if > 0 - already on istack
700 1: mr sp,r3 # switch to istack
702 2: stwu r14,-4(sp) # save old SP on stack
706 subi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE # make a null frame
709 stw r0,0(sp) # backchain = 0
710 stw r0,8(sp) # return pc = 0
712 stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame
713 # where C code can save LR
715 #if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
717 lwi r3,0x0301 # r3 = type = INTR,RAISE
718 lwz r4,CYGARC_PPCREG_VECTOR(r14) # arg1 = vector address
719 srwi r4,r4,8 # arg1 = vector number
720 xor r5,r5,r5 # arg2 = 0
721 bl cyg_instrument # call instrument function
725 hal_intc_decode r15,r14 # get table index
727 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
728 || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
729 # If we are supporting Ctrl-C interrupts from GDB, we must squirrel
730 # away a pointer to the save interrupt state here so that we can
731 # plant a breakpoint at some later time.
733 .extern hal_saved_interrupt_state
734 lwi r3,hal_saved_interrupt_state
739 #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
741 #ifdef CYGPKG_HAL_POWERPC_MPC8xx
742 # The CPM controller allows nested interrupts. However,
743 # it sits on the back of the SIU controller which has no
744 # HW support for this. In effect, SW masking of lower
745 # priority IRQs in the SIU would be required for this to work.
750 lwz r3,CYGARC_PPCREG_VECTOR(r14) # retrieve decoded vector #
752 lwi r6,hal_interrupt_handlers # get interrupt handler table
753 lwzx r6,r6,r15 # load routine pointer
755 lwi r4,hal_interrupt_data # get interrupt data table
756 lwzx r4,r4,r15 # load data pointer
758 mr r5,r14 # R5 = saved registers
760 mtctr r6 # put isr address in ctr
762 bctrl # branch to ctr reg and link
764 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
766 # If we are returning from the last nested interrupt, move back
767 # to the thread stack. interrupt_end() must be called on the
768 # thread stack since it potentially causes a context switch.
769 # Since we have arranged for the top of stack location to
770 # contain the sp we need to go back to here, just pop it off
774 lwz sp,CYGARC_PPC_STACK_FRAME_SIZE*2(sp) # sp = *sp
776 subi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE # make a null frame
779 stw r0,0(sp) # backchain = 0
780 stw r0,8(sp) # return pc = 0
782 stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame
783 # where C code can save LR
786 # On return r3 bit 1 will indicate whether a DSR is
787 # to be posted. Pass this together with a pointer to
788 # the interrupt object we have just used to the
789 # interrupt tidy up routine.
791 # Note that r14 and r15 are defined to be preserved across
792 # calls by the calling convention, so they still contain
793 # the register dump and the vector number respectively.
795 lwi r4,hal_interrupt_objects # get interrupt object table
796 lwzx r4,r4,r15 # load object pointer
797 mr r5,r14 # arg3 = saved register dump
799 .extern interrupt_end
800 bl interrupt_end # call into C to finish off
803 # All done, restore CPU state and continue
805 # retrieve CPU state pointer
806 addi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE*2
808 # Restore FPU registers
811 # Restore variant registers
814 # get sprs we want to restore
815 # stuff some of them into the CPU
816 lwz r3,CYGARC_PPCREG_XER(sp)
817 lwz r4,CYGARC_PPCREG_LR(sp)
818 lwz r5,CYGARC_PPCREG_CTR(sp)
823 # Restore registers used in vsr (r14+r15)
824 lwz r14,CYGARC_PPCREG_REGS+14*4(r1)
825 lwz r15,CYGARC_PPCREG_REGS+15*4(r1)
827 # restore registers r6..r12/r31
829 .rept MAX_SAVE_REG+1-6
830 lwz _reg,(CYGARC_PPCREG_REGS+_reg*4)(sp)
837 lwz r0,CYGARC_PPCREG_REGS+0*4(sp)
838 lwz r2,CYGARC_PPCREG_REGS+2*4(sp)
840 # Here all the registers are loaded except
841 # sp = HAL_SavedRegisters
846 # We have to disable interrupts while srr0 and
847 # srr1 are loaded, since another interrupt will
850 lwz r3,CYGARC_PPCREG_CR(sp)
851 lwz r4,CYGARC_PPCREG_PC(sp)
852 lwz r5,CYGARC_PPCREG_MSR(sp)
854 mtsrr0 r4 # load old pc
855 mtsrr1 r5 # load old msr
857 #ifdef CYGDBG_HAL_POWERPC_FRAME_WALLS
858 # Mark this frame as (almost) dead.
860 stw r3,CYGARC_PPCREG_WALL_HEAD(sp)
862 stw r3,CYGARC_PPCREG_WALL_TAIL(sp)
865 lwz r3,CYGARC_PPCREG_REGS+3*4(sp) # load r3 value
866 lwz r4,CYGARC_PPCREG_REGS+4*4(sp) # load r4 value
867 lwz r5,CYGARC_PPCREG_REGS+5*4(sp) # load r5 value
868 lwz sp,CYGARC_PPCREG_REGS+1*4(sp) # restore sp
870 sync # settle things down
876 ##-----------------------------------------------------------------------------
877 ## Execute pending DSRs on the interrupt stack with interrupts enabled.
878 ## Note: this can only be called from code running on a thread stack
880 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
881 .extern cyg_interrupt_call_pending_DSRs
883 FUNC_START(hal_interrupt_stack_call_pending_DSRs)
884 # Change to interrupt stack, save state and set up stack for
887 lwi r4,__interrupt_stack
888 subi r4,r4,24 # make space on stack
890 stw r3,12(sp) # save old sp
892 stw r3,16(sp) # save old MSR
894 stw r3,20(sp) # save old LR
897 stw r0,0(sp) # clear back chain
898 stw r0,8(sp) # zero return pc
902 # Call into kernel which will execute DSRs
903 stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp)
904 bl cyg_interrupt_call_pending_DSRs
905 addi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE
907 lwz r3,20(sp) # restore LR
909 lwz r5,12(sp) # get SP from saved state
910 lwz r3,16(sp) # restore interrupt setting
913 mr sp,r5 # restore stack pointer
914 blr # and return to caller
917 #---------------------------------------------------------------------------
918 ## Temporary interrupt stack
923 .global cyg_interrupt_stack_base
924 cyg_interrupt_stack_base:
925 __interrupt_stack_base:
926 .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
930 .global cyg_interrupt_stack
934 .long 0,0,0,0,0,0,0,0
936 #---------------------------------------------------------------------------