1
2
3
4
5
6
7
8#ifndef __ASM_PARISC_PROCESSOR_H
9#define __ASM_PARISC_PROCESSOR_H
10
11#ifndef __ASSEMBLY__
12#include <linux/threads.h>
13
14#include <asm/prefetch.h>
15#include <asm/hardware.h>
16#include <asm/pdc.h>
17#include <asm/ptrace.h>
18#include <asm/types.h>
19#include <asm/system.h>
20#include <asm/percpu.h>
21
22#endif
23
24#define KERNEL_STACK_SIZE (4*PAGE_SIZE)
25
26
27
28
29
30#ifdef CONFIG_PA20
31#define current_ia(x) __asm__("mfia %0" : "=r"(x))
32#else
33#define current_ia(x) __asm__("blr 0,%0\n\tnop" : "=r"(x))
34#endif
35#define current_text_addr() ({ void *pc; current_ia(pc); pc; })
36
37#define TASK_SIZE_OF(tsk) ((tsk)->thread.task_size)
38#define TASK_SIZE TASK_SIZE_OF(current)
39#define TASK_UNMAPPED_BASE (current->thread.map_base)
40
41#define DEFAULT_TASK_SIZE32 (0xFFF00000UL)
42#define DEFAULT_MAP_BASE32 (0x40000000UL)
43
44#ifdef CONFIG_64BIT
45#define DEFAULT_TASK_SIZE (MAX_ADDRESS-0xf000000)
46#define DEFAULT_MAP_BASE (0x200000000UL)
47#else
48#define DEFAULT_TASK_SIZE DEFAULT_TASK_SIZE32
49#define DEFAULT_MAP_BASE DEFAULT_MAP_BASE32
50#endif
51
52#ifdef __KERNEL__
53
54
55
56
57#define STACK_TOP TASK_SIZE
58#define STACK_TOP_MAX DEFAULT_TASK_SIZE
59
60#endif
61
62#ifndef __ASSEMBLY__
63
64
65
66
67
68
69
70struct system_cpuinfo_parisc {
71 unsigned int cpu_count;
72 unsigned int cpu_hz;
73 unsigned int hversion;
74 unsigned int sversion;
75 enum cpu_type cpu_type;
76
77 struct {
78 struct pdc_model model;
79 unsigned long versions;
80 unsigned long cpuid;
81 unsigned long capabilities;
82 char sys_model_name[81];
83 } pdc;
84
85 const char *cpu_name;
86 const char *family_name;
87};
88
89
90
91struct cpuinfo_parisc {
92 unsigned long it_value;
93 unsigned long it_delta;
94 unsigned long irq_count;
95 unsigned long irq_max_cr16;
96 unsigned long cpuid;
97 unsigned long hpa;
98 unsigned long txn_addr;
99#ifdef CONFIG_SMP
100 unsigned long pending_ipi;
101 unsigned long ipi_count;
102#endif
103 unsigned long bh_count;
104 unsigned long prof_counter;
105 unsigned long prof_multiplier;
106 unsigned long fp_rev;
107 unsigned long fp_model;
108 unsigned int state;
109 struct parisc_device *dev;
110 unsigned long loops_per_jiffy;
111};
112
113extern struct system_cpuinfo_parisc boot_cpu_data;
114DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
115
116#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
117
118typedef struct {
119 int seg;
120} mm_segment_t;
121
122#define ARCH_MIN_TASKALIGN 8
123
124struct thread_struct {
125 struct pt_regs regs;
126 unsigned long task_size;
127 unsigned long map_base;
128 unsigned long flags;
129};
130
131#define task_pt_regs(tsk) ((struct pt_regs *)&((tsk)->thread.regs))
132
133
134#define PARISC_UAC_NOPRINT (1UL << 0)
135#define PARISC_UAC_SIGBUS (1UL << 1)
136#define PARISC_KERNEL_DEATH (1UL << 31)
137
138#define PARISC_UAC_SHIFT 0
139#define PARISC_UAC_MASK (PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS)
140
141#define SET_UNALIGN_CTL(task,value) \
142 ({ \
143 (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \
144 | (((value) << PARISC_UAC_SHIFT) & \
145 PARISC_UAC_MASK)); \
146 0; \
147 })
148
149#define GET_UNALIGN_CTL(task,addr) \
150 ({ \
151 put_user(((task)->thread.flags & PARISC_UAC_MASK) \
152 >> PARISC_UAC_SHIFT, (int __user *) (addr)); \
153 })
154
155#define INIT_THREAD { \
156 .regs = { .gr = { 0, }, \
157 .fr = { 0, }, \
158 .sr = { 0, }, \
159 .iasq = { 0, }, \
160 .iaoq = { 0, }, \
161 .cr27 = 0, \
162 }, \
163 .task_size = DEFAULT_TASK_SIZE, \
164 .map_base = DEFAULT_MAP_BASE, \
165 .flags = 0 \
166 }
167
168
169
170
171
172unsigned long thread_saved_pc(struct task_struct *t);
173void show_trace(struct task_struct *task, unsigned long *stack);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190typedef unsigned int elf_caddr_t;
191
192#define start_thread_som(regs, new_pc, new_sp) do { \
193 unsigned long *sp = (unsigned long *)new_sp; \
194 __u32 spaceid = (__u32)current->mm->context; \
195 unsigned long pc = (unsigned long)new_pc; \
196 \
197 pc |= 3; \
198 \
199 set_fs(USER_DS); \
200 regs->iasq[0] = spaceid; \
201 regs->iasq[1] = spaceid; \
202 regs->iaoq[0] = pc; \
203 regs->iaoq[1] = pc + 4; \
204 regs->sr[2] = LINUX_GATEWAY_SPACE; \
205 regs->sr[3] = 0xffff; \
206 regs->sr[4] = spaceid; \
207 regs->sr[5] = spaceid; \
208 regs->sr[6] = spaceid; \
209 regs->sr[7] = spaceid; \
210 regs->gr[ 0] = USER_PSW; \
211 regs->gr[30] = ((new_sp)+63)&~63; \
212 regs->gr[31] = pc; \
213 \
214 get_user(regs->gr[26],&sp[0]); \
215 get_user(regs->gr[25],&sp[-1]); \
216 get_user(regs->gr[24],&sp[-2]); \
217 get_user(regs->gr[23],&sp[-3]); \
218} while(0)
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290#ifdef CONFIG_64BIT
291#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT))
292#else
293#define USER_WIDE_MODE 0
294#endif
295
296#define start_thread(regs, new_pc, new_sp) do { \
297 elf_addr_t *sp = (elf_addr_t *)new_sp; \
298 __u32 spaceid = (__u32)current->mm->context; \
299 elf_addr_t pc = (elf_addr_t)new_pc | 3; \
300 elf_caddr_t *argv = (elf_caddr_t *)bprm->exec + 1; \
301 \
302 set_fs(USER_DS); \
303 regs->iasq[0] = spaceid; \
304 regs->iasq[1] = spaceid; \
305 regs->iaoq[0] = pc; \
306 regs->iaoq[1] = pc + 4; \
307 regs->sr[2] = LINUX_GATEWAY_SPACE; \
308 regs->sr[3] = 0xffff; \
309 regs->sr[4] = spaceid; \
310 regs->sr[5] = spaceid; \
311 regs->sr[6] = spaceid; \
312 regs->sr[7] = spaceid; \
313 regs->gr[ 0] = USER_PSW | (USER_WIDE_MODE ? PSW_W : 0); \
314 regs->fr[ 0] = 0LL; \
315 regs->fr[ 1] = 0LL; \
316 regs->fr[ 2] = 0LL; \
317 regs->fr[ 3] = 0LL; \
318 regs->gr[30] = (((unsigned long)sp + 63) &~ 63) | (USER_WIDE_MODE ? 1 : 0); \
319 regs->gr[31] = pc; \
320 \
321 get_user(regs->gr[25], (argv - 1)); \
322 regs->gr[24] = (long) argv; \
323 regs->gr[23] = 0; \
324} while(0)
325
326struct task_struct;
327struct mm_struct;
328
329
330extern void release_thread(struct task_struct *);
331extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
332
333
334#define prepare_to_copy(tsk) do { } while (0)
335
336extern void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm);
337
338extern unsigned long get_wchan(struct task_struct *p);
339
340#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
341#define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30])
342
343#define cpu_relax() barrier()
344
345
346
347
348static inline int parisc_requires_coherency(void)
349{
350#ifdef CONFIG_PA8X00
351 return (boot_cpu_data.cpu_type == mako) ||
352 (boot_cpu_data.cpu_type == mako2);
353#else
354 return 0;
355#endif
356}
357
358#endif
359
360#endif
361