~ubuntu-branches/ubuntu/trusty/apex/trusty

« back to all changes in this revision

Viewing changes to include/asm-arm/system.h

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2009-11-10 11:55:15 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091110115515-6jjsf6rc8py35awe
Tags: 1.6.10ubuntu1
* Merge from debian testing, remaining changes:
  - Move apex VMA address to 4MiB to leave enough space for the ubuntu
  kernel and not overwrite apex in ram when loading.
  - nslu2 configuration: set CONFIG_RAMDISK_SIZE=0x0055FFF0 instead of
  0x005FFFF0 to make enough room for ubuntu initramfs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 
4
4
#ifdef __KERNEL__
5
5
 
6
 
#include <linux/config.h>
 
6
#include <asm/memory.h>
7
7
 
8
8
#define CPU_ARCH_UNKNOWN        0
9
9
#define CPU_ARCH_ARMv3          1
14
14
#define CPU_ARCH_ARMv5TE        6
15
15
#define CPU_ARCH_ARMv5TEJ       7
16
16
#define CPU_ARCH_ARMv6          8
 
17
#define CPU_ARCH_ARMv7          9
17
18
 
18
19
/*
19
20
 * CR1 bits (CP#15 CR1)
47
48
#define CPUID_TCM       2
48
49
#define CPUID_TLBTYPE   3
49
50
 
50
 
#define read_cpuid(reg)                                                 \
51
 
        ({                                                              \
52
 
                unsigned int __val;                                     \
53
 
                asm("mrc%? p15, 0, %0, c0, c0, " __stringify(reg)       \
54
 
                    : "=r" (__val));                                    \
55
 
                __val;                                                  \
56
 
        })
57
 
 
58
 
#define __cacheid_present(val)          (val != read_cpuid(CPUID_ID))
59
 
#define __cacheid_vivt(val)             ((val & (15 << 25)) != (14 << 25))
60
 
#define __cacheid_vipt(val)             ((val & (15 << 25)) == (14 << 25))
61
 
#define __cacheid_vipt_nonaliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25))
62
 
#define __cacheid_vipt_aliasing(val)    ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23))
63
 
 
64
 
#define cache_is_vivt()                                                 \
65
 
        ({                                                              \
66
 
                unsigned int __val = read_cpuid(CPUID_CACHETYPE);       \
67
 
                (!__cacheid_present(__val)) || __cacheid_vivt(__val);   \
68
 
        })
69
 
                
70
 
#define cache_is_vipt()                                                 \
71
 
        ({                                                              \
72
 
                unsigned int __val = read_cpuid(CPUID_CACHETYPE);       \
73
 
                __cacheid_present(__val) && __cacheid_vipt(__val);      \
74
 
        })
75
 
 
76
 
#define cache_is_vipt_nonaliasing()                                     \
77
 
        ({                                                              \
78
 
                unsigned int __val = read_cpuid(CPUID_CACHETYPE);       \
79
 
                __cacheid_present(__val) &&                             \
80
 
                 __cacheid_vipt_nonaliasing(__val);                     \
81
 
        })
82
 
 
83
 
#define cache_is_vipt_aliasing()                                        \
84
 
        ({                                                              \
85
 
                unsigned int __val = read_cpuid(CPUID_CACHETYPE);       \
86
 
                __cacheid_present(__val) &&                             \
87
 
                 __cacheid_vipt_aliasing(__val);                        \
88
 
        })
89
 
 
90
51
/*
91
52
 * This is used to ensure the compiler did actually allocate the register we
92
53
 * asked it for some inline assembly sequences.  Apparently we can't trust
93
54
 * the compiler from one version to another so a bit of paranoia won't hurt.
94
55
 * This string is meant to be concatenated with the inline asm string and
95
56
 * will cause compilation to stop on mismatch.
 
57
 * (for details, see gcc PR 15089)
96
58
 */
97
59
#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
98
60
 
99
61
#ifndef __ASSEMBLY__
100
62
 
101
63
#include <linux/linkage.h>
 
64
#include <linux/stringify.h>
 
65
#include <linux/irqflags.h>
 
66
 
 
67
#ifdef CONFIG_CPU_CP15
 
68
#define read_cpuid(reg)                                                 \
 
