linux/arch/mips/include/asm/irqflags.h
<<
>>
Prefs
   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 <linux/stringify.h>
  18#include <asm/compiler.h>
  19#include <asm/hazards.h>
  20
  21#if defined(CONFIG_CPU_MIPSR2) || defined (CONFIG_CPU_MIPSR6)
  22
  23static inline void arch_local_irq_disable(void)
  24{
  25        __asm__ __volatile__(
  26        "       .set    push                                            \n"
  27        "       .set    noat                                            \n"
  28        "       di                                                      \n"
  29        "       " __stringify(__irq_disable_hazard) "                   \n"
  30        "       .set    pop                                             \n"
  31        : /* no outputs */
  32        : /* no inputs */
  33        : "memory");
  34}
  35
  36static inline unsigned long arch_local_irq_save(void)
  37{
  38        unsigned long flags;
  39
  40        asm __volatile__(
  41        "       .set    push                                            \n"
  42        "       .set    reorder                                         \n"
  43        "       .set    noat                                            \n"
  44        "       di      %[flags]                                        \n"
  45        "       andi    %[flags], 1                                     \n"
  46        "       " __stringify(__irq_disable_hazard) "                   \n"
  47        "       .set    pop                                             \n"
  48        : [flags] "=r" (flags)
  49        : /* no inputs */
  50        : "memory");
  51
  52        return flags;
  53}
  54
  55static inline void arch_local_irq_restore(unsigned long flags)
  56{
  57        unsigned long __tmp1;
  58
  59        __asm__ __volatile__(
  60        "       .set    push                                            \n"
  61        "       .set    noreorder                                       \n"
  62        "       .set    noat                                            \n"
  63#if defined(CONFIG_IRQ_MIPS_CPU)
  64        /*
  65         * Slow, but doesn't suffer from a relatively unlikely race
  66         * condition we're having since days 1.
  67         */
  68        "       beqz    %[flags], 1f                                    \n"
  69        "       di                                                      \n"
  70        "       ei                                                      \n"
  71        "1:                                                             \n"
  72#else
  73        /*
  74         * Fast, dangerous.  Life is fun, life is good.
  75         */
  76        "       mfc0    $1, $12                                         \n"
  77        "       ins     $1, %[flags], 0, 1                              \n"
  78        "       mtc0    $1, $12                                         \n"
  79#endif
  80        "       " __stringify(__irq_disable_hazard) "                   \n"
  81        "       .set    pop                                             \n"
  82        : [flags] "=r" (__tmp1)
  83        : "0" (flags)
  84        : "memory");
  85}
  86
  87#else
  88/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
  89void arch_local_irq_disable(void);
  90unsigned long arch_local_irq_save(void);
  91void arch_local_irq_restore(unsigned long flags);
  92#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
  93
  94static inline void arch_local_irq_enable(void)
  95{
  96        __asm__ __volatile__(
  97        "       .set    push                                            \n"
  98        "       .set    reorder                                         \n"
  99        "       .set    noat                                            \n"
 100#if   defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
 101        "       ei                                                      \n"
 102#else
 103        "       mfc0    $1,$12                                          \n"
 104        "       ori     $1,0x1f                                         \n"
 105        "       xori    $1,0x1e                                         \n"
 106        "       mtc0    $1,$12                                          \n"
 107#endif
 108        "       " __stringify(__irq_enable_hazard) "                    \n"
 109        "       .set    pop                                             \n"
 110        : /* no outputs */
 111        : /* no inputs */
 112        : "memory");
 113}
 114
 115static inline unsigned long arch_local_save_flags(void)
 116{
 117        unsigned long flags;
 118
 119        asm __volatile__(
 120        "       .set    push                                            \n"
 121        "       .set    reorder                                         \n"
 122        "       mfc0    %[flags], $12                                   \n"
 123        "       .set    pop                                             \n"
 124        : [flags] "=r" (flags));
 125
 126        return flags;
 127}
 128
 129
 130static inline int arch_irqs_disabled_flags(unsigned long flags)
 131{
 132        return !(flags & 1);
 133}
 134
 135#endif /* #ifndef __ASSEMBLY__ */
 136
 137/*
 138 * Do the CPU's IRQ-state tracing from assembly code.
 139 */
 140#ifdef CONFIG_TRACE_IRQFLAGS
 141/* Reload some registers clobbered by trace_hardirqs_on */
 142#ifdef CONFIG_64BIT
 143# define TRACE_IRQS_RELOAD_REGS                                         \
 144        LONG_L  $11, PT_R11(sp);                                        \
 145        LONG_L  $10, PT_R10(sp);                                        \
 146        LONG_L  $9, PT_R9(sp);                                          \
 147        LONG_L  $8, PT_R8(sp);                                          \
 148        LONG_L  $7, PT_R7(sp);                                          \
 149        LONG_L  $6, PT_R6(sp);                                          \
 150        LONG_L  $5, PT_R5(sp);                                          \
 151        LONG_L  $4, PT_R4(sp);                                          \
 152        LONG_L  $2, PT_R2(sp)
 153#else
 154# define TRACE_IRQS_RELOAD_REGS                                         \
 155        LONG_L  $7, PT_R7(sp);                                          \
 156        LONG_L  $6, PT_R6(sp);                                          \
 157        LONG_L  $5, PT_R5(sp);                                          \
 158        LONG_L  $4, PT_R4(sp);                                          \
 159        LONG_L  $2, PT_R2(sp)
 160#endif
 161# define TRACE_IRQS_ON                                                  \
 162        CLI;    /* make sure trace_hardirqs_on() is called in kernel level */ \
 163        jal     trace_hardirqs_on
 164# define TRACE_IRQS_ON_RELOAD                                           \
 165        TRACE_IRQS_ON;                                                  \
 166        TRACE_IRQS_RELOAD_REGS
 167# define TRACE_IRQS_OFF                                                 \
 168        jal     trace_hardirqs_off
 169#else
 170# define TRACE_IRQS_ON
 171# define TRACE_IRQS_ON_RELOAD
 172# define TRACE_IRQS_OFF
 173#endif
 174
 175#endif /* _ASM_IRQFLAGS_H */
 176