Merge tag 'for-linus-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw...
[linux-2.6-microblaze.git] / arch / powerpc / kernel / head_40x.S
index 067ae13..e1360b8 100644 (file)
@@ -89,7 +89,11 @@ _ENTRY(crit_srr0)
        .space  4
 _ENTRY(crit_srr1)
        .space  4
-_ENTRY(saved_ksp_limit)
+_ENTRY(crit_r1)
+       .space  4
+_ENTRY(crit_dear)
+       .space  4
+_ENTRY(crit_esr)
        .space  4
 
 /*
@@ -100,50 +104,61 @@ _ENTRY(saved_ksp_limit)
  * Instead we use a couple of words of memory at low physical addresses.
  * This is OK since we don't support SMP on these processors.
  */
-.macro CRITICAL_EXCEPTION_PROLOG
+.macro CRITICAL_EXCEPTION_PROLOG trapno name
        stw     r10,crit_r10@l(0)       /* save two registers to work with */
        stw     r11,crit_r11@l(0)
        mfspr   r10,SPRN_SRR0
        mfspr   r11,SPRN_SRR1
        stw     r10,crit_srr0@l(0)
        stw     r11,crit_srr1@l(0)
+       mfspr   r10,SPRN_DEAR
+       mfspr   r11,SPRN_ESR
+       stw     r10,crit_dear@l(0)
+       stw     r11,crit_esr@l(0)
        mfcr    r10                     /* save CR in r10 for now          */
        mfspr   r11,SPRN_SRR3           /* check whether user or kernel    */
        andi.   r11,r11,MSR_PR
-       lis     r11,critirq_ctx@ha
-       tophys(r11,r11)
-       lwz     r11,critirq_ctx@l(r11)
+       lis     r11,(critirq_ctx-PAGE_OFFSET)@ha
+       lwz     r11,(critirq_ctx-PAGE_OFFSET)@l(r11)
        beq     1f
        /* COMING FROM USER MODE */
        mfspr   r11,SPRN_SPRG_THREAD    /* if from user, start at top of   */
        lwz     r11,TASK_STACK-THREAD(r11) /* this thread's kernel stack */
-1:     addi    r11,r11,THREAD_SIZE-INT_FRAME_SIZE /* Alloc an excpt frm  */
-       tophys(r11,r11)
+1:     stw     r1,crit_r1@l(0)
+       addi    r1,r11,THREAD_SIZE-INT_FRAME_SIZE /* Alloc an excpt frm  */
+       LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)) /* re-enable MMU */
+       mtspr   SPRN_SRR1, r11
+       lis     r11, 1f@h
+       ori     r11, r11, 1f@l
+       mtspr   SPRN_SRR0, r11
+       rfi
+
+       .text
+1:
+\name\()_virt:
+       lwz     r11,crit_r1@l(0)
+       stw     r11,GPR1(r1)
+       stw     r11,0(r1)
+       mr      r11,r1
        stw     r10,_CCR(r11)           /* save various registers          */
        stw     r12,GPR12(r11)
        stw     r9,GPR9(r11)
        mflr    r10
        stw     r10,_LINK(r11)
-       lwz     r10,crit_r10@l(0)
-       lwz     r12,crit_r11@l(0)
+       lis     r9,PAGE_OFFSET@ha
+       lwz     r10,crit_r10@l(r9)
+       lwz     r12,crit_r11@l(r9)
        stw     r10,GPR10(r11)
        stw     r12,GPR11(r11)
-       mfspr   r12,SPRN_DEAR           /* save DEAR and ESR in the frame  */
+       lwz     r12,crit_dear@l(r9)
+       lwz     r9,crit_esr@l(r9)
        stw     r12,_DEAR(r11)          /* since they may have had stuff   */
-       mfspr   r9,SPRN_ESR             /* in them at the point where the  */
        stw     r9,_ESR(r11)            /* exception was taken             */
        mfspr   r12,SPRN_SRR2
-       stw     r1,GPR1(r11)
        mfspr   r9,SPRN_SRR3
-       stw     r1,0(r11)
-       tovirt(r1,r11)
        rlwinm  r9,r9,0,14,12           /* clear MSR_WE (necessary?)       */
-       stw     r0,GPR0(r11)
-       lis     r10, STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
-       addi    r10, r10, STACK_FRAME_REGS_MARKER@l
-       stw     r10, 8(r11)
-       SAVE_4GPRS(3, r11)
-       SAVE_2GPRS(7, r11)
+       COMMON_EXCEPTION_PROLOG_END \trapno + 2
+_ASM_NOKPROBE_SYMBOL(\name\()_virt)
 .endm
 
        /*
@@ -164,10 +179,10 @@ _ENTRY(saved_ksp_limit)
  */
 #define CRITICAL_EXCEPTION(n, label, hdlr)                     \
        START_EXCEPTION(n, label);                              \
