home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-mips / interrupt.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  5.0 KB  |  222 lines

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
  7.  * Copyright (C) 1996 by Paul M. Antoine
  8.  * Copyright (C) 1999 Silicon Graphics
  9.  * Copyright (C) 2000 MIPS Technologies, Inc.
  10.  */
  11. #ifndef _ASM_INTERRUPT_H
  12. #define _ASM_INTERRUPT_H
  13.  
  14. #include <asm/hazards.h>
  15.  
  16. __asm__ (
  17.     "    .macro    local_irq_enable                \n"
  18.     "    .set    push                        \n"
  19.     "    .set    reorder                        \n"
  20.     "    .set    noat                        \n"
  21. #ifdef CONFIG_MIPS_MT_SMTC
  22.     "    mfc0    $1, $2, 1    # SMTC - clear TCStatus.IXMT    \n"
  23.     "    ori    $1, 0x400                    \n"
  24.     "    xori    $1, 0x400                    \n"
  25.     "    mtc0    $1, $2, 1                    \n"
  26. #elif defined(CONFIG_CPU_MIPSR2)
  27.     "    ei                            \n"
  28. #else
  29.     "    mfc0    $1,$12                        \n"
  30.     "    ori    $1,0x1f                        \n"
  31.     "    xori    $1,0x1e                        \n"
  32.     "    mtc0    $1,$12                        \n"
  33. #endif
  34.     "    irq_enable_hazard                    \n"
  35.     "    .set    pop                        \n"
  36.     "    .endm");
  37.  
  38. static inline void local_irq_enable(void)
  39. {
  40.     __asm__ __volatile__(
  41.         "local_irq_enable"
  42.         : /* no outputs */
  43.         : /* no inputs */
  44.         : "memory");
  45. }
  46.  
  47. /*
  48.  * For cli() we have to insert nops to make sure that the new value
  49.  * has actually arrived in the status register before the end of this
  50.  * macro.
  51.  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  52.  * no nops at all.
  53.  */
  54. /*
  55.  * For TX49, operating only IE bit is not enough.
  56.  *
  57.  * If mfc0 $12 follows store and the mfc0 is last instruction of a
  58.  * page and fetching the next instruction causes TLB miss, the result
  59.  * of the mfc0 might wrongly contain EXL bit.
  60.  *
  61.  * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
  62.  *
  63.  * Workaround: mask EXL bit of the result or place a nop before mfc0.
  64.  */
  65. __asm__ (
  66.     "    .macro    local_irq_disable\n"
  67.     "    .set    push                        \n"
  68.     "    .set    noat                        \n"
  69. #ifdef CONFIG_MIPS_MT_SMTC
  70.     "    mfc0    $1, $2, 1                    \n"
  71.     "    ori    $1, 0x400                    \n"
  72.     "    .set    noreorder                    \n"
  73.     "    mtc0    $1, $2, 1                    \n"
  74. #elif defined(CONFIG_CPU_MIPSR2)
  75.     "    di                            \n"
  76. #else
  77.     "    mfc0    $1,$12                        \n"
  78.     "    ori    $1,0x1f                        \n"
  79.     "    xori    $1,0x1f                        \n"
  80.     "    .set    noreorder                    \n"
  81.     "    mtc0    $1,$12                        \n"
  82. #endif
  83.     "    irq_disable_hazard                    \n"
  84.     "    .set    pop                        \n"
  85.     "    .endm                            \n");
  86.  
  87. static inline void local_irq_disable(void)
  88. {
  89.     __asm__ __volatile__(
  90.         "local_irq_disable"
  91.         : /* no outputs */
  92.         : /* no inputs */
  93.         : "memory");
  94. }
  95.  
  96. __asm__ (
  97.     "    .macro    local_save_flags flags                \n"
  98.     "    .set    push                        \n"
  99.     "    .set    reorder                        \n"
  100. #ifdef CONFIG_MIPS_MT_SMTC
  101.     "    mfc0    \\flags, $2, 1                    \n"
  102. #else
  103.     "    mfc0    \\flags, $12                    \n"
  104. #endif
  105.     "    .set    pop                        \n"
  106.     "    .endm                            \n");
  107.  
  108. #define local_save_flags(x)                        \
  109. __asm__ __volatile__(                            \
  110.     "local_save_flags %0"                        \
  111.     : "=r" (x))
  112.  
  113. __asm__ (
  114.     "    .macro    local_irq_save result                \n"
  115.     "    .set    push                        \n"
  116.     "    .set    reorder                        \n"
  117.     "    .set    noat                        \n"
  118. #ifdef CONFIG_MIPS_MT_SMTC
  119.     "    mfc0    \\result, $2, 1                    \n"
  120.     "    ori    $1, \\result, 0x400                \n"
  121.     "    .set    noreorder                    \n"
  122.     "    mtc0    $1, $2, 1                    \n"
  123.     "    andi    \\result, \\result, 0x400            \n"
  124. #elif defined(CONFIG_CPU_MIPSR2)
  125.     "    di    \\result                    \n"
  126.     "    andi    \\result, 1                    \n"
  127. #else
  128.     "    mfc0    \\result, $12                    \n"
  129.     "    ori    $1, \\result, 0x1f                \n"
  130.     "    xori    $1, 0x1f                    \n"
  131.     "    .set    noreorder                    \n"
  132.     "    mtc0    $1, $12                        \n"
  133. #endif
  134.     "    irq_disable_hazard                    \n"
  135.     "    .set    pop                        \n"
  136.     "    .endm                            \n");
  137.  
  138. #define local_irq_save(x)                        \
  139. __asm__ __volatile__(                            \
  140.     "local_irq_save\t%0"                        \
  141.     : "=r" (x)                            \
  142.     : /* no inputs */                        \
  143.     : "memory")
  144.  
  145. __asm__ (
  146.     "    .macro    local_irq_restore flags                \n"
  147.     "    .set    push                        \n"
  148.     "    .set    noreorder                    \n"
  149.     "    .set    noat                        \n"
  150. #ifdef CONFIG_MIPS_MT_SMTC
  151.     "mfc0    $1, $2, 1                        \n"
  152.     "andi    \\flags, 0x400                        \n"
  153.     "ori    $1, 0x400                        \n"
  154.     "xori    $1, 0x400                        \n"
  155.     "or    \\flags, $1                        \n"
  156.     "mtc0    \\flags, $2, 1                        \n"
  157. #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
  158.     /*
  159.      * Slow, but doesn't suffer from a relativly unlikely race
  160.      * condition we're having since days 1.
  161.      */
  162.     "    beqz    \\flags, 1f                    \n"
  163.     "     di                            \n"
  164.     "    ei                            \n"
  165.     "1:                                \n"
  166. #elif defined(CONFIG_CPU_MIPSR2)
  167.     /*
  168.      * Fast, dangerous.  Life is fun, life is good.
  169.      */
  170.     "    mfc0    $1, $12                        \n"
  171.     "    ins    $1, \\flags, 0, 1                \n"
  172.     "    mtc0    $1, $12                        \n"
  173. #else
  174.     "    mfc0    $1, $12                        \n"
  175.     "    andi    \\flags, 1                    \n"
  176.     "    ori    $1, 0x1f                    \n"
  177.     "    xori    $1, 0x1f                    \n"
  178.     "    or    \\flags, $1                    \n"
  179.     "    mtc0    \\flags, $12                    \n"
  180. #endif
  181.     "    irq_disable_hazard                    \n"
  182.     "    .set    pop                        \n"
  183.     "    .endm                            \n");
  184.  
  185. #define local_irq_restore(flags)                    \
  186. do {                                    \
  187.     unsigned long __tmp1;                        \
  188.                                     \
  189.     __asm__ __volatile__(                        \
  190.         "local_irq_restore\t%0"                    \
  191.         : "=r" (__tmp1)                        \
  192.         : "0" (flags)                        \
  193.         : "memory");                        \
  194. } while(0)
  195.  
  196. static inline int irqs_disabled(void)
  197. {
  198. #ifdef CONFIG_MIPS_MT_SMTC
  199.     /*
  200.      * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU
  201.      */
  202.     unsigned long __result;
  203.  
  204.     __asm__ __volatile__(
  205.     "    .set    noreorder                    \n"
  206.     "    mfc0    %0, $2, 1                    \n"
  207.     "    andi    %0, 0x400                    \n"
  208.     "    slt    %0, $0, %0                    \n"
  209.     "    .set    reorder                        \n"
  210.     : "=r" (__result));
  211.  
  212.     return __result;
  213. #else
  214.     unsigned long flags;
  215.     local_save_flags(flags);
  216.  
  217.     return !(flags & 1);
  218. #endif
  219. }
  220.  
  221. #endif /* _ASM_INTERRUPT_H */
  222.