69
        ({                                                              \
 
70
                unsigned int __val;                                     \
 
71
                asm("mrc        p15, 0, %0, c0, c0, " __stringify(reg)  \
 
72
                    : "=r" (__val)                                      \
 
73
                    :                                                   \
 
74
                    : "cc");                                            \
 
75
                __val;                                                  \
 
76
        })
 
77
#else
 
78
extern unsigned int processor_id;
 
79
#define read_cpuid(reg) (processor_id)
 
80
#endif
 
81
 
 
82
/*
 
83
 * The CPU ID never changes at run time, so we might as well tell the
 
84
 * compiler that it's constant.  Use this function to read the CPU ID
 
85
 * rather than directly reading processor_id or read_cpuid() directly.
 
86
 */
 
87
static inline unsigned int read_cpuid_id(void) __attribute_const__;
 
88
 
 
89
static inline unsigned int read_cpuid_id(void)
 
90
{
 
91
        return read_cpuid(CPUID_ID);
 
92
}
 
93
 
 
94
#define __exception     __attribute__((section(".exception.text")))
102
95
 
103
96
struct thread_info;
104
97
struct task_struct;
114
107
void die(const char *msg, struct pt_regs *regs, int err)
115
108
                __attribute__((noreturn));
116
109
 
117
 
void die_if_kernel(const char *str, struct pt_regs *regs, int err);
 
110
struct siginfo;
 
111
void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
 
112
                unsigned long err, unsigned long trap);
118
113
 
119
114
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
120
115
                                       struct pt_regs *),
121
116
                     int sig, const char *name);
122
117
 
123
 
//#include <asm/proc-fns.h>
124
 
 
125
118
#define xchg(ptr,x) \
126
119
        ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
127
120
 
128
 
#define tas(ptr) (xchg((ptr),1))
129
 
 
130
121
extern asmlinkage void __backtrace(void);
 
122
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
 
123
 
 
124
struct mm_struct;
 
125
extern void show_pte(struct mm_struct *mm, unsigned long addr);
 
126
extern void __show_regs(struct pt_regs *);
131
127
 
132
128
extern int cpu_architecture(void);
133
 
 
134
 
#define set_cr(x)                                       \
135
 
        __asm__ __volatile__(                           \
136
 
        "mcr    p15, 0, %0, c1, c0, 0   @ set CR"       \
137
 
        : : "r" (x) : "cc")
138
 
 
139
 
#define get_cr()                                        \
140
 
        ({                                              \
141
 
        unsigned int __val;                             \
142
 
        __asm__ __volatile__(                           \
143
 
        "mrc    p15, 0, %0, c1, c0, 0   @ get CR"       \
144
 
        : "=r" (__val) : : "cc");                       \
145
 
        __val;                                          \
146
 
        })
147
 
 
148
 
extern unsigned long cr_no_alignment;   /* defined in entry-armv.S */
149
 
extern unsigned long cr_alignment;      /* defined in entry-armv.S */
 
129
extern void cpu_init(void);
 
130
 
 
131
void arm_machine_restart(char mode);
 
132
extern void (*arm_pm_restart)(char str);
 
133
 
 
134
/*
 
135
 * Intel's XScale3 core supports some v6 features (supersections, L2)
 
136
 * but advertises itself as v5 as it does not support the v6 ISA.  For
 
137
 * this reason, we need a way to explicitly test for this type of CPU.
 
138
 */
 
139
#ifndef CONFIG_CPU_XSC3
 
140
#define cpu_is_xsc3()   0
 
141
#else
 
142
static inline int cpu_is_xsc3(void)
 
143
{
 
144
        extern unsigned int processor_id;
 
145
 
 
146
        if ((processor_id & 0xffffe000) == 0x69056000)
 
147
                return 1;
 
148
 
 
149
        return 0;
 
150
}
 
151
#endif
 
152
 
 
153
#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
 
154
#define cpu_is_xscale() 0
 
155
#else
 
156
#define cpu_is_xscale() 1
 
157
#endif
150
158
 
151
159
#define UDBG_UNDEFINED  (1 << 0)
152
160
#define UDBG_SYSCALL    (1 << 1)
157
165
extern unsigned int user_debug;
158
166
 
