^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1996 by Paul M. Antoine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 1999 Silicon Graphics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2000 MIPS Technologies, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/hazards.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/preempt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/stringify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #if !defined(CONFIG_CPU_HAS_DIEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * For cli() we have to insert nops to make sure that the new value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * has actually arrived in the status register before the end of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * macro.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * no nops at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * For TX49, operating only IE bit is not enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * If mfc0 $12 follows store and the mfc0 is last instruction of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * page and fetching the next instruction causes TLB miss, the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * of the mfc0 might wrongly contain EXL bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Workaround: mask EXL bit of the result or place a nop before mfc0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) notrace void arch_local_irq_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) preempt_disable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) __asm__ __volatile__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) " .set push \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) " .set noat \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) " mfc0 $1,$12 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) " ori $1,0x1f \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) " xori $1,0x1f \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) " .set noreorder \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) " mtc0 $1,$12 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) " " __stringify(__irq_disable_hazard) " \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) " .set pop \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) : /* no outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) : /* no inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) preempt_enable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) EXPORT_SYMBOL(arch_local_irq_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) notrace unsigned long arch_local_irq_save(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) preempt_disable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __asm__ __volatile__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) " .set push \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) " .set reorder \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) " .set noat \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) " mfc0 %[flags], $12 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) " ori $1, %[flags], 0x1f \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) " xori $1, 0x1f \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) " .set noreorder \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) " mtc0 $1, $12 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) " " __stringify(__irq_disable_hazard) " \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) " .set pop \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) : [flags] "=r" (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) : /* no inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) preempt_enable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) EXPORT_SYMBOL(arch_local_irq_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) notrace void arch_local_irq_restore(unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long __tmp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) preempt_disable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) __asm__ __volatile__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) " .set push \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) " .set noreorder \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) " .set noat \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) " mfc0 $1, $12 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) " andi %[flags], 1 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) " ori $1, 0x1f \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) " xori $1, 0x1f \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) " or %[flags], $1 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) " mtc0 %[flags], $12 \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) " " __stringify(__irq_disable_hazard) " \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) " .set pop \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) : [flags] "=r" (__tmp1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) : "0" (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) preempt_enable_notrace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) EXPORT_SYMBOL(arch_local_irq_restore);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #endif /* !CONFIG_CPU_HAS_DIEI */