Home | History | Annotate | Download | only in asm
      1 /*
      2  * include/asm-microblaze/system.h -- Low-level interrupt/thread ops
      3  *
      4  *  Copyright (C) 2003	John Williams (jwilliams (at) itee.uq.edu.au)
      5  *			based upon microblaze version
      6  *  Copyright (C) 2001	NEC Corporation
      7  *  Copyright (C) 2001	Miles Bader <miles (at) gnu.org>
      8  *
      9  * This file is subject to the terms and conditions of the GNU General
     10  * Public License.  See the file COPYING in the main directory of this
     11  * archive for more details.
     12  *
     13  * Written by Miles Bader <miles (at) gnu.org>
     14  * Microblaze port by John Williams
     15  * Microblaze port by John Williams
     16  */
     17 
     18 #ifndef __MICROBLAZE_SYSTEM_H__
     19 #define __MICROBLAZE_SYSTEM_H__
     20 
     21 #if 0
     22 #include <linux/linkage.h>
     23 #endif
     24 #include <asm/ptrace.h>
     25 
     26 #define prepare_to_switch()	do { } while (0)
     27 
     28 /*
     29  * switch_to(n) should switch tasks to task ptr, first checking that
     30  * ptr isn't the current task, in which case it does nothing.
     31  */
     32 struct thread_struct;
     33 extern void *switch_thread (struct thread_struct *last,
     34 			    struct thread_struct *next);
     35 #define switch_to(prev,next,last) do {					\
     36 	if (prev != next) {						\
     37 		(last) = switch_thread (&prev->thread, &next->thread);	\
     38 	}								\
     39 } while (0)
     40 
     41 
     42 /* Enable/disable interrupts.  */
     43 #define __sti() \
     44 {								\
     45 	register unsigned tmp;					\
     46 	__asm__ __volatile__ ("					\
     47 			mfs	%0, rmsr;			\
     48 			ori	%0, %0, 2;			\
     49 			mts	rmsr, %0"			\
     50 			: "=r" (tmp)				\
     51 			:					\
     52 			: "memory");				\
     53 }
     54 
     55 #define __cli() \
     56 {								\
     57 	register unsigned tmp;					\
     58 	__asm__ __volatile__ ("					\
     59 			mfs	%0, rmsr;			\
     60 			andi	%0, %0, ~2;			\
     61 			mts	rmsr, %0"			\
     62 			: "=r" (tmp)				\
     63 			:					\
     64 			: "memory");				\
     65 }
     66 
     67 #define __save_flags(flags) \
     68 	__asm__ __volatile__ ("mfs	%0, rmsr" : "=r" (flags))
     69 #define __restore_flags(flags) \
     70 	__asm__ __volatile__ ("mts	rmsr, %0" :: "r" (flags))
     71 
     72 #define __save_flags_cli(flags) \
     73 {								\
     74 	register unsigned tmp;					\
     75 	__asm__ __volatile__ ("					\
     76 			mfs	%0, rmsr;			\
     77 			andi	%1, %0, ~2;			\
     78 			mts	rmsr, %1;"			\
     79 			: "=r" (flags), "=r" (tmp)		\
     80 			:					\
     81 			: "memory");				\
     82 }
     83 
     84 #define __save_flags_sti(flags)					\
     85 {								\
     86 	register unsigned tmp;					\
     87 	__asm__ __volatile__ ("					\
     88 			mfs	%0, rmsr;			\
     89 			ori	%1, %0, 2;			\
     90 			mts	rmsr, %1;"			\
     91 			: "=r" (flags) ,"=r" (tmp)		\
     92 			:					\
     93 			: "memory");				\
     94 }
     95 
     96 /* For spinlocks etc */
     97 #define local_irq_save(flags)	__save_flags_cli (flags)
     98 #define local_irq_set(flags)	__save_flags_sti (flags)
     99 #define local_irq_restore(flags) __restore_flags (flags)
    100 #define local_irq_disable()	__cli ()
    101 #define local_irq_enable()	__sti ()
    102 
    103 #define cli()			__cli ()
    104 #define sti()			__sti ()
    105 #define save_flags(flags)	__save_flags (flags)
    106 #define restore_flags(flags)	__restore_flags (flags)
    107 #define save_flags_cli(flags)	__save_flags_cli (flags)
    108 
    109 /*
    110  * Force strict CPU ordering.
    111  * Not really required on microblaze...
    112  */
    113 #define nop()			__asm__ __volatile__ ("nop")
    114 #define mb()			__asm__ __volatile__ ("nop" ::: "memory")
    115 #define rmb()			mb ()
    116 #define wmb()			mb ()
    117 #define set_mb(var, value)	do { var = value; mb(); } while (0)
    118 #define set_wmb(var, value)	do { var = value; wmb (); } while (0)
    119 
    120 #ifdef CONFIG_SMP
    121 #define smp_mb()	mb ()
    122 #define smp_rmb()	rmb ()
    123 #define smp_wmb()	wmb ()
    124 #else
    125 #define smp_mb()	barrier ()
    126 #define smp_rmb()	barrier ()
    127 #define smp_wmb()	barrier ()
    128 #endif
    129 
    130 #define xchg(ptr, with) \
    131   ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
    132 #define tas(ptr) (xchg ((ptr), 1))
    133 
    134 static inline unsigned long __xchg(unsigned long with,
    135 				    __volatile__ void *ptr, int size)
    136 {
    137 	unsigned long tmp, flags;
    138 
    139 	save_flags_cli (flags);
    140 
    141 	switch (size) {
    142 	case 1:
    143 		tmp = *(unsigned char *)ptr;
    144 		*(unsigned char *)ptr = with;
    145 		break;
    146 	case 2:
    147 		tmp = *(unsigned short *)ptr;
    148 		*(unsigned short *)ptr = with;
    149 		break;
    150 	case 4:
    151 		tmp = *(unsigned long *)ptr;
    152 		*(unsigned long *)ptr = with;
    153 		break;
    154 	}
    155 
    156 	restore_flags (flags);
    157 
    158 	return tmp;
    159 }
    160 
    161 #endif /* __MICROBLAZE_SYSTEM_H__ */
    162