159
167
#if __LINUX_ARM_ARCH__ >= 4
160
 
#define vectors_base()  ((cr_alignment & CR_V) ? 0xffff0000 : 0)
161
 
#else
162
 
#define vectors_base()  (0)
163
 
#endif
164
 
 
165
 
#define mb() __asm__ __volatile__ ("" : : : "memory")
166
 
#define rmb() mb()
167
 
#define wmb() mb()
168
 
#define read_barrier_depends() do { } while(0)
169
 
#define set_mb(var, value)  do { var = value; mb(); } while (0)
170
 
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
168
#define vectors_high()  (cr_alignment & CR_V)
 
169
#else
 
170
#define vectors_high()  (0)
 
171
#endif
 
172
 
 
173
#if __LINUX_ARM_ARCH__ >= 7
 
174
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
 
175
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
 
176
#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
 
177
#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
 
178
#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
 
179
                                    : : "r" (0) : "memory")
 
180
#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
 
181
                                    : : "r" (0) : "memory")
 
182
#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
 
183
                                    : : "r" (0) : "memory")
 
184
#else
 
185
#define isb() __asm__ __volatile__ ("" : : : "memory")
 
186
#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
 
187
                                    : : "r" (0) : "memory")
 
188
#define dmb() __asm__ __volatile__ ("" : : : "memory")
 
189
#endif
 
190
 
 
191
#ifndef CONFIG_SMP
 
192
#define mb()    do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 
193
#define rmb()   do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 
194
#define wmb()   do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 
195
#define smp_mb()        barrier()
 
196
#define smp_rmb()       barrier()
 
197
#define smp_wmb()       barrier()
 
198
#else
 
199
#define mb()            dmb()
 
200
#define rmb()           dmb()
 
201
#define wmb()           dmb()
 
202
#define smp_mb()        dmb()
 
203
#define smp_rmb()       dmb()
 
204
#define smp_wmb()       dmb()
 
205
#endif
 
206
#define read_barrier_depends()          do { } while(0)
 
207
#define smp_read_barrier_depends()      do { } while(0)
 
208
 
 
209
#define set_mb(var, value)      do { var = value; smp_mb(); } while (0)
171
210
#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
172
211
 
173
 
#ifdef CONFIG_SMP
174
 
/*
175
 
 * Define our own context switch locking.  This allows us to enable
176
 
 * interrupts over the context switch, otherwise we end up with high
177
 
 * interrupt latency.  The real problem area is switch_mm() which may
178
 
 * do a full cache flush.
179
 
 */
180
 
#define prepare_arch_switch(rq,next)                                    \
181
 
do {                                                                    \
182
 
        spin_lock(&(next)->switch_lock);                                \
183
 
        spin_unlock_irq(&(rq)->lock);                                   \
184
 
} while (0)
185
 
 
186
 
#define finish_arch_switch(rq,prev)                                     \
187
 
        spin_unlock(&(prev)->switch_lock)
188
 
 
189
 
#define task_running(rq,p)                                              \
190
 
        ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
191
 
#else
192
 
/*
193
 
 * Our UP-case is more simple, but we assume knowledge of how
194
 
 * spin_unlock_irq() and friends are implemented.  This avoids
195
 
 * us needlessly decrementing and incrementing the preempt count.
196
 
 */
197
 
#define prepare_arch_switch(rq,next)    local_irq_enable()
198
 
#define finish_arch_switch(rq,prev)     spin_unlock(&(rq)->lock)
199
 
#define task_running(rq,p)              ((rq)->curr == (p))
 
212
extern unsigned long cr_no_alignment;   /* defined in entry-armv.S */
 
213
extern unsigned long cr_alignment;      /* defined in entry-armv.S */
 
214
 
 
215
static inline unsigned int get_cr(void)
 
216
{
 
217
        unsigned int val;
 
218
        asm("mrc p15, 0, %0, c1, c0, 0  @ get CR" : "=r" (val) : : "cc");
 
219
        return val;
 
220
}
 
221
 
 
222
static inline void set_cr(unsigned int val)
 
223
{
 
224
        asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
 
225
          : : "r" (val) : "cc");
 
226
        isb();
 
227
}
 
228
 
 
229
#ifndef CONFIG_SMP
 