-       CRITICAL_EXCEPTION_PROLOG;                              \
-       addi    r3,r1,STACK_FRAME_OVERHEAD;                     \
-       EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
-                         crit_transfer_to_handler, ret_from_crit_exc)
+       CRITICAL_EXCEPTION_PROLOG n label;                              \
+       prepare_transfer_to_handler;                            \
+       bl      hdlr;                                           \
+       b       ret_from_crit_exc
 
 /*
  * 0x0100 - Critical Interrupt Exception
@@ -187,69 +202,67 @@ _ENTRY(saved_ksp_limit)
  * if they can't resolve the lightweight TLB fault.
  */
        START_EXCEPTION(0x0300, DataStorage)
-       EXCEPTION_PROLOG
-       mfspr   r5, SPRN_ESR            /* Grab the ESR, save it */
-       stw     r5, _ESR(r11)
-       mfspr   r4, SPRN_DEAR           /* Grab the DEAR, save it */
-       stw     r4, _DEAR(r11)
-       EXC_XFER_LITE(0x300, handle_page_fault)
+       EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1
+       prepare_transfer_to_handler
+       bl      do_page_fault
+       b       interrupt_return
 
 /*
  * 0x0400 - Instruction Storage Exception
  * This is caused by a fetch from non-execute or guarded pages.
  */
        START_EXCEPTION(0x0400, InstructionAccess)
-       EXCEPTION_PROLOG
+       EXCEPTION_PROLOG 0x400 InstructionAccess
        li      r5,0
        stw     r5, _ESR(r11)           /* Zero ESR */
        stw     r12, _DEAR(r11)         /* SRR0 as DEAR */
-       EXC_XFER_LITE(0x400, handle_page_fault)
+       prepare_transfer_to_handler
+       bl      do_page_fault
+       b       interrupt_return
 
 /* 0x0500 - External Interrupt Exception */
-       EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
+       EXCEPTION(0x0500, HardwareInterrupt, do_IRQ)
 
 /* 0x0600 - Alignment Exception */
        START_EXCEPTION(0x0600, Alignment)
-       EXCEPTION_PROLOG
-       mfspr   r4,SPRN_DEAR            /* Grab the DEAR and save it */
-       stw     r4,_DEAR(r11)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       EXC_XFER_STD(0x600, alignment_exception)
+       EXCEPTION_PROLOG 0x600 Alignment handle_dar_dsisr=1
+       prepare_transfer_to_handler
+       bl      alignment_exception
+       REST_NVGPRS(r1)
+       b       interrupt_return
 
 /* 0x0700 - Program Exception */
        START_EXCEPTION(0x0700, ProgramCheck)
-       EXCEPTION_PROLOG
-       mfspr   r4,SPRN_ESR             /* Grab the ESR and save it */
-       stw     r4,_ESR(r11)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       EXC_XFER_STD(0x700, program_check_exception)
+       EXCEPTION_PROLOG 0x700 ProgramCheck handle_dar_dsisr=1
+       prepare_transfer_to_handler
+       bl      program_check_exception
+       REST_NVGPRS(r1)
+       b       interrupt_return
 
-       EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_STD)
+       EXCEPTION(0x0800, Trap_08, unknown_exception)
+       EXCEPTION(0x0900, Trap_09, unknown_exception)
+       EXCEPTION(0x0A00, Trap_0A, unknown_exception)
+       EXCEPTION(0x0B00, Trap_0B, unknown_exception)
 
 /* 0x0C00 - System Call Exception */
        START_EXCEPTION(0x0C00, SystemCall)
        SYSCALL_ENTRY   0xc00
 /*     Trap_0D is commented out to get more space for system call exception */
 
-/*     EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD) */
-       EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_STD)
+/*     EXCEPTION(0x0D00, Trap_0D, unknown_exception) */
+       EXCEPTION(0x0E00, Trap_0E, unknown_exception)
+       EXCEPTION(0x0F00, Trap_0F, unknown_exception)
 
 /* 0x1000 - Programmable Interval Timer (PIT) Exception */
-       . = 0x1000
+       START_EXCEPTION(0x1000, DecrementerTrap)
        b Decrementer
 
