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