230
extern void adjust_cr(unsigned long mask, unsigned long set);
200
231
#endif
201
232
 
 
233
#define CPACC_FULL(n)           (3 << (n * 2))
 
234
#define CPACC_SVC(n)            (1 << (n * 2))
 
235
#define CPACC_DISABLE(n)        (0 << (n * 2))
 
236
 
 
237
static inline unsigned int get_copro_access(void)
 
238
{
 
239
        unsigned int val;
 
240
        asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
 
241
          : "=r" (val) : : "cc");
 
242
        return val;
 
243
}
 
244
 
 
245
static inline void set_copro_access(unsigned int val)
 
246
{
 
247
        asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
 
248
          : : "r" (val) : "cc");
 
249
        isb();
 
250
}
 
251
 
 
252
/*
 
253
 * switch_mm() may do a full cache flush over the context switch,
 
254
 * so enable interrupts over the context switch to avoid high
 
255
 * latency.
 
256
 */
 
257
#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
 
258
 
202
259
/*
203
260
 * switch_to(prev, next) should switch from task `prev' to `next'
204
261
 * `prev' will never be the same as `next'.  schedule() itself
208
265
 
209
266
#define switch_to(prev,next,last)                                       \
210
267
do {                                                                    \
211
 
        last = __switch_to(prev,prev->thread_info,next->thread_info);   \
 
268
        last = __switch_to(prev,task_thread_info(prev), task_thread_info(next));        \
212
269
} while (0)
213
270
 
214
 
/*
215
 
 * CPU interrupt mask handling.
216
 
 */
217
 
#if __LINUX_ARM_ARCH__ >= 6
218
 
 
219
 
#define local_irq_save(x)                                       \
220
 
        ({                                                      \
221
 
        __asm__ __volatile__(                                   \
222
 
        "mrs    %0, cpsr                @ local_irq_save\n"     \
223
 
        "cpsid  i"                                              \
224
 
        : "=r" (x) : : "memory", "cc");                         \
225
 
        })
226
 
 
227
 
#define local_irq_enable()  __asm__("cpsie i    @ __sti" : : : "memory", "cc")
228
 
#define local_irq_disable() __asm__("cpsid i    @ __cli" : : : "memory", "cc")
229
 
#define local_fiq_enable()  __asm__("cpsie f    @ __stf" : : : "memory", "cc")
230
 
#define local_fiq_disable() __asm__("cpsid f    @ __clf" : : : "memory", "cc")
231
 
 
232
 
#else
233
 
 
234
 
/*
235
 
 * Save the current interrupt enable state & disable IRQs
236
 
 */
237
 
#define local_irq_save(x)                                       \
238
 
        ({                                                      \
239
 
                unsigned long temp;                             \
240
 
                (void) (&temp == &x);                           \
241
 
        __asm__ __volatile__(                                   \
242
 
        "mrs    %0, cpsr                @ local_irq_save\n"     \
243
 
"       orr     %1, %0, #128\n"                                 \
244
 
"       msr     cpsr_c, %1"                                     \
245
 
        : "=r" (x), "=r" (temp)                                 \
246
 
        :                                                       \
247
 
        : "memory", "cc");                                      \
248
 
        })
249
 
        
250
 
/*
251
 
 * Enable IRQs
252
 
 */
253
 
#define local_irq_enable()                                      \
254
 
        ({                                                      \
255
 
                unsigned long temp;                             \
256
 
        __asm__ __volatile__(                                   \
257
 
        "mrs    %0, cpsr                @ local_irq_enable\n"   \
258
 
"       bic     %0, %0, #128\n"                                 \
259
 
"       msr     cpsr_c, %0"                                     \
260
 
        : "=r" (temp)                                           \
261
 
        :                                                       \
262
 
        : "memory", "cc");                                      \
263
 
        })
264
 
 
265
 
/*
266
 
 * Disable IRQs
267
 
 */
268
 
#define local_irq_disable()                                     \
269
 
        ({                                                      \
270
 
                unsigned long temp;                             \
271
 
        __asm__ __volatile__(                                   \
272
 
        "mrs    %0, cpsr                @ local_irq_disable\n"  \
273
 
"       orr     %0, %0, #128\n"                                 \
274
 
"       msr     cpsr_c, %0"                                     \
275
 
        : "=r" (temp)                                           \
276
 
        :                                                       \
277
 
        : "memory", "cc");                                      \
278
 
        })
