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 / mips / include / asm / irqflags.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  6.5 KB  |  284 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_IRQFLAGS_H
  12. #define _ASM_IRQFLAGS_H
  13.  
  14. #ifndef __ASSEMBLY__
  15.  
  16. #include <linux/compiler.h>
  17. #include <asm/hazards.h>
  18.  
  19. __asm__(
  20.     "    .macro    raw_local_irq_enable                \n"
  21.     "    .set    push                        \n"
  22.     "    .set    reorder                        \n"
  23.     "    .set    noat                        \n"
  24. #ifdef CONFIG_MIPS_MT_SMTC
  25.     "    mfc0    $1, $2, 1    # SMTC - clear TCStatus.IXMT    \n"
  26.     "    ori    $1, 0x400                    \n"
  27.     "    xori    $1, 0x400                    \n"
  28.     "    mtc0    $1, $2, 1                    \n"
  29. #elif defined(CONFIG_CPU_MIPSR2)
  30.     "    ei                            \n"
  31. #else
  32.     "    mfc0    $1,$12                        \n"
  33.     "    ori    $1,0x1f                        \n"
  34.     "    xori    $1,0x1e                        \n"
  35.     "    mtc0    $1,$12                        \n"
  36. #endif
  37.     "    irq_enable_hazard                    \n"
  38.     "    .set    pop                        \n"
  39.     "    .endm");
  40.  
  41. extern void smtc_ipi_replay(void);
  42.  
  43. static inline void raw_local_irq_enable(void)
  44. {
  45. #ifdef CONFIG_MIPS_MT_SMTC
  46.     /*
  47.      * SMTC kernel needs to do a software replay of queued
  48.      * IPIs, at the cost of call overhead on each local_irq_enable()
  49.      */
  50.     smtc_ipi_replay();
  51. #endif
  52.     __asm__ __volatile__(
  53.         "raw_local_irq_enable"
  54.         : /* no outputs */
  55.         : /* no inputs */
  56.         : "memory");
  57. }
  58.  
  59.  
  60. /*
  61.  * For cli() we have to insert nops to make sure that the new value
  62.  * has actually arrived in the status register before the end of this
  63.  * macro.
  64.  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  65.  * no nops at all.
  66.  */
  67. /*
  68.  * For TX49, operating only IE bit is not enough.
  69.  *
  70.  * If mfc0 $12 follows store and the mfc0 is last instruction of a
  71.  * page and fetching the next instruction causes TLB miss, the result
  72.  * of the mfc0 might wrongly contain EXL bit.
  73.  *
  74.  * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
  75.  *
  76.  * Workaround: mask EXL bit of the result or place a nop before mfc0.
  77.  */
  78. __asm__(
  79.     "    .macro    raw_local_irq_disable\n"
  80.     "    .set    push                        \n"
  81.     "    .set    noat                        \n"
  82. #ifdef CONFIG_MIPS_MT_SMTC
  83.     "    mfc0    $1, $2, 1                    \n"
  84.     "    ori    $1, 0x400                    \n"
  85.     "    .set    noreorder                    \n"
  86.     "    mtc0    $1, $2, 1                    \n"
  87. #elif defined(CONFIG_CPU_MIPSR2)
  88.     "    di                            \n"
  89. #else
  90.     "    mfc0    $1,$12                        \n"
  91.     "    ori    $1,0x1f                        \n"
  92.     "    xori    $1,0x1f                        \n"
  93.     "    .set    noreorder                    \n"
  94.     "    mtc0    $1,$12                        \n"
  95. #endif
  96.     "    irq_disable_hazard                    \n"
  97.     "    .set    pop                        \n"
  98.     "    .endm                            \n");
  99.  
  100. static inline void raw_local_irq_disable(void)
  101. {
  102.     __asm__ __volatile__(
  103.         "raw_local_irq_disable"
  104.         : /* no outputs */
  105.         : /* no inputs */
  106.         : "memory");
  107. }
  108.  
  109. __asm__(
  110.     "    .macro    raw_local_save_flags flags            \n"
  111.     "    .set    push                        \n"
  112.     "    .set    reorder                        \n"
  113. #ifdef CONFIG_MIPS_MT_SMTC
  114.     "    mfc0    \\flags, $2, 1                    \n"
  115. #else
  116.     "    mfc0    \\flags, $12                    \n"
  117. #endif
  118.     "    .set    pop                        \n"
  119.     "    .endm                            \n");
  120.  
  121. #define raw_local_save_flags(x)                        \
  122. __asm__ __volatile__(                            \
  123.     "raw_local_save_flags %0"                    \
  124.     : "=r" (x))
  125.  
  126. __asm__(
  127.     "    .macro    raw_local_irq_save result            \n"
  128.     "    .set    push                        \n"
  129.     "    .set    reorder                        \n"
  130.     "    .set    noat                        \n"
  131. #ifdef CONFIG_MIPS_MT_SMTC
  132.     "    mfc0    \\result, $2, 1                    \n"
  133.     "    ori    $1, \\result, 0x400                \n"
  134.     "    .set    noreorder                    \n"
  135.     "    mtc0    $1, $2, 1                    \n"
  136.     "    andi    \\result, \\result, 0x400            \n"
  137. #elif defined(CONFIG_CPU_MIPSR2)
  138.     "    di    \\result                    \n"
  139.     "    andi    \\result, 1                    \n"
  140. #else
  141.     "    mfc0    \\result, $12                    \n"
  142.     "    ori    $1, \\result, 0x1f                \n"
  143.     "    xori    $1, 0x1f                    \n"
  144.     "    .set    noreorder                    \n"
  145.     "    mtc0    $1, $12                        \n"
  146. #endif
  147.     "    irq_disable_hazard                    \n"
  148.     "    .set    pop                        \n"
  149.     "    .endm                            \n");
  150.  
  151. #define raw_local_irq_save(x)                        \
  152. __asm__ __volatile__(                            \
  153.     "raw_local_irq_save\t%0"                    \
  154.     : "=r" (x)                            \
  155.     : /* no inputs */                        \
  156.     : "memory")
  157.  
  158. __asm__(
  159.     "    .macro    raw_local_irq_restore flags            \n"
  160.     "    .set    push                        \n"
  161.     "    .set    noreorder                    \n"
  162.     "    .set    noat                        \n"
  163. #ifdef CONFIG_MIPS_MT_SMTC
  164.     "mfc0    $1, $2, 1                        \n"
  165.     "andi    \\flags, 0x400                        \n"
  166.     "ori    $1, 0x400                        \n"
  167.     "xori    $1, 0x400                        \n"
  168.     "or    \\flags, $1                        \n"
  169.     "mtc0    \\flags, $2, 1                        \n"
  170. #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
  171.     /*
  172.      * Slow, but doesn't suffer from a relativly unlikely race
  173.      * condition we're having since days 1.
  174.      */
  175.     "    beqz    \\flags, 1f                    \n"
  176.     "     di                            \n"
  177.     "    ei                            \n"
  178.     "1:                                \n"
  179. #elif defined(CONFIG_CPU_MIPSR2)
  180.     /*
  181.      * Fast, dangerous.  Life is fun, life is good.
  182.      */
  183.     "    mfc0    $1, $12                        \n"
  184.     "    ins    $1, \\flags, 0, 1                \n"
  185.     "    mtc0    $1, $12                        \n"
  186. #else
  187.     "    mfc0    $1, $12                        \n"
  188.     "    andi    \\flags, 1                    \n"
  189.     "    ori    $1, 0x1f                    \n"
  190.     "    xori    $1, 0x1f                    \n"
  191.     "    or    \\flags, $1                    \n"
  192.     "    mtc0    \\flags, $12                    \n"
  193. #endif
  194.     "    irq_disable_hazard                    \n"
  195.     "    .set    pop                        \n"
  196.     "    .endm                            \n");
  197.  
  198.  
  199. static inline void raw_local_irq_restore(unsigned long flags)
  200. {
  201.     unsigned long __tmp1;
  202.  
  203. #ifdef CONFIG_MIPS_MT_SMTC
  204.     /*
  205.      * SMTC kernel needs to do a software replay of queued
  206.      * IPIs, at the cost of branch and call overhead on each
  207.      * local_irq_restore()
  208.      */
  209.     if (unlikely(!(flags & 0x0400)))
  210.         smtc_ipi_replay();
  211. #endif
  212.  
  213.     __asm__ __volatile__(
  214.         "raw_local_irq_restore\t%0"
  215.         : "=r" (__tmp1)
  216.         : "0" (flags)
  217.         : "memory");
  218. }
  219.  
  220. static inline void __raw_local_irq_restore(unsigned long flags)
  221. {
  222.     unsigned long __tmp1;
  223.  
  224.     __asm__ __volatile__(
  225.         "raw_local_irq_restore\t%0"
  226.         : "=r" (__tmp1)
  227.         : "0" (flags)
  228.         : "memory");
  229. }
  230.  
  231. static inline int raw_irqs_disabled_flags(unsigned long flags)
  232. {
  233. #ifdef CONFIG_MIPS_MT_SMTC
  234.     /*
  235.      * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU
  236.      */
  237.     return flags & 0x400;
  238. #else
  239.     return !(flags & 1);
  240. #endif
  241. }
  242.  
  243. #endif
  244.  
  245. /*
  246.  * Do the CPU's IRQ-state tracing from assembly code.
  247.  */
  248. #ifdef CONFIG_TRACE_IRQFLAGS
  249. /* Reload some registers clobbered by trace_hardirqs_on */
  250. #ifdef CONFIG_64BIT
  251. # define TRACE_IRQS_RELOAD_REGS                        \
  252.     LONG_L    $11, PT_R11(sp);                    \
  253.     LONG_L    $10, PT_R10(sp);                    \
  254.     LONG_L    $9, PT_R9(sp);                        \
  255.     LONG_L    $8, PT_R8(sp);                        \
  256.     LONG_L    $7, PT_R7(sp);                        \
  257.     LONG_L    $6, PT_R6(sp);                        \
  258.     LONG_L    $5, PT_R5(sp);                        \
  259.     LONG_L    $4, PT_R4(sp);                        \
  260.     LONG_L    $2, PT_R2(sp)
  261. #else
  262. # define TRACE_IRQS_RELOAD_REGS                        \
  263.     LONG_L    $7, PT_R7(sp);                        \
  264.     LONG_L    $6, PT_R6(sp);                        \
  265.     LONG_L    $5, PT_R5(sp);                        \
  266.     LONG_L    $4, PT_R4(sp);                        \
  267.     LONG_L    $2, PT_R2(sp)
  268. #endif
  269. # define TRACE_IRQS_ON                            \
  270.     CLI;    /* make sure trace_hardirqs_on() is called in kernel level */ \
  271.     jal    trace_hardirqs_on
  272. # define TRACE_IRQS_ON_RELOAD                        \
  273.     TRACE_IRQS_ON;                            \
  274.     TRACE_IRQS_RELOAD_REGS
  275. # define TRACE_IRQS_OFF                            \
  276.     jal    trace_hardirqs_off
  277. #else
  278. # define TRACE_IRQS_ON
  279. # define TRACE_IRQS_ON_RELOAD
  280. # define TRACE_IRQS_OFF
  281. #endif
  282.  
  283. #endif /* _ASM_IRQFLAGS_H */
  284.