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