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