system.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:14k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _ASM_IA64_SYSTEM_H
  2. #define _ASM_IA64_SYSTEM_H
  3. /*
  4.  * System defines. Note that this is included both from .c and .S
  5.  * files, so it does only defines, not any C code.  This is based
  6.  * on information published in the Processor Abstraction Layer
  7.  * and the System Abstraction Layer manual.
  8.  *
  9.  * Copyright (C) 1998-2001 Hewlett-Packard Co
  10.  * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  11.  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  12.  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  13.  */
  14. #include <linux/config.h>
  15. #include <asm/page.h>
  16. #define KERNEL_START (PAGE_OFFSET + 68*1024*1024)
  17. /*
  18.  * The following #defines must match with vmlinux.lds.S:
  19.  */
  20. #define IVT_ADDR (KERNEL_START)
  21. #define IVT_END_ADDR (KERNEL_START + 0x8000)
  22. #define ZERO_PAGE_ADDR PAGE_ALIGN(IVT_END_ADDR)
  23. #define SWAPPER_PGD_ADDR (ZERO_PAGE_ADDR + 1*PAGE_SIZE)
  24. #define GATE_ADDR (0xa000000000000000 + PAGE_SIZE)
  25. #define PERCPU_ADDR (0xa000000000000000 + 2*PAGE_SIZE)
  26. #ifndef __ASSEMBLY__
  27. #include <linux/kernel.h>
  28. #include <linux/types.h>
  29. struct pci_vector_struct {
  30. __u16 bus; /* PCI Bus number */
  31. __u32 pci_id; /* ACPI split 16 bits device, 16 bits function (see section 6.1.1) */
  32. __u8 pin; /* PCI PIN (0 = A, 1 = B, 2 = C, 3 = D) */
  33. __u8 irq; /* IRQ assigned */
  34. };
  35. extern struct ia64_boot_param {
  36. __u64 command_line; /* physical address of command line arguments */
  37. __u64 efi_systab; /* physical address of EFI system table */
  38. __u64 efi_memmap; /* physical address of EFI memory map */
  39. __u64 efi_memmap_size; /* size of EFI memory map */
  40. __u64 efi_memdesc_size; /* size of an EFI memory map descriptor */
  41. __u32 efi_memdesc_version; /* memory descriptor version */
  42. struct {
  43. __u16 num_cols; /* number of columns on console output device */
  44. __u16 num_rows; /* number of rows on console output device */
  45. __u16 orig_x; /* cursor's x position */
  46. __u16 orig_y; /* cursor's y position */
  47. } console_info;
  48. __u64 fpswa; /* physical address of the fpswa interface */
  49. __u64 initrd_start;
  50. __u64 initrd_size;
  51. } *ia64_boot_param;
  52. static inline void
  53. ia64_insn_group_barrier (void)
  54. {
  55. __asm__ __volatile__ (";;" ::: "memory");
  56. }
  57. /*
  58.  * Macros to force memory ordering.  In these descriptions, "previous"
  59.  * and "subsequent" refer to program order; "visible" means that all
  60.  * architecturally visible effects of a memory access have occurred
  61.  * (at a minimum, this means the memory has been read or written).
  62.  *
  63.  *   wmb(): Guarantees that all preceding stores to memory-
  64.  * like regions are visible before any subsequent
  65.  * stores and that all following stores will be
  66.  * visible only after all previous stores.
  67.  *   rmb(): Like wmb(), but for reads.
  68.  *   mb(): wmb()/rmb() combo, i.e., all previous memory
  69.  * accesses are visible before all subsequent
  70.  * accesses and vice versa.  This is also known as
  71.  * a "fence."
  72.  *
  73.  * Note: "mb()" and its variants cannot be used as a fence to order
  74.  * accesses to memory mapped I/O registers.  For that, mf.a needs to
  75.  * be used.  However, we don't want to always use mf.a because (a)
  76.  * it's (presumably) much slower than mf and (b) mf.a is supported for
  77.  * sequential memory pages only.
  78.  */
  79. #define mb() __asm__ __volatile__ ("mf" ::: "memory")
  80. #define rmb() mb()
  81. #define wmb() mb()
  82. #ifdef CONFIG_SMP
  83. # define smp_mb() mb()
  84. # define smp_rmb() rmb()
  85. # define smp_wmb() wmb()
  86. #else
  87. # define smp_mb() barrier()
  88. # define smp_rmb() barrier()
  89. # define smp_wmb() barrier()
  90. #endif
  91. /*
  92.  * XXX check on these---I suspect what Linus really wants here is
  93.  * acquire vs release semantics but we can't discuss this stuff with
  94.  * Linus just yet.  Grrr...
  95.  */
  96. #define set_mb(var, value) do { (var) = (value); mb(); } while (0)
  97. #define set_wmb(var, value) do { (var) = (value); mb(); } while (0)
  98. /*
  99.  * The group barrier in front of the rsm & ssm are necessary to ensure
  100.  * that none of the previous instructions in the same group are
  101.  * affected by the rsm/ssm.
  102.  */
  103. /* For spinlocks etc */
  104. #ifdef CONFIG_IA64_DEBUG_IRQ
  105.   extern unsigned long last_cli_ip;
  106. # define local_irq_save(x)
  107. do {
  108. unsigned long ip, psr;
  109. __asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;" : "=r" (psr) :: "memory");
  110. if (psr & (1UL << 14)) {
  111. __asm__ ("mov %0=ip" : "=r"(ip));
  112. last_cli_ip = ip;
  113. }
  114. (x) = psr;
  115. } while (0)
  116. # define local_irq_disable()
  117. do {
  118. unsigned long ip, psr;
  119. __asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;" : "=r" (psr) :: "memory");
  120. if (psr & (1UL << 14)) {
  121. __asm__ ("mov %0=ip" : "=r"(ip));
  122. last_cli_ip = ip;
  123. }
  124. } while (0)
  125. # define local_irq_restore(x)  
  126. do {  
  127. unsigned long ip, old_psr, psr = (x);  
  128.  
  129. __asm__ __volatile__ (";;mov %0=psr; mov psr.l=%1;; srlz.d"  
  130.       : "=&r" (old_psr) : "r" (psr) : "memory"); 
  131. if ((old_psr & (1UL << 14)) && !(psr & (1UL << 14))) {  
  132. __asm__ ("mov %0=ip" : "=r"(ip));  
  133. last_cli_ip = ip;  
  134. }  
  135. } while (0)
  136. #else /* !CONFIG_IA64_DEBUG_IRQ */
  137.   /* clearing of psr.i is implicitly serialized (visible by next insn) */
  138. # define local_irq_save(x) __asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;"
  139.       : "=r" (x) :: "memory")
  140. # define local_irq_disable() __asm__ __volatile__ (";; rsm psr.i;;" ::: "memory")
  141. /* (potentially) setting psr.i requires data serialization: */
  142. # define local_irq_restore(x) __asm__ __volatile__ (";; mov psr.l=%0;; srlz.d"
  143.       :: "r" (x) : "memory")
  144. #endif /* !CONFIG_IA64_DEBUG_IRQ */
  145. #define local_irq_enable() __asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory")
  146. #define __cli() local_irq_disable ()
  147. #define __save_flags(flags) __asm__ __volatile__ ("mov %0=psr" : "=r" (flags) :: "memory")
  148. #define __save_and_cli(flags) local_irq_save(flags)
  149. #define save_and_cli(flags) __save_and_cli(flags)
  150. #define __sti() local_irq_enable ()
  151. #define __restore_flags(flags) local_irq_restore(flags)
  152. #ifdef CONFIG_SMP
  153.   extern void __global_cli (void);
  154.   extern void __global_sti (void);
  155.   extern unsigned long __global_save_flags (void);
  156.   extern void __global_restore_flags (unsigned long);
  157. # define cli() __global_cli()
  158. # define sti() __global_sti()
  159. # define save_flags(flags) ((flags) = __global_save_flags())
  160. # define restore_flags(flags) __global_restore_flags(flags)
  161. #else /* !CONFIG_SMP */
  162. # define cli() __cli()
  163. # define sti() __sti()
  164. # define save_flags(flags) __save_flags(flags)
  165. # define restore_flags(flags) __restore_flags(flags)
  166. #endif /* !CONFIG_SMP */
  167. /*
  168.  * Force an unresolved reference if someone tries to use
  169.  * ia64_fetch_and_add() with a bad value.
  170.  */
  171. extern unsigned long __bad_size_for_ia64_fetch_and_add (void);
  172. extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
  173. #define IA64_FETCHADD(tmp,v,n,sz)
  174. ({
  175. switch (sz) {
  176.       case 4:
  177. __asm__ __volatile__ ("fetchadd4.rel %0=[%1],%2"
  178.       : "=r"(tmp) : "r"(v), "i"(n) : "memory");
  179. break;
  180.       case 8:
  181. __asm__ __volatile__ ("fetchadd8.rel %0=[%1],%2"
  182.       : "=r"(tmp) : "r"(v), "i"(n) : "memory");
  183. break;
  184.       default:
  185. __bad_size_for_ia64_fetch_and_add();
  186. }
  187. })
  188. #define ia64_fetch_and_add(i,v)
  189. ({
  190. __u64 _tmp;
  191. volatile __typeof__(*(v)) *_v = (v);
  192. switch (i) {
  193.       case -16: IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v))); break;
  194.       case  -8: IA64_FETCHADD(_tmp, _v,  -8, sizeof(*(v))); break;
  195.       case  -4: IA64_FETCHADD(_tmp, _v,  -4, sizeof(*(v))); break;
  196.       case  -1: IA64_FETCHADD(_tmp, _v,  -1, sizeof(*(v))); break;
  197.       case   1: IA64_FETCHADD(_tmp, _v,   1, sizeof(*(v))); break;
  198.       case   4: IA64_FETCHADD(_tmp, _v,   4, sizeof(*(v))); break;
  199.       case   8: IA64_FETCHADD(_tmp, _v,   8, sizeof(*(v))); break;
  200.       case  16: IA64_FETCHADD(_tmp, _v,  16, sizeof(*(v))); break;
  201.       default:
  202. _tmp = __bad_increment_for_ia64_fetch_and_add();
  203. break;
  204. }
  205. (__typeof__(*v)) (_tmp + (i)); /* return new value */
  206. })
  207. /*
  208.  * This function doesn't exist, so you'll get a linker error if
  209.  * something tries to do an invalid xchg().
  210.  */
  211. extern void __xchg_called_with_bad_pointer (void);
  212. static __inline__ unsigned long
  213. __xchg (unsigned long x, volatile void *ptr, int size)
  214. {
  215. unsigned long result;
  216. switch (size) {
  217.       case 1:
  218. __asm__ __volatile ("xchg1 %0=[%1],%2" : "=r" (result)
  219.     : "r" (ptr), "r" (x) : "memory");
  220. return result;
  221.       case 2:
  222. __asm__ __volatile ("xchg2 %0=[%1],%2" : "=r" (result)
  223.     : "r" (ptr), "r" (x) : "memory");
  224. return result;
  225.       case 4:
  226. __asm__ __volatile ("xchg4 %0=[%1],%2" : "=r" (result)
  227.     : "r" (ptr), "r" (x) : "memory");
  228. return result;
  229.       case 8:
  230. __asm__ __volatile ("xchg8 %0=[%1],%2" : "=r" (result)
  231.     : "r" (ptr), "r" (x) : "memory");
  232. return result;
  233. }
  234. __xchg_called_with_bad_pointer();
  235. return x;
  236. }
  237. #define xchg(ptr,x)      
  238.   ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr))))
  239. /*
  240.  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  241.  * store NEW in MEM.  Return the initial value in MEM.  Success is
  242.  * indicated by comparing RETURN with OLD.
  243.  */
  244. #define __HAVE_ARCH_CMPXCHG 1
  245. /*
  246.  * This function doesn't exist, so you'll get a linker error
  247.  * if something tries to do an invalid cmpxchg().
  248.  */
  249. extern long __cmpxchg_called_with_bad_pointer(void);
  250. #define ia64_cmpxchg(sem,ptr,old,new,size)
  251. ({
  252. __typeof__(ptr) _p_ = (ptr);
  253. __typeof__(new) _n_ = (new);
  254. __u64 _o_, _r_;
  255. switch (size) {
  256.       case 1: _o_ = (__u8 ) (long) (old); break;
  257.       case 2: _o_ = (__u16) (long) (old); break;
  258.       case 4: _o_ = (__u32) (long) (old); break;
  259.       case 8: _o_ = (__u64) (long) (old); break;
  260.       default: break;
  261. }
  262.  __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_));
  263. switch (size) {
  264.       case 1:
  265. __asm__ __volatile__ ("cmpxchg1."sem" %0=[%1],%2,ar.ccv"
  266.       : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");
  267. break;
  268.       case 2:
  269. __asm__ __volatile__ ("cmpxchg2."sem" %0=[%1],%2,ar.ccv"
  270.       : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");
  271. break;
  272.       case 4:
  273. __asm__ __volatile__ ("cmpxchg4."sem" %0=[%1],%2,ar.ccv"
  274.       : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");
  275. break;
  276.       case 8:
  277. __asm__ __volatile__ ("cmpxchg8."sem" %0=[%1],%2,ar.ccv"
  278.       : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory");
  279. break;
  280.       default:
  281. _r_ = __cmpxchg_called_with_bad_pointer();
  282. break;
  283. }
  284. (__typeof__(old)) _r_;
  285. })
  286. #define cmpxchg_acq(ptr,o,n) ia64_cmpxchg("acq", (ptr), (o), (n), sizeof(*(ptr)))
  287. #define cmpxchg_rel(ptr,o,n) ia64_cmpxchg("rel", (ptr), (o), (n), sizeof(*(ptr)))
  288. /* for compatibility with other platforms: */
  289. #define cmpxchg(ptr,o,n) cmpxchg_acq(ptr,o,n)
  290. #ifdef CONFIG_IA64_DEBUG_CMPXCHG
  291. # define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128;
  292. # define CMPXCHG_BUGCHECK(v)
  293.   do {
  294. if (_cmpxchg_bugcheck_count-- <= 0) {
  295. void *ip;
  296. extern int printk(const char *fmt, ...);
  297. asm ("mov %0=ip" : "=r"(ip));
  298. printk("CMPXCHG_BUGCHECK: stuck at %p on word %pn", ip, (v));
  299. break;
  300. }
  301.   } while (0)
  302. #else /* !CONFIG_IA64_DEBUG_CMPXCHG */
  303. # define CMPXCHG_BUGCHECK_DECL
  304. # define CMPXCHG_BUGCHECK(v)
  305. #endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
  306. #ifdef __KERNEL__
  307. #define prepare_to_switch()    do { } while(0)
  308. #ifdef CONFIG_IA32_SUPPORT
  309. # define IS_IA32_PROCESS(regs) (ia64_psr(regs)->is != 0)
  310. #else
  311. # define IS_IA32_PROCESS(regs) 0
  312. #endif
  313. /*
  314.  * Context switch from one thread to another.  If the two threads have
  315.  * different address spaces, schedule() has already taken care of
  316.  * switching to the new address space by calling switch_mm().
  317.  *
  318.  * Disabling access to the fph partition and the debug-register
  319.  * context switch MUST be done before calling ia64_switch_to() since a
  320.  * newly created thread returns directly to
  321.  * ia64_ret_from_syscall_clear_r8.
  322.  */
  323. extern struct task_struct *ia64_switch_to (void *next_task);
  324. extern void ia64_save_extra (struct task_struct *task);
  325. extern void ia64_load_extra (struct task_struct *task);
  326. #define __switch_to(prev,next,last) do {
  327. if (((prev)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID))
  328.     || IS_IA32_PROCESS(ia64_task_regs(prev)))
  329. ia64_save_extra(prev);
  330. if (((next)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID))
  331.     || IS_IA32_PROCESS(ia64_task_regs(next)))
  332. ia64_load_extra(next);
  333. (last) = ia64_switch_to((next));
  334. } while (0)
  335. #ifdef CONFIG_SMP
  336.   /*
  337.    * In the SMP case, we save the fph state when context-switching
  338.    * away from a thread that modified fph.  This way, when the thread
  339.    * gets scheduled on another CPU, the CPU can pick up the state from
  340.    * task->thread.fph, avoiding the complication of having to fetch
  341.    * the latest fph state from another CPU.
  342.    */
  343. # define switch_to(prev,next,last) do {
  344. if (ia64_psr(ia64_task_regs(prev))->mfh) {
  345. ia64_psr(ia64_task_regs(prev))->mfh = 0;
  346. (prev)->thread.flags |= IA64_THREAD_FPH_VALID;
  347. __ia64_save_fpu((prev)->thread.fph);
  348. }
  349. ia64_psr(ia64_task_regs(prev))->dfh = 1;
  350. __switch_to(prev,next,last);
  351.   } while (0)
  352. /* Return true if this CPU can call the console drivers in printk() */
  353. #define arch_consoles_callable() (cpu_online_map & (1UL << smp_processor_id()))
  354. #else
  355. # define switch_to(prev,next,last) do {
  356. ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next));
  357. __switch_to(prev,next,last);
  358. } while (0)
  359. #endif
  360. #endif /* __KERNEL__ */
  361. #endif /* __ASSEMBLY__ */
  362. #endif /* _ASM_IA64_SYSTEM_H */