1 |
1275 |
phoenix |
/* $Id: processor.h,v 1.1.1.1 2004-04-15 02:40:24 phoenix 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 |
|
|
|
47 |
|
|
struct fpq {
|
48 |
|
|
unsigned long *insn_addr;
|
49 |
|
|
unsigned long insn;
|
50 |
|
|
};
|
51 |
|
|
|
52 |
|
|
typedef struct {
|
53 |
|
|
int seg;
|
54 |
|
|
} mm_segment_t;
|
55 |
|
|
|
56 |
|
|
/* The Sparc processor specific thread struct. */
|
57 |
|
|
struct 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. */
|
118 |
|
|
extern __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. */
|
124 |
|
|
extern __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 |
|
|
: /* no outputs */
|
144 |
|
|
: "r" (regs),
|
145 |
|
|
"r" (sp - sizeof(struct reg_window)),
|
146 |
|
|
"r" (zero),
|
147 |
|
|
"i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))
|
148 |
|
|
: "memory");
|
149 |
|
|
}
|
150 |
|
|
|
151 |
|
|
/* Free all resources held by a thread. */
|
152 |
|
|
#define release_thread(tsk) do { } while(0)
|
153 |
|
|
extern pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
|
154 |
|
|
|
155 |
|
|
|
156 |
|
|
#define copy_segments(tsk, mm) do { } while (0)
|
157 |
|
|
#define release_segments(mm) do { } while (0)
|
158 |
|
|
|
159 |
|
|
#define get_wchan(__TSK) \
|
160 |
|
|
({ extern void scheduling_functions_start_here(void); \
|
161 |
|
|
extern void scheduling_functions_end_here(void); \
|
162 |
|
|
unsigned long pc, fp, bias = 0; \
|
163 |
|
|
unsigned long task_base = (unsigned long) (__TSK); \
|
164 |
|
|
unsigned long __ret = 0; \
|
165 |
|
|
struct reg_window *rw; \
|
166 |
|
|
int count = 0; \
|
167 |
|
|
if (!(__TSK) || (__TSK) == current || \
|
168 |
|
|
(__TSK)->state == TASK_RUNNING) \
|
169 |
|
|
goto __out; \
|
170 |
|
|
fp = (__TSK)->thread.ksp + bias; \
|
171 |
|
|
do { \
|
172 |
|
|
/* Bogus frame pointer? */ \
|
173 |
|
|
if (fp < (task_base + sizeof(struct task_struct)) || \
|
174 |
|
|
fp >= (task_base + (2 * PAGE_SIZE))) \
|
175 |
|
|
break; \
|
176 |
|
|
rw = (struct reg_window *) fp; \
|
177 |
|
|
pc = rw->ins[7]; \
|
178 |
|
|
if (pc < ((unsigned long) scheduling_functions_start_here) || \
|
179 |
|
|
pc >= ((unsigned long) scheduling_functions_end_here)) { \
|
180 |
|
|
__ret = pc; \
|
181 |
|
|
goto __out; \
|
182 |
|
|
} \
|
183 |
|
|
fp = rw->ins[6] + bias; \
|
184 |
|
|
} while (++count < 16); \
|
185 |
|
|
__out: __ret; \
|
186 |
|
|
})
|
187 |
|
|
|
188 |
|
|
#define KSTK_EIP(tsk) ((tsk)->thread.kregs->pc)
|
189 |
|
|
#define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP])
|
190 |
|
|
|
191 |
|
|
#ifdef __KERNEL__
|
192 |
|
|
#define THREAD_SIZE (2*PAGE_SIZE)
|
193 |
|
|
|
194 |
|
|
extern struct task_struct *last_task_used_math;
|
195 |
|
|
|
196 |
|
|
/* Allocation and freeing of basic task resources. */
|
197 |
|
|
BTFIXUPDEF_CALL(struct task_struct *, alloc_task_struct, void)
|
198 |
|
|
BTFIXUPDEF_CALL(void, free_task_struct, struct task_struct *)
|
199 |
|
|
BTFIXUPDEF_CALL(void, get_task_struct, struct task_struct *)
|
200 |
|
|
|
201 |
|
|
#define alloc_task_struct() BTFIXUP_CALL(alloc_task_struct)()
|
202 |
|
|
#define free_task_struct(tsk) BTFIXUP_CALL(free_task_struct)(tsk)
|
203 |
|
|
#define get_task_struct(tsk) BTFIXUP_CALL(get_task_struct)(tsk)
|
204 |
|
|
|
205 |
|
|
#define init_task (init_task_union.task)
|
206 |
|
|
#define init_stack (init_task_union.stack)
|
207 |
|
|
|
208 |
|
|
#define cpu_relax() barrier()
|
209 |
|
|
|
210 |
|
|
#endif
|
211 |
|
|
|
212 |
|
|
#endif /* __ASM_SPARC_PROCESSOR_H */
|