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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: processor.h,v 1.80.2.1 2002/02/02 02:11:52 kanoj Exp $
  2.  * include/asm-sparc64/processor.h
  3.  *
  4.  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  5.  */
  6. #ifndef __ASM_SPARC64_PROCESSOR_H
  7. #define __ASM_SPARC64_PROCESSOR_H
  8. /*
  9.  * Sparc64 implementation of macro that returns current
  10.  * instruction pointer ("program counter").
  11.  */
  12. #define current_text_addr() ({ void *pc; __asm__("rd %%pc, %0" : "=r" (pc)); pc; })
  13. #include <linux/config.h>
  14. #include <asm/asi.h>
  15. #include <asm/a.out.h>
  16. #include <asm/pstate.h>
  17. #include <asm/ptrace.h>
  18. #include <asm/signal.h>
  19. #include <asm/segment.h>
  20. #include <asm/page.h>
  21. #include <asm/delay.h>
  22. /* Bus types */
  23. #define EISA_bus 0
  24. #define EISA_bus__is_a_macro /* for versions in ksyms.c */
  25. #define MCA_bus 0
  26. #define MCA_bus__is_a_macro /* for versions in ksyms.c */
  27. /* The sparc has no problems with write protection */
  28. #define wp_works_ok 1
  29. #define wp_works_ok__is_a_macro /* for versions in ksyms.c */
  30. /*
  31.  * User lives in his very own context, and cannot reference us. Note
  32.  * that TASK_SIZE is a misnomer, it really gives maximum user virtual 
  33.  * address that the kernel will allocate out.
  34.  */
  35. #define VA_BITS 44
  36. #define VPTE_SIZE (1UL << (VA_BITS - PAGE_SHIFT + 3))
  37. #define TASK_SIZE ((unsigned long)-VPTE_SIZE)
  38. #ifndef __ASSEMBLY__
  39. #define NSWINS 7
  40. typedef struct {
  41. unsigned char seg;
  42. } mm_segment_t;
  43. /* The Sparc processor specific thread struct. */
  44. struct thread_struct {
  45. /* D$ line 1 */
  46. unsigned long ksp __attribute__ ((aligned(16)));
  47. unsigned char wstate, cwp, flags;
  48. mm_segment_t current_ds;
  49. unsigned char w_saved, fpdepth, fault_code, use_blkcommit;
  50. unsigned long fault_address;
  51. unsigned char fpsaved[7];
  52. unsigned char __pad2;
  53. /* D$ line 2, 3, 4 */
  54. struct pt_regs *kregs;
  55. unsigned long *utraps;
  56. unsigned long gsr[7];
  57. unsigned long xfsr[7];
  58. #ifdef CONFIG_DEBUG_SPINLOCK
  59. /* How many spinlocks held by this thread.
  60.  * Used with spin lock debugging to catch tasks
  61.  * sleeping illegally with locks held.
  62.  */
  63. int smp_lock_count;
  64. unsigned int smp_lock_pc;
  65. #endif
  66. struct reg_window reg_window[NSWINS];
  67. unsigned long rwbuf_stkptrs[NSWINS];
  68. /* Performance counter state */
  69. u64 *user_cntd0, *user_cntd1;
  70. u64 kernel_cntd0, kernel_cntd1;
  71. u64 pcr_reg;
  72. };
  73. #endif /* !(__ASSEMBLY__) */
  74. #define SPARC_FLAG_UNALIGNED    0x01    /* is allowed to do unaligned accesses */
  75. #define SPARC_FLAG_NEWSIGNALS   0x02    /* task wants new-style signals */
  76. #define SPARC_FLAG_32BIT        0x04    /* task is older 32-bit binary */
  77. #define SPARC_FLAG_NEWCHILD     0x08    /* task is just-spawned child process */
  78. #define SPARC_FLAG_PERFCTR 0x10    /* task has performance counters active */
  79. #define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */
  80. #define FAULT_CODE_DTLB 0x02 /* Miss happened in D-TLB */
  81. #define FAULT_CODE_ITLB 0x04 /* Miss happened in I-TLB */
  82. #define FAULT_CODE_WINFIXUP 0x08 /* Miss happened during spill/fill */
  83. #ifndef CONFIG_DEBUG_SPINLOCK
  84. #define INIT_THREAD  {
  85. /* ksp, wstate, cwp, flags, current_ds, */ 
  86.    0,   0,      0,   0,     KERNEL_DS,
  87. /* w_saved, fpdepth, fault_code, use_blkcommit, */
  88.    0,       0,       0,          0,
  89. /* fault_address, fpsaved, __pad2, kregs, */
  90.    0,             { 0 },   0,      0,
  91. /* utraps, gsr,   xfsr, */
  92.    0,    { 0 }, { 0 },
  93. /* reg_window */
  94.    { { { 0, }, { 0, } }, }, 
  95. /* rwbuf_stkptrs */
  96.    { 0, 0, 0, 0, 0, 0, 0, },
  97. /* user_cntd0, user_cndd1, kernel_cntd0, kernel_cntd0, pcr_reg */ 
  98.    0,          0,          0,  0,            0, 
  99. }
  100. #else /* CONFIG_DEBUG_SPINLOCK */
  101. #define INIT_THREAD  {
  102. /* ksp, wstate, cwp, flags, current_ds, */ 
  103.    0,   0,      0,   0,     KERNEL_DS,
  104. /* w_saved, fpdepth, fault_code, use_blkcommit, */
  105.    0,       0,       0,          0,
  106. /* fault_address, fpsaved, __pad2, kregs, */
  107.    0,             { 0 },   0,      0,
  108. /* utraps, gsr,   xfsr,  smp_lock_count, smp_lock_pc, */
  109.    0,    { 0 }, { 0 }, 0,  0,
  110. /* reg_window */
  111.    { { { 0, }, { 0, } }, }, 
  112. /* rwbuf_stkptrs */
  113.    { 0, 0, 0, 0, 0, 0, 0, },
  114. /* user_cntd0, user_cndd1, kernel_cntd0, kernel_cntd0, pcr_reg */ 
  115.    0,          0,          0,  0,            0, 
  116. }
  117. #endif /* !(CONFIG_DEBUG_SPINLOCK) */
  118. #ifdef __KERNEL__
  119. #if PAGE_SHIFT == 13
  120. #define THREAD_SIZE (2*PAGE_SIZE)
  121. #define THREAD_SHIFT (PAGE_SHIFT + 1)
  122. #else /* PAGE_SHIFT == 13 */
  123. #define THREAD_SIZE PAGE_SIZE
  124. #define THREAD_SHIFT PAGE_SHIFT
  125. #endif /* PAGE_SHIFT == 13 */
  126. #endif /* __KERNEL__ */
  127. #ifndef __ASSEMBLY__
  128. /* Return saved PC of a blocked thread. */
  129. extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
  130. {
  131. unsigned long ret = 0xdeadbeefUL;
  132. if (t->ksp) {
  133. unsigned long *sp;
  134. sp = (unsigned long *)(t->ksp + STACK_BIAS);
  135. if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL &&
  136.     sp[14]) {
  137. unsigned long *fp;
  138. fp = (unsigned long *)(sp[14] + STACK_BIAS);
  139. if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL)
  140. ret = fp[15];
  141. }
  142. }
  143. return ret;
  144. }
  145. /* On Uniprocessor, even in RMO processes see TSO semantics */
  146. #ifdef CONFIG_SMP
  147. #define TSTATE_INITIAL_MM TSTATE_TSO
  148. #else
  149. #define TSTATE_INITIAL_MM TSTATE_RMO
  150. #endif
  151. /* Do necessary setup to start up a newly executed thread. */
  152. #define start_thread(regs, pc, sp) 
  153. do { 
  154. regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_INITIAL_MM|TSTATE_IE) | (ASI_PNF << 24); 
  155. regs->tpc = ((pc & (~3)) - 4); 
  156. regs->tnpc = regs->tpc + 4; 
  157. regs->y = 0; 
  158. current->thread.wstate = (1 << 3); 
  159. if (current->thread.utraps) { 
  160. if (*(current->thread.utraps) < 2) 
  161. kfree (current->thread.utraps); 
  162. else 
  163. (*(current->thread.utraps))--; 
  164. current->thread.utraps = NULL; 
  165. __asm__ __volatile__( 
  166. "stx %%g0, [%0 + %2 + 0x00]nt" 
  167. "stx %%g0, [%0 + %2 + 0x08]nt" 
  168. "stx %%g0, [%0 + %2 + 0x10]nt" 
  169. "stx %%g0, [%0 + %2 + 0x18]nt" 
  170. "stx %%g0, [%0 + %2 + 0x20]nt" 
  171. "stx %%g0, [%0 + %2 + 0x28]nt" 
  172. "stx %%g0, [%0 + %2 + 0x30]nt" 
  173. "stx %%g0, [%0 + %2 + 0x38]nt" 
  174. "stx %%g0, [%0 + %2 + 0x40]nt" 
  175. "stx %%g0, [%0 + %2 + 0x48]nt" 
  176. "stx %%g0, [%0 + %2 + 0x50]nt" 
  177. "stx %%g0, [%0 + %2 + 0x58]nt" 
  178. "stx %%g0, [%0 + %2 + 0x60]nt" 
  179. "stx %%g0, [%0 + %2 + 0x68]nt" 
  180. "stx %1,   [%0 + %2 + 0x70]nt" 
  181. "stx %%g0, [%0 + %2 + 0x78]nt" 
  182. "wrpr %%g0, (1 << 3), %%wstatent" 
  183. : "r" (regs), "r" (sp - REGWIN_SZ - STACK_BIAS), 
  184.   "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); 
  185. } while(0)
  186. #define start_thread32(regs, pc, sp) 
  187. do { 
  188. pc &= 0x00000000ffffffffUL; 
  189. sp &= 0x00000000ffffffffUL; 
  190. regs->tstate = (regs->tstate & (TSTATE_CWP))|(TSTATE_INITIAL_MM|TSTATE_IE|TSTATE_AM); 
  191. regs->tpc = ((pc & (~3)) - 4); 
  192. regs->tnpc = regs->tpc + 4; 
  193. regs->y = 0; 
  194. current->thread.wstate = (2 << 3); 
  195. if (current->thread.utraps) { 
  196. if (*(current->thread.utraps) < 2) 
  197. kfree (current->thread.utraps); 
  198. else 
  199. (*(current->thread.utraps))--; 
  200. current->thread.utraps = NULL; 
  201. __asm__ __volatile__( 
  202. "stx %%g0, [%0 + %2 + 0x00]nt" 
  203. "stx %%g0, [%0 + %2 + 0x08]nt" 
  204. "stx %%g0, [%0 + %2 + 0x10]nt" 
  205. "stx %%g0, [%0 + %2 + 0x18]nt" 
  206. "stx %%g0, [%0 + %2 + 0x20]nt" 
  207. "stx %%g0, [%0 + %2 + 0x28]nt" 
  208. "stx %%g0, [%0 + %2 + 0x30]nt" 
  209. "stx %%g0, [%0 + %2 + 0x38]nt" 
  210. "stx %%g0, [%0 + %2 + 0x40]nt" 
  211. "stx %%g0, [%0 + %2 + 0x48]nt" 
  212. "stx %%g0, [%0 + %2 + 0x50]nt" 
  213. "stx %%g0, [%0 + %2 + 0x58]nt" 
  214. "stx %%g0, [%0 + %2 + 0x60]nt" 
  215. "stx %%g0, [%0 + %2 + 0x68]nt" 
  216. "stx %1,   [%0 + %2 + 0x70]nt" 
  217. "stx %%g0, [%0 + %2 + 0x78]nt" 
  218. "wrpr %%g0, (2 << 3), %%wstatent" 
  219. : "r" (regs), "r" (sp - REGWIN32_SZ), 
  220.   "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); 
  221. } while(0)
  222. /* Free all resources held by a thread. */
  223. #define release_thread(tsk) do { } while(0)
  224. extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
  225. #define copy_segments(tsk, mm) do { } while (0)
  226. #define release_segments(mm) do { } while (0)
  227. #define get_wchan(__TSK) 
  228. ({ extern void scheduling_functions_start_here(void); 
  229. extern void scheduling_functions_end_here(void); 
  230. unsigned long pc, fp, bias = 0; 
  231. unsigned long task_base = (unsigned long) (__TSK); 
  232. struct reg_window *rw; 
  233.         unsigned long __ret = 0; 
  234. int count = 0; 
  235. if (!(__TSK) || (__TSK) == current || 
  236.             (__TSK)->state == TASK_RUNNING) 
  237. goto __out; 
  238. bias = STACK_BIAS; 
  239. fp = (__TSK)->thread.ksp + bias; 
  240. do { 
  241. /* Bogus frame pointer? */ 
  242. if (fp < (task_base + sizeof(struct task_struct)) || 
  243.     fp >= (task_base + THREAD_SIZE)) 
  244. break; 
  245. rw = (struct reg_window *) fp; 
  246. pc = rw->ins[7]; 
  247. if (pc < ((unsigned long) scheduling_functions_start_here) || 
  248.     pc >= ((unsigned long) scheduling_functions_end_here)) { 
  249. __ret = pc; 
  250. goto __out; 
  251. fp = rw->ins[6] + bias; 
  252. } while (++count < 16); 
  253. __out: __ret; 
  254. })
  255. #define KSTK_EIP(tsk)  ((tsk)->thread.kregs->tpc)
  256. #define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
  257. #ifdef __KERNEL__
  258. /* Allocation and freeing of task_struct and kernel stack. */
  259. #if PAGE_SHIFT == 13
  260. #define alloc_task_struct()   ((struct task_struct *)__get_free_pages(GFP_KERNEL, 1))
  261. #define free_task_struct(tsk) free_pages((unsigned long)(tsk),1)
  262. #else /* PAGE_SHIFT == 13 */
  263. #define alloc_task_struct()   ((struct task_struct *)__get_free_pages(GFP_KERNEL, 0))
  264. #define free_task_struct(tsk) free_pages((unsigned long)(tsk),0)
  265. #endif /* PAGE_SHIFT == 13 */
  266. #define get_task_struct(tsk)      atomic_inc(&virt_to_page(tsk)->count)
  267. #define init_task (init_task_union.task)
  268. #define init_stack (init_task_union.stack)
  269. #define cpu_relax() udelay(1 + smp_processor_id())
  270. #endif /* __KERNEL__ */
  271. #endif /* !(__ASSEMBLY__) */
  272. #endif /* !(__ASM_SPARC64_PROCESSOR_H) */