|  | /* | 
|  | * include/asm-v850/system.h -- Low-level interrupt/thread ops | 
|  | * | 
|  | *  Copyright (C) 2001,02,03  NEC Electronics Corporation | 
|  | *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org> | 
|  | * | 
|  | * This file is subject to the terms and conditions of the GNU General | 
|  | * Public License.  See the file COPYING in the main directory of this | 
|  | * archive for more details. | 
|  | * | 
|  | * Written by Miles Bader <miles@gnu.org> | 
|  | */ | 
|  |  | 
|  | #ifndef __V850_SYSTEM_H__ | 
|  | #define __V850_SYSTEM_H__ | 
|  |  | 
|  | #include <linux/linkage.h> | 
|  | #include <asm/ptrace.h> | 
|  |  | 
|  |  | 
|  | /* | 
|  | * switch_to(n) should switch tasks to task ptr, first checking that | 
|  | * ptr isn't the current task, in which case it does nothing. | 
|  | */ | 
|  | struct thread_struct; | 
|  | extern void *switch_thread (struct thread_struct *last, | 
|  | struct thread_struct *next); | 
|  | #define switch_to(prev,next,last)					      \ | 
|  | do {									      \ | 
|  | if (prev != next) {						      \ | 
|  | (last) = switch_thread (&prev->thread, &next->thread);	      \ | 
|  | }								      \ | 
|  | } while (0) | 
|  |  | 
|  |  | 
|  | /* Enable/disable interrupts.  */ | 
|  | #define local_irq_enable()	__asm__ __volatile__ ("ei") | 
|  | #define local_irq_disable()	__asm__ __volatile__ ("di") | 
|  |  | 
|  | #define local_save_flags(flags) \ | 
|  | __asm__ __volatile__ ("stsr %1, %0" : "=r" (flags) : "i" (SR_PSW)) | 
|  | #define local_restore_flags(flags) \ | 
|  | __asm__ __volatile__ ("ldsr %0, %1" :: "r" (flags), "i" (SR_PSW)) | 
|  |  | 
|  | /* For spinlocks etc */ | 
|  | #define	local_irq_save(flags) \ | 
|  | do { local_save_flags (flags); local_irq_disable (); } while (0) | 
|  | #define local_irq_restore(flags) \ | 
|  | local_restore_flags (flags); | 
|  |  | 
|  |  | 
|  | static inline int irqs_disabled (void) | 
|  | { | 
|  | unsigned flags; | 
|  | local_save_flags (flags); | 
|  | return !!(flags & 0x20); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* | 
|  | * Force strict CPU ordering. | 
|  | * Not really required on v850... | 
|  | */ | 
|  | #define nop()			__asm__ __volatile__ ("nop") | 
|  | #define mb()			__asm__ __volatile__ ("" ::: "memory") | 
|  | #define rmb()			mb () | 
|  | #define wmb()			mb () | 
|  | #define read_barrier_depends()	((void)0) | 
|  | #define set_rmb(var, value)	do { xchg (&var, value); } while (0) | 
|  | #define set_mb(var, value)	set_rmb (var, value) | 
|  |  | 
|  | #define smp_mb()	mb () | 
|  | #define smp_rmb()	rmb () | 
|  | #define smp_wmb()	wmb () | 
|  | #define smp_read_barrier_depends()	read_barrier_depends() | 
|  |  | 
|  | #define xchg(ptr, with) \ | 
|  | ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr)))) | 
|  | #define tas(ptr) (xchg ((ptr), 1)) | 
|  |  | 
|  | static inline unsigned long __xchg (unsigned long with, | 
|  | __volatile__ void *ptr, int size) | 
|  | { | 
|  | unsigned long tmp, flags; | 
|  |  | 
|  | local_irq_save (flags); | 
|  |  | 
|  | switch (size) { | 
|  | case 1: | 
|  | tmp = *(unsigned char *)ptr; | 
|  | *(unsigned char *)ptr = with; | 
|  | break; | 
|  | case 2: | 
|  | tmp = *(unsigned short *)ptr; | 
|  | *(unsigned short *)ptr = with; | 
|  | break; | 
|  | case 4: | 
|  | tmp = *(unsigned long *)ptr; | 
|  | *(unsigned long *)ptr = with; | 
|  | break; | 
|  | } | 
|  |  | 
|  | local_irq_restore (flags); | 
|  |  | 
|  | return tmp; | 
|  | } | 
|  |  | 
|  | #define arch_align_stack(x) (x) | 
|  |  | 
|  | #endif /* __V850_SYSTEM_H__ */ |