File: /usr/src/linux/include/asm-cris/system.h

1     /* $Id: system.h,v 1.4 2001/03/20 19:46:00 bjornw Exp $ */
2     
3     #ifndef __ASM_CRIS_SYSTEM_H
4     #define __ASM_CRIS_SYSTEM_H
5     
6     #include <linux/config.h>
7     
8     #include <asm/segment.h>
9     
10     /* the switch_to macro calls resume, an asm function in entry.S which does the actual
11      * task switching.
12      */
13     
14     extern struct task_struct *resume(struct task_struct *prev, struct task_struct *next, int);
15     #define prepare_to_switch()     do { } while(0)
16     #define switch_to(prev,next,last) last = resume(prev,next, \
17     					 (int)&((struct task_struct *)0)->thread)
18     
19     /* read/write the user-mode stackpointer */
20     
21     extern inline unsigned long rdusp(void) {
22     	unsigned long usp;
23     	__asm__ __volatile__("move usp,%0" : "=rm" (usp));
24     	return usp;
25     }
26     
27     #define wrusp(usp) \
28     	__asm__ __volatile__("move %0,usp" : /* no outputs */ : "rm" (usp))
29     
30     /* read the current stackpointer */
31     
32     extern inline unsigned long rdsp(void) {
33     	unsigned long sp;
34     	__asm__ __volatile__("move.d sp,%0" : "=rm" (sp));
35     	return sp;
36     }
37     
38     static inline unsigned long _get_base(char * addr)
39     {
40       return 0;
41     }
42     
43     #define nop() __asm__ __volatile__ ("nop");
44     
45     #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
46     #define tas(ptr) (xchg((ptr),1))
47     
48     struct __xchg_dummy { unsigned long a[100]; };
49     #define __xg(x) ((struct __xchg_dummy *)(x))
50     
51     #if 0
52     /* use these and an oscilloscope to see the fraction of time we're running with IRQ's disabled */
53     /* it assumes the LED's are on port 0x90000000 of course. */
54     #define sti() __asm__ __volatile__ ( "ei\n\tpush r0\n\tmoveq 0,r0\n\tmove.d r0,[0x90000000]\n\tpop r0" );
55     #define cli() __asm__ __volatile__ ( "di\n\tpush r0\n\tmove.d 0x40000,r0\n\tmove.d r0,[0x90000000]\n\tpop r0");
56     #define save_flags(x) __asm__ __volatile__ ("move ccr,%0" : "=rm" (x) : : "memory");
57     #define restore_flags(x) __asm__ __volatile__ ("move %0,ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush r0\n\tmoveq 0,r0\n\tmove.d r0,[0x90000000]\n\tpop r0\n1:\n" : : "r" (x) : "memory");
58     #else
59     #define __cli() __asm__ __volatile__ ( "di");
60     #define __sti() __asm__ __volatile__ ( "ei" );
61     #define __save_flags(x) __asm__ __volatile__ ("move ccr,%0" : "=rm" (x) : : "memory");
62     #define __restore_flags(x) __asm__ __volatile__ ("move %0,ccr" : : "rm" (x) : "memory");
63     
64     /* For spinlocks etc */
65     #define local_irq_save(x) __asm__ __volatile__ ("move ccr,%0\n\tdi" : "=rm" (x) : : "memory"); 
66     #define local_irq_restore(x) restore_flags(x)
67     
68     #define local_irq_disable()  cli()
69     #define local_irq_enable()   sti()
70     
71     #endif
72     
73     #define cli() __cli()
74     #define sti() __sti()
75     #define save_flags(x) __save_flags(x)
76     #define restore_flags(x) __restore_flags(x)
77     #define save_and_cli(x) do { __save_flags(x); cli(); } while(0)
78     
79     static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
80     {
81       /* since Etrax doesn't have any atomic xchg instructions, we need to disable
82          irq's (if enabled) and do it with move.d's */
83     #if 0
84       unsigned int flags;
85       save_flags(flags); /* save flags, including irq enable bit */
86       cli();             /* shut off irq's */
87       switch (size) {
88       case 1:
89         __asm__ __volatile__ (
90            "move.b %0,r0\n\t"
91            "move.b %1,%0\n\t"
92            "move.b r0,%1\n\t"
93            : "=r" (x)
94            : "m" (*__xg(ptr)), "r" (x)
95            : "memory","r0");    
96         break;
97       case 2:
98         __asm__ __volatile__ (
99            "move.w %0,r0\n\t"
100            "move.w %1,%0\n\t"
101            "move.w r0,%1\n\t"
102            : "=r" (x)
103            : "m" (*__xg(ptr)), "r" (x)
104            : "memory","r0");
105         break;
106       case 4:
107         __asm__ __volatile__ (
108            "move.d %0,r0\n\t"
109            "move.d %1,%0\n\t"
110            "move.d r0,%1\n\t"
111            : "=r" (x)
112            : "m" (*__xg(ptr)), "r" (x)
113            : "memory","r0");
114         break;
115       }
116       restore_flags(flags); /* restore irq enable bit */
117       return x;
118     #else
119       unsigned long flags,temp;
120       save_flags(flags); /* save flags, including irq enable bit */
121       cli();             /* shut off irq's */
122       switch (size) {
123       case 1:
124         *((unsigned char *)&temp) = x;
125         x = *(unsigned char *)ptr;
126         *(unsigned char *)ptr = *((unsigned char *)&temp);
127         break;
128       case 2:
129         *((unsigned short *)&temp) = x;
130         x = *(unsigned short *)ptr;
131         *(unsigned short *)ptr = *((unsigned short *)&temp);
132         break;
133       case 4:
134         temp = x;
135         x = *(unsigned long *)ptr;
136         *(unsigned long *)ptr = temp;
137         break;
138       }
139       restore_flags(flags); /* restore irq enable bit */
140       return x;
141     #endif
142     }
143     
144     #define mb() __asm__ __volatile__ ("" : : : "memory")
145     #define rmb() mb()
146     #define wmb() mb()
147     
148     #ifdef CONFIG_SMP
149     #define smp_mb()        mb()
150     #define smp_rmb()       rmb()
151     #define smp_wmb()       wmb()
152     #else
153     #define smp_mb()        barrier()
154     #define smp_rmb()       barrier()
155     #define smp_wmb()       barrier()
156     #endif
157     
158     #define iret()
159     
160     /*
161      * disable hlt during certain critical i/o operations
162      */
163     #define HAVE_DISABLE_HLT
164     void disable_hlt(void);
165     void enable_hlt(void);
166     
167     #endif
168