279
 
 
280
 
/*
281
 
 * Enable FIQs
282
 
 */
283
 
#define __stf()                                                 \
284
 
        ({                                                      \
285
 
                unsigned long temp;                             \
286
 
        __asm__ __volatile__(                                   \
287
 
        "mrs    %0, cpsr                @ stf\n"                \
288
 
"       bic     %0, %0, #64\n"                                  \
289
 
"       msr     cpsr_c, %0"                                     \
290
 
        : "=r" (temp)                                           \
291
 
        :                                                       \
292
 
        : "memory", "cc");                                      \
293
 
        })
294
 
 
295
 
/*
296
 
 * Disable FIQs
297
 
 */
298
 
#define __clf()                                                 \
299
 
        ({                                                      \
300
 
                unsigned long temp;                             \
301
 
        __asm__ __volatile__(                                   \
302
 
        "mrs    %0, cpsr                @ clf\n"                \
303
 
"       orr     %0, %0, #64\n"                                  \
304
 
"       msr     cpsr_c, %0"                                     \
305
 
        : "=r" (temp)                                           \
306
 
        :                                                       \
307
 
        : "memory", "cc");                                      \
308
 
        })
309
 
 
310
 
#endif
311
 
 
312
 
/*
313
 
 * Save the current interrupt enable state.
314
 
 */
315
 
#define local_save_flags(x)                                     \
316
 
        ({                                                      \
317
 
        __asm__ __volatile__(                                   \
318
 
        "mrs    %0, cpsr                @ local_save_flags"     \
319
 
        : "=r" (x) : : "memory", "cc");                         \
320
 
        })
321
 
 
322
 
/*
323
 
 * restore saved IRQ & FIQ state
324
 
 */
325
 
#define local_irq_restore(x)                                    \
326
 
        __asm__ __volatile__(                                   \
327
 
        "msr    cpsr_c, %0              @ local_irq_restore\n"  \
328
 
        :                                                       \
329
 
        : "r" (x)                                               \
330
 
        : "memory", "cc")
331
 
 
332
 
#ifdef CONFIG_SMP
333
 
#error SMP not supported
334
 
 
335
 
#define smp_mb()                mb()
336
 
#define smp_rmb()               rmb()
337
 
#define smp_wmb()               wmb()
338
 
#define smp_read_barrier_depends()              read_barrier_depends()
339
 
 
340
 
#else
341
 
 
342
 
#define smp_mb()                barrier()
343
 
#define smp_rmb()               barrier()
344
 
#define smp_wmb()               barrier()
345
 
#define smp_read_barrier_depends()              do { } while(0)
346
 
 
347
 
#define clf()                   __clf()
348
 
#define stf()                   __stf()
349
 
 
350
 
#define irqs_disabled()                 \
351
 
({                                      \
352
 
        unsigned long flags;            \
353
 
        local_save_flags(flags);        \
354
 
        flags & PSR_I_BIT;              \
355
 
})
356
 
 
357
271
#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
358
272
/*
359
273
 * On the StrongARM, "swp" is terminally broken since it bypasses the
366
280
 *
367
281
 * We choose (1) since its the "easiest" to achieve here and is not
368
282
 * dependent on the processor type.
 
283
 *
 
284
 * NOTE that this solution won't work on an SMP system, so explcitly
 
285
 * forbid it here.
369
286
 */
370
287
#define swp_is_buggy
371
288
#endif
377
294
#ifdef swp_is_buggy
378
295
        unsigned long flags;
379
296
#endif
 
297
#if __LINUX_ARM_ARCH__ >= 6
 
298
        unsigned int tmp;
 
299
#endif
380
300
 
