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

1     /*
2      *  include/asm-s390/system.h
3      *
4      *  S390 version
5      *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6      *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
7      *
8      *  Derived from "include/asm-i386/system.h"
9      */
10     
11     #ifndef __ASM_SYSTEM_H
12     #define __ASM_SYSTEM_H
13     
14     #include <linux/config.h>
15     #ifdef __KERNEL__
16     #include <asm/lowcore.h>
17     #endif
18     #include <linux/kernel.h>
19     
20     #define prepare_to_switch()	do { } while(0)
21     #define switch_to(prev,next,last) do {                                       \
22             if (prev == next)                                                    \
23                     break;                                                       \
24     	save_fp_regs1(&prev->thread.fp_regs);                                \
25     	restore_fp_regs1(&next->thread.fp_regs);              		     \
26     	last = resume(&prev->thread,&next->thread);                          \
27     } while (0)
28     
29     struct task_struct;
30     
31     #define nop() __asm__ __volatile__ ("nop")
32     
33     #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
34     
35     extern void __misaligned_u16(void);
36     extern void __misaligned_u32(void);
37     
38     static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
39     {
40             switch (size) {
41                     case 1:
42                             asm volatile (
43                                     "   lhi   1,3\n"
44                                     "   nr    1,%0\n"     /* isolate last 2 bits */
45                                     "   xr    %0,1\n"     /* align ptr */
46                                     "   bras  2,0f\n"
47                                     "   icm   1,8,3(%1)\n"   /* for ptr&3 == 0 */
48                                     "   stcm  0,8,3(%1)\n"
49                                     "   icm   1,4,3(%1)\n"   /* for ptr&3 == 1 */
50                                     "   stcm  0,4,3(%1)\n"
51                                     "   icm   1,2,3(%1)\n"   /* for ptr&3 == 2 */
52                                     "   stcm  0,2,3(%1)\n"
53                                     "   icm   1,1,3(%1)\n"   /* for ptr&3 == 3 */
54                                     "   stcm  0,1,3(%1)\n"
55                                     "0: sll   1,3\n"
56                                     "   la    2,0(1,2)\n" /* r2 points to an icm */
57                                     "   l     0,0(%0)\n"  /* get fullword */
58                                     "1: lr    1,0\n"      /* cs loop */
59                                     "   ex    0,0(2)\n"   /* insert x */
60                                     "   cs    0,1,0(%0)\n"
61                                     "   jl    1b\n"
62                                     "   ex    0,4(2)"     /* store *ptr to x */
63                                     : "+a&" (ptr) : "a" (&x)
64                                     : "memory", "cc", "0", "1", "2");
65     			break;
66                     case 2:
67                             if(((__u32)ptr)&1)
68     				__misaligned_u16();
69                             asm volatile (
70                                     "   lhi   1,2\n"
71                                     "   nr    1,%0\n"     /* isolate bit 2^1 */
72                                     "   xr    %0,1\n"     /* align ptr */
73                                     "   bras  2,0f\n"
74                                     "   icm   1,12,2(%1)\n"   /* for ptr&2 == 0 */
75                                     "   stcm  0,12,2(%1)\n"
76                                     "   icm   1,3,2(%1)\n"    /* for ptr&2 == 1 */
77                                     "   stcm  0,3,2(%1)\n"
78                                     "0: sll   1,2\n"
79                                     "   la    2,0(1,2)\n" /* r2 points to an icm */
80                                     "   l     0,0(%0)\n"  /* get fullword */
81                                     "1: lr    1,0\n"      /* cs loop */
82                                     "   ex    0,0(2)\n"   /* insert x */
83                                     "   cs    0,1,0(%0)\n"
84                                     "   jl    1b\n"
85                                     "   ex    0,4(2)"     /* store *ptr to x */
86                                     : "+a&" (ptr) : "a" (&x)
87                                     : "memory", "cc", "0", "1", "2");
88                             break;
89                     case 4:
90                             if(((__u32)ptr)&3)
91     				__misaligned_u32();
92                             asm volatile (
93                                     "    l   0,0(%1)\n"
94                                     "0:  cs  0,%0,0(%1)\n"
95                                     "    jl  0b\n"
96                                     "    lr  %0,0\n"
97                                     : "+d&" (x) : "a" (ptr)
98                                     : "memory", "cc", "0" );
99                             break;
100                    default:
101                             abort();
102             }
103             return x;
104     }
105     
106     /*
107      * Force strict CPU ordering.
108      * And yes, this is required on UP too when we're talking
109      * to devices.
110      *
111      * This is very similar to the ppc eieio/sync instruction in that is
112      * does a checkpoint syncronisation & makes sure that 
113      * all memory ops have completed wrt other CPU's ( see 7-15 POP  DJB ).
114      */
115     
116     #define eieio()  __asm__ __volatile__ ("BCR 15,0") 
117     # define SYNC_OTHER_CORES(x)   eieio() 
118     #define mb()    eieio()
119     #define rmb()   eieio()
120     #define wmb()   eieio()
121     #define smp_mb()       mb()
122     #define smp_rmb()      rmb()
123     #define smp_wmb()      wmb()
124     #define smp_mb__before_clear_bit()     smp_mb()
125     #define smp_mb__after_clear_bit()      smp_mb()
126     
127     
128     #define set_mb(var, value)      do { var = value; mb(); } while (0)
129     #define set_wmb(var, value)     do { var = value; wmb(); } while (0)
130     
131     /* interrupt control.. */
132     #define __sti() ({ \
133             __u8 dummy; \
134             __asm__ __volatile__ ( \
135                     "stosm %0,0x03" : "=m" (dummy) : : "memory"); \
136             })
137     
138     #define __cli() ({ \
139             __u32 flags; \
140             __asm__ __volatile__ ( \
141                     "stnsm %0,0xFC" : "=m" (flags) : : "memory"); \
142             flags; \
143             })
144     
145     #define __save_flags(x) \
146             __asm__ __volatile__("stosm %0,0" : "=m" (x) : : "memory")
147     
148     #define __restore_flags(x) \
149             __asm__ __volatile__("ssm   %0" : : "m" (x) : "memory")
150     
151     #define __load_psw(psw) \
152     	__asm__ __volatile__("lpsw %0" : : "m" (psw) : "cc" );
153     
154     #define __ctl_load(array, low, high) ({ \
155     	__asm__ __volatile__ ( \
156     		"   la    1,%0\n" \
157     		"   bras  2,0f\n" \
158                     "   lctl  0,0,0(1)\n" \
159     		"0: ex    %1,0(2)" \
160     		: : "m" (array), "a" (((low)<<4)+(high)) : "1", "2" ); \
161     	})
162     
163     #define __ctl_store(array, low, high) ({ \
164     	__asm__ __volatile__ ( \
165     		"   la    1,%0\n" \
166     		"   bras  2,0f\n" \
167     		"   stctl 0,0,0(1)\n" \
168     		"0: ex    %1,0(2)" \
169     		: "=m" (array) : "a" (((low)<<4)+(high)): "1", "2" ); \
170     	})
171     
172     #define __ctl_set_bit(cr, bit) ({ \
173             __u8 dummy[16]; \
174             __asm__ __volatile__ ( \
175                     "    la    1,%0\n"       /* align to 8 byte */ \
176                     "    ahi   1,7\n" \
177                     "    srl   1,3\n" \
178                     "    sll   1,3\n" \
179                     "    bras  2,0f\n"       /* skip indirect insns */ \
180                     "    stctl 0,0,0(1)\n" \
181                     "    lctl  0,0,0(1)\n" \
182                     "0:  ex    %1,0(2)\n"    /* execute stctl */ \
183                     "    l     0,0(1)\n" \
184                     "    or    0,%2\n"       /* set the bit */ \
185                     "    st    0,0(1)\n" \
186                     "1:  ex    %1,4(2)"      /* execute lctl */ \
187                     : "=m" (dummy) : "a" (cr*17), "a" (1<<(bit)) \
188                     : "cc", "0", "1", "2"); \
189             })
190     
191     #define __ctl_clear_bit(cr, bit) ({ \
192             __u8 dummy[16]; \
193             __asm__ __volatile__ ( \
194                     "    la    1,%0\n"       /* align to 8 byte */ \
195                     "    ahi   1,7\n" \
196                     "    srl   1,3\n" \
197                     "    sll   1,3\n" \
198                     "    bras  2,0f\n"       /* skip indirect insns */ \
199                     "    stctl 0,0,0(1)\n" \
200                     "    lctl  0,0,0(1)\n" \
201                     "0:  ex    %1,0(2)\n"    /* execute stctl */ \
202                     "    l     0,0(1)\n" \
203                     "    nr    0,%2\n"       /* set the bit */ \
204                     "    st    0,0(1)\n" \
205                     "1:  ex    %1,4(2)"      /* execute lctl */ \
206                     : "=m" (dummy) : "a" (cr*17), "a" (~(1<<(bit))) \
207                     : "cc", "0", "1", "2"); \
208             })
209     
210     /* For spinlocks etc */
211     #define local_irq_save(x)	((x) = __cli())
212     #define local_irq_restore(x)	__restore_flags(x)
213     #define local_irq_disable()	__cli()
214     #define local_irq_enable()	__sti()
215     
216     #ifdef CONFIG_SMP
217     
218     extern void __global_cli(void);
219     extern void __global_sti(void);
220     
221     extern unsigned long __global_save_flags(void);
222     extern void __global_restore_flags(unsigned long);
223     #define cli() __global_cli()
224     #define sti() __global_sti()
225     #define save_flags(x) ((x)=__global_save_flags())
226     #define restore_flags(x) __global_restore_flags(x)
227     
228     extern void smp_ctl_set_bit(int cr, int bit);
229     extern void smp_ctl_clear_bit(int cr, int bit);
230     #define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit)
231     #define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit)
232     
233     #else
234     
235     #define cli() __cli()
236     #define sti() __sti()
237     #define save_flags(x) __save_flags(x)
238     #define restore_flags(x) __restore_flags(x)
239     
240     #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
241     #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)
242     
243     
244     #endif
245     
246     #ifdef __KERNEL__
247     extern struct task_struct *resume(void *,void *);
248     
249     extern int save_fp_regs1(s390_fp_regs *fpregs);
250     extern void save_fp_regs(s390_fp_regs *fpregs);
251     extern int restore_fp_regs1(s390_fp_regs *fpregs);
252     extern void restore_fp_regs(s390_fp_regs *fpregs);
253     #endif
254     
255     #endif
256     
257     
258     
259