1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ASM_ARM_SYSTEM_H 2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ASM_ARM_SYSTEM_H 3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef __KERNEL__ 5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_UNKNOWN 0 8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv3 1 9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv4 2 10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv4T 3 11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv5 4 12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv5T 5 13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv5TE 6 14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv5TEJ 7 15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPU_ARCH_ARMv6 8 16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * CR1 bits (CP#15 CR1) 19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_M (1 << 0) /* MMU enable */ 21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_A (1 << 1) /* Alignment abort enable */ 22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_C (1 << 2) /* Dcache enable */ 23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_W (1 << 3) /* Write buffer enable */ 24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_P (1 << 4) /* 32-bit exception handler */ 25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_D (1 << 5) /* 32-bit data address range */ 26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_L (1 << 6) /* Implementation defined */ 27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_B (1 << 7) /* Big endian */ 28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_S (1 << 8) /* System MMU protection */ 29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_R (1 << 9) /* ROM MMU protection */ 30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_F (1 << 10) /* Implementation defined */ 31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_Z (1 << 11) /* Implementation defined */ 32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_I (1 << 12) /* Icache enable */ 33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ 34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_RR (1 << 14) /* Round Robin cache replacement */ 35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_L4 (1 << 15) /* LDR pc can set T bit */ 36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_DT (1 << 16) 37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_IT (1 << 18) 38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_ST (1 << 19) 39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ 40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_U (1 << 22) /* Unaligned access operation */ 41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_XP (1 << 23) /* Extended page tables */ 42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CR_VE (1 << 24) /* Vectored interrupts */ 43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPUID_ID 0 45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPUID_CACHETYPE 1 46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPUID_TCM 2 47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CPUID_TLBTYPE 3 48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define read_cpuid(reg) \ 50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned int __val; \ 52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \ 53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (__val) \ 54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : \ 55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); \ 56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __val; \ 57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This is used to ensure the compiler did actually allocate the register we 61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * asked it for some inline assembly sequences. Apparently we can't trust 62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the compiler from one version to another so a bit of paranoia won't hurt. 63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This string is meant to be concatenated with the inline asm string and 64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * will cause compilation to stop on mismatch. 65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (for details, see gcc PR 15089) 66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" 68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ASSEMBLY__ 70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/linkage.h> 72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct thread_info; 74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct task_struct; 75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* information about the system we're running on */ 77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned int system_rev; 78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned int system_serial_low; 79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned int system_serial_high; 80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned int mem_fclk_21285; 81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct pt_regs; 83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruvoid die(const char *msg, struct pt_regs *regs, int err) 85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __attribute__((noreturn)); 86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct siginfo; 88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruvoid notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, 89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long err, unsigned long trap); 90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruvoid hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, 92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru struct pt_regs *), 93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru int sig, const char *name); 94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define xchg(ptr,x) \ 96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) 97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define tas(ptr) (xchg((ptr),1)) 99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern asmlinkage void __backtrace(void); 101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern asmlinkage void c_backtrace(unsigned long fp, int pmode); 102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct mm_struct; 104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void show_pte(struct mm_struct *mm, unsigned long addr); 105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void __show_regs(struct pt_regs *); 106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int cpu_architecture(void); 108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void cpu_init(void); 109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruvoid arm_machine_restart(char mode); 111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void (*arm_pm_restart)(char str); 112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Intel's XScale3 core supports some v6 features (supersections, L2) 115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * but advertises itself as v5 as it does not support the v6 ISA. For 116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * this reason, we need a way to explicitly test for this type of CPU. 117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef CONFIG_CPU_XSC3 119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define cpu_is_xsc3() 0 120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int cpu_is_xsc3(void) 122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru extern unsigned int processor_id; 124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if ((processor_id & 0xffffe000) == 0x69056000) 126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 1; 127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 0; 129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3) 133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define cpu_is_xscale() 0 134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define cpu_is_xscale() 1 136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define set_cr(x) \ 139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mcr p15, 0, %0, c1, c0, 0 @ set CR" \ 141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : : "r" (x) : "cc") 142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_cr() \ 144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned int __val; \ 146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrc p15, 0, %0, c1, c0, 0 @ get CR" \ 148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (__val) : : "cc"); \ 149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __val; \ 150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long cr_no_alignment; /* defined in entry-armv.S */ 153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long cr_alignment; /* defined in entry-armv.S */ 154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define UDBG_UNDEFINED (1 << 0) 156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define UDBG_SYSCALL (1 << 1) 157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define UDBG_BADABORT (1 << 2) 158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define UDBG_SEGV (1 << 3) 159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define UDBG_BUS (1 << 4) 160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned int user_debug; 162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if __LINUX_ARM_ARCH__ >= 4 164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define vectors_high() (cr_alignment & CR_V) 165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define vectors_high() (0) 167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if __LINUX_ARM_ARCH__ >= 6 170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ 171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : : "r" (0) : "memory") 172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define mb() __asm__ __volatile__ ("" : : : "memory") 174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define rmb() mb() 176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define wmb() mb() 177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define read_barrier_depends() do { } while(0) 178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define set_mb(var, value) do { var = value; mb(); } while (0) 179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); 180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * switch_mm() may do a full cache flush over the context switch, 183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * so enable interrupts over the context switch to avoid high 184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * latency. 185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ARCH_WANT_INTERRUPTS_ON_CTXSW 187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * switch_to(prev, next) should switch from task `prev' to `next' 190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * `prev' will never be the same as `next'. schedule() itself 191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * contains the memory barrier to tell GCC not to cache `current'. 192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); 194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define switch_to(prev,next,last) \ 196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querudo { \ 197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ 198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} while (0) 199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * On SMP systems, when the scheduler does migration-cost autodetection, 202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * it needs a way to flush as much of the CPU's caches as possible. 203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * TODO: fill this in! 205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void sched_cacheflush(void) 207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * CPU interrupt mask handling. 212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if __LINUX_ARM_ARCH__ >= 6 214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_save(x) \ 216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrs %0, cpsr @ local_irq_save\n" \ 219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "cpsid i" \ 220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (x) : : "memory", "cc"); \ 221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 222c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 223c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc") 224c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc") 225c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") 226c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") 227c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 228c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 229c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 230c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 231c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Save the current interrupt enable state & disable IRQs 232c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 233c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_save(x) \ 234c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 235c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long temp; \ 236c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (void) (&temp == &x); \ 237c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 238c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrs %0, cpsr @ local_irq_save\n" \ 239c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" orr %1, %0, #128\n" \ 240c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" msr cpsr_c, %1" \ 241c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (x), "=r" (temp) \ 242c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : \ 243c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); \ 244c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 245c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 246c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 247c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Enable IRQs 248c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 249c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_enable() \ 250c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 251c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long temp; \ 252c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 253c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrs %0, cpsr @ local_irq_enable\n" \ 254c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" bic %0, %0, #128\n" \ 255c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" msr cpsr_c, %0" \ 256c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (temp) \ 257c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : \ 258c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); \ 259c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 260c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 261c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 262c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Disable IRQs 263c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 264c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_disable() \ 265c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 266c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long temp; \ 267c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 268c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrs %0, cpsr @ local_irq_disable\n" \ 269c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" orr %0, %0, #128\n" \ 270c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" msr cpsr_c, %0" \ 271c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (temp) \ 272c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : \ 273c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); \ 274c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 275c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 276c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 277c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Enable FIQs 278c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 279c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_fiq_enable() \ 280c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 281c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long temp; \ 282c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 283c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrs %0, cpsr @ stf\n" \ 284c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" bic %0, %0, #64\n" \ 285c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" msr cpsr_c, %0" \ 286c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (temp) \ 287c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : \ 288c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); \ 289c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 290c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 291c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 292c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Disable FIQs 293c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 294c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_fiq_disable() \ 295c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 296c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long temp; \ 297c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 298c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrs %0, cpsr @ clf\n" \ 299c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" orr %0, %0, #64\n" \ 300c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" msr cpsr_c, %0" \ 301c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (temp) \ 302c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : \ 303c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); \ 304c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 305c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 306c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 307c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 308c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 309c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Save the current interrupt enable state. 310c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 311c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_save_flags(x) \ 312c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ({ \ 313c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 314c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "mrs %0, cpsr @ local_save_flags" \ 315c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=r" (x) : : "memory", "cc"); \ 316c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru }) 317c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 318c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 319c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * restore saved IRQ & FIQ state 320c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 321c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define local_irq_restore(x) \ 322c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( \ 323c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "msr cpsr_c, %0 @ local_irq_restore\n" \ 324c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : \ 325c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x) \ 326c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc") 327c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 328c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define irqs_disabled() \ 329c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({ \ 330c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long flags; \ 331c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru local_save_flags(flags); \ 332c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru (int)(flags & PSR_I_BIT); \ 333c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}) 334c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 335c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_SMP 336c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 337c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_mb() mb() 338c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_rmb() rmb() 339c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_wmb() wmb() 340c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_read_barrier_depends() read_barrier_depends() 341c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 342c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 343c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 344c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_mb() barrier() 345c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_rmb() barrier() 346c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_wmb() barrier() 347c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_read_barrier_depends() do { } while(0) 348c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 349c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* CONFIG_SMP */ 350c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 351c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) 352c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 353c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * On the StrongARM, "swp" is terminally broken since it bypasses the 354c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * cache totally. This means that the cache becomes inconsistent, and, 355c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * since we use normal loads/stores as well, this is really bad. 356c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Typically, this causes oopsen in filp_close, but could have other, 357c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * more disasterous effects. There are two work-arounds: 358c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 1. Disable interrupts and emulate the atomic swap 359c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 2. Clean the cache, perform atomic swap, flush the cache 360c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 361c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * We choose (1) since its the "easiest" to achieve here and is not 362c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * dependent on the processor type. 363c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 364c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * NOTE that this solution won't work on an SMP system, so explcitly 365c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * forbid it here. 366c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 367c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define swp_is_buggy 368c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 369c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 370c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) 371c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 372c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru extern void __bad_xchg(volatile void *, int); 373c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long ret; 374c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef swp_is_buggy 375c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long flags; 376c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 377c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if __LINUX_ARM_ARCH__ >= 6 378c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned int tmp; 379c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 380c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 381c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru switch (size) { 382c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if __LINUX_ARM_ARCH__ >= 6 383c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 1: 384c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile("@ __xchg1\n" 385c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1: ldrexb %0, [%3]\n" 386c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " strexb %1, %2, [%3]\n" 387c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " teq %1, #0\n" 388c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " bne 1b" 389c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (ret), "=&r" (tmp) 390c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x), "r" (ptr) 391c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); 392c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; 393c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 4: 394c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile("@ __xchg4\n" 395c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1: ldrex %0, [%3]\n" 396c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " strex %1, %2, [%3]\n" 397c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " teq %1, #0\n" 398c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " bne 1b" 399c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (ret), "=&r" (tmp) 400c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x), "r" (ptr) 401c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); 402c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; 403c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#elif defined(swp_is_buggy) 404c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_SMP 405c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#error SMP is not supported on this platform 406c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 407c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 1: 408c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru local_irq_save(flags); 409c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ret = *(volatile unsigned char *)ptr; 410c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *(volatile unsigned char *)ptr = x; 411c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru local_irq_restore(flags); 412c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; 413c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 414c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 4: 415c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru local_irq_save(flags); 416c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ret = *(volatile unsigned long *)ptr; 417c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *(volatile unsigned long *)ptr = x; 418c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru local_irq_restore(flags); 419c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; 420c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 421c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 1: 422c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile("@ __xchg1\n" 423c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " swpb %0, %1, [%2]" 424c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (ret) 425c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x), "r" (ptr) 426c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); 427c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; 428c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru case 4: 429c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile("@ __xchg4\n" 430c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru " swp %0, %1, [%2]" 431c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (ret) 432c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (x), "r" (ptr) 433c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory", "cc"); 434c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; 435c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 436c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru default: 437c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __bad_xchg(ptr, size), ret = 0; 438c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru break; 439c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } 440c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 441c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return ret; 442c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 443c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 444c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void disable_hlt(void); 445c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void enable_hlt(void); 446c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 447c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __ASSEMBLY__ */ 448c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 449c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define arch_align_stack(x) (x) 450c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 451c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __KERNEL__ */ 452c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 453c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 454