381
301
        switch (size) {
382
 
#ifdef swp_is_buggy
383
 
                case 1:
384
 
                        local_irq_save(flags);
385
 
                        ret = *(volatile unsigned char *)ptr;
386
 
                        *(volatile unsigned char *)ptr = x;
387
 
                        local_irq_restore(flags);
388
 
                        break;
 
302
#if __LINUX_ARM_ARCH__ >= 6
 
303
        case 1:
 
304
                asm volatile("@ __xchg1\n"
 
305
                "1:     ldrexb  %0, [%3]\n"
 
306
                "       strexb  %1, %2, [%3]\n"
 
307
                "       teq     %1, #0\n"
 
308
                "       bne     1b"
 
309
                        : "=&r" (ret), "=&r" (tmp)
 
310
                        : "r" (x), "r" (ptr)
 
311
                        : "memory", "cc");
 
312
                break;
 
313
        case 4:
 
314
                asm volatile("@ __xchg4\n"
 
315
                "1:     ldrex   %0, [%3]\n"
 
316
                "       strex   %1, %2, [%3]\n"
 
317
                "       teq     %1, #0\n"
 
318
                "       bne     1b"
 
319
                        : "=&r" (ret), "=&r" (tmp)
 
320
                        : "r" (x), "r" (ptr)
 
321
                        : "memory", "cc");
 
322
                break;
 
323
#elif defined(swp_is_buggy)
 
324
#ifdef CONFIG_SMP
 
325
#error SMP is not supported on this platform
 
326
#endif
 
327
        case 1:
 
328
                raw_local_irq_save(flags);
 
329
                ret = *(volatile unsigned char *)ptr;
 
330
                *(volatile unsigned char *)ptr = x;
 
331
                raw_local_irq_restore(flags);
 
332
                break;
389
333
 
390
 
                case 4:
391
 
                        local_irq_save(flags);
392
 
                        ret = *(volatile unsigned long *)ptr;
393
 
                        *(volatile unsigned long *)ptr = x;
394
 
                        local_irq_restore(flags);
395
 
                        break;
 
334
        case 4:
 
335
                raw_local_irq_save(flags);
 
336
                ret = *(volatile unsigned long *)ptr;
 
337
                *(volatile unsigned long *)ptr = x;
 
338
                raw_local_irq_restore(flags);
 
339
                break;
396
340
#else
397
 
                case 1: __asm__ __volatile__ ("swpb %0, %1, [%2]"
398
 
                                        : "=&r" (ret)
399
 
                                        : "r" (x), "r" (ptr)
400
 
                                        : "memory", "cc");
401
 
                        break;
402
 
                case 4: __asm__ __volatile__ ("swp %0, %1, [%2]"
403
 
                                        : "=&r" (ret)
404
 
                                        : "r" (x), "r" (ptr)
405
 
                                        : "memory", "cc");
406
 
                        break;
 
341
        case 1:
 
342
                asm volatile("@ __xchg1\n"
 
343
                "       swpb    %0, %1, [%2]"
 
344
                        : "=&r" (ret)
 
345
                        : "r" (x), "r" (ptr)
 
346
                        : "memory", "cc");
 
347
                break;
 
348
        case 4:
 
349
                asm volatile("@ __xchg4\n"
 
350
                "       swp     %0, %1, [%2]"
 
351
                        : "=&r" (ret)
 
352
                        : "r" (x), "r" (ptr)
 
353
                        : "memory", "cc");
 
354
                break;
407
355
#endif
408
 
                default: __bad_xchg(ptr, size), ret = 0;
 
356
        default:
 
357
                __bad_xchg(ptr, size), ret = 0;
 
358
                break;
409
359
        }
410
360
 
411
361
        return ret;
412
362
}
413
363
 
414
 
#endif /* CONFIG_SMP */
 
364
extern void disable_hlt(void);
 
365
extern void enable_hlt(void);
 
366
 
 
367
#include <asm-generic/cmpxchg-local.h>
 
368
 
 
369
/*
 
370
 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
 
371
 * them available.
 
372
 */
 
373
#define cmpxchg_local(ptr, o, n)                                               \
 
374
        ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
 
375
                        (unsigned long)(n), sizeof(*(ptr))))
 
376
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
 
377
 
 
378
#ifndef CONFIG_SMP
 
379
#include <asm-generic/cmpxchg.h>
 
380
#endif
415
381
 
416
382
#endif /* __ASSEMBLY__ */
417
383
 
 
384
#define arch_align_stack(x) (x)
 
385
 
418
386
#endif /* __KERNEL__ */
419
387
 
420
388
#endif