OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-x86_64/] [system.h] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#ifndef __ASM_SYSTEM_H
2
#define __ASM_SYSTEM_H
3
 
4
#include <linux/config.h>
5
#include <linux/kernel.h>
6
#include <asm/segment.h>
7
 
8
#ifdef __KERNEL__
9
 
10
#ifdef CONFIG_SMP
11
#define LOCK_PREFIX "lock ; "
12
#else
13
#define LOCK_PREFIX ""
14
#endif
15
 
16
#define prepare_to_switch() do {} while(0)
17
 
18
#define __STR(x) #x
19
#define STR(x) __STR(x)
20
 
21
#define __PUSH(x) "pushq %%" __STR(x) "\n\t"
22
#define __POP(x)  "popq  %%" __STR(x) "\n\t"
23
 
24
struct save_context_frame {
25
        unsigned long rbp;
26
        unsigned long rbx;
27
        unsigned long r11;
28
        unsigned long r10;
29
        unsigned long r9;
30
        unsigned long r8;
31
        unsigned long rcx;
32
        unsigned long rdx;
33
        unsigned long r15;
34
        unsigned long r14;
35
        unsigned long r13;
36
        unsigned long r12;
37
        unsigned long rdi;
38
        unsigned long rsi;
39
};
40
 
41
/* frame pointer must be last for get_wchan */
42
#define SAVE_CONTEXT \
43
        __PUSH(rsi) __PUSH(rdi) \
44
    __PUSH(r12) __PUSH(r13) __PUSH(r14) __PUSH(r15)  \
45
        __PUSH(rdx) __PUSH(rcx) __PUSH(r8) __PUSH(r9) __PUSH(r10) __PUSH(r11)  \
46
        __PUSH(rbx) __PUSH(rbp)
47
#define RESTORE_CONTEXT \
48
        __POP(rbp) __POP(rbx) \
49
        __POP(r11) __POP(r10) __POP(r9) __POP(r8) __POP(rcx) __POP(rdx) \
50
        __POP(r15) __POP(r14) __POP(r13) __POP(r12) \
51
        __POP(rdi) __POP(rsi)
52
 
53
#define switch_to(prev,next,last) do { void *l; \
54
        asm volatile(SAVE_CONTEXT                                       \
55
                     "movq %%rsp,%0\n\t"        /* save RSP */          \
56
                     "movq %3,%%rsp\n\t"        /* restore RSP */       \
57
                     "leaq thread_return(%%rip),%%rax\n\t"              \
58
                     "movq %%rax,%1\n\t"        /* save RIP */          \
59
                     "pushq %4\n\t"             /* setup new RIP */     \
60
                     "jmp __switch_to\n\t"                              \
61
                     ".globl thread_return\n"                           \
62
                     "thread_return:\n\t"                               \
63
                     RESTORE_CONTEXT                                    \
64
                     :"=m" (prev->thread.rsp),"=m" (prev->thread.rip), "=a" (l) \
65
                     :"m" (next->thread.rsp),"m" (next->thread.rip),    \
66
                      "S" (next), "D" (prev)                            \
67
                     :"memory","cc");                                   \
68
        last = l;                                                       \
69
} while(0)
70
 
71
extern void load_gs_index(unsigned);
72
 
73
/*
74
 * Load a segment. Fall back on loading the zero
75
 * segment if something goes wrong..
76
 */
77
#define loadsegment(seg,value)  \
78
        asm volatile("\n"                       \
79
                "1:\t"                          \
80
                "movl %0,%%" #seg "\n"          \
81
                "2:\n"                          \
82
                ".section .fixup,\"ax\"\n"      \
83
                "3:\t"                          \
84
                "movl %1,%%" #seg "\n\t" \
85
                "jmp 2b\n"                      \
86
                ".previous\n"                   \
87
                ".section __ex_table,\"a\"\n\t" \
88
                ".align 4\n\t"                  \
89
                ".quad 1b,3b\n"                 \
90
                ".previous"                     \
91
                : :"r" ((int)(value)), "r" (0))
92
 
