File: /usr/src/linux/include/asm-parisc/processor.h

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