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_MMAP { &init_mm, 0, 0, NULL, PAGE_SHARED, \
111 VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
112
113 #define INIT_THREAD { { \
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 0, 0, 0, 0, 0, 0, 0, 0 }, \
122 { 0, 0, 0, 0, 0, 0, 0, 0 }, \
123 { 0, 0}, { 0, 0}, 0, 0, 0, 0 \
124 }, __pa((unsigned long) swapper_pg_dir) }
125
126 /*
127 * Return saved PC of a blocked thread. This is used by ps mostly.
128 */
129
130 extern inline unsigned long thread_saved_pc(struct thread_struct *t)
131 {
132 return 0xabcdef;
133 }
134
135 /*
136 * Start user thread in another space.
137 *
138 * Note that we set both the iaoq and r31 to the new pc. When
139 * the kernel initially calls execve it will return through an
140 * rfi path that will use the values in the iaoq. The execve
141 * syscall path will return through the gateway page, and
142 * that uses r31 to branch to.
143 *
144 * For ELF we clear r23, because the dynamic linker uses it to pass
145 * the address of the finalizer function.
146 *
147 * We also initialize sr3 to an illegal value (illegal for our
148 * implementation, not for the architecture).
149 */
150
151 /* The ELF abi wants things done a "wee bit" differently than
152 * som does. Supporting this behavior here avoids
153 * having our own version of create_elf_tables.
154 *
155 * Oh, and yes, that is not a typo, we are really passing argc in r25
156 * and argv in r24 (rather than r26 and r25). This is because that's
157 * where __libc_start_main wants them.
158 *
159 * Duplicated from dl-machine.h for the benefit of readers:
160 *
161 * Our initial stack layout is rather different from everyone else's
162 * due to the unique PA-RISC ABI. As far as I know it looks like
163 * this:
164
165 ----------------------------------- (user startup code creates this frame)
166 | 32 bytes of magic |
167 |---------------------------------|
168 | 32 bytes argument/sp save area |
169 |---------------------------------| ((current->mm->env_end) + 63 & ~63)
170 | N bytes of slack |
171 |---------------------------------|
172 | envvar and arg strings |
173 |---------------------------------|
174 | ELF auxiliary info |
175 | (up to 28 words) |
176 |---------------------------------|
177 | Environment variable pointers |
178 | upwards to NULL |
179 |---------------------------------|
180 | Argument pointers |
181 | upwards to NULL |
182 |---------------------------------|
183 | argc (1 word) |
184 -----------------------------------
185
186 * The pleasant part of this is that if we need to skip arguments we
187 * can just decrement argc and move argv, because the stack pointer
188 * is utterly unrelated to the location of the environment and
189 * argument vectors.
190 *
191 * Note that the S/390 people took the easy way out and hacked their
192 * GCC to make the stack grow downwards. */
193
194 #define start_thread_som(regs, new_pc, new_sp) do { \
195 unsigned long *sp = (unsigned long *)new_sp; \
196 __u32 spaceid = (__u32)current->mm->context; \
197 unsigned long pc = (unsigned long)new_pc; \
198 /* offset pc for priv. level */ \
199 pc |= 3; \
200 \
201 set_fs(USER_DS); \
202 regs->iasq[0] = spaceid; \
203 regs->iasq[1] = spaceid; \
204 regs->iaoq[0] = pc; \
205 regs->iaoq[1] = pc; \
206 regs->sr[2] = LINUX_GATEWAY_SPACE; \
207 regs->sr[3] = 0xffff; \
208 regs->sr[4] = spaceid; \
209 regs->sr[5] = spaceid; \
210 regs->sr[6] = spaceid; \
211 regs->sr[7] = spaceid; \
212 regs->gr[ 0] = USER_INIT_PSW; \
213 regs->gr[30] = ((new_sp)+63)&~63; \
214 regs->gr[31] = pc; \
215 \
216 get_user(regs->gr[26],&sp[0]); \
217 get_user(regs->gr[25],&sp[-1]); \
218 get_user(regs->gr[24],&sp[-2]); \
219 get_user(regs->gr[23],&sp[-3]); \
220 \
221 regs->cr30 = (u32) current; \
222 } while(0)
223
224
225 #define start_thread(regs, new_pc, new_sp) do { \
226 unsigned long *sp = (unsigned long *)new_sp; \
227 __u32 spaceid = (__u32)current->mm->context; \
228 unsigned long pc = (unsigned long)new_pc; \
229 /* offset pc for priv. level */ \
230 pc |= 3; \
231 \
232 \
233 set_fs(USER_DS); \
234 regs->iasq[0] = spaceid; \
235 regs->iasq[1] = spaceid; \
236 regs->iaoq[0] = pc; \
237 regs->iaoq[1] = pc; \
238 regs->sr[2] = LINUX_GATEWAY_SPACE; \
239 regs->sr[3] = 0xffff; \
240 regs->sr[4] = spaceid; \
241 regs->sr[5] = spaceid; \
242 regs->sr[6] = spaceid; \
243 regs->sr[7] = spaceid; \
244 regs->gr[ 0] = USER_INIT_PSW; \
245 regs->fr[ 0] = 0LL; \
246 regs->fr[ 1] = 0LL; \
247 regs->fr[ 2] = 0LL; \
248 regs->fr[ 3] = 0LL; \
249 regs->gr[30] = ((current->mm->env_end)+63)&~63; \
250 regs->gr[31] = pc; \
251 \
252 get_user(regs->gr[25],&sp[0]); \
253 regs->gr[24] = (unsigned long) &sp[1]; \
254 regs->gr[23] = 0; \
255 \
256 regs->cr30 = (u32) current; \
257 } while(0)
258
259 #ifdef __LP64__
260
261 /*
262 * For 64 bit kernels we need a version of start thread for 32 bit
263 * elf files.
264 *
265 * FIXME: It should be possible to not duplicate the above code
266 * by playing games with concatenation to form both
267 * macros at compile time. The only difference between
268 * this macro and the above is the name and the types
269 * for sp and pc.
270 */
271
272 #define start_thread32(regs, new_pc, new_sp) do { \
273 __u32 *sp = (__u32 *)new_sp; \
274 __u32 spaceid = (__u32)current->mm->context; \
275 __u32 pc = (__u32)new_pc; \
276 /* offset pc for priv. level */ \
277 pc |= 3; \
278 \
279 set_fs(USER_DS); \
280 regs->iasq[0] = spaceid; \
281 regs->iasq[1] = spaceid; \
282 regs->iaoq[0] = pc; \
283 regs->iaoq[1] = pc; \
284 regs->sr[2] = LINUX_GATEWAY_SPACE; \
285 regs->sr[3] = 0xffff; \
286 regs->sr[4] = spaceid; \
287 regs->sr[5] = spaceid; \
288 regs->sr[6] = spaceid; \
289 regs->sr[7] = spaceid; \
290 regs->gr[ 0] = USER_INIT_PSW; \
291 regs->fr[ 0] = 0LL; \
292 regs->fr[ 1] = 0LL; \
293 regs->fr[ 2] = 0LL; \
294 regs->fr[ 3] = 0LL; \
295 regs->gr[30] = ((current->mm->env_end)+63)&~63; \
296 regs->gr[31] = pc; \
297 \
298 get_user(regs->gr[25],&sp[0]); \
299 regs->gr[24] = (unsigned long) &sp[1]; \
300 regs->gr[23] = 0; \
301 \
302 regs->cr30 = (u32) current; \
303 } while(0)
304
305 #endif
306
307 struct task_struct;
308
309 /* Free all resources held by a thread. */
310 extern void release_thread(struct task_struct *);
311 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
312
313 #define copy_segments(tsk, mm) do { } while (0)
314 #define release_segments(mm) do { } while (0)
315
316 extern inline unsigned long get_wchan(struct task_struct *p)
317 {
318 return 0xdeadbeef; /* XXX */
319 }
320
321 #define KSTK_EIP(tsk) (0xdeadbeef)
322 #define KSTK_ESP(tsk) (0xdeadbeef)
323
324 /* Be sure to hunt all references to this down when you change the size of
325 * the kernel stack */
326
327 #endif /* __ASSEMBLY__ */
328
329 #define THREAD_SIZE (4*PAGE_SIZE)
330
331 #define alloc_task_struct() \
332 ((struct task_struct *) __get_free_pages(GFP_KERNEL,2))
333 #define free_task_struct(p) free_pages((unsigned long)(p),2)
334 #define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
335
336 #define init_task (init_task_union.task)
337 #define init_stack (init_task_union.stack)
338
339
340 #endif /* __ASM_PARISC_PROCESSOR_H */
341
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.