summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/shared/irq
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2009-10-30 13:52:34 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2009-10-30 13:52:34 +0000
commitf7ac681b5166bd91781c026ed81493e524860955 (patch)
tree2524b9a2c61f2aeadf977e2edac2b7f97a19b31d /c/src/lib/libbsp/powerpc/shared/irq
parentadd cache.rel to Makefile (diff)
downloadrtems-f7ac681b5166bd91781c026ed81493e524860955.tar.bz2
remove depratated powerpc exception API
Diffstat (limited to 'c/src/lib/libbsp/powerpc/shared/irq')
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/README.deprecated17
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/irq.c349
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S415
3 files changed, 0 insertions, 781 deletions
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/README.deprecated b/c/src/lib/libbsp/powerpc/shared/irq/README.deprecated
deleted file mode 100644
index 6a898f150d..0000000000
--- a/c/src/lib/libbsp/powerpc/shared/irq/README.deprecated
+++ /dev/null
@@ -1,17 +0,0 @@
-The files:
-
- irq.c, irq_asm.S
-
-in this directory are DEPRECATED.
-
-DO NOT COPY/MODIFY FOR NEW BSPs
-
-as this has created major maintenance headache.
-Consider using the library in
-
-libcpu/powercp/new-exceptions/bspsupport/
-
-which implements the same functionality in a
-(hopefully) generic way.
-
-T.S., 12/2007
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq.c b/c/src/lib/libbsp/powerpc/shared/irq/irq.c
deleted file mode 100644
index 36c5c04330..0000000000
--- a/c/src/lib/libbsp/powerpc/shared/irq/irq.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- *
- * This file contains the PIC-independent implementation of the
- * functions described in irq.h
- *
- * Copyright (C) 1998, 1999 valette@crf.canon.fr
- *
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
- *
- * $Id$
- */
-
-#include <stdlib.h>
-
-#include <bsp.h>
-#include <bsp/irq_supp.h>
-#include <rtems/irq.h>
-#include <rtems/score/apiext.h> /* for post ISR signal processing */
-#include <libcpu/raw_exception.h>
-#include <bsp/vectors.h>
-#include <stdlib.h>
-
-#include <rtems/bspIo.h> /* for printk */
-
-extern unsigned int external_exception_vector_prolog_code_size[];
-extern void external_exception_vector_prolog_code();
-extern unsigned int decrementer_exception_vector_prolog_code_size[];
-extern void decrementer_exception_vector_prolog_code();
-
-/*
- * default handler connected on each irq after bsp initialization
- */
-static rtems_irq_connect_data default_rtems_entry;
-
-/*
- * location used to store initial tables used for interrupt
- * management.
- */
-static rtems_irq_global_settings* internal_config;
-static rtems_irq_connect_data* rtems_hdl_tbl;
-
-/*
- * ------------------------ RTEMS Irq helper functions ----------------
- */
-
-/*
- * This function check that the value given for the irq line
- * is valid.
- */
-
-static int isValidInterrupt(int irq)
-{
- if ( (irq < internal_config->irqBase) ||
- (irq >= internal_config->irqBase + internal_config->irqNb))
- return 0;
- return 1;
-}
-
-/*
- * ------------------- RTEMS Shared Irq Handler Mngt Routines ------------
- */
-int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq)
-{
- rtems_interrupt_level level;
- rtems_irq_connect_data* vchain;
-
- if (!isValidInterrupt(irq->name)) {
- printk("Invalid interrupt vector %d\n",irq->name);
- return 0;
- }
-
- rtems_interrupt_disable(level);
-
- if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) {
- rtems_interrupt_enable(level);
- printk(
- "IRQ vector %d already connected to an unshared handler\n",
- irq->name
- );
- return 0;
- }
-
- vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
-
- /* save off topmost handler */
- vchain[0]= rtems_hdl_tbl[irq->name];
-
- /*
- * store the data provided by user
- */
- rtems_hdl_tbl[irq->name] = *irq;
-
- /* link chain to new topmost handler */
- rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
-
- /*
- * enable_irq_at_pic is supposed to ignore
- * requests to disable interrupts outside
- * of the range handled by the PIC
- */
- BSP_enable_irq_at_pic(irq->name);
-
- /*
- * Enable interrupt on device
- */
- if (irq->on)
- irq->on(irq);
-
- rtems_interrupt_enable(level);
-
- return 1;
-}
-
-/*
- * ------------------- RTEMS Single Irq Handler Mngt Routines ------------
- */
-
-int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
-{
- rtems_interrupt_level level;
-
- if (!isValidInterrupt(irq->name)) {
- printk("Invalid interrupt vector %d\n",irq->name);
- return 0;
- }
- /*
- * Check if default handler is actually connected. If not issue an error.
- * You must first get the current handler via i386_get_current_idt_entry
- * and then disconnect it using i386_delete_idt_entry.
- * RATIONALE : to always have the same transition by forcing the user
- * to get the previous handler before accepting to disconnect.
- */
- rtems_interrupt_disable(level);
- if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
- rtems_interrupt_enable(level);
- printk("IRQ vector %d already connected\n",irq->name);
- return 0;
- }
-
- /*
- * store the data provided by user
- */
- rtems_hdl_tbl[irq->name] = *irq;
- rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
-
- /*
- * enable_irq_at_pic is supposed to ignore
- * requests to disable interrupts outside
- * of the range handled by the PIC
- */
- BSP_enable_irq_at_pic(irq->name);
-
- /*
- * Enable interrupt on device
- */
- if (irq->on)
- irq->on(irq);
-
- rtems_interrupt_enable(level);
-
- return 1;
-}
-
-int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
-{
- rtems_interrupt_level level;
-
- if (!isValidInterrupt(irq->name)) {
- return 0;
- }
- rtems_interrupt_disable(level);
- *irq = rtems_hdl_tbl[irq->name];
- rtems_interrupt_enable(level);
- return 1;
-}
-
-int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
-{
- rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
- rtems_interrupt_level level;
-
- if (!isValidInterrupt(irq->name)) {
- return 0;
- }
- /*
- * Check if default handler is actually connected. If not issue an error.
- * You must first get the current handler via i386_get_current_idt_entry
- * and then disconnect it using i386_delete_idt_entry.
- * RATIONALE : to always have the same transition by forcing the user
- * to get the previous handler before accepting to disconnect.
- */
- rtems_interrupt_disable(level);
- if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
- rtems_interrupt_enable(level);
- return 0;
- }
-
- if ( (int)rtems_hdl_tbl[irq->name].next_handler != -1 ) {
- int found = 0;
-
- for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
- (vchain->hdl != default_rtems_entry.hdl);
- (pchain= vchain,
- vchain = (rtems_irq_connect_data*)vchain->next_handler) ) {
- if ( vchain->hdl == irq->hdl ) {
- found = -1;
- break;
- }
- }
-
- if ( !found ) {
- rtems_interrupt_enable(level);
- return 0;
- }
- } else {
- if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
- rtems_interrupt_enable(level);
- return 0;
- }
- }
-
- /*
- * disable_irq_at_pic is supposed to ignore
- * requests to disable interrupts outside
- * of the range handled by the PIC
- */
- BSP_disable_irq_at_pic(irq->name);
-
- /*
- * Disable interrupt on device
- */
- if (irq->off)
- irq->off(irq);
-
- /*
- * restore the default irq value
- */
- if( !vchain ) {
- /* single handler vector... */
- rtems_hdl_tbl[irq->name] = default_rtems_entry;
- } else {
- if ( pchain ) {
- /* non-first handler being removed */
- pchain->next_handler = vchain->next_handler;
- } else {
- /* first handler isn't malloc'ed, so just overwrite it. Since
- * the contents of vchain are being struct copied, vchain itself
- * goes away
- */
- vchain = vchain->next_handler;
- rtems_hdl_tbl[irq->name]= *vchain;
- }
- free(vchain);
- }
-
- rtems_interrupt_enable(level);
-
- return 1;
-}
-
-/*
- * RTEMS Global Interrupt Handler Management Routines
- */
-
-int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
-{
- int i;
- rtems_interrupt_level level;
- rtems_irq_connect_data* vchain;
- rtems_raw_except_connect_data vectorDesc;
-
- /*
- * Store various code accelerators
- */
- internal_config = config;
- default_rtems_entry = config->defaultEntry;
- rtems_hdl_tbl = config->irqHdlTbl;
-
- rtems_interrupt_disable(level);
-
- if ( !BSP_setup_the_pic(config) ) {
- printk("PIC setup failed; leaving IRQs OFF\n");
- return 0;
- }
-
- for ( i = config->irqBase; i < config->irqBase + config->irqNb; i++ ) {
- for( vchain = &rtems_hdl_tbl[i];
- ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
- vchain = (rtems_irq_connect_data*)vchain->next_handler ) {
- if (vchain->on)
- vchain->on(vchain);
- }
- }
-
- rtems_interrupt_enable(level);
-
- /*
- * We must connect the raw irq handler for the two
- * expected interrupt sources : decrementer and external interrupts.
- */
- vectorDesc.exceptIndex = ASM_DEC_VECTOR;
- vectorDesc.hdl.vector = ASM_DEC_VECTOR;
- vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code;
- vectorDesc.hdl.raw_hdl_size =
- (unsigned) decrementer_exception_vector_prolog_code_size;
- vectorDesc.on = 0;
- vectorDesc.off = 0;
- vectorDesc.isOn = 0;
- if (!ppc_set_exception (&vectorDesc)) {
- BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
- }
-
- vectorDesc.exceptIndex = ASM_EXT_VECTOR;
- vectorDesc.hdl.vector = ASM_EXT_VECTOR;
- vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code;
- vectorDesc.hdl.raw_hdl_size =
- (unsigned) external_exception_vector_prolog_code_size;
- if (!ppc_set_exception (&vectorDesc)) {
- BSP_panic("Unable to initialize RTEMS external raw exception\n");
- }
- return 1;
-}
-
-int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
-{
- *config = internal_config;
- return 0;
-}
-
-void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
-{
- /*
- * Process pending signals that have not already been
- * processed by _Thread_Displatch. This happens quite
- * unfrequently : the ISR must have posted an action
- * to the current running thread.
- */
- if ( _Thread_Do_post_task_switch_extension ||
- _Thread_Executing->do_post_task_switch_extension ) {
- _Thread_Executing->do_post_task_switch_extension = false;
- _API_extensions_Run_postswitch();
- }
- /*
- * I plan to process other thread related events here.
- * This will include DEBUG session requested from keyboard...
- */
-}
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S b/c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S
deleted file mode 100644
index 5541632c0f..0000000000
--- a/c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * This file contains the assembly code for the PowerPC
- * IRQ veneers for RTEMS.
- *
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
- *
- * Modified to support the MCP750.
- * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
- *
- * Till Straumann <strauman@slac.stanford.edu>, 2003/7:
- * - store isr nesting level in _ISR_Nest_level rather than
- * SPRG0 - RTEMS relies on that variable.
- * Till Straumann <strauman@slac.stanford.edu>, 2005/4:
- * - DONT enable FP across ISR since fpregs are not saved!!
- * FPU is used by Thread_Dispatch however...
- *
- * $Id$
- */
-
-#include <rtems/asm.h>
-#include <rtems/score/cpu.h>
-#include <bsp/vectors.h>
-#include <libcpu/raw_exception.h>
-
-#define MSR_EXC_BITS (MSR_DR | MSR_IR | MSR_RI)
-
-#define SYNC \
- sync; \
- isync
-
- .text
- .p2align 5
-#if defined(ASM_DEC_VECTOR)
- PUBLIC_VAR(decrementer_exception_vector_prolog_code)
-
-SYM (decrementer_exception_vector_prolog_code):
- /*
- * let room for exception frame
- */
- stwu r1, - (EXCEPTION_FRAME_END)(r1)
- stw r4, GPR4_OFFSET(r1)
- li r4, ASM_DEC_VECTOR
- ba shared_raw_irq_code_entry
-
- PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
-
- decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
-#endif
-
-#if defined(ASM_60X_SYSMGMT_VECTOR)
- PUBLIC_VAR(sysmgmt_exception_vector_prolog_code)
-
-SYM (sysmgmt_exception_vector_prolog_code):
- /*
- * let room for exception frame
- */
- stwu r1, - (EXCEPTION_FRAME_END)(r1)
- stw r4, GPR4_OFFSET(r1)
- li r4, ASM_60X_SYSMGMT_VECTOR
- ba shared_raw_irq_code_entry
-
- PUBLIC_VAR (sysmgmt_exception_vector_prolog_code_size)
-
- sysmgmt_exception_vector_prolog_code_size = . - sysmgmt_exception_vector_prolog_code
-#endif
-
-
-#if defined(ASM_BOOKE_DEC_VECTOR)
- PUBLIC_VAR(pit_exception_vector_prolog_code)
-
-SYM (pit_exception_vector_prolog_code):
- /*
- * let room for exception frame
- */
- stwu r1, - (EXCEPTION_FRAME_END)(r1)
- stw r4, GPR4_OFFSET(r1)
- li r4, ASM_BOOKE_DEC_VECTOR
- ba shared_raw_irq_code_entry
-
- PUBLIC_VAR (pit_exception_vector_prolog_code_size)
-
- pit_exception_vector_prolog_code_size = . - pit_exception_vector_prolog_code
-#endif
-
-#if defined(ASM_BOOKE_FIT_VECTOR)
- PUBLIC_VAR(fit_exception_vector_prolog_code)
-
-SYM (fit_exception_vector_prolog_code):
- /*
- * let room for exception frame
- */
- stwu r1, - (EXCEPTION_FRAME_END)(r1)
- stw r4, GPR4_OFFSET(r1)
- li r4, ASM_BOOKE_FIT_VECTOR
- ba shared_raw_irq_code_entry
-
- PUBLIC_VAR (fit_exception_vector_prolog_code_size)
-
- fit_exception_vector_prolog_code_size = . - fit_exception_vector_prolog_code
-#endif
-
- PUBLIC_VAR(external_exception_vector_prolog_code)
-
-#if defined(ASM_EXT_VECTOR)
-SYM (external_exception_vector_prolog_code):
- /*
- * let room for exception frame
- */
- stwu r1, - (EXCEPTION_FRAME_END)(r1)
- stw r4, GPR4_OFFSET(r1)
- li r4, ASM_EXT_VECTOR
- ba shared_raw_irq_code_entry
-
- PUBLIC_VAR (external_exception_vector_prolog_code_size)
-
- external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
-#endif
-
- PUBLIC_VAR(shared_raw_irq_code_entry)
- PUBLIC_VAR(C_dispatch_irq_handler)
-
- .p2align 5
-SYM (shared_raw_irq_code_entry):
- /*
- * Entry conditions :
- * Registers already saved : R1, R4
- * R1 : points to a location with enough room for the
- * interrupt frame
- * R4 : vector number
- */
- /*
- * Save SRR0/SRR1 As soon As possible as it is the minimal needed
- * to reenable exception processing
- */
- stw r0, GPR0_OFFSET(r1)
- /* PPC EABI: R2 is reserved (pointer to short data .sdata2) - we won't touch it
- * but we still save/restore it, just in case...
- */
- stw r2, GPR2_OFFSET(r1)
- stw r3, GPR3_OFFSET(r1)
-
- mfsrr0 r0
- mfsrr1 r3
-
- stw r0, SRR0_FRAME_OFFSET(r1)
- stw r3, SRR1_FRAME_OFFSET(r1)
-
- /*
- * Enable data and instruction address translation, exception recovery
- * by merging original bits from saved SRR1.
- */
- li r0, MSR_EXC_BITS
- and r0, r0, r3
- mfmsr r3
- or r3, r3, r0
- mtmsr r3
- SYNC
- /*
- * Push C scratch registers on the current stack. It may
- * actually be the thread stack or the interrupt stack.
- * Anyway we have to make it in order to be able to call C/C++
- * functions. Depending on the nesting interrupt level, we will
- * switch to the right stack later.
- */
- stw r5, GPR5_OFFSET(r1)
- stw r6, GPR6_OFFSET(r1)
- stw r7, GPR7_OFFSET(r1)
- stw r8, GPR8_OFFSET(r1)
- stw r9, GPR9_OFFSET(r1)
- stw r10, GPR10_OFFSET(r1)
- stw r11, GPR11_OFFSET(r1)
- stw r12, GPR12_OFFSET(r1)
- stw r13, GPR13_OFFSET(r1)
-
- mfcr r5
- mfctr r6
- mfxer r7
- mflr r8
-
- stw r5, EXC_CR_OFFSET(r1)
- stw r6, EXC_CTR_OFFSET(r1)
- stw r7, EXC_XER_OFFSET(r1)
- stw r8, EXC_LR_OFFSET(r1)
-
- /*
- * Add some non volatile registers to store information
- * that will be used when returning from C handler
- */
- stw r14, GPR14_OFFSET(r1)
- stw r15, GPR15_OFFSET(r1)
- /*
- * save current stack pointer location in R14
- */
- addi r14, r1, 0
- /*
- * store part of _Thread_Dispatch_disable_level address in R15
- */
- addis r15,0, _Thread_Dispatch_disable_level@ha
-#if BROKEN_ISR_NEST_LEVEL
- /*
- * Get current nesting level in R3
- */
- mfspr r3, SPRG0
-#else
- /*
- * Retrieve current nesting level from _ISR_Nest_level
- */
- lis r7, _ISR_Nest_level@ha
- lwz r3, _ISR_Nest_level@l(r7)
-#endif
- /*
- * Check if stack switch is necessary
- */
- cmpwi r3,0
- bne nested
- mfspr r1, SPRG1
-
-nested:
- /*
- * Start Incrementing nesting level in R3
- */
- addi r3,r3,1
- /*
- * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
- */
- lwz r6,_Thread_Dispatch_disable_level@l(r15)
-#if BROKEN_ISR_NEST_LEVEL
- /*
- * Store new nesting level in SPRG0
- */
- mtspr SPRG0, r3
-#else
- /* store new nesting level in _ISR_Nest_level */
- stw r3, _ISR_Nest_level@l(r7)
-#endif
-
- addi r6, r6, 1
- mfmsr r5
- /*
- * store new _Thread_Dispatch_disable_level value
- */
- stw r6, _Thread_Dispatch_disable_level@l(r15)
- /*
- * We are now running on the interrupt stack. External and decrementer
- * exceptions are still disabled. I see no purpose trying to optimize
- * further assembler code.
- */
- /*
- * Call C exception handler for decrementer Interrupt frame is passed just
- * in case...
- */
- addi r3, r14, 0x8
- /* clear CR[6] to make sure no varargs fn callee assumes there are FP args passed */
- crxor 6,6,6
- bl C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
- /*
- * start decrementing nesting level. Note : do not test result against 0
- * value as an easy exit condition because if interrupt nesting level > 1
- * then _Thread_Dispatch_disable_level > 1
- */
-#if BROKEN_ISR_NEST_LEVEL
- mfspr r4, SPRG0
-#else
- lis r7, _ISR_Nest_level@ha
- lwz r4, _ISR_Nest_level@l(r7)
-#endif
- /*
- * start decrementing _Thread_Dispatch_disable_level
- */
- lwz r3,_Thread_Dispatch_disable_level@l(r15)
- addi r4, r4, -1 /* Continue decrementing nesting level */
- addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
-#if BROKEN_ISR_NEST_LEVEL
- mtspr SPRG0, r4 /* End decrementing nesting level */
-#else
- stw r4, _ISR_Nest_level@l(r7) /* End decrementing nesting level */
-#endif
- stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
- cmpwi r3, 0
- /*
- * switch back to original stack (done here just optimize registers
- * contention. Could have been done before...)
- */
- addi r1, r14, 0
- bne easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
- /*
- * Here we are running again on the thread system stack.
- * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
- * Interrupt are still disabled. Time to check if scheduler request to
- * do something with the current thread...
- */
- addis r4, 0, _Context_Switch_necessary@ha
- lbz r5, _Context_Switch_necessary@l(r4)
- cmpwi r5, 0
- bne switch
-
- addis r6, 0, _ISR_Signals_to_thread_executing@ha
- lbz r7, _ISR_Signals_to_thread_executing@l(r6)
- cmpwi r7, 0
- li r8, 0
- beq easy_exit
- stb r8, _ISR_Signals_to_thread_executing@l(r6)
- /*
- * going to call _ThreadProcessSignalsFromIrq
- * Push a complete exception like frame...
- */
- stmw r16, GPR16_OFFSET(r1)
- addi r3, r1, 0x8
- /*
- * compute SP at exception entry
- */
- addi r4, r1, EXCEPTION_FRAME_END
- /*
- * store it at the right place
- */
- stw r4, GPR1_OFFSET(r1)
- /*
- * Call High Level signal handling code
- */
- bl _ThreadProcessSignalsFromIrq
- /*
- * start restoring exception like frame
- */
- lwz r31, EXC_CTR_OFFSET(r1)
- lwz r30, EXC_XER_OFFSET(r1)
- lwz r29, EXC_CR_OFFSET(r1)
- lwz r28, EXC_LR_OFFSET(r1)
-
- mtctr r31
- mtxer r30
- mtcr r29
- mtlr r28
-
- lmw r4, GPR4_OFFSET(r1)
- lwz r2, GPR2_OFFSET(r1)
- lwz r0, GPR0_OFFSET(r1)
-
- /*
- * Disable data and instruction translation. Make path non recoverable...
- */
- li r0, MSR_EXC_BITS
- mfmsr r3
- andc r3, r3, r0
- mtmsr r3
- SYNC
- /*
- * Restore rfi related settings
- */
-
- lwz r3, SRR1_FRAME_OFFSET(r1)
- mtsrr1 r3
- lwz r3, SRR0_FRAME_OFFSET(r1)
- mtsrr0 r3
-
- lwz r3, GPR3_OFFSET(r1)
- addi r1,r1, EXCEPTION_FRAME_END
- SYNC
- rfi
-
-switch:
- bl SYM (_Thread_Dispatch)
-
-easy_exit:
- /*
- * start restoring interrupt frame
- */
- lwz r3, EXC_CTR_OFFSET(r1)
- lwz r4, EXC_XER_OFFSET(r1)
- lwz r5, EXC_CR_OFFSET(r1)
- lwz r6, EXC_LR_OFFSET(r1)
-
- mtctr r3
- mtxer r4
- mtcr r5
- mtlr r6
-
- lwz r15, GPR15_OFFSET(r1)
- lwz r14, GPR14_OFFSET(r1)
- lwz r13, GPR13_OFFSET(r1)
- lwz r12, GPR12_OFFSET(r1)
- lwz r11, GPR11_OFFSET(r1)
- lwz r10, GPR10_OFFSET(r1)
- lwz r9, GPR9_OFFSET(r1)
- lwz r8, GPR8_OFFSET(r1)
- lwz r7, GPR7_OFFSET(r1)
- lwz r6, GPR6_OFFSET(r1)
- lwz r5, GPR5_OFFSET(r1)
-
- /*
- * Disable nested exception processing, data and instruction
- * translation.
- */
- li r0, MSR_EXC_BITS
- mfmsr r3
- andc r3, r3, r0
- mtmsr r3
- SYNC
- /*
- * Restore rfi related settings
- */
-
- lwz r4, SRR1_FRAME_OFFSET(r1)
- lwz r3, SRR0_FRAME_OFFSET(r1)
- lwz r2, GPR2_OFFSET(r1)
- lwz r0, GPR0_OFFSET(r1)
-
- mtsrr1 r4
- mtsrr0 r3
- lwz r4, GPR4_OFFSET(r1)
- lwz r3, GPR3_OFFSET(r1)
- addi r1,r1, EXCEPTION_FRAME_END
- SYNC
- rfi