linux-old/include/asm-ppc64/system.h
<<
>>
Prefs
   1#ifndef __PPC64_SYSTEM_H
   2#define __PPC64_SYSTEM_H
   3
   4/*
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License
   7 * as published by the Free Software Foundation; either version
   8 * 2 of the License, or (at your option) any later version.
   9 */
  10
  11#include <linux/config.h>
  12#include <linux/kdev_t.h>
  13#include <asm/page.h>
  14#include <asm/processor.h>
  15#include <asm/hw_irq.h>
  16#include <asm/memory.h>
  17
  18/*
  19 * Memory barrier.
  20 * The sync instruction guarantees that all memory accesses initiated
  21 * by this processor have been performed (with respect to all other
  22 * mechanisms that access memory).  The eieio instruction is a barrier
  23 * providing an ordering (separately) for (a) cacheable stores and (b)
  24 * loads and stores to non-cacheable memory (e.g. I/O devices).
  25 *
  26 * mb() prevents loads and stores being reordered across this point.
  27 * rmb() prevents loads being reordered across this point.
  28 * wmb() prevents stores being reordered across this point.
  29 *
  30 * We can use the eieio instruction for wmb, but since it doesn't
  31 * give any ordering guarantees about loads, we have to use the
  32 * stronger but slower sync instruction for mb and rmb.
  33 */
  34#define mb()   __asm__ __volatile__ ("sync" : : : "memory")
  35#define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
  36#define wmb()  __asm__ __volatile__ ("eieio" : : : "memory")
  37
  38#define set_mb(var, value)      do { var = value; mb(); } while (0)
  39#define set_wmb(var, value)     do { var = value; wmb(); } while (0)
  40
  41#ifdef CONFIG_SMP
  42#define smp_mb()        mb()
  43#define smp_rmb()       rmb()
  44#define smp_wmb()       wmb()
  45#else
  46#define smp_mb()        __asm__ __volatile__("": : :"memory")
  47#define smp_rmb()       __asm__ __volatile__("": : :"memory")
  48#define smp_wmb()       __asm__ __volatile__("": : :"memory")
  49#endif /* CONFIG_SMP */
  50
  51#ifdef CONFIG_XMON
  52extern void xmon_irq(int, void *, struct pt_regs *);
  53extern void xmon(struct pt_regs *excp);
  54#endif
  55
  56extern void print_backtrace(unsigned long *);
  57extern void show_regs(struct pt_regs * regs);
  58extern void flush_instruction_cache(void);
  59extern void hard_reset_now(void);
  60extern void poweroff_now(void);
  61extern int _get_PVR(void);
  62extern long _get_L2CR(void);
  63extern void _set_L2CR(unsigned long);
  64extern void giveup_fpu(struct task_struct *);
  65extern void enable_kernel_fp(void);
  66extern void giveup_altivec(struct task_struct *);
  67extern void load_up_altivec(struct task_struct *);
  68extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
  69extern void cvt_df(double *from, float *to, unsigned long *fpscr);
  70extern int abs(int);
  71extern void cacheable_memzero(void *p, unsigned int nb);
  72extern void vpa_init(int cpu);
  73
  74struct device_node;
  75
  76struct task_struct;
  77#define prepare_to_switch()     do { } while(0)
  78#define switch_to(prev,next,last) _switch_to((prev),(next),&(last))
  79extern void _switch_to(struct task_struct *, struct task_struct *,
  80                       struct task_struct **);
  81
  82struct thread_struct;
  83extern struct task_struct *_switch(struct thread_struct *prev,
  84                                   struct thread_struct *next);
  85
  86struct pt_regs;
  87extern void dump_regs(struct pt_regs *);
  88
  89#ifndef CONFIG_SMP
  90
  91#define cli()   __cli()
  92#define sti()   __sti()
  93#define save_flags(flags)       __save_flags(flags)
  94#define restore_flags(flags)    __restore_flags(flags)
  95#define save_and_cli(flags)     __save_and_cli(flags)
  96#define save_and_sti(flags)     __save_and_sti(flags)
  97
  98#else /* CONFIG_SMP */
  99
 100extern void __global_cli(void);
 101extern void __global_sti(void);
 102extern unsigned long __global_save_flags(void);
 103extern void __global_restore_flags(unsigned long);
 104#define cli() __global_cli()
 105#define sti() __global_sti()
 106#define save_flags(x) ((x)=__global_save_flags())
 107#define restore_flags(x) __global_restore_flags(x)
 108
 109#define save_and_cli(x) do { save_flags(x); cli(); } while(0);
 110#define save_and_sti(x) do { save_flags(x); sti(); } while(0);
 111
 112#endif /* !CONFIG_SMP */
 113
 114#define local_irq_disable()             __cli()
 115#define local_irq_enable()              __sti()
 116#define local_irq_save(flags)           __save_and_cli(flags)
 117#define local_irq_set(flags)            __save_and_sti(flags)
 118#define local_irq_restore(flags)        __restore_flags(flags)
 119
 120static __inline__ int __is_processor(unsigned long pv)
 121{
 122      unsigned long pvr;
 123      asm volatile("mfspr %0, 0x11F" : "=r" (pvr)); 
 124      return(PVR_VER(pvr) == pv);
 125}
 126
 127/*
 128 * Atomic exchange
 129 *
 130 * Changes the memory location '*ptr' to be val and returns
 131 * the previous value stored there.
 132 *
 133 * Inline asm pulled from arch/ppc/kernel/misc.S so ppc64
 134 * is more like most of the other architectures.
 135 */
 136static __inline__ unsigned long
 137__xchg_u32(volatile int *m, unsigned long val)
 138{
 139        unsigned long dummy;
 140
 141        __asm__ __volatile__(
 142        EIEIO_ON_SMP
 143"1:     lwarx %0,0,%3           # __xchg_u32\n\
 144        stwcx. %2,0,%3\n\
 1452:      bne- 1b"
 146        ISYNC_ON_SMP
 147        : "=&r" (dummy), "=m" (*m)
 148        : "r" (val), "r" (m)
 149        : "cc", "memory");
 150
 151        return (dummy);
 152}
 153
 154static __inline__ unsigned long
 155__xchg_u64(volatile long *m, unsigned long val)
 156{
 157        unsigned long dummy;
 158
 159        __asm__ __volatile__(
 160        EIEIO_ON_SMP
 161"1:     ldarx %0,0,%3           # __xchg_u64\n\
 162        stdcx. %2,0,%3\n\
 1632:      bne- 1b"
 164        ISYNC_ON_SMP
 165        : "=&r" (dummy), "=m" (*m)
 166        : "r" (val), "r" (m)
 167        : "cc", "memory");
 168
 169        return (dummy);
 170}
 171
 172/*
 173 * This function doesn't exist, so you'll get a linker error
 174 * if something tries to do an invalid xchg().
 175 */
 176extern void __xchg_called_with_bad_pointer(void);
 177
 178static __inline__ unsigned long
 179__xchg(volatile void *ptr, unsigned long x, int size)
 180{
 181        switch (size) {
 182        case 4:
 183                return __xchg_u32(ptr, x);
 184        case 8:
 185                return __xchg_u64(ptr, x);
 186        }
 187        __xchg_called_with_bad_pointer();
 188        return x;
 189}
 190
 191#define xchg(ptr,x)                                                          \
 192  ({                                                                         \
 193     __typeof__(*(ptr)) _x_ = (x);                                           \
 194     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
 195  })
 196
 197#define tas(ptr) (xchg((ptr),1))
 198
 199#define __HAVE_ARCH_CMPXCHG     1
 200
 201static __inline__ unsigned long
 202__cmpxchg_u32(volatile int *p, int old, int new)
 203{
 204        int prev;
 205
 206        __asm__ __volatile__ (
 207        EIEIO_ON_SMP
 208"1:     lwarx   %0,0,%2         # __cmpxchg_u32\n\
 209        cmpw    0,%0,%3\n\
 210        bne-    2f\n\
 211        stwcx.  %4,0,%2\n\
 212        bne-    1b"
 213        ISYNC_ON_SMP
 214        "\n\
 2152:"
 216        : "=&r" (prev), "=m" (*p)
 217        : "r" (p), "r" (old), "r" (new), "m" (*p)
 218        : "cc", "memory");
 219
 220        return prev;
 221}
 222
 223static __inline__ unsigned long
 224__cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new)
 225{
 226        int prev;
 227
 228        __asm__ __volatile__ (
 229        EIEIO_ON_SMP
 230"1:     ldarx   %0,0,%2         # __cmpxchg_u64\n\
 231        cmpd    0,%0,%3\n\
 232        bne-    2f\n\
 233        stdcx.  %4,0,%2\n\
 234        bne-    1b"
 235        ISYNC_ON_SMP
 236        "\n\
 2372:"
 238        : "=&r" (prev), "=m" (*p)
 239        : "r" (p), "r" (old), "r" (new), "m" (*p)
 240        : "cc", "memory");
 241
 242        return prev;
 243}
 244
 245/* This function doesn't exist, so you'll get a linker error
 246   if something tries to do an invalid cmpxchg().  */
 247extern void __cmpxchg_called_with_bad_pointer(void);
 248
 249static __inline__ unsigned long
 250__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 251{
 252        switch (size) {
 253        case 4:
 254                return __cmpxchg_u32(ptr, old, new);
 255        case 8:
 256                return __cmpxchg_u64(ptr, old, new);
 257        }
 258        __cmpxchg_called_with_bad_pointer();
 259        return old;
 260}
 261
 262#define cmpxchg(ptr,o,n)                                                 \
 263  ({                                                                     \
 264     __typeof__(*(ptr)) _o_ = (o);                                       \
 265     __typeof__(*(ptr)) _n_ = (n);                                       \
 266     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,           \
 267                                    (unsigned long)_n_, sizeof(*(ptr))); \
 268  })
 269
 270#endif
 271
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.