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-arm / system.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  10.9 KB  |  452 lines

  1. #ifndef __ASM_ARM_SYSTEM_H
  2. #define __ASM_ARM_SYSTEM_H
  3.  
  4. #ifdef __KERNEL__
  5.  
  6.  
  7. #define CPU_ARCH_UNKNOWN    0
  8. #define CPU_ARCH_ARMv3        1
  9. #define CPU_ARCH_ARMv4        2
  10. #define CPU_ARCH_ARMv4T        3
  11. #define CPU_ARCH_ARMv5        4
  12. #define CPU_ARCH_ARMv5T        5
  13. #define CPU_ARCH_ARMv5TE    6
  14. #define CPU_ARCH_ARMv5TEJ    7
  15. #define CPU_ARCH_ARMv6        8
  16.  
  17. /*
  18.  * CR1 bits (CP#15 CR1)
  19.  */
  20. #define CR_M    (1 << 0)    /* MMU enable                */
  21. #define CR_A    (1 << 1)    /* Alignment abort enable        */
  22. #define CR_C    (1 << 2)    /* Dcache enable            */
  23. #define CR_W    (1 << 3)    /* Write buffer enable            */
  24. #define CR_P    (1 << 4)    /* 32-bit exception handler        */
  25. #define CR_D    (1 << 5)    /* 32-bit data address range        */
  26. #define CR_L    (1 << 6)    /* Implementation defined        */
  27. #define CR_B    (1 << 7)    /* Big endian                */
  28. #define CR_S    (1 << 8)    /* System MMU protection        */
  29. #define CR_R    (1 << 9)    /* ROM MMU protection            */
  30. #define CR_F    (1 << 10)    /* Implementation defined        */
  31. #define CR_Z    (1 << 11)    /* Implementation defined        */
  32. #define CR_I    (1 << 12)    /* Icache enable            */
  33. #define CR_V    (1 << 13)    /* Vectors relocated to 0xffff0000    */
  34. #define CR_RR    (1 << 14)    /* Round Robin cache replacement    */
  35. #define CR_L4    (1 << 15)    /* LDR pc can set T bit            */
  36. #define CR_DT    (1 << 16)
  37. #define CR_IT    (1 << 18)
  38. #define CR_ST    (1 << 19)
  39. #define CR_FI    (1 << 21)    /* Fast interrupt (lower latency mode)    */
  40. #define CR_U    (1 << 22)    /* Unaligned access operation        */
  41. #define CR_XP    (1 << 23)    /* Extended page tables            */
  42. #define CR_VE    (1 << 24)    /* Vectored interrupts            */
  43.  
  44. #define CPUID_ID    0
  45. #define CPUID_CACHETYPE    1
  46. #define CPUID_TCM    2
  47. #define CPUID_TLBTYPE    3
  48.  
  49. #define read_cpuid(reg)                            \
  50.     ({                                \
  51.         unsigned int __val;                    \
  52.         asm("mrc    p15, 0, %0, c0, c0, " __stringify(reg)    \
  53.             : "=r" (__val)                    \
  54.             :                            \
  55.             : "cc");                        \
  56.         __val;                            \
  57.     })
  58.  
  59. /*
  60.  * This is used to ensure the compiler did actually allocate the register we
  61.  * asked it for some inline assembly sequences.  Apparently we can't trust
  62.  * the compiler from one version to another so a bit of paranoia won't hurt.
  63.  * This string is meant to be concatenated with the inline asm string and
  64.  * will cause compilation to stop on mismatch.
  65.  * (for details, see gcc PR 15089)
  66.  */
  67. #define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
  68.  
  69. #ifndef __ASSEMBLY__
  70.  
  71. #include <linux/linkage.h>
  72.  
  73. struct thread_info;
  74. struct task_struct;
  75.  
  76. /* information about the system we're running on */
  77. extern unsigned int system_rev;
  78. extern unsigned int system_serial_low;
  79. extern unsigned int system_serial_high;
  80. extern unsigned int mem_fclk_21285;
  81.  
  82. struct pt_regs;
  83.  
  84. void die(const char *msg, struct pt_regs *regs, int err)
  85.         __attribute__((noreturn));
  86.  
  87. struct siginfo;
  88. void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
  89.         unsigned long err, unsigned long trap);
  90.  
  91. void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
  92.                        struct pt_regs *),
  93.              int sig, const char *name);
  94.  
  95. #define xchg(ptr,x) \
  96.     ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  97.  
  98. #define tas(ptr) (xchg((ptr),1))
  99.  
  100. extern asmlinkage void __backtrace(void);
  101. extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
  102.  
  103. struct mm_struct;
  104. extern void show_pte(struct mm_struct *mm, unsigned long addr);
  105. extern void __show_regs(struct pt_regs *);
  106.  
  107. extern int cpu_architecture(void);
  108. extern void cpu_init(void);
  109.  
  110. /*
  111.  * Intel's XScale3 core supports some v6 features (supersections, L2)
  112.  * but advertises itself as v5 as it does not support the v6 ISA.  For
  113.  * this reason, we need a way to explicitly test for this type of CPU.
  114.  */
  115. #ifndef CONFIG_CPU_XSC3
  116. #define cpu_is_xsc3()    0
  117. #else
  118. static inline int cpu_is_xsc3(void)
  119. {
  120.     extern unsigned int processor_id;
  121.  
  122.     if ((processor_id & 0xffffe000) == 0x69056000)
  123.         return 1;
  124.  
  125.     return 0;
  126. }
  127. #endif
  128.  
  129. #if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
  130. #define    cpu_is_xscale()    0
  131. #else
  132. #define    cpu_is_xscale()    1
  133. #endif
  134.  
  135. #define set_cr(x)                    \
  136.     __asm__ __volatile__(                \
  137.     "mcr    p15, 0, %0, c1, c0, 0    @ set CR"    \
  138.     : : "r" (x) : "cc")
  139.  
  140. #define get_cr()                    \
  141.     ({                        \
  142.     unsigned int __val;                \
  143.     __asm__ __volatile__(                \
  144.     "mrc    p15, 0, %0, c1, c0, 0    @ get CR"    \
  145.     : "=r" (__val) : : "cc");            \
  146.     __val;                        \
  147.     })
  148.  
  149. extern unsigned long cr_no_alignment;    /* defined in entry-armv.S */
  150. extern unsigned long cr_alignment;    /* defined in entry-armv.S */
  151.  
  152. #define UDBG_UNDEFINED    (1 << 0)
  153. #define UDBG_SYSCALL    (1 << 1)
  154. #define UDBG_BADABORT    (1 << 2)
  155. #define UDBG_SEGV    (1 << 3)
  156. #define UDBG_BUS    (1 << 4)
  157.  
  158. extern unsigned int user_debug;
  159.  
  160. #if __LINUX_ARM_ARCH__ >= 4
  161. #define vectors_high()    (cr_alignment & CR_V)
  162. #else
  163. #define vectors_high()    (0)
  164. #endif
  165.  
  166. #if __LINUX_ARM_ARCH__ >= 6
  167. #define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
  168.                                    : : "r" (0) : "memory")
  169. #else
  170. #define mb() __asm__ __volatile__ ("" : : : "memory")
  171. #endif
  172. #define rmb() mb()
  173. #define wmb() mb()
  174. #define read_barrier_depends() do { } while(0)
  175. #define set_mb(var, value)  do { var = value; mb(); } while (0)
  176. #define set_wmb(var, value) do { var = value; wmb(); } while (0)
  177. #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
  178.  
  179. /*
  180.  * switch_mm() may do a full cache flush over the context switch,
  181.  * so enable interrupts over the context switch to avoid high
  182.  * latency.
  183.  */
  184. #define __ARCH_WANT_INTERRUPTS_ON_CTXSW
  185.  
  186. /*
  187.  * switch_to(prev, next) should switch from task `prev' to `next'
  188.  * `prev' will never be the same as `next'.  schedule() itself
  189.  * contains the memory barrier to tell GCC not to cache `current'.
  190.  */
  191. extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
  192.  
  193. #define switch_to(prev,next,last)                    \
  194. do {                                    \
  195.     last = __switch_to(prev,task_thread_info(prev), task_thread_info(next));    \
  196. } while (0)
  197.  
  198. /*
  199.  * On SMP systems, when the scheduler does migration-cost autodetection,
  200.  * it needs a way to flush as much of the CPU's caches as possible.
  201.  *
  202.  * TODO: fill this in!
  203.  */
  204. static inline void sched_cacheflush(void)
  205. {
  206. }
  207.  
  208. /*
  209.  * CPU interrupt mask handling.
  210.  */
  211. #if __LINUX_ARM_ARCH__ >= 6
  212.  
  213. #define local_irq_save(x)                    \
  214.     ({                            \
  215.     __asm__ __volatile__(                    \
  216.     "mrs    %0, cpsr        @ local_irq_save\n"    \
  217.     "cpsid    i"                        \
  218.     : "=r" (x) : : "memory", "cc");                \
  219.     })
  220.  
  221. #define local_irq_enable()  __asm__("cpsie i    @ __sti" : : : "memory", "cc")
  222. #define local_irq_disable() __asm__("cpsid i    @ __cli" : : : "memory", "cc")
  223. #define local_fiq_enable()  __asm__("cpsie f    @ __stf" : : : "memory", "cc")
  224. #define local_fiq_disable() __asm__("cpsid f    @ __clf" : : : "memory", "cc")
  225.  
  226. #else
  227.  
  228. /*
  229.  * Save the current interrupt enable state & disable IRQs
  230.  */
  231. #define local_irq_save(x)                    \
  232.     ({                            \
  233.         unsigned long temp;                \
  234.         (void) (&temp == &x);                \
  235.     __asm__ __volatile__(                    \
  236.     "mrs    %0, cpsr        @ local_irq_save\n"    \
  237. "    orr    %1, %0, #128\n"                    \
  238. "    msr    cpsr_c, %1"                    \
  239.     : "=r" (x), "=r" (temp)                    \
  240.     :                            \
  241.     : "memory", "cc");                    \
  242.     })
  243.     
  244. /*
  245.  * Enable IRQs
  246.  */
  247. #define local_irq_enable()                    \
  248.     ({                            \
  249.         unsigned long temp;                \
  250.     __asm__ __volatile__(                    \
  251.     "mrs    %0, cpsr        @ local_irq_enable\n"    \
  252. "    bic    %0, %0, #128\n"                    \
  253. "    msr    cpsr_c, %0"                    \
  254.     : "=r" (temp)                        \
  255.     :                            \
  256.     : "memory", "cc");                    \
  257.     })
  258.  
  259. /*
  260.  * Disable IRQs
  261.  */
  262. #define local_irq_disable()                    \
  263.     ({                            \
  264.         unsigned long temp;                \
  265.     __asm__ __volatile__(                    \
  266.     "mrs    %0, cpsr        @ local_irq_disable\n"    \
  267. "    orr    %0, %0, #128\n"                    \
  268. "    msr    cpsr_c, %0"                    \
  269.     : "=r" (temp)                        \
  270.     :                            \
  271.     : "memory", "cc");                    \
  272.     })
  273.  
  274. /*
  275.  * Enable FIQs
  276.  */
  277. #define local_fiq_enable()                    \
  278.     ({                            \
  279.         unsigned long temp;                \
  280.     __asm__ __volatile__(                    \
  281.     "mrs    %0, cpsr        @ stf\n"        \
  282. "    bic    %0, %0, #64\n"                    \
  283. "    msr    cpsr_c, %0"                    \
  284.     : "=r" (temp)                        \
  285.     :                            \
  286.     : "memory", "cc");                    \
  287.     })
  288.  
  289. /*
  290.  * Disable FIQs
  291.  */
  292. #define local_fiq_disable()                    \
  293.     ({                            \
  294.         unsigned long temp;                \
  295.     __asm__ __volatile__(                    \
  296.     "mrs    %0, cpsr        @ clf\n"        \
  297. "    orr    %0, %0, #64\n"                    \
  298. "    msr    cpsr_c, %0"                    \
  299.     : "=r" (temp)                        \
  300.     :                            \
  301.     : "memory", "cc");                    \
  302.     })
  303.  
  304. #endif
  305.  
  306. /*
  307.  * Save the current interrupt enable state.
  308.  */
  309. #define local_save_flags(x)                    \
  310.     ({                            \
  311.     __asm__ __volatile__(                    \
  312.     "mrs    %0, cpsr        @ local_save_flags"    \
  313.     : "=r" (x) : : "memory", "cc");                \
  314.     })
  315.  
  316. /*
  317.  * restore saved IRQ & FIQ state
  318.  */
  319. #define local_irq_restore(x)                    \
  320.     __asm__ __volatile__(                    \
  321.     "msr    cpsr_c, %0        @ local_irq_restore\n"    \
  322.     :                            \
  323.     : "r" (x)                        \
  324.     : "memory", "cc")
  325.  
  326. #define irqs_disabled()            \
  327. ({                    \
  328.     unsigned long flags;        \
  329.     local_save_flags(flags);    \
  330.     (int)(flags & PSR_I_BIT);    \
  331. })
  332.  
  333. #ifdef CONFIG_SMP
  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. #endif /* CONFIG_SMP */
  348.  
  349. #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
  350. /*
  351.  * On the StrongARM, "swp" is terminally broken since it bypasses the
  352.  * cache totally.  This means that the cache becomes inconsistent, and,
  353.  * since we use normal loads/stores as well, this is really bad.
  354.  * Typically, this causes oopsen in filp_close, but could have other,
  355.  * more disasterous effects.  There are two work-arounds:
  356.  *  1. Disable interrupts and emulate the atomic swap
  357.  *  2. Clean the cache, perform atomic swap, flush the cache
  358.  *
  359.  * We choose (1) since its the "easiest" to achieve here and is not
  360.  * dependent on the processor type.
  361.  *
  362.  * NOTE that this solution won't work on an SMP system, so explcitly
  363.  * forbid it here.
  364.  */
  365. #define swp_is_buggy
  366. #endif
  367.  
  368. static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  369. {
  370.     extern void __bad_xchg(volatile void *, int);
  371.     unsigned long ret;
  372. #ifdef swp_is_buggy
  373.     unsigned long flags;
  374. #endif
  375. #if __LINUX_ARM_ARCH__ >= 6
  376.     unsigned int tmp;
  377. #endif
  378.  
  379.     switch (size) {
  380. #if __LINUX_ARM_ARCH__ >= 6
  381.     case 1:
  382.         asm volatile("@    __xchg1\n"
  383.         "1:    ldrexb    %0, [%3]\n"
  384.         "    strexb    %1, %2, [%3]\n"
  385.         "    teq    %1, #0\n"
  386.         "    bne    1b"
  387.             : "=&r" (ret), "=&r" (tmp)
  388.             : "r" (x), "r" (ptr)
  389.             : "memory", "cc");
  390.         break;
  391.     case 4:
  392.         asm volatile("@    __xchg4\n"
  393.         "1:    ldrex    %0, [%3]\n"
  394.         "    strex    %1, %2, [%3]\n"
  395.         "    teq    %1, #0\n"
  396.         "    bne    1b"
  397.             : "=&r" (ret), "=&r" (tmp)
  398.             : "r" (x), "r" (ptr)
  399.             : "memory", "cc");
  400.         break;
  401. #elif defined(swp_is_buggy)
  402. #ifdef CONFIG_SMP
  403. #error SMP is not supported on this platform
  404. #endif
  405.     case 1:
  406.         local_irq_save(flags);
  407.         ret = *(volatile unsigned char *)ptr;
  408.         *(volatile unsigned char *)ptr = x;
  409.         local_irq_restore(flags);
  410.         break;
  411.  
  412.     case 4:
  413.         local_irq_save(flags);
  414.         ret = *(volatile unsigned long *)ptr;
  415.         *(volatile unsigned long *)ptr = x;
  416.         local_irq_restore(flags);
  417.         break;
  418. #else
  419.     case 1:
  420.         asm volatile("@    __xchg1\n"
  421.         "    swpb    %0, %1, [%2]"
  422.             : "=&r" (ret)
  423.             : "r" (x), "r" (ptr)
  424.             : "memory", "cc");
  425.         break;
  426.     case 4:
  427.         asm volatile("@    __xchg4\n"
  428.         "    swp    %0, %1, [%2]"
  429.             : "=&r" (ret)
  430.             : "r" (x), "r" (ptr)
  431.             : "memory", "cc");
  432.         break;
  433. #endif
  434.     default:
  435.         __bad_xchg(ptr, size), ret = 0;
  436.         break;
  437.     }
  438.  
  439.     return ret;
  440. }
  441.  
  442. extern void disable_hlt(void);
  443. extern void enable_hlt(void);
  444.  
  445. #endif /* __ASSEMBLY__ */
  446.  
  447. #define arch_align_stack(x) (x)
  448.  
  449. #endif /* __KERNEL__ */
  450.  
  451. #endif
  452.