1/* $Id: processor.h,v 1.1.1.1 2008/10/15 03:29:17 james26_jang Exp $ 2 * include/asm-sparc/processor.h 3 * 4 * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) 5 */ 6 7#ifndef __ASM_SPARC_PROCESSOR_H 8#define __ASM_SPARC_PROCESSOR_H 9 10/* 11 * Sparc32 implementation of macro that returns current 12 * instruction pointer ("program counter"). 13 */ 14#define current_text_addr() ({ void *pc; __asm__("sethi %%hi(1f), %0; or %0, %%lo(1f), %0;\n1:" : "=r" (pc)); pc; }) 15 16#include <linux/a.out.h> 17 18#include <asm/psr.h> 19#include <asm/ptrace.h> 20#include <asm/head.h> 21#include <asm/signal.h> 22#include <asm/segment.h> 23#include <asm/btfixup.h> 24#include <asm/page.h> 25#include <asm/atomic.h> 26 27/* 28 * Bus types 29 */ 30#define EISA_bus 0 31#define EISA_bus__is_a_macro /* for versions in ksyms.c */ 32#define MCA_bus 0 33#define MCA_bus__is_a_macro /* for versions in ksyms.c */ 34 35/* 36 * The sparc has no problems with write protection 37 */ 38#define wp_works_ok 1 39#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ 40 41/* Whee, this is STACK_TOP + PAGE_SIZE and the lowest kernel address too... 42 * That one page is used to protect kernel from intruders, so that 43 * we can make our access_ok test faster 44 */ 45#define TASK_SIZE PAGE_OFFSET 46 47struct fpq { 48 unsigned long *insn_addr; 49 unsigned long insn; 50}; 51 52typedef struct { 53 int seg; 54} mm_segment_t; 55 56/* The Sparc processor specific thread struct. */ 57struct thread_struct { 58 unsigned long uwinmask __attribute__ ((aligned (8))); 59 struct pt_regs *kregs; 60 61 /* Context switch saved kernel state. */ 62 unsigned long ksp __attribute__ ((aligned (8))); 63 unsigned long kpc; 64 unsigned long kpsr; 65 unsigned long kwim; 66 67 /* Special child fork kpsr/kwim values. */ 68 unsigned long fork_kpsr __attribute__ ((aligned (8))); 69 unsigned long fork_kwim; 70 71 /* A place to store user windows and stack pointers 72 * when the stack needs inspection. 73 */ 74#define NSWINS 8 75 struct reg_window reg_window[NSWINS] __attribute__ ((aligned (8))); 76 unsigned long rwbuf_stkptrs[NSWINS] __attribute__ ((aligned (8))); 77 unsigned long w_saved; 78 79 /* Floating point regs */ 80 unsigned long float_regs[32] __attribute__ ((aligned (8))); 81 unsigned long fsr; 82 unsigned long fpqdepth; 83 struct fpq fpqueue[16]; 84 unsigned long flags; 85 mm_segment_t current_ds; 86 struct exec core_exec; /* just what it says. */ 87 int new_signal; 88 atomic_t refcount; /* used for sun4c only */ 89}; 90 91#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */ 92#define SPARC_FLAG_UNALIGNED 0x2 /* is allowed to do unaligned accesses */ 93 94#define INIT_THREAD { \ 95/* uwinmask, kregs, ksp, kpc, kpsr, kwim */ \ 96 0, 0, 0, 0, 0, 0, \ 97/* fork_kpsr, fork_kwim */ \ 98 0, 0, \ 99/* reg_window */ \ 100{ { { 0, }, { 0, } }, }, \ 101/* rwbuf_stkptrs */ \ 102{ 0, 0, 0, 0, 0, 0, 0, 0, }, \ 103/* w_saved */ \ 104 0, \ 105/* FPU regs */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \ 107/* FPU status, FPU qdepth, FPU queue */ \ 108 0, 0, { { 0, 0, }, }, \ 109/* flags, current_ds, */ \ 110 SPARC_FLAG_KTHREAD, KERNEL_DS, \ 111/* core_exec */ \ 112{ 0, }, \ 113/* new_signal */ \ 114 0, \ 115} 116 117/* Return saved PC of a blocked thread. */ 118extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t) 119{ 120 return t->kpc; 121} 122 123/* Do necessary setup to start up a newly executed thread. */ 124extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc, 125 unsigned long sp) 126{ 127 register unsigned long zero asm("g1"); 128 129 regs->psr = (regs->psr & (PSR_CWP)) | PSR_S; 130 regs->pc = ((pc & (~3)) - 4); 131 regs->npc = regs->pc + 4; 132 regs->y = 0; 133 zero = 0; 134 __asm__ __volatile__("std\t%%g0, [%0 + %3 + 0x00]\n\t" 135 "std\t%%g0, [%0 + %3 + 0x08]\n\t" 136 "std\t%%g0, [%0 + %3 + 0x10]\n\t" 137 "std\t%%g0, [%0 + %3 + 0x18]\n\t" 138 "std\t%%g0, [%0 + %3 + 0x20]\n\t" 139 "std\t%%g0, [%0 + %3 + 0x28]\n\t" 140 "std\t%%g0, [%0 + %3 + 0x30]\n\t" 141 "st\t%1, [%0 + %3 + 0x38]\n\t" 142 "st\t%%g0, [%0 + %3 + 0x3c]" 143 : : "r" (regs), "r" (sp - REGWIN_SZ), "r" (zero), 144 "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); 145} 146 147/* Free all resources held by a thread. */ 148#define release_thread(tsk) do { } while(0) 149extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 150 151 152#define copy_segments(tsk, mm) do { } while (0) 153#define release_segments(mm) do { } while (0) 154 155#define get_wchan(__TSK) \ 156({ extern void scheduling_functions_start_here(void); \ 157 extern void scheduling_functions_end_here(void); \ 158 unsigned long pc, fp, bias = 0; \ 159 unsigned long task_base = (unsigned long) (__TSK); \ 160 unsigned long __ret = 0; \ 161 struct reg_window *rw; \ 162 int count = 0; \ 163 if (!(__TSK) || (__TSK) == current || \ 164 (__TSK)->state == TASK_RUNNING) \ 165 goto __out; \ 166 fp = (__TSK)->thread.ksp + bias; \ 167 do { \ 168 /* Bogus frame pointer? */ \ 169 if (fp < (task_base + sizeof(struct task_struct)) || \ 170 fp >= (task_base + (2 * PAGE_SIZE))) \ 171 break; \ 172 rw = (struct reg_window *) fp; \ 173 pc = rw->ins[7]; \ 174 if (pc < ((unsigned long) scheduling_functions_start_here) || \ 175 pc >= ((unsigned long) scheduling_functions_end_here)) { \ 176 __ret = pc; \ 177 goto __out; \ 178 } \ 179 fp = rw->ins[6] + bias; \ 180 } while (++count < 16); \ 181__out: __ret; \ 182}) 183 184#define KSTK_EIP(tsk) ((tsk)->thread.kregs->pc) 185#define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP]) 186 187#ifdef __KERNEL__ 188#define THREAD_SIZE (2*PAGE_SIZE) 189 190extern struct task_struct *last_task_used_math; 191 192/* Allocation and freeing of basic task resources. */ 193BTFIXUPDEF_CALL(struct task_struct *, alloc_task_struct, void) 194BTFIXUPDEF_CALL(void, free_task_struct, struct task_struct *) 195BTFIXUPDEF_CALL(void, get_task_struct, struct task_struct *) 196 197#define alloc_task_struct() BTFIXUP_CALL(alloc_task_struct)() 198#define free_task_struct(tsk) BTFIXUP_CALL(free_task_struct)(tsk) 199#define get_task_struct(tsk) BTFIXUP_CALL(get_task_struct)(tsk) 200 201#define init_task (init_task_union.task) 202#define init_stack (init_task_union.stack) 203 204#define cpu_relax() do { } while (0) 205 206#endif 207 208#endif /* __ASM_SPARC_PROCESSOR_H */ 209