home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / powerpc / include / asm / exception.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  8.9 KB  |  280 lines

  1. #ifndef _ASM_POWERPC_EXCEPTION_H
  2. #define _ASM_POWERPC_EXCEPTION_H
  3. /*
  4.  * Extracted from head_64.S
  5.  *
  6.  *  PowerPC version
  7.  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  8.  *
  9.  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  10.  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
  11.  *  Adapted for Power Macintosh by Paul Mackerras.
  12.  *  Low-level exception handlers and MMU support
  13.  *  rewritten by Paul Mackerras.
  14.  *    Copyright (C) 1996 Paul Mackerras.
  15.  *
  16.  *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
  17.  *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
  18.  *
  19.  *  This file contains the low-level support and setup for the
  20.  *  PowerPC-64 platform, including trap and interrupt dispatch.
  21.  *
  22.  *  This program is free software; you can redistribute it and/or
  23.  *  modify it under the terms of the GNU General Public License
  24.  *  as published by the Free Software Foundation; either version
  25.  *  2 of the License, or (at your option) any later version.
  26.  */
  27. /*
  28.  * The following macros define the code that appears as
  29.  * the prologue to each of the exception handlers.  They
  30.  * are split into two parts to allow a single kernel binary
  31.  * to be used for pSeries and iSeries.
  32.  *
  33.  * We make as much of the exception code common between native
  34.  * exception handlers (including pSeries LPAR) and iSeries LPAR
  35.  * implementations as possible.
  36.  */
  37.  
  38. #define EX_R9        0
  39. #define EX_R10        8
  40. #define EX_R11        16
  41. #define EX_R12        24
  42. #define EX_R13        32
  43. #define EX_SRR0        40
  44. #define EX_DAR        48
  45. #define EX_DSISR    56
  46. #define EX_CCR        60
  47. #define EX_R3        64
  48. #define EX_LR        72
  49.  
  50. /*
  51.  * We're short on space and time in the exception prolog, so we can't
  52.  * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
  53.  * low halfword of the address, but for Kdump we need the whole low
  54.  * word.
  55.  */
  56. #define LOAD_HANDLER(reg, label)                    \
  57.     addi    reg,reg,(label)-_stext;    /* virt addr of handler ... */
  58.  
  59. #define EXCEPTION_PROLOG_1(area)                \
  60.     mfspr    r13,SPRN_SPRG3;        /* get paca address into r13 */    \
  61.     std    r9,area+EX_R9(r13);    /* save r9 - r12 */        \
  62.     std    r10,area+EX_R10(r13);                    \
  63.     std    r11,area+EX_R11(r13);                    \
  64.     std    r12,area+EX_R12(r13);                    \
  65.     mfspr    r9,SPRN_SPRG1;                        \
  66.     std    r9,area+EX_R13(r13);                    \
  67.     mfcr    r9
  68.  
  69. #define EXCEPTION_PROLOG_PSERIES(area, label)                \
  70.     EXCEPTION_PROLOG_1(area);                    \
  71.     ld    r12,PACAKBASE(r13);    /* get high part of &label */    \
  72.     ld    r10,PACAKMSR(r13);    /* get MSR value for kernel */    \
  73.     mfspr    r11,SPRN_SRR0;        /* save SRR0 */            \
  74.     LOAD_HANDLER(r12,label)                        \
  75.     mtspr    SPRN_SRR0,r12;                        \
  76.     mfspr    r12,SPRN_SRR1;        /* and SRR1 */            \
  77.     mtspr    SPRN_SRR1,r10;                        \
  78.     rfid;                                \
  79.     b    .    /* prevent speculative execution */
  80.  
  81. /*
  82.  * The common exception prolog is used for all except a few exceptions
  83.  * such as a segment miss on a kernel address.  We have to be prepared
  84.  * to take another exception from the point where we first touch the
  85.  * kernel stack onwards.
  86.  *
  87.  * On entry r13 points to the paca, r9-r13 are saved in the paca,
  88.  * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
  89.  * SRR1, and relocation is on.
  90.  */
  91. #define EXCEPTION_PROLOG_COMMON(n, area)                   \
  92.     andi.    r10,r12,MSR_PR;        /* See if coming from user    */ \
  93.     mr    r10,r1;            /* Save r1            */ \
  94.     subi    r1,r1,INT_FRAME_SIZE;    /* alloc frame on kernel stack    */ \
  95.     beq-    1f;                               \
  96.     ld    r1,PACAKSAVE(r13);    /* kernel stack to use        */ \
  97. 1:    cmpdi    cr1,r1,0;        /* check if r1 is in userspace    */ \
  98.     bge-    cr1,2f;            /* abort if it is        */ \
  99.     b    3f;                               \
  100. 2:    li    r1,(n);            /* will be reloaded later    */ \
  101.     sth    r1,PACA_TRAP_SAVE(r13);                       \
  102.     b    bad_stack;                           \
  103. 3:    std    r9,_CCR(r1);        /* save CR in stackframe    */ \
  104.     std    r11,_NIP(r1);        /* save SRR0 in stackframe    */ \
  105.     std    r12,_MSR(r1);        /* save SRR1 in stackframe    */ \
  106.     std    r10,0(r1);        /* make stack chain pointer    */ \
  107.     std    r0,GPR0(r1);        /* save r0 in stackframe    */ \
  108.     std    r10,GPR1(r1);        /* save r1 in stackframe    */ \
  109.     ACCOUNT_CPU_USER_ENTRY(r9, r10);                   \
  110.     std    r2,GPR2(r1);        /* save r2 in stackframe    */ \
  111.     SAVE_4GPRS(3, r1);        /* save r3 - r6 in stackframe    */ \
  112.     SAVE_2GPRS(7, r1);        /* save r7, r8 in stackframe    */ \
  113.     ld    r9,area+EX_R9(r13);    /* move r9, r10 to stackframe    */ \
  114.     ld    r10,area+EX_R10(r13);                       \
  115.     std    r9,GPR9(r1);                           \
  116.     std    r10,GPR10(r1);                           \
  117.     ld    r9,area+EX_R11(r13);    /* move r11 - r13 to stackframe    */ \
  118.     ld    r10,area+EX_R12(r13);                       \
  119.     ld    r11,area+EX_R13(r13);                       \
  120.     std    r9,GPR11(r1);                           \
  121.     std    r10,GPR12(r1);                           \
  122.     std    r11,GPR13(r1);                           \
  123.     ld    r2,PACATOC(r13);    /* get kernel TOC into r2    */ \
  124.     mflr    r9;            /* save LR in stackframe    */ \
  125.     std    r9,_LINK(r1);                           \
  126.     mfctr    r10;            /* save CTR in stackframe    */ \
  127.     std    r10,_CTR(r1);                           \
  128.     lbz    r10,PACASOFTIRQEN(r13);                   \
  129.     mfspr    r11,SPRN_XER;        /* save XER in stackframe    */ \
  130.     std    r10,SOFTE(r1);                           \
  131.     std    r11,_XER(r1);                           \
  132.     li    r9,(n)+1;                           \
  133.     std    r9,_TRAP(r1);        /* set trap number        */ \
  134.     li    r10,0;                               \
  135.     ld    r11,exception_marker@toc(r2);                   \
  136.     std    r10,RESULT(r1);        /* clear regs->result        */ \
  137.     std    r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame    */
  138.  
  139. /*
  140.  * Exception vectors.
  141.  */
  142. #define STD_EXCEPTION_PSERIES(n, label)            \
  143.     . = n;                        \
  144.     .globl label##_pSeries;                \
  145. label##_pSeries:                    \
  146.     HMT_MEDIUM;                    \
  147.     mtspr    SPRN_SPRG1,r13;        /* save r13 */    \
  148.     EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
  149.  
  150. #define HSTD_EXCEPTION_PSERIES(n, label)        \
  151.     . = n;                        \
  152.     .globl label##_pSeries;                \
  153. label##_pSeries:                    \
  154.     HMT_MEDIUM;                    \
  155.     mtspr    SPRN_SPRG1,r20;        /* save r20 */    \
  156.     mfspr    r20,SPRN_HSRR0;        /* copy HSRR0 to SRR0 */ \
  157.     mtspr    SPRN_SRR0,r20;                \
  158.     mfspr    r20,SPRN_HSRR1;        /* copy HSRR0 to SRR0 */ \
  159.     mtspr    SPRN_SRR1,r20;                \
  160.     mfspr    r20,SPRN_SPRG1;        /* restore r20 */ \
  161.     mtspr    SPRN_SPRG1,r13;        /* save r13 */    \
  162.     EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
  163.  
  164.  
  165. #define MASKABLE_EXCEPTION_PSERIES(n, label)                \
  166.     . = n;                                \
  167.     .globl label##_pSeries;                        \
  168. label##_pSeries:                            \
  169.     HMT_MEDIUM;                            \
  170.     mtspr    SPRN_SPRG1,r13;        /* save r13 */            \
  171.     mfspr    r13,SPRN_SPRG3;        /* get paca address into r13 */    \
  172.     std    r9,PACA_EXGEN+EX_R9(r13);    /* save r9, r10 */    \
  173.     std    r10,PACA_EXGEN+EX_R10(r13);                \
  174.     lbz    r10,PACASOFTIRQEN(r13);                    \
  175.     mfcr    r9;                            \
  176.     cmpwi    r10,0;                            \
  177.     beq    masked_interrupt;                    \
  178.     mfspr    r10,SPRN_SPRG1;                        \
  179.     std    r10,PACA_EXGEN+EX_R13(r13);                \
  180.     std    r11,PACA_EXGEN+EX_R11(r13);                \
  181.     std    r12,PACA_EXGEN+EX_R12(r13);                \
  182.     ld    r12,PACAKBASE(r13);    /* get high part of &label */    \
  183.     ld    r10,PACAKMSR(r13);    /* get MSR value for kernel */    \
  184.     mfspr    r11,SPRN_SRR0;        /* save SRR0 */            \
  185.     LOAD_HANDLER(r12,label##_common)                \
  186.     mtspr    SPRN_SRR0,r12;                        \
  187.     mfspr    r12,SPRN_SRR1;        /* and SRR1 */            \
  188.     mtspr    SPRN_SRR1,r10;                        \
  189.     rfid;                                \
  190.     b    .    /* prevent speculative execution */
  191.  
  192. #ifdef CONFIG_PPC_ISERIES
  193. #define DISABLE_INTS                \
  194.     li    r11,0;                \
  195.     stb    r11,PACASOFTIRQEN(r13);        \
  196. BEGIN_FW_FTR_SECTION;                \
  197.     stb    r11,PACAHARDIRQEN(r13);        \
  198. END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);    \
  199.     TRACE_DISABLE_INTS;            \
  200. BEGIN_FW_FTR_SECTION;                \
  201.     mfmsr    r10;                \
  202.     ori    r10,r10,MSR_EE;            \
  203.     mtmsrd    r10,1;                \
  204. END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
  205. #else
  206. #define DISABLE_INTS                \
  207.     li    r11,0;                \
  208.     stb    r11,PACASOFTIRQEN(r13);        \
  209.     stb    r11,PACAHARDIRQEN(r13);        \
  210.     TRACE_DISABLE_INTS
  211. #endif /* CONFIG_PPC_ISERIES */
  212.  
  213. #define ENABLE_INTS                \
  214.     ld    r12,_MSR(r1);            \
  215.     mfmsr    r11;                \
  216.     rlwimi    r11,r12,0,MSR_EE;        \
  217.     mtmsrd    r11,1
  218.  
  219. #define STD_EXCEPTION_COMMON(trap, label, hdlr)        \
  220.     .align    7;                    \
  221.     .globl label##_common;                \
  222. label##_common:                        \
  223.     EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);    \
  224.     DISABLE_INTS;                    \
  225.     bl    .save_nvgprs;                \
  226.     addi    r3,r1,STACK_FRAME_OVERHEAD;        \
  227.     bl    hdlr;                    \
  228.     b    .ret_from_except
  229.  
  230. /*
  231.  * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
  232.  * in the idle task and therefore need the special idle handling.
  233.  */
  234. #define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr)    \
  235.     .align    7;                    \
  236.     .globl label##_common;                \
  237. label##_common:                        \
  238.     EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);    \
  239.     FINISH_NAP;                    \
  240.     DISABLE_INTS;                    \
  241.     bl    .save_nvgprs;                \
  242.     addi    r3,r1,STACK_FRAME_OVERHEAD;        \
  243.     bl    hdlr;                    \
  244.     b    .ret_from_except
  245.  
  246. #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)    \
  247.     .align    7;                    \
  248.     .globl label##_common;                \
  249. label##_common:                        \
  250.     EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);    \
  251.     FINISH_NAP;                    \
  252.     DISABLE_INTS;                    \
  253. BEGIN_FTR_SECTION                    \
  254.     bl    .ppc64_runlatch_on;            \
  255. END_FTR_SECTION_IFSET(CPU_FTR_CTRL)            \
  256.     addi    r3,r1,STACK_FRAME_OVERHEAD;        \
  257.     bl    hdlr;                    \
  258.     b    .ret_from_except_lite
  259.  
  260. /*
  261.  * When the idle code in power4_idle puts the CPU into NAP mode,
  262.  * it has to do so in a loop, and relies on the external interrupt
  263.  * and decrementer interrupt entry code to get it out of the loop.
  264.  * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
  265.  * to signal that it is in the loop and needs help to get out.
  266.  */
  267. #ifdef CONFIG_PPC_970_NAP
  268. #define FINISH_NAP                \
  269. BEGIN_FTR_SECTION                \
  270.     clrrdi    r11,r1,THREAD_SHIFT;        \
  271.     ld    r9,TI_LOCAL_FLAGS(r11);        \
  272.     andi.    r10,r9,_TLF_NAPPING;        \
  273.     bnel    power4_fixup_nap;        \
  274. END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
  275. #else
  276. #define FINISH_NAP
  277. #endif
  278.  
  279. #endif    /* _ASM_POWERPC_EXCEPTION_H */
  280.