xref: /openbsd-src/sys/arch/powerpc64/include/cpu.h (revision d9a6171acb5469c258797f6c715a1c8ab071b042)
1*d9a6171aSgkoehler /*	$OpenBSD: cpu.h,v 1.39 2024/11/28 18:54:36 gkoehler Exp $	*/
212e5a6fbSkettenis 
312e5a6fbSkettenis /*
412e5a6fbSkettenis  * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
512e5a6fbSkettenis  *
612e5a6fbSkettenis  * Permission to use, copy, modify, and distribute this software for any
712e5a6fbSkettenis  * purpose with or without fee is hereby granted, provided that the above
812e5a6fbSkettenis  * copyright notice and this permission notice appear in all copies.
912e5a6fbSkettenis  *
1012e5a6fbSkettenis  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1112e5a6fbSkettenis  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1212e5a6fbSkettenis  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1312e5a6fbSkettenis  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1412e5a6fbSkettenis  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1512e5a6fbSkettenis  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1612e5a6fbSkettenis  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1712e5a6fbSkettenis  */
1812e5a6fbSkettenis 
1913861200Skettenis #ifndef _MACHINE_CPU_H_
2013861200Skettenis #define _MACHINE_CPU_H_
2113861200Skettenis 
2212e5a6fbSkettenis /*
2312e5a6fbSkettenis  * User-visible definitions
2412e5a6fbSkettenis  */
2512e5a6fbSkettenis 
260dc8bf2fSkettenis /*
270dc8bf2fSkettenis  * CTL_MACHDEP definitions.
280dc8bf2fSkettenis  */
290dc8bf2fSkettenis #define CPU_ALTIVEC		1	/* altivec is present */
300dc8bf2fSkettenis #define CPU_MAXID		2	/* number of valid machdep ids */
310dc8bf2fSkettenis 
320dc8bf2fSkettenis #define	CTL_MACHDEP_NAMES { \
330dc8bf2fSkettenis 	{ 0, 0 }, \
340dc8bf2fSkettenis 	{ "altivec", CTLTYPE_INT }, \
350dc8bf2fSkettenis }
3612e5a6fbSkettenis 
3712e5a6fbSkettenis #ifdef _KERNEL
3812e5a6fbSkettenis 
3912e5a6fbSkettenis /*
4012e5a6fbSkettenis  * Kernel-only definitions
4112e5a6fbSkettenis  */
4212e5a6fbSkettenis 
4312e5a6fbSkettenis #include <machine/cpufunc.h>
440b0568a1Sjca #include <machine/elf.h>
4513861200Skettenis #include <machine/frame.h>
4612e5a6fbSkettenis #include <machine/intr.h>
4712e5a6fbSkettenis #include <machine/psl.h>
48b079169dSkettenis #include <machine/pte.h>
4913861200Skettenis 
50aca18452Scheloha #include <sys/clockintr.h>
5113861200Skettenis #include <sys/device.h>
5213861200Skettenis #include <sys/sched.h>
53ea057ba5Skettenis #include <sys/srp.h>
5413861200Skettenis 
5513861200Skettenis struct cpu_info {
5613861200Skettenis 	struct device	*ci_dev;
5713861200Skettenis 	struct cpu_info	*ci_next;
5813861200Skettenis 	struct schedstate_percpu ci_schedstate;
5913861200Skettenis 
60ea057ba5Skettenis 	uint32_t	ci_cpuid;
61ea057ba5Skettenis 	uint32_t	ci_pir;
62fcf94dc6Skettenis 	int		ci_node;
63ea057ba5Skettenis 
6413861200Skettenis 	struct proc	*ci_curproc;
6545dd89a7Skettenis 	struct pcb	*ci_curpcb;
6613861200Skettenis 
67b079169dSkettenis 	struct slb	ci_kernel_slb[32];
6837d56e14Skettenis 	paddr_t		ci_user_slb_pa;
6967fd21e2Skettenis 	register_t	ci_slbsave[18];
7067fd21e2Skettenis 	char		ci_slbstack[1024];
71b079169dSkettenis 
72b0c94682Skettenis #define CPUSAVE_LEN	9
73b0c94682Skettenis 	register_t	ci_tempsave[CPUSAVE_LEN];
74196daab3Sgkoehler 	register_t	ci_idle_sp_save;
75b0c94682Skettenis 
76c737cf90Scheloha 	struct clockqueue ci_queue;
77ff56acc2Skettenis 
78ff56acc2Skettenis 	volatile int 	ci_cpl;
79f27ca60cScheloha 	volatile int	ci_dec_deferred;
8013861200Skettenis 	uint32_t	ci_ipending;
811af8fcf9Skettenis 	uint32_t	ci_idepth;
8213861200Skettenis #ifdef DIAGNOSTIC
8313861200Skettenis 	int		ci_mutex_level;
8413861200Skettenis #endif
8513861200Skettenis 	int		ci_want_resched;
8613861200Skettenis 
8713861200Skettenis 	uint32_t	ci_randseed;
88ea057ba5Skettenis 
89ea057ba5Skettenis #ifdef MULTIPROCESSOR
90ea057ba5Skettenis 	struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM];
91ea057ba5Skettenis 	void		*ci_initstack_end;
92fcf94dc6Skettenis 	void		*ci_ipi;
93284a504dSkettenis 	int		ci_ipi_reason;
94284a504dSkettenis 	volatile int	ci_flags;
95284a504dSkettenis #endif
96284a504dSkettenis 
97284a504dSkettenis #ifdef DDB
98284a504dSkettenis 	volatile int    ci_ddb_paused;
99284a504dSkettenis #define	CI_DDB_RUNNING	0
100284a504dSkettenis #define	CI_DDB_SHOULDSTOP	1
101284a504dSkettenis #define	CI_DDB_STOPPED		2
102284a504dSkettenis #define	CI_DDB_ENTERDDB		3
103284a504dSkettenis #define	CI_DDB_INDDB		4
104ea057ba5Skettenis #endif
1051a4a9ab2Scheloha 	char		ci_panicbuf[512];
10613861200Skettenis };
10713861200Skettenis 
108ea057ba5Skettenis #define CPUF_PRIMARY 		(1 << 0)
109ea057ba5Skettenis #define CPUF_AP	 		(1 << 1)
110ea057ba5Skettenis #define CPUF_IDENTIFY		(1 << 2)
111ea057ba5Skettenis #define CPUF_IDENTIFIED		(1 << 3)
112ea057ba5Skettenis #define CPUF_PRESENT		(1 << 4)
113ea057ba5Skettenis #define CPUF_GO			(1 << 5)
114ea057ba5Skettenis #define CPUF_RUNNING		(1 << 6)
115ea057ba5Skettenis 
116ea057ba5Skettenis extern struct cpu_info cpu_info[];
117ea057ba5Skettenis extern struct cpu_info *cpu_info_primary;
11813861200Skettenis 
11987c5ae51Skettenis static __inline struct cpu_info *
12087c5ae51Skettenis curcpu(void)
12187c5ae51Skettenis {
12287c5ae51Skettenis 	struct cpu_info *ci;
12387c5ae51Skettenis 	__asm volatile ("mfsprg0 %0" : "=r"(ci));
12487c5ae51Skettenis 	return ci;
12587c5ae51Skettenis }
12613861200Skettenis 
127ea057ba5Skettenis #define CPU_INFO_ITERATOR	int
128ea057ba5Skettenis 
129ea057ba5Skettenis #ifndef MULTIPROCESSOR
130ea057ba5Skettenis 
13113861200Skettenis #define MAXCPUS			1
13213861200Skettenis #define CPU_IS_PRIMARY(ci)	1
133d73de46fSkettenis #define CPU_IS_RUNNING(ci)	1
134ea057ba5Skettenis #define cpu_number()		0
135ea057ba5Skettenis 
13613861200Skettenis #define CPU_INFO_UNIT(ci)	0
13713861200Skettenis #define CPU_INFO_FOREACH(cii, ci) \
13813861200Skettenis 	for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
139ea057ba5Skettenis 
140fcf94dc6Skettenis #define cpu_kick(ci)
141196daab3Sgkoehler #define cpu_unidle(ci)
142fcf94dc6Skettenis 
143ea057ba5Skettenis #else
144ea057ba5Skettenis 
1455fc7d48aSkettenis #define MAXCPUS			48
146ea057ba5Skettenis #define CPU_IS_PRIMARY(ci)	((ci) == cpu_info_primary)
147d73de46fSkettenis #define CPU_IS_RUNNING(ci)	((ci)->ci_flags & CPUF_RUNNING)
148ea057ba5Skettenis #define cpu_number()		(curcpu()->ci_cpuid)
149ea057ba5Skettenis 
150ea057ba5Skettenis #define CPU_INFO_UNIT(ci)	((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
151ea057ba5Skettenis #define CPU_INFO_FOREACH(cii, ci) \
152ea057ba5Skettenis 	for (cii = 0, ci = &cpu_info[0]; cii < ncpus; cii++, ci++)
153ea057ba5Skettenis 
154fcf94dc6Skettenis void	cpu_kick(struct cpu_info *);
155196daab3Sgkoehler void	cpu_unidle(struct cpu_info *);
156ea057ba5Skettenis void	cpu_boot_secondary_processors(void);
157ea057ba5Skettenis 
158c7966c0cSgkoehler extern void (*ul_setperf)(int);
159c7966c0cSgkoehler void	mp_setperf(int);
160c7966c0cSgkoehler 
161ea057ba5Skettenis #endif
16213861200Skettenis 
163351f0751Skettenis #define clockframe trapframe
164351f0751Skettenis 
165351f0751Skettenis #define CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
166351f0751Skettenis #define CLKF_USERMODE(frame)	(frame->srr1 & PSL_PR)
167351f0751Skettenis #define CLKF_PC(frame)		(frame->srr0)
16813861200Skettenis 
16913861200Skettenis #define aston(p)		((p)->p_md.md_astpending = 1)
17013861200Skettenis #define need_proftick(p)	aston(p)
17113861200Skettenis 
1729ae0232dSgkoehler void signotify(struct proc *);
1739ae0232dSgkoehler 
174b43d7c27Sjca #define CPU_BUSY_CYCLE()	__asm volatile ("" ::: "memory")
17513861200Skettenis 
17645dd89a7Skettenis #define curpcb			curcpu()->ci_curpcb
17745dd89a7Skettenis 
178c2b3d03cSkettenis void cpu_init_features(void);
179c2b3d03cSkettenis void cpu_init(void);
180c2b3d03cSkettenis 
1810e6cad35Sguenther #define	cpu_idle_enter()	do { /* nothing */ } while (0)
1820e6cad35Sguenther #define	cpu_idle_leave()	do { /* nothing */ } while (0)
183196daab3Sgkoehler extern uint64_t cpu_idle_state_psscr;
184196daab3Sgkoehler extern void (*cpu_idle_cycle_fcn)(void);
185196daab3Sgkoehler 
186354e4bfbSkettenis static inline unsigned int
187354e4bfbSkettenis cpu_rnd_messybits(void)
188354e4bfbSkettenis {
189354e4bfbSkettenis 	uint64_t tb;
190354e4bfbSkettenis 
191354e4bfbSkettenis 	__asm volatile("mftb %0" : "=r" (tb));
192f585323aSnaddy 	return ((tb >> 32) ^ tb);
193354e4bfbSkettenis }
19401802d2cSdlg 
19513861200Skettenis void need_resched(struct cpu_info *);
19613861200Skettenis #define clear_resched(ci)	((ci)->ci_want_resched = 0)
19713861200Skettenis 
19813861200Skettenis void delay(u_int);
19913861200Skettenis #define DELAY(x)	delay(x)
20013861200Skettenis 
201717af3c7Skettenis #define PROC_STACK(p)		((p)->p_md.md_regs->fixreg[1])
202717af3c7Skettenis #define PROC_PC(p)		((p)->p_md.md_regs->srr0)
20313861200Skettenis 
2040d8e59b5Skettenis void	proc_trampoline(void);
2050d8e59b5Skettenis 
20612e5a6fbSkettenis static inline void
20712e5a6fbSkettenis intr_enable(void)
20812e5a6fbSkettenis {
20912e5a6fbSkettenis 	mtmsr(mfmsr() | PSL_EE);
21012e5a6fbSkettenis }
21112e5a6fbSkettenis 
21212e5a6fbSkettenis static inline u_long
21312e5a6fbSkettenis intr_disable(void)
21412e5a6fbSkettenis {
21512e5a6fbSkettenis 	u_long msr;
21612e5a6fbSkettenis 
21712e5a6fbSkettenis 	msr = mfmsr();
21812e5a6fbSkettenis 	mtmsr(msr & ~PSL_EE);
21912e5a6fbSkettenis 	return msr;
22012e5a6fbSkettenis }
22112e5a6fbSkettenis 
22212e5a6fbSkettenis static inline void
22312e5a6fbSkettenis intr_restore(u_long msr)
22412e5a6fbSkettenis {
22512e5a6fbSkettenis 	mtmsr(msr);
22612e5a6fbSkettenis }
22712e5a6fbSkettenis 
22812e5a6fbSkettenis #endif /* _KERNEL */
22906db26f9Sgkoehler 
230ea057ba5Skettenis #ifdef MULTIPROCESSOR
231ea057ba5Skettenis #include <sys/mplock.h>
232ea057ba5Skettenis #endif /* MULTIPROCESSOR */
233ea057ba5Skettenis 
23413861200Skettenis #endif /* _MACHINE_CPU_H_ */
235