xref: /openbmc/linux/arch/parisc/include/asm/processor.h (revision b97d6790d03b763eca08847a9a5869a4291b9f9a)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2deae26bfSKyle McMartin /*
3deae26bfSKyle McMartin  * include/asm-parisc/processor.h
4deae26bfSKyle McMartin  *
5deae26bfSKyle McMartin  * Copyright (C) 1994 Linus Torvalds
6deae26bfSKyle McMartin  * Copyright (C) 2001 Grant Grundler
7deae26bfSKyle McMartin  */
8deae26bfSKyle McMartin 
9deae26bfSKyle McMartin #ifndef __ASM_PARISC_PROCESSOR_H
10deae26bfSKyle McMartin #define __ASM_PARISC_PROCESSOR_H
11deae26bfSKyle McMartin 
12deae26bfSKyle McMartin #ifndef __ASSEMBLY__
13deae26bfSKyle McMartin #include <linux/threads.h>
14f310f8ddSHelge Deller #include <linux/irqreturn.h>
15deae26bfSKyle McMartin 
16b7d8c16aSHelge Deller #include <asm/assembly.h>
17deae26bfSKyle McMartin #include <asm/prefetch.h>
18deae26bfSKyle McMartin #include <asm/hardware.h>
19deae26bfSKyle McMartin #include <asm/pdc.h>
20deae26bfSKyle McMartin #include <asm/ptrace.h>
21deae26bfSKyle McMartin #include <asm/types.h>
22ef017bebSHelge Deller #include <asm/percpu.h>
23deae26bfSKyle McMartin #endif /* __ASSEMBLY__ */
24deae26bfSKyle McMartin 
259dabf60dSHelge Deller #define HAVE_ARCH_PICK_MMAP_LAYOUT
269dabf60dSHelge Deller 
27deae26bfSKyle McMartin #define TASK_SIZE_OF(tsk)       ((tsk)->thread.task_size)
28deae26bfSKyle McMartin #define TASK_SIZE	        TASK_SIZE_OF(current)
29deae26bfSKyle McMartin #define TASK_UNMAPPED_BASE      (current->thread.map_base)
30deae26bfSKyle McMartin 
31deae26bfSKyle McMartin #define DEFAULT_TASK_SIZE32	(0xFFF00000UL)
32deae26bfSKyle McMartin #define DEFAULT_MAP_BASE32	(0x40000000UL)
33deae26bfSKyle McMartin 
34deae26bfSKyle McMartin #ifdef CONFIG_64BIT
35deae26bfSKyle McMartin #define DEFAULT_TASK_SIZE       (MAX_ADDRESS-0xf000000)
36deae26bfSKyle McMartin #define DEFAULT_MAP_BASE        (0x200000000UL)
37deae26bfSKyle McMartin #else
38deae26bfSKyle McMartin #define DEFAULT_TASK_SIZE	DEFAULT_TASK_SIZE32
39deae26bfSKyle McMartin #define DEFAULT_MAP_BASE	DEFAULT_MAP_BASE32
40deae26bfSKyle McMartin #endif
41deae26bfSKyle McMartin 
42deae26bfSKyle McMartin /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
43deae26bfSKyle McMartin  * prumpf */
44deae26bfSKyle McMartin 
45deae26bfSKyle McMartin #define STACK_TOP	TASK_SIZE
46deae26bfSKyle McMartin #define STACK_TOP_MAX	DEFAULT_TASK_SIZE
47deae26bfSKyle McMartin 
48deae26bfSKyle McMartin #ifndef __ASSEMBLY__
49deae26bfSKyle McMartin 
50*2345ef96SHelge Deller struct rlimit;
51*2345ef96SHelge Deller unsigned long mmap_upper_limit(struct rlimit *rlim_stack);
5222ee3ea5SHelge Deller unsigned long calc_max_stack_size(unsigned long stack_max);
5322ee3ea5SHelge Deller 
54deae26bfSKyle McMartin /*
55deae26bfSKyle McMartin  * Data detected about CPUs at boot time which is the same for all CPU's.
56deae26bfSKyle McMartin  * HP boxes are SMP - ie identical processors.
57deae26bfSKyle McMartin  *
58deae26bfSKyle McMartin  * FIXME: some CPU rev info may be processor specific...
59deae26bfSKyle McMartin  */
60deae26bfSKyle McMartin struct system_cpuinfo_parisc {
61deae26bfSKyle McMartin 	unsigned int	cpu_count;
62deae26bfSKyle McMartin 	unsigned int	cpu_hz;
63deae26bfSKyle McMartin 	unsigned int	hversion;
64deae26bfSKyle McMartin 	unsigned int	sversion;
65deae26bfSKyle McMartin 	enum cpu_type	cpu_type;
66deae26bfSKyle McMartin 
67deae26bfSKyle McMartin 	struct {
68deae26bfSKyle McMartin 		struct pdc_model model;
69deae26bfSKyle McMartin 		unsigned long versions;
70deae26bfSKyle McMartin 		unsigned long cpuid;
71deae26bfSKyle McMartin 		unsigned long capabilities;
72deae26bfSKyle McMartin 		char   sys_model_name[81]; /* PDC-ROM returnes this model name */
73deae26bfSKyle McMartin 	} pdc;
74deae26bfSKyle McMartin 
75deae26bfSKyle McMartin 	const char	*cpu_name;	/* e.g. "PA7300LC (PCX-L2)" */
76deae26bfSKyle McMartin 	const char	*family_name;	/* e.g. "1.1e" */
77deae26bfSKyle McMartin };
78deae26bfSKyle McMartin 
79deae26bfSKyle McMartin 
80deae26bfSKyle McMartin /* Per CPU data structure - ie varies per CPU.  */
81deae26bfSKyle McMartin struct cpuinfo_parisc {
82deae26bfSKyle McMartin 	unsigned long it_value;     /* Interval Timer at last timer Intr */
83deae26bfSKyle McMartin 	unsigned long irq_count;    /* number of IRQ's since boot */
84deae26bfSKyle McMartin 	unsigned long cpuid;        /* aka slot_number or set to NO_PROC_ID */
85deae26bfSKyle McMartin 	unsigned long hpa;          /* Host Physical address */
86deae26bfSKyle McMartin 	unsigned long txn_addr;     /* MMIO addr of EIR or id_eid */
87deae26bfSKyle McMartin #ifdef CONFIG_SMP
88deae26bfSKyle McMartin 	unsigned long pending_ipi;  /* bitmap of type ipi_message_type */
89deae26bfSKyle McMartin #endif
90deae26bfSKyle McMartin 	unsigned long bh_count;     /* number of times bh was invoked */
91deae26bfSKyle McMartin 	unsigned long fp_rev;
92deae26bfSKyle McMartin 	unsigned long fp_model;
93c8c37359SHelge Deller 	unsigned long cpu_num;      /* CPU number from PAT firmware */
94c8c37359SHelge Deller 	unsigned long cpu_loc;      /* CPU location from PAT firmware */
95deae26bfSKyle McMartin 	unsigned int state;
96deae26bfSKyle McMartin 	struct parisc_device *dev;
97deae26bfSKyle McMartin };
98deae26bfSKyle McMartin 
99deae26bfSKyle McMartin extern struct system_cpuinfo_parisc boot_cpu_data;
100ef017bebSHelge Deller DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
1011afde47dSHelge Deller extern int time_keeper_id;		/* CPU used for timekeeping */
102deae26bfSKyle McMartin 
103deae26bfSKyle McMartin #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
104deae26bfSKyle McMartin 
105deae26bfSKyle McMartin struct thread_struct {
106deae26bfSKyle McMartin 	struct pt_regs regs;
107deae26bfSKyle McMartin 	unsigned long  task_size;
108deae26bfSKyle McMartin 	unsigned long  map_base;
109deae26bfSKyle McMartin 	unsigned long  flags;
110deae26bfSKyle McMartin };
111deae26bfSKyle McMartin 
112abf1e11aSKyle McMartin #define task_pt_regs(tsk) ((struct pt_regs *)&((tsk)->thread.regs))
113abf1e11aSKyle McMartin 
114deae26bfSKyle McMartin /* Thread struct flags. */
115deae26bfSKyle McMartin #define PARISC_UAC_NOPRINT	(1UL << 0)	/* see prctl and unaligned.c */
116deae26bfSKyle McMartin #define PARISC_UAC_SIGBUS	(1UL << 1)
117deae26bfSKyle McMartin #define PARISC_KERNEL_DEATH	(1UL << 31)	/* see die_if_kernel()... */
118deae26bfSKyle McMartin 
119deae26bfSKyle McMartin #define PARISC_UAC_SHIFT	0
120deae26bfSKyle McMartin #define PARISC_UAC_MASK		(PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS)
121deae26bfSKyle McMartin 
122deae26bfSKyle McMartin #define SET_UNALIGN_CTL(task,value)                                       \
123deae26bfSKyle McMartin         ({                                                                \
124deae26bfSKyle McMartin         (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \
125deae26bfSKyle McMartin                                 | (((value) << PARISC_UAC_SHIFT) &        \
126deae26bfSKyle McMartin                                    PARISC_UAC_MASK));                     \
127deae26bfSKyle McMartin         0;                                                                \
128deae26bfSKyle McMartin         })
129deae26bfSKyle McMartin 
130deae26bfSKyle McMartin #define GET_UNALIGN_CTL(task,addr)                                        \
131deae26bfSKyle McMartin         ({                                                                \
132deae26bfSKyle McMartin         put_user(((task)->thread.flags & PARISC_UAC_MASK)                 \
133deae26bfSKyle McMartin                  >> PARISC_UAC_SHIFT, (int __user *) (addr));             \
134deae26bfSKyle McMartin         })
135deae26bfSKyle McMartin 
136deae26bfSKyle McMartin #define INIT_THREAD { \
137deae26bfSKyle McMartin 	.regs = {	.gr	= { 0, }, \
138deae26bfSKyle McMartin 			.fr	= { 0, }, \
139deae26bfSKyle McMartin 			.sr	= { 0, }, \
140deae26bfSKyle McMartin 			.iasq	= { 0, }, \
141deae26bfSKyle McMartin 			.iaoq	= { 0, }, \
142deae26bfSKyle McMartin 			.cr27	= 0, \
143deae26bfSKyle McMartin 		}, \
144deae26bfSKyle McMartin 	.task_size	= DEFAULT_TASK_SIZE, \
145deae26bfSKyle McMartin 	.map_base	= DEFAULT_MAP_BASE, \
146deae26bfSKyle McMartin 	.flags		= 0 \
147deae26bfSKyle McMartin 	}
148deae26bfSKyle McMartin 
149527dcdccSDavid Howells struct task_struct;
150deae26bfSKyle McMartin void show_trace(struct task_struct *task, unsigned long *stack);
151deae26bfSKyle McMartin 
152deae26bfSKyle McMartin /*
153deae26bfSKyle McMartin  * Start user thread in another space.
154deae26bfSKyle McMartin  *
155deae26bfSKyle McMartin  * Note that we set both the iaoq and r31 to the new pc. When
156deae26bfSKyle McMartin  * the kernel initially calls execve it will return through an
157deae26bfSKyle McMartin  * rfi path that will use the values in the iaoq. The execve
158deae26bfSKyle McMartin  * syscall path will return through the gateway page, and
159deae26bfSKyle McMartin  * that uses r31 to branch to.
160deae26bfSKyle McMartin  *
161deae26bfSKyle McMartin  * For ELF we clear r23, because the dynamic linker uses it to pass
162deae26bfSKyle McMartin  * the address of the finalizer function.
163deae26bfSKyle McMartin  *
164deae26bfSKyle McMartin  * We also initialize sr3 to an illegal value (illegal for our
165deae26bfSKyle McMartin  * implementation, not for the architecture).
166deae26bfSKyle McMartin  */
167deae26bfSKyle McMartin typedef unsigned int elf_caddr_t;
168deae26bfSKyle McMartin 
169deae26bfSKyle McMartin /* The ELF abi wants things done a "wee bit" differently than
170deae26bfSKyle McMartin  * som does.  Supporting this behavior here avoids
171deae26bfSKyle McMartin  * having our own version of create_elf_tables.
172deae26bfSKyle McMartin  *
173deae26bfSKyle McMartin  * Oh, and yes, that is not a typo, we are really passing argc in r25
174deae26bfSKyle McMartin  * and argv in r24 (rather than r26 and r25).  This is because that's
175deae26bfSKyle McMartin  * where __libc_start_main wants them.
176deae26bfSKyle McMartin  *
177deae26bfSKyle McMartin  * Duplicated from dl-machine.h for the benefit of readers:
178deae26bfSKyle McMartin  *
179deae26bfSKyle McMartin  *  Our initial stack layout is rather different from everyone else's
180deae26bfSKyle McMartin  *  due to the unique PA-RISC ABI.  As far as I know it looks like
181deae26bfSKyle McMartin  *  this:
182deae26bfSKyle McMartin 
183deae26bfSKyle McMartin    -----------------------------------  (user startup code creates this frame)
184deae26bfSKyle McMartin    |         32 bytes of magic       |
185deae26bfSKyle McMartin    |---------------------------------|
186deae26bfSKyle McMartin    | 32 bytes argument/sp save area  |
187deae26bfSKyle McMartin    |---------------------------------| (bprm->p)
188deae26bfSKyle McMartin    |	    ELF auxiliary info	     |
189deae26bfSKyle McMartin    |         (up to 28 words)        |
190deae26bfSKyle McMartin    |---------------------------------|
191deae26bfSKyle McMartin    |		   NULL		     |
192deae26bfSKyle McMartin    |---------------------------------|
193deae26bfSKyle McMartin    |	   Environment pointers	     |
194deae26bfSKyle McMartin    |---------------------------------|
195deae26bfSKyle McMartin    |		   NULL		     |
196deae26bfSKyle McMartin    |---------------------------------|
197deae26bfSKyle McMartin    |        Argument pointers        |
198deae26bfSKyle McMartin    |---------------------------------| <- argv
199deae26bfSKyle McMartin    |          argc (1 word)          |
200deae26bfSKyle McMartin    |---------------------------------| <- bprm->exec (HACK!)
201deae26bfSKyle McMartin    |         N bytes of slack        |
202deae26bfSKyle McMartin    |---------------------------------|
203deae26bfSKyle McMartin    |	filename passed to execve    |
204deae26bfSKyle McMartin    |---------------------------------| (mm->env_end)
205deae26bfSKyle McMartin    |           env strings           |
206deae26bfSKyle McMartin    |---------------------------------| (mm->env_start, mm->arg_end)
207deae26bfSKyle McMartin    |           arg strings           |
208deae26bfSKyle McMartin    |---------------------------------|
209deae26bfSKyle McMartin    | additional faked arg strings if |
210deae26bfSKyle McMartin    | we're invoked via binfmt_script |
211deae26bfSKyle McMartin    |---------------------------------| (mm->arg_start)
212deae26bfSKyle McMartin    stack base is at TASK_SIZE - rlim_max.
213deae26bfSKyle McMartin 
214deae26bfSKyle McMartin on downward growing arches, it looks like this:
215deae26bfSKyle McMartin    stack base at TASK_SIZE
216deae26bfSKyle McMartin    | filename passed to execve
217deae26bfSKyle McMartin    | env strings
218deae26bfSKyle McMartin    | arg strings
219deae26bfSKyle McMartin    | faked arg strings
220deae26bfSKyle McMartin    | slack
221deae26bfSKyle McMartin    | ELF
222deae26bfSKyle McMartin    | envps
223deae26bfSKyle McMartin    | argvs
224deae26bfSKyle McMartin    | argc
225deae26bfSKyle McMartin 
226deae26bfSKyle McMartin  *  The pleasant part of this is that if we need to skip arguments we
227deae26bfSKyle McMartin  *  can just decrement argc and move argv, because the stack pointer
228deae26bfSKyle McMartin  *  is utterly unrelated to the location of the environment and
229deae26bfSKyle McMartin  *  argument vectors.
230deae26bfSKyle McMartin  *
231deae26bfSKyle McMartin  * Note that the S/390 people took the easy way out and hacked their
232deae26bfSKyle McMartin  * GCC to make the stack grow downwards.
233deae26bfSKyle McMartin  *
234deae26bfSKyle McMartin  * Final Note: For entry from syscall, the W (wide) bit of the PSW
235deae26bfSKyle McMartin  * is stuffed into the lowest bit of the user sp (%r30), so we fill
236deae26bfSKyle McMartin  * it in here from the current->personality
237deae26bfSKyle McMartin  */
238deae26bfSKyle McMartin 
2395b00ca0bSHelge Deller #define USER_WIDE_MODE	(!is_32bit_task())
240deae26bfSKyle McMartin 
241deae26bfSKyle McMartin #define start_thread(regs, new_pc, new_sp) do {		\
242deae26bfSKyle McMartin 	elf_addr_t *sp = (elf_addr_t *)new_sp;		\
243df24e178SHelge Deller 	__u32 spaceid = (__u32)current->mm->context.space_id;	\
244deae26bfSKyle McMartin 	elf_addr_t pc = (elf_addr_t)new_pc | 3;		\
245deae26bfSKyle McMartin 	elf_caddr_t *argv = (elf_caddr_t *)bprm->exec + 1;	\
246deae26bfSKyle McMartin 							\
247deae26bfSKyle McMartin 	regs->iasq[0] = spaceid;			\
248deae26bfSKyle McMartin 	regs->iasq[1] = spaceid;			\
249deae26bfSKyle McMartin 	regs->iaoq[0] = pc;				\
250deae26bfSKyle McMartin 	regs->iaoq[1] = pc + 4;                         \
251deae26bfSKyle McMartin 	regs->sr[2] = LINUX_GATEWAY_SPACE;              \
252deae26bfSKyle McMartin 	regs->sr[3] = 0xffff;				\
253deae26bfSKyle McMartin 	regs->sr[4] = spaceid;				\
254deae26bfSKyle McMartin 	regs->sr[5] = spaceid;				\
255deae26bfSKyle McMartin 	regs->sr[6] = spaceid;				\
256deae26bfSKyle McMartin 	regs->sr[7] = spaceid;				\
257deae26bfSKyle McMartin 	regs->gr[ 0] = USER_PSW | (USER_WIDE_MODE ? PSW_W : 0); \
258deae26bfSKyle McMartin 	regs->fr[ 0] = 0LL;                            	\
259deae26bfSKyle McMartin 	regs->fr[ 1] = 0LL;                            	\
260deae26bfSKyle McMartin 	regs->fr[ 2] = 0LL;                            	\
261deae26bfSKyle McMartin 	regs->fr[ 3] = 0LL;                            	\
262deae26bfSKyle McMartin 	regs->gr[30] = (((unsigned long)sp + 63) &~ 63) | (USER_WIDE_MODE ? 1 : 0); \
263deae26bfSKyle McMartin 	regs->gr[31] = pc;				\
264deae26bfSKyle McMartin 							\
265deae26bfSKyle McMartin 	get_user(regs->gr[25], (argv - 1));		\
266deae26bfSKyle McMartin 	regs->gr[24] = (long) argv;			\
267deae26bfSKyle McMartin 	regs->gr[23] = 0;				\
268deae26bfSKyle McMartin } while(0)
269deae26bfSKyle McMartin 
270deae26bfSKyle McMartin struct mm_struct;
271deae26bfSKyle McMartin 
27242a20f86SKees Cook extern unsigned long __get_wchan(struct task_struct *p);
273deae26bfSKyle McMartin 
274deae26bfSKyle McMartin #define KSTK_EIP(tsk)	((tsk)->thread.regs.iaoq[0])
275deae26bfSKyle McMartin #define KSTK_ESP(tsk)	((tsk)->thread.regs.gr[30])
276deae26bfSKyle McMartin 
277deae26bfSKyle McMartin #define cpu_relax()	barrier()
278deae26bfSKyle McMartin 
279fc632575SHelge Deller /*
280fc632575SHelge Deller  * parisc_requires_coherency() is used to identify the combined VIPT/PIPT
281fc632575SHelge Deller  * cached CPUs which require a guarantee of coherency (no inequivalent aliases
282fc632575SHelge Deller  * with different data, whether clean or not) to operate
283fc632575SHelge Deller  */
284deae26bfSKyle McMartin #ifdef CONFIG_PA8X00
285fc632575SHelge Deller extern int _parisc_requires_coherency;
286fc632575SHelge Deller #define parisc_requires_coherency()	_parisc_requires_coherency
287deae26bfSKyle McMartin #else
288fc632575SHelge Deller #define parisc_requires_coherency()	(0)
289deae26bfSKyle McMartin #endif
290deae26bfSKyle McMartin 
2915ffa8518SHelge Deller extern int running_on_qemu;
2925ffa8518SHelge Deller 
29330f30899SHelge Deller extern void __noreturn toc_intr(struct pt_regs *regs);
294bc294838SSven Schnelle extern void toc_handler(void);
295bc294838SSven Schnelle extern unsigned int toc_handler_size;
296bc294838SSven Schnelle extern unsigned int toc_handler_csum;
297bcfaf17fSHelge Deller extern void do_cpu_irq_mask(struct pt_regs *);
298bcfaf17fSHelge Deller extern irqreturn_t timer_interrupt(int, void *);
299bcfaf17fSHelge Deller extern irqreturn_t ipi_interrupt(int, void *);
300147e17e2SHelge Deller extern void start_cpu_itimer(void);
3016414b30bSHelge Deller extern void handle_interruption(int, struct pt_regs *);
302bc294838SSven Schnelle 
303f310f8ddSHelge Deller /* called from assembly code: */
304f310f8ddSHelge Deller extern void start_parisc(void);
305f310f8ddSHelge Deller extern void smp_callin(unsigned long);
306f310f8ddSHelge Deller extern void sys_rt_sigreturn(struct pt_regs *, int);
307f310f8ddSHelge Deller extern void do_notify_resume(struct pt_regs *, long);
308f310f8ddSHelge Deller extern long do_syscall_trace_enter(struct pt_regs *);
309f310f8ddSHelge Deller extern void do_syscall_trace_exit(struct pt_regs *);
310f310f8ddSHelge Deller 
311f310f8ddSHelge Deller /* CPU startup and info */
312f310f8ddSHelge Deller struct seq_file;
313f310f8ddSHelge Deller extern void early_trap_init(void);
314f310f8ddSHelge Deller extern void collect_boot_cpu_data(void);
315e5ef93d0SHelge Deller extern void btlb_init_per_cpu(void);
316f310f8ddSHelge Deller extern int show_cpuinfo (struct seq_file *m, void *v);
317f310f8ddSHelge Deller 
318f310f8ddSHelge Deller /* driver code in driver/parisc */
319f310f8ddSHelge Deller extern void processor_init(void);
320f310f8ddSHelge Deller struct parisc_device;
321f310f8ddSHelge Deller struct resource;
322f310f8ddSHelge Deller extern void sba_distributed_lmmio(struct parisc_device *, struct resource *);
323f310f8ddSHelge Deller extern void sba_directed_lmmio(struct parisc_device *, struct resource *);
324f310f8ddSHelge Deller extern void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask);
325f310f8ddSHelge Deller extern void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp);
326f310f8ddSHelge Deller 
327deae26bfSKyle McMartin #endif /* __ASSEMBLY__ */
328deae26bfSKyle McMartin 
329deae26bfSKyle McMartin #endif /* __ASM_PARISC_PROCESSOR_H */
330