-/* 0x1010 - Fixed Interval Timer (FIT) Exception
-*/
-       . = 0x1010
+/* 0x1010 - Fixed Interval Timer (FIT) Exception */
+       START_EXCEPTION(0x1010, FITExceptionTrap)
        b FITException
 
-/* 0x1020 - Watchdog Timer (WDT) Exception
-*/
-       . = 0x1020
+/* 0x1020 - Watchdog Timer (WDT) Exception */
+       START_EXCEPTION(0x1020, WDTExceptionTrap)
        b WDTException
 
 /* 0x1100 - Data TLB Miss Exception
@@ -413,19 +426,19 @@ _ENTRY(saved_ksp_limit)
        mfspr   r10, SPRN_SPRG_SCRATCH5
        b       InstructionAccess
 
-       EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_STD)
+       EXCEPTION(0x1300, Trap_13, unknown_exception)
+       EXCEPTION(0x1400, Trap_14, unknown_exception)
+       EXCEPTION(0x1500, Trap_15, unknown_exception)
+       EXCEPTION(0x1600, Trap_16, unknown_exception)
+       EXCEPTION(0x1700, Trap_17, unknown_exception)
+       EXCEPTION(0x1800, Trap_18, unknown_exception)
+       EXCEPTION(0x1900, Trap_19, unknown_exception)
+       EXCEPTION(0x1A00, Trap_1A, unknown_exception)
+       EXCEPTION(0x1B00, Trap_1B, unknown_exception)
+       EXCEPTION(0x1C00, Trap_1C, unknown_exception)
+       EXCEPTION(0x1D00, Trap_1D, unknown_exception)
+       EXCEPTION(0x1E00, Trap_1E, unknown_exception)
+       EXCEPTION(0x1F00, Trap_1F, unknown_exception)
 
 /* Check for a single step debug exception while in an exception
  * handler before state has been saved.  This is to catch the case
@@ -442,7 +455,7 @@ _ENTRY(saved_ksp_limit)
  */
        /* 0x2000 - Debug Exception */
        START_EXCEPTION(0x2000, DebugTrap)
-       CRITICAL_EXCEPTION_PROLOG
+       CRITICAL_EXCEPTION_PROLOG 0x2000 DebugTrap
 
        /*
         * If this is a single step or branch-taken exception in an
@@ -484,32 +497,35 @@ _ENTRY(saved_ksp_limit)
        /* continue normal handling for a critical exception... */
 2:     mfspr   r4,SPRN_DBSR
        stw     r4,_ESR(r11)            /* DebugException takes DBSR in _ESR */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       EXC_XFER_TEMPLATE(DebugException, 0x2002, \
-               (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
-               crit_transfer_to_handler, ret_from_crit_exc)
+       prepare_transfer_to_handler
+       bl      DebugException
+       b       ret_from_crit_exc
 
        /* Programmable Interval Timer (PIT) Exception. (from 0x1000) */
+       __HEAD
 Decrementer:
-       EXCEPTION_PROLOG
+       EXCEPTION_PROLOG 0x1000 Decrementer
        lis     r0,TSR_PIS@h
        mtspr   SPRN_TSR,r0             /* Clear the PIT exception */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       EXC_XFER_LITE(0x1000, timer_interrupt)
+       prepare_transfer_to_handler
+       bl      timer_interrupt
+       b       interrupt_return
 
        /* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
+       __HEAD
 FITException:
-       EXCEPTION_PROLOG
-       addi    r3,r1,STACK_FRAME_OVERHEAD;
-       EXC_XFER_STD(0x1010, unknown_exception)
+       EXCEPTION_PROLOG 0x1010 FITException
+       prepare_transfer_to_handler
+       bl      unknown_exception
+       b       interrupt_return
 
        /* Watchdog Timer (WDT) Exception. (from 0x1020) */
+       __HEAD
 WDTException:
-       CRITICAL_EXCEPTION_PROLOG;
-       addi    r3,r1,STACK_FRAME_OVERHEAD;
-       EXC_XFER_TEMPLATE(WatchdogException, 0x1020+2,
-                         (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)),
-                         crit_transfer_to_handler, ret_from_crit_exc)
+       CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException
+       prepare_transfer_to_handler
+       bl      WatchdogException
+       b       ret_from_crit_exc
 
 /* Other PowerPC processors, namely those derived from the 6xx-series
  * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
@@ -517,6 +533,7 @@ WDTException:
  * reserved.
  */
 
+       __HEAD
        /* Damn, I came up one instruction too many to fit into the
         * exception space :-).  Both the instruction and data TLB
         * miss get to this point to load the TLB.