File: /usr/src/linux/include/asm-parisc/processor.h
1 /*
2 * include/asm-parisc/processor.h
3 *
4 * Copyright (C) 1994 Linus Torvalds
5 */
6
7 #ifndef __ASM_PARISC_PROCESSOR_H
8 #define __ASM_PARISC_PROCESSOR_H
9
10 #ifndef __ASSEMBLY__
11 #include <linux/threads.h>
12
13 #include <asm/hardware.h>
14 #include <asm/page.h>
15 #include <asm/pdc.h>
16 #include <asm/ptrace.h>
17 #include <asm/types.h>
18 #endif /* __ASSEMBLY__ */
19
20 /*
21 * Default implementation of macro that returns current
22 * instruction pointer ("program counter").
23 */
24
25 /* We cannot use MFIA as it was added for PA2.0 - prumpf
26
27 At one point there were no "0f/0b" type local symbols in gas for
28 PA-RISC. This is no longer true, but this still seems like the
29 nicest way to implement this. */
30
31 #define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; })
32
33 #define TASK_SIZE (PAGE_OFFSET)
34 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
35
36 #ifndef __ASSEMBLY__
37
38 /*
39 ** Data detected about CPUs at boot time which is the same for all CPU's.
40 ** HP boxes are SMP - ie identical processors.
41 **
42 ** FIXME: some CPU rev info may be processor specific...
43 */
44 struct system_cpuinfo_parisc {
45 unsigned int cpu_count;
46 unsigned int cpu_hz;
47 unsigned int hversion;
48 unsigned int sversion;
49 enum cpu_type cpu_type;
50
51 struct {
52 struct pdc_model model;
53 struct pdc_model_cpuid /* ARGH */ versions;
54 struct pdc_model_cpuid cpuid;
55 #if 0
56 struct pdc_model_caps caps;
57 #endif
58 char sys_model_name[81]; /* PDC-ROM returnes this model name */
59 } pdc;
60
61 char *model_name;
62 char *cpu_name;
63 char *family_name;
64 };
65
66
67 /*
68 ** Per CPU data structure - ie varies per CPU.
69 */
70 struct cpuinfo_parisc {
71 unsigned cpuid;
72
73 struct irq_region *region;
74
75 unsigned long it_value; /* Interval Timer value at last timer interrupt */
76 unsigned long it_delta; /* Interval Timer delta (tic_10ms / HZ * 100) */
77
78 unsigned long hpa; /* Host Physical address */
79 unsigned long txn_addr; /* External Interrupt Register or id_eid */
80
81 unsigned long bh_count; /* number of times bh was invoked */
82 unsigned long irq_count; /* number of IRQ's since boot */
83 unsigned long irq_max_cr16; /* longest time to handle a single IRQ */
84 };
85
86 extern struct system_cpuinfo_parisc boot_cpu_data;
87 extern struct cpuinfo_parisc cpu_data[NR_CPUS];
88 #define current_cpu_data cpu_data[smp_processor_id()]
89
90 extern void identify_cpu(struct cpuinfo_parisc *);
91
92 #define EISA_bus 0 /* we don't have ISA support yet */
93 #define EISA_bus__is_a_macro /* for versions in ksyms.c */
94 #define MCA_bus 0
95 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
96
97 typedef struct {
98 int seg;
99 } mm_segment_t;
100
101 struct thread_struct {
102 struct pt_regs regs;
103 unsigned long pg_tables;
104 unsigned long flags;
105 };
106
107 /* Thread struct flags. */
108 #define PARISC_KERNEL_DEATH (1UL << 31) /* see die_if_kernel()... */
109
110 #define INIT_THREAD { { \
111 { 0, 0, 0, 0, 0, 0, 0, 0, \
112 0, 0, 0, 0, 0, 0, 0, 0, \
113 0, 0, 0, 0, 0, 0, 0, 0, \
114 0, 0, 0, 0, 0, 0, 0, 0 }, \
115 { 0, 0, 0, 0, 0, 0, 0, 0, \
116 0, 0, 0, 0, 0, 0, 0, 0, \
117 0, 0, 0, 0, 0, 0, 0, 0, \
118 0, 0, 0, 0, 0, 0, 0, 0 }, \
119 { 0, 0, 0, 0, 0, 0, 0, 0 }, \
120 { 0, 0}, { 0, 0}, 0, 0, 0, 0 \
121 }, __pa((unsigned long) swapper_pg_dir) }
122
123 /*
124 * Return saved PC of a blocked thread. This is used by ps mostly.
125 */
126
127 extern inline unsigned long thread_saved_pc(struct thread_struct *t)
128 {
129 return 0xabcdef;
130 }
131
132 /*
133 * Start user thread in another space.
134 *
135 * Note that we set both the iaoq and r31 to the new pc. When
136 * the kernel initially calls execve it will return through an
137 * rfi path that will use the values in the iaoq. The execve
138 * syscall path will return through the gateway page, and
139 * that uses r31 to branch to.
140 *
141 * For ELF we clear r23, because the dynamic linker uses it to pass
142 * the address of the finalizer function.
143 *
144 * We also initialize sr3 to an illegal value (illegal for our
145 * implementation, not for the architecture).
146 */
147
148 /* The ELF abi wants things done a "wee bit" differently than
149 * som does. Supporting this behavior here avoids
150 * having our own version of create_elf_tables.
151 *
152 * Oh, and yes, that is not a typo, we are really passing argc in r25
153 * and argv in r24 (rather than r26 and r25). This is because that's
154 * where __libc_start_main wants them.
155 *
156 * Duplicated from dl-machine.h for the benefit of readers:
157 *
158 * Our initial stack layout is rather different from everyone else's
159 * due to the unique PA-RISC ABI. As far as I know it looks like
160 * this:
161
162 ----------------------------------- (user startup code creates this frame)
163 | 32 bytes of magic |
164 |---------------------------------|
165 | 32 bytes argument/sp save area |
166 |---------------------------------| ((current->mm->env_end) + 63 & ~63)
167 | N bytes of slack |
168 |---------------------------------|
169 | envvar and arg strings |
170 |---------------------------------|
171 | ELF auxiliary info |
172 | (up to 28 words) |
173 |---------------------------------|
174 | Environment variable pointers |
175 | upwards to NULL |
176 |---------------------------------|
177 | Argument pointers |
178 | upwards to NULL |
179 |---------------------------------|
180 | argc (1 word) |
181 -----------------------------------
182
183 * The pleasant part of this is that if we need to skip arguments we
184 * can just decrement argc and move argv, because the stack pointer
185 * is utterly unrelated to the location of the environment and
186 * argument vectors.
187 *
188 * Note that the S/390 people took the easy way out and hacked their
189 * GCC to make the stack grow downwards. */
190
191 #define start_thread_som(regs, new_pc, new_sp) do { \
192 unsigned long *sp = (unsigned long *)new_sp; \
193 __u32 spaceid = (__u32)current->mm->context; \
194 unsigned long pc = (unsigned long)new_pc; \
195 /* offset pc for priv. level */ \
196 pc |= 3; \
197 \
198 set_fs(USER_DS); \
199 regs->iasq[0] = spaceid; \
200 regs->iasq[1] = spaceid; \
201 regs->iaoq[0] = pc; \
202 regs->iaoq[1] = pc; \
203 regs->sr[2] = LINUX_GATEWAY_SPACE; \
204 regs->sr[3] = 0xffff; \
205 regs->sr[4] = spaceid; \
206 regs->sr[5] = spaceid; \
207 regs->sr[6] = spaceid; \
208 regs->sr[7] = spaceid; \
209 regs->gr[ 0] = USER_INIT_PSW; \
210 regs->gr[30] = ((new_sp)+63)&~63; \
211 regs->gr[31] = pc; \
212 \
213 get_user(regs->gr[26],&sp[0]); \
214 get_user(regs->gr[25],&sp[-1]); \
215 get_user(regs->gr[24],&sp[-2]); \
216 get_user(regs->gr[23],&sp[-3]); \
217 \
218 regs->cr30 = (u32) current; \
219 } while(0)
220
221
222 #define start_thread(regs, new_pc, new_sp) do { \
223 unsigned long *sp = (unsigned long *)new_sp; \
224 __u32 spaceid = (__u32)current->mm->context; \
225 unsigned long pc = (unsigned long)new_pc; \
226 /* offset pc for priv. level */ \
227 pc |= 3; \
228 \
229 \
230 set_fs(USER_DS); \
231 regs->iasq[0] = spaceid; \
232 regs->iasq[1] = spaceid; \
233 regs->iaoq[0] = pc; \
234 regs->iaoq[1] = pc; \
235 regs->sr[2] = LINUX_GATEWAY_SPACE; \
236 regs->sr[3] = 0xffff; \
237 regs->sr[4] = spaceid; \
238 regs->sr[5] = spaceid; \
239 regs->sr[6] = spaceid; \
240 regs->sr[7] = spaceid; \
241 regs->gr[ 0] = USER_INIT_PSW; \
242 regs->fr[ 0] = 0LL; \
243 regs->fr[ 1] = 0LL; \
244 regs->fr[ 2] = 0LL; \
245 regs->fr[ 3] = 0LL; \
246 regs->gr[30] = ((current->mm->env_end)+63)&~63; \
247 regs->gr[31] = pc; \
248 \
249 get_user(regs->gr[25],&sp[0]); \
250 regs->gr[24] = (unsigned long) &sp[1]; \
251 regs->gr[23] = 0; \
252 \
253 regs->cr30 = (u32) current; \
254 } while(0)
255
256 #ifdef __LP64__
257
258 /*
259 * For 64 bit kernels we need a version of start thread for 32 bit
260 * elf files.
261 *
262 * FIXME: It should be possible to not duplicate the above code
263 * by playing games with concatenation to form both
264 * macros at compile time. The only difference between
265 * this macro and the above is the name and the types
266 * for sp and pc.
267 */
268
269 #define start_thread32(regs, new_pc, new_sp) do { \
270 __u32 *sp = (__u32 *)new_sp; \
271 __u32 spaceid = (__u32)current->mm->context; \
272 __u32 pc = (__u32)new_pc; \
273 /* offset pc for priv. level */ \
274 pc |= 3; \
275 \
276 set_fs(USER_DS); \
277 regs->iasq[0] = spaceid; \
278 regs->iasq[1] = spaceid; \
279 regs->iaoq[0] = pc; \
280 regs->iaoq[1] = pc; \
281 regs->sr[2] = LINUX_GATEWAY_SPACE; \
282 regs->sr[3] = 0xffff; \
283 regs->sr[4] = spaceid; \
284 regs->sr[5] = spaceid; \
285 regs->sr[6] = spaceid; \
286 regs->sr[7] = spaceid; \
287 regs->gr[ 0] = USER_INIT_PSW; \
288 regs->fr[ 0] = 0LL; \
289 regs->fr[ 1] = 0LL; \
290 regs->fr[ 2] = 0LL; \
291 regs->fr[ 3] = 0LL; \
292 regs->gr[30] = ((current->mm->env_end)+63)&~63; \
293 regs->gr[31] = pc; \
294 \
295 get_user(regs->gr[25],&sp[0]); \
296 regs->gr[24] = (unsigned long) &sp[1]; \
297 regs->gr[23] = 0; \
298 \
299 regs->cr30 = (u32) current; \
300 } while(0)
301
302 #endif
303
304 struct task_struct;
305
306 /* Free all resources held by a thread. */
307 extern void release_thread(struct task_struct *);
308 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
309
310 #define copy_segments(tsk, mm) do { } while (0)
311 #define release_segments(mm) do { } while (0)
312
313 extern inline unsigned long get_wchan(struct task_struct *p)
314 {
315 return 0xdeadbeef; /* XXX */
316 }
317
318 #define KSTK_EIP(tsk) (0xdeadbeef)
319 #define KSTK_ESP(tsk) (0xdeadbeef)
320
321 /* Be sure to hunt all references to this down when you change the size of
322 * the kernel stack */
323
324 #endif /* __ASSEMBLY__ */
325
326 #define THREAD_SIZE (4*PAGE_SIZE)
327
328 #define alloc_task_struct() \
329 ((struct task_struct *) __get_free_pages(GFP_KERNEL,2))
330 #define free_task_struct(p) free_pages((unsigned long)(p),2)
331 #define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
332
333 #define init_task (init_task_union.task)
334 #define init_stack (init_task_union.stack)
335
336
337 #endif /* __ASM_PARISC_PROCESSOR_H */
338