93
#define set_debug(value,register) \
94
                __asm__("movq %0,%%db" #register  \
95
                : /* no output */ \
96
                :"r" ((unsigned long) value))
97
 
98
 
99
/*
100
 * Clear and set 'TS' bit respectively
101
 */
102
#define clts() __asm__ __volatile__ ("clts")
103
#define read_cr0() ({ \
104
        unsigned long __dummy; \
105
        __asm__( \
106
                "movq %%cr0,%0\n\t" \
107
                :"=r" (__dummy)); \
108
        __dummy; \
109
})
110
#define write_cr0(x) \
111
        __asm__("movq %0,%%cr0": :"r" (x));
112
 
113
#define read_cr4() ({ \
114
        unsigned long __dummy; \
115
        __asm__( \
116
                "movq %%cr4,%0\n\t" \
117
                :"=r" (__dummy)); \
118
        __dummy; \
119
})
120
#define write_cr4(x) \
121
        __asm__("movq %0,%%cr4": :"r" (x));
122
#define stts() write_cr0(8 | read_cr0())
123
 
124
#define wbinvd() \
125
        __asm__ __volatile__ ("wbinvd": : :"memory");
126
 
127
#endif  /* __KERNEL__ */
128
 
129
#define nop() __asm__ __volatile__ ("nop")
130
 
131
#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
132
 
133
#define tas(ptr) (xchg((ptr),1))
134
 
135
#define __xg(x) ((volatile long *)(x))
136
 
137
extern inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
138
{
139
        *ptr = val;
140
}
141
 
142
#define _set_64bit set_64bit
143
 
144
/*
145
 * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
146
 * Note 2: xchg has side effect, so that attribute volatile is necessary,
147
 *        but generally the primitive is invalid, *ptr is output argument. --ANK
148
 */
149
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
150
{
151
        switch (size) {
152
                case 1:
153
                        __asm__ __volatile__("xchgb %b0,%1"
154
                                :"=q" (x)
155
                                :"m" (*__xg(ptr)), "0" (x)
156
                                :"memory");
157
                        break;
158
                case 2:
159
                        __asm__ __volatile__("xchgw %w0,%1"
160
                                :"=r" (x)
161
                                :"m" (*__xg(ptr)), "0" (x)
162
                                :"memory");
163
                        break;
164
                case 4:
165
                        __asm__ __volatile__("xchgl %k0,%1"
166
                                :"=r" (x)
167
                                :"m" (*__xg(ptr)), "0" (x)
168
                                :"memory");
169
                        break;
170
                case 8:
171
                        __asm__ __volatile__("xchgq %0,%1"
172
                                :"=r" (x)
173
                                :"m" (*__xg(ptr)), "0" (x)
174
                                :"memory");
175
                        break;
176
        }
177
        return x;
178
}
179
 
180
/*
181
 * Atomic compare and exchange.  Compare OLD with MEM, if identical,
182
 * store NEW in MEM.  Return the initial value in MEM.  Success is
183
 * indicated by comparing RETURN with OLD.
184
 */
185
 
186
#define __HAVE_ARCH_CMPXCHG 1
187
 
188
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
189
                                      unsigned long new, int size)
190
{
191
        unsigned long prev;
192
        switch (size) {
193
        case 1:
194
                __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
195
                                     : "=a"(prev)
196
                                     : "q"(new), "m"(*__xg(ptr)), "0"(old)
197
                                     : "memory");
198
                return prev;
199
        case 2:
200
                __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
201
                                     : "=a"(prev)
202
                                     : "q"(new), "m"(*__xg(ptr)), "0"(old)
203
                                     : "memory");
204
                return prev;
205
        case 4:
206
                __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
207
                                     : "=a"(prev)
208
                                     : "q"(new), "m"(*__xg(ptr)), "0"(old)
209
                                     : "memory");
210
                return prev;
211
        case 8:
212
                __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
213
                                     : "=a"(prev)
214
                                     : "q"(new), "m"(*__xg(ptr)), "0"(old)
215
                                     : "memory");
216
                return prev;
217
        }
218
        return old;
219
}
220
 
221
#define cmpxchg(ptr,o,n)\
222
        ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
