home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-powerpc / system.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  12.1 KB  |  438 lines

  1. /*
  2.  * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
  3.  */
  4. #ifndef _ASM_POWERPC_SYSTEM_H
  5. #define _ASM_POWERPC_SYSTEM_H
  6.  
  7. #include <linux/kernel.h>
  8.  
  9. #include <asm/hw_irq.h>
  10. #include <asm/atomic.h>
  11.  
  12. /*
  13.  * Memory barrier.
  14.  * The sync instruction guarantees that all memory accesses initiated
  15.  * by this processor have been performed (with respect to all other
  16.  * mechanisms that access memory).  The eieio instruction is a barrier
  17.  * providing an ordering (separately) for (a) cacheable stores and (b)
  18.  * loads and stores to non-cacheable memory (e.g. I/O devices).
  19.  *
  20.  * mb() prevents loads and stores being reordered across this point.
  21.  * rmb() prevents loads being reordered across this point.
  22.  * wmb() prevents stores being reordered across this point.
  23.  * read_barrier_depends() prevents data-dependent loads being reordered
  24.  *    across this point (nop on PPC).
  25.  *
  26.  * We have to use the sync instructions for mb(), since lwsync doesn't
  27.  * order loads with respect to previous stores.  Lwsync is fine for
  28.  * rmb(), though.  Note that lwsync is interpreted as sync by
  29.  * 32-bit and older 64-bit CPUs.
  30.  *
  31.  * For wmb(), we use sync since wmb is used in drivers to order
  32.  * stores to system memory with respect to writes to the device.
  33.  * However, smp_wmb() can be a lighter-weight eieio barrier on
  34.  * SMP since it is only used to order updates to system memory.
  35.  */
  36. #define mb()   __asm__ __volatile__ ("sync" : : : "memory")
  37. #define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
  38. #define wmb()  __asm__ __volatile__ ("sync" : : : "memory")
  39. #define read_barrier_depends()  do { } while(0)
  40.  
  41. #define set_mb(var, value)    do { var = value; mb(); } while (0)
  42. #define set_wmb(var, value)    do { var = value; wmb(); } while (0)
  43.  
  44. #ifdef __KERNEL__
  45. #ifdef CONFIG_SMP
  46. #define smp_mb()    mb()
  47. #define smp_rmb()    rmb()
  48. #define smp_wmb()    __asm__ __volatile__ ("eieio" : : : "memory")
  49. #define smp_read_barrier_depends()    read_barrier_depends()
  50. #else
  51. #define smp_mb()    barrier()
  52. #define smp_rmb()    barrier()
  53. #define smp_wmb()    barrier()
  54. #define smp_read_barrier_depends()    do { } while(0)
  55. #endif /* CONFIG_SMP */
  56.  
  57. struct task_struct;
  58. struct pt_regs;
  59.  
  60. #ifdef CONFIG_DEBUGGER
  61.  
  62. extern int (*__debugger)(struct pt_regs *regs);
  63. extern int (*__debugger_ipi)(struct pt_regs *regs);
  64. extern int (*__debugger_bpt)(struct pt_regs *regs);
  65. extern int (*__debugger_sstep)(struct pt_regs *regs);
  66. extern int (*__debugger_iabr_match)(struct pt_regs *regs);
  67. extern int (*__debugger_dabr_match)(struct pt_regs *regs);
  68. extern int (*__debugger_fault_handler)(struct pt_regs *regs);
  69.  
  70. #define DEBUGGER_BOILERPLATE(__NAME) \
  71. static inline int __NAME(struct pt_regs *regs) \
  72. { \
  73.     if (unlikely(__ ## __NAME)) \
  74.         return __ ## __NAME(regs); \
  75.     return 0; \
  76. }
  77.  
  78. DEBUGGER_BOILERPLATE(debugger)
  79. DEBUGGER_BOILERPLATE(debugger_ipi)
  80. DEBUGGER_BOILERPLATE(debugger_bpt)
  81. DEBUGGER_BOILERPLATE(debugger_sstep)
  82. DEBUGGER_BOILERPLATE(debugger_iabr_match)
  83. DEBUGGER_BOILERPLATE(debugger_dabr_match)
  84. DEBUGGER_BOILERPLATE(debugger_fault_handler)
  85.  
  86. #ifdef CONFIG_XMON
  87. extern void xmon_init(int enable);
  88. #endif
  89.  
  90. #else
  91. static inline int debugger(struct pt_regs *regs) { return 0; }
  92. static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
  93. static inline int debugger_bpt(struct pt_regs *regs) { return 0; }
  94. static inline int debugger_sstep(struct pt_regs *regs) { return 0; }
  95. static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; }
  96. static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
  97. static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
  98. #endif
  99.  
  100. extern int set_dabr(unsigned long dabr);
  101. extern void print_backtrace(unsigned long *);
  102. extern void show_regs(struct pt_regs * regs);
  103. extern void flush_instruction_cache(void);
  104. extern void hard_reset_now(void);
  105. extern void poweroff_now(void);
  106.  
  107. #ifdef CONFIG_6xx
  108. extern long _get_L2CR(void);
  109. extern long _get_L3CR(void);
  110. extern void _set_L2CR(unsigned long);
  111. extern void _set_L3CR(unsigned long);
  112. #else
  113. #define _get_L2CR()    0L
  114. #define _get_L3CR()    0L
  115. #define _set_L2CR(val)    do { } while(0)
  116. #define _set_L3CR(val)    do { } while(0)
  117. #endif
  118.  
  119. extern void via_cuda_init(void);
  120. extern void read_rtc_time(void);
  121. extern void pmac_find_display(void);
  122. extern void giveup_fpu(struct task_struct *);
  123. extern void disable_kernel_fp(void);
  124. extern void enable_kernel_fp(void);
  125. extern void flush_fp_to_thread(struct task_struct *);
  126. extern void enable_kernel_altivec(void);
  127. extern void giveup_altivec(struct task_struct *);
  128. extern void load_up_altivec(struct task_struct *);
  129. extern int emulate_altivec(struct pt_regs *);
  130. extern void giveup_spe(struct task_struct *);
  131. extern void load_up_spe(struct task_struct *);
  132. extern int fix_alignment(struct pt_regs *);
  133. extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
  134. extern void cvt_df(double *from, float *to, struct thread_struct *thread);
  135.  
  136. #ifndef CONFIG_SMP
  137. extern void discard_lazy_cpu_state(void);
  138. #else
  139. static inline void discard_lazy_cpu_state(void)
  140. {
  141. }
  142. #endif
  143.  
  144. #ifdef CONFIG_ALTIVEC
  145. extern void flush_altivec_to_thread(struct task_struct *);
  146. #else
  147. static inline void flush_altivec_to_thread(struct task_struct *t)
  148. {
  149. }
  150. #endif
  151.  
  152. #ifdef CONFIG_SPE
  153. extern void flush_spe_to_thread(struct task_struct *);
  154. #else
  155. static inline void flush_spe_to_thread(struct task_struct *t)
  156. {
  157. }
  158. #endif
  159.  
  160. extern int call_rtas(const char *, int, int, unsigned long *, ...);
  161. extern void cacheable_memzero(void *p, unsigned int nb);
  162. extern void *cacheable_memcpy(void *, const void *, unsigned int);
  163. extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long);
  164. extern void bad_page_fault(struct pt_regs *, unsigned long, int);
  165. extern int die(const char *, struct pt_regs *, long);
  166. extern void _exception(int, struct pt_regs *, int, unsigned long);
  167. #ifdef CONFIG_BOOKE_WDT
  168. extern u32 booke_wdt_enabled;
  169. extern u32 booke_wdt_period;
  170. #endif /* CONFIG_BOOKE_WDT */
  171.  
  172. /* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
  173. extern unsigned char e2a(unsigned char);
  174. extern unsigned char* strne2a(unsigned char *dest,
  175.         const unsigned char *src, size_t n);
  176.  
  177. struct device_node;
  178. extern void note_scsi_host(struct device_node *, void *);
  179.  
  180. extern struct task_struct *__switch_to(struct task_struct *,
  181.     struct task_struct *);
  182. #define switch_to(prev, next, last)    ((last) = __switch_to((prev), (next)))
  183.  
  184. struct thread_struct;
  185. extern struct task_struct *_switch(struct thread_struct *prev,
  186.                    struct thread_struct *next);
  187.  
  188. /*
  189.  * On SMP systems, when the scheduler does migration-cost autodetection,
  190.  * it needs a way to flush as much of the CPU's caches as possible.
  191.  *
  192.  * TODO: fill this in!
  193.  */
  194. static inline void sched_cacheflush(void)
  195. {
  196. }
  197.  
  198. extern unsigned int rtas_data;
  199. extern int mem_init_done;    /* set on boot once kmalloc can be called */
  200. extern unsigned long memory_limit;
  201. extern unsigned long klimit;
  202.  
  203. extern int powersave_nap;    /* set if nap mode can be used in idle loop */
  204.  
  205. /*
  206.  * Atomic exchange
  207.  *
  208.  * Changes the memory location '*ptr' to be val and returns
  209.  * the previous value stored there.
  210.  */
  211. static __inline__ unsigned long
  212. __xchg_u32(volatile void *p, unsigned long val)
  213. {
  214.     unsigned long prev;
  215.  
  216.     __asm__ __volatile__(
  217.     LWSYNC_ON_SMP
  218. "1:    lwarx    %0,0,%2 \n"
  219.     PPC405_ERR77(0,%2)
  220. "    stwcx.    %3,0,%2 \n\
  221.     bne-    1b"
  222.     ISYNC_ON_SMP
  223.     : "=&r" (prev), "=m" (*(volatile unsigned int *)p)
  224.     : "r" (p), "r" (val), "m" (*(volatile unsigned int *)p)
  225.     : "cc", "memory");
  226.  
  227.     return prev;
  228. }
  229.  
  230. #ifdef CONFIG_PPC64
  231. static __inline__ unsigned long
  232. __xchg_u64(volatile void *p, unsigned long val)
  233. {
  234.     unsigned long prev;
  235.  
  236.     __asm__ __volatile__(
  237.     LWSYNC_ON_SMP
  238. "1:    ldarx    %0,0,%2 \n"
  239.     PPC405_ERR77(0,%2)
  240. "    stdcx.    %3,0,%2 \n\
  241.     bne-    1b"
  242.     ISYNC_ON_SMP
  243.     : "=&r" (prev), "=m" (*(volatile unsigned long *)p)
  244.     : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p)
  245.     : "cc", "memory");
  246.  
  247.     return prev;
  248. }
  249. #endif
  250.  
  251. /*
  252.  * This function doesn't exist, so you'll get a linker error
  253.  * if something tries to do an invalid xchg().
  254.  */
  255. extern void __xchg_called_with_bad_pointer(void);
  256.  
  257. static __inline__ unsigned long
  258. __xchg(volatile void *ptr, unsigned long x, unsigned int size)
  259. {
  260.     switch (size) {
  261.     case 4:
  262.         return __xchg_u32(ptr, x);
  263. #ifdef CONFIG_PPC64
  264.     case 8:
  265.         return __xchg_u64(ptr, x);
  266. #endif
  267.     }
  268.     __xchg_called_with_bad_pointer();
  269.     return x;
  270. }
  271.  
  272. #define xchg(ptr,x)                                 \
  273.   ({                                         \
  274.      __typeof__(*(ptr)) _x_ = (x);                         \
  275.      (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
  276.   })
  277.  
  278. #define tas(ptr) (xchg((ptr),1))
  279.  
  280. /*
  281.  * Compare and exchange - if *p == old, set it to new,
  282.  * and return the old value of *p.
  283.  */
  284. #define __HAVE_ARCH_CMPXCHG    1
  285.  
  286. static __inline__ unsigned long
  287. __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
  288. {
  289.     unsigned int prev;
  290.  
  291.     __asm__ __volatile__ (
  292.     LWSYNC_ON_SMP
  293. "1:    lwarx    %0,0,%2        # __cmpxchg_u32\n\
  294.     cmpw    0,%0,%3\n\
  295.     bne-    2f\n"
  296.     PPC405_ERR77(0,%2)
  297. "    stwcx.    %4,0,%2\n\
  298.     bne-    1b"
  299.     ISYNC_ON_SMP
  300.     "\n\
  301. 2:"
  302.     : "=&r" (prev), "=m" (*p)
  303.     : "r" (p), "r" (old), "r" (new), "m" (*p)
  304.     : "cc", "memory");
  305.  
  306.     return prev;
  307. }
  308.  
  309. #ifdef CONFIG_PPC64
  310. static __inline__ unsigned long
  311. __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
  312. {
  313.     unsigned long prev;
  314.  
  315.     __asm__ __volatile__ (
  316.     LWSYNC_ON_SMP
  317. "1:    ldarx    %0,0,%2        # __cmpxchg_u64\n\
  318.     cmpd    0,%0,%3\n\
  319.     bne-    2f\n\
  320.     stdcx.    %4,0,%2\n\
  321.     bne-    1b"
  322.     ISYNC_ON_SMP
  323.     "\n\
  324. 2:"
  325.     : "=&r" (prev), "=m" (*p)
  326.     : "r" (p), "r" (old), "r" (new), "m" (*p)
  327.     : "cc", "memory");
  328.  
  329.     return prev;
  330. }
  331. #endif
  332.  
  333. /* This function doesn't exist, so you'll get a linker error
  334.    if something tries to do an invalid cmpxchg().  */
  335. extern void __cmpxchg_called_with_bad_pointer(void);
  336.  
  337. static __inline__ unsigned long
  338. __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
  339.       unsigned int size)
  340. {
  341.     switch (size) {
  342.     case 4:
  343.         return __cmpxchg_u32(ptr, old, new);
  344. #ifdef CONFIG_PPC64
  345.     case 8:
  346.         return __cmpxchg_u64(ptr, old, new);
  347. #endif
  348.     }
  349.     __cmpxchg_called_with_bad_pointer();
  350.     return old;
  351. }
  352.  
  353. #define cmpxchg(ptr,o,n)                         \
  354.   ({                                     \
  355.      __typeof__(*(ptr)) _o_ = (o);                     \
  356.      __typeof__(*(ptr)) _n_ = (n);                     \
  357.      (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,         \
  358.                     (unsigned long)_n_, sizeof(*(ptr))); \
  359.   })
  360.  
  361. #ifdef CONFIG_PPC64
  362. /*
  363.  * We handle most unaligned accesses in hardware. On the other hand 
  364.  * unaligned DMA can be very expensive on some ppc64 IO chips (it does
  365.  * powers of 2 writes until it reaches sufficient alignment).
  366.  *
  367.  * Based on this we disable the IP header alignment in network drivers.
  368.  * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining
  369.  * cacheline alignment of buffers.
  370.  */
  371. #define NET_IP_ALIGN    0
  372. #define NET_SKB_PAD    L1_CACHE_BYTES
  373. #endif
  374.  
  375. #define arch_align_stack(x) (x)
  376.  
  377. /* Used in very early kernel initialization. */
  378. extern unsigned long reloc_offset(void);
  379. extern unsigned long add_reloc_offset(unsigned long);
  380. extern void reloc_got2(unsigned long);
  381.  
  382. #define PTRRELOC(x)    ((typeof(x)) add_reloc_offset((unsigned long)(x)))
  383.  
  384. static inline void create_instruction(unsigned long addr, unsigned int instr)
  385. {
  386.     unsigned int *p;
  387.     p  = (unsigned int *)addr;
  388.     *p = instr;
  389.     asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (p));
  390. }
  391.  
  392. /* Flags for create_branch:
  393.  * "b"   == create_branch(addr, target, 0);
  394.  * "ba"  == create_branch(addr, target, BRANCH_ABSOLUTE);
  395.  * "bl"  == create_branch(addr, target, BRANCH_SET_LINK);
  396.  * "bla" == create_branch(addr, target, BRANCH_ABSOLUTE | BRANCH_SET_LINK);
  397.  */
  398. #define BRANCH_SET_LINK    0x1
  399. #define BRANCH_ABSOLUTE    0x2
  400.  
  401. static inline void create_branch(unsigned long addr,
  402.         unsigned long target, int flags)
  403. {
  404.     unsigned int instruction;
  405.  
  406.     if (! (flags & BRANCH_ABSOLUTE))
  407.         target = target - addr;
  408.  
  409.     /* Mask out the flags and target, so they don't step on each other. */
  410.     instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC);
  411.  
  412.     create_instruction(addr, instruction);
  413. }
  414.  
  415. static inline void create_function_call(unsigned long addr, void * func)
  416. {
  417.     unsigned long func_addr;
  418.  
  419. #ifdef CONFIG_PPC64
  420.     /*
  421.      * On PPC64 the function pointer actually points to the function's
  422.      * descriptor. The first entry in the descriptor is the address
  423.      * of the function text.
  424.      */
  425.     func_addr = *(unsigned long *)func;
  426. #else
  427.     func_addr = (unsigned long)func;
  428. #endif
  429.     create_branch(addr, func_addr, BRANCH_SET_LINK);
  430. }
  431.  
  432. #ifdef CONFIG_VIRT_CPU_ACCOUNTING
  433. extern void account_system_vtime(struct task_struct *);
  434. #endif
  435.  
  436. #endif /* __KERNEL__ */
  437. #endif /* _ASM_POWERPC_SYSTEM_H */
  438.