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