223
                                        (unsigned long)(n),sizeof(*(ptr))))
224
 
225
 
226
#ifdef CONFIG_SMP
227
#define smp_mb()        mb()
228
#define smp_rmb()       rmb()
229
#define smp_wmb()       wmb()
230
#else
231
#define smp_mb()        barrier()
232
#define smp_rmb()       barrier()
233
#define smp_wmb()       barrier()
234
#endif
235
 
236
 
237
/*
238
 * Force strict CPU ordering.
239
 * And yes, this is required on UP too when we're talking
240
 * to devices.
241
 *
242
 * For now, "wmb()" doesn't actually do anything, as all
243
 * Intel CPU's follow what Intel calls a *Processor Order*,
244
 * in which all writes are seen in the program order even
245
 * outside the CPU.
246
 *
247
 * I expect future Intel CPU's to have a weaker ordering,
248
 * but I'd also expect them to finally get their act together
249
 * and add some real memory barriers if so.
250
 */
251
#define mb()    asm volatile("mfence":::"memory")
252
#define rmb()   asm volatile("lfence":::"memory")
253
#define wmb()   asm volatile("sfence":::"memory")
254
#define set_mb(var, value) do { xchg(&var, value); } while (0)
255
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
256
 
257
#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
258
 
259
/* interrupt control.. */
260
#define __save_flags(x)         do { warn_if_not_ulong(x); __asm__ __volatile__("# save_flags \n\t pushfq ; popq %q0":"=g" (x): /* no input */ :"memory"); } while (0)
261
#define __restore_flags(x)      __asm__ __volatile__("# restore_flags \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc")
262
#define __cli()                 __asm__ __volatile__("cli": : :"memory")
263
#define __sti()                 __asm__ __volatile__("sti": : :"memory")
264
/* used in the idle loop; sti takes one instruction cycle to complete */
265
#define safe_halt()             __asm__ __volatile__("sti; hlt": : :"memory")
266
 
267
#define __save_and_cli(x)      do { __save_flags(x); __cli(); } while(0)
268
#define __save_and_sti(x)      do { __save_flags(x); __sti(); } while(0)
269
 
270
/* For spinlocks etc */
271
#define local_irq_save(x)       do { warn_if_not_ulong(x); __asm__ __volatile__("# local_irq_save \n\t pushfq ; popq %0 ; cli":"=g" (x): /* no input */ :"memory"); } while (0)
272
#define local_irq_set(x)        do { warn_if_not_ulong(x); __asm__ __volatile__("# local_irq_set \n\t pushfq ; popq %0 ; sti":"=g" (x): /* no input */ :"memory"); } while (0)
273
#define local_irq_restore(x)    __asm__ __volatile__("# local_irq_restore \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory")
274
#define local_irq_disable()     __cli()
275
#define local_irq_enable()      __sti()
276
 
277
#ifdef CONFIG_SMP
278
 
279
extern void __global_cli(void);
280
extern void __global_sti(void);
281
extern unsigned long __global_save_flags(void);
282
extern void __global_restore_flags(unsigned long);
283
#define cli() __global_cli()
284
#define sti() __global_sti()
285
#define save_flags(x) ((x)=__global_save_flags())
286
#define restore_flags(x) __global_restore_flags(x)
287
#define save_and_cli(x) do { save_flags(x); cli(); } while(0)
288
#define save_and_sti(x) do { save_flags(x); sti(); } while(0)
289
 
290
#else
291
 
292
#define cli() __cli()
293
#define sti() __sti()
294
#define save_flags(x) __save_flags(x)
295
#define restore_flags(x) __restore_flags(x)
296
#define save_and_cli(x) __save_and_cli(x)
297
#define save_and_sti(x) __save_and_sti(x)
298
 
299
#endif
300
 
301
/* Default simics "magic" breakpoint */
302
#define icebp() asm volatile("xchg %%bx,%%bx" ::: "ebx")
303
 
304
/*
305
 * disable hlt during certain critical i/o operations
306
 */
307
#define HAVE_DISABLE_HLT
308
void disable_hlt(void);
309
void enable_hlt(void);
310
 
311
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.