xref: /openbsd/sys/arch/powerpc64/include/cpu.h (revision 55cc5ba3)
1 /*	$OpenBSD: cpu.h,v 1.29 2020/12/30 06:06:30 gkoehler Exp $	*/
2 
3 /*
4  * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _MACHINE_CPU_H_
20 #define _MACHINE_CPU_H_
21 
22 /*
23  * User-visible definitions
24  */
25 
26 /*
27  * CTL_MACHDEP definitions.
28  */
29 #define CPU_ALTIVEC		1	/* altivec is present */
30 #define CPU_MAXID		2	/* number of valid machdep ids */
31 
32 #define	CTL_MACHDEP_NAMES { \
33 	{ 0, 0 }, \
34 	{ "altivec", CTLTYPE_INT }, \
35 }
36 
37 #ifdef _KERNEL
38 
39 /*
40  * Kernel-only definitions
41  */
42 
43 #include <machine/cpufunc.h>
44 #include <machine/frame.h>
45 #include <machine/intr.h>
46 #include <machine/psl.h>
47 #include <machine/pte.h>
48 
49 #include <sys/device.h>
50 #include <sys/sched.h>
51 #include <sys/srp.h>
52 
53 struct cpu_info {
54 	struct device	*ci_dev;
55 	struct cpu_info	*ci_next;
56 	struct schedstate_percpu ci_schedstate;
57 
58 	uint32_t	ci_cpuid;
59 	uint32_t	ci_pir;
60 	int		ci_node;
61 
62 	struct proc	*ci_curproc;
63 	struct pcb	*ci_curpcb;
64 
65 	struct slb	ci_kernel_slb[32];
66 	paddr_t		ci_user_slb_pa;
67 	register_t	ci_slbsave[18];
68 	char		ci_slbstack[1024];
69 
70 #define CPUSAVE_LEN	9
71 	register_t	ci_tempsave[CPUSAVE_LEN];
72 	register_t	ci_idle_sp_save;
73 
74 	uint64_t	ci_lasttb;
75 	uint64_t	ci_nexttimerevent;
76 	uint64_t	ci_nextstatevent;
77 	int		ci_statspending;
78 
79 	volatile int 	ci_cpl;
80 	uint32_t	ci_ipending;
81 	uint32_t	ci_idepth;
82 #ifdef DIAGNOSTIC
83 	int		ci_mutex_level;
84 #endif
85 	int		ci_want_resched;
86 
87 	uint32_t	ci_randseed;
88 
89 #ifdef MULTIPROCESSOR
90 	struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM];
91 	void		*ci_initstack_end;
92 	void		*ci_ipi;
93 	int		ci_ipi_reason;
94 	volatile int	ci_flags;
95 #endif
96 
97 #ifdef DDB
98 	volatile int    ci_ddb_paused;
99 #define	CI_DDB_RUNNING	0
100 #define	CI_DDB_SHOULDSTOP	1
101 #define	CI_DDB_STOPPED		2
102 #define	CI_DDB_ENTERDDB		3
103 #define	CI_DDB_INDDB		4
104 #endif
105 };
106 
107 #define CPUF_PRIMARY 		(1 << 0)
108 #define CPUF_AP	 		(1 << 1)
109 #define CPUF_IDENTIFY		(1 << 2)
110 #define CPUF_IDENTIFIED		(1 << 3)
111 #define CPUF_PRESENT		(1 << 4)
112 #define CPUF_GO			(1 << 5)
113 #define CPUF_RUNNING		(1 << 6)
114 
115 extern struct cpu_info cpu_info[];
116 extern struct cpu_info *cpu_info_primary;
117 
118 static __inline struct cpu_info *
119 curcpu(void)
120 {
121 	struct cpu_info *ci;
122 	__asm volatile ("mfsprg0 %0" : "=r"(ci));
123 	return ci;
124 }
125 
126 #define CPU_INFO_ITERATOR	int
127 
128 #ifndef MULTIPROCESSOR
129 
130 #define MAXCPUS			1
131 #define CPU_IS_PRIMARY(ci)	1
132 #define cpu_number()		0
133 
134 #define CPU_INFO_UNIT(ci)	0
135 #define CPU_INFO_FOREACH(cii, ci) \
136 	for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
137 
138 #define cpu_kick(ci)
139 #define cpu_unidle(ci)
140 
141 #else
142 
143 #define MAXCPUS			48
144 #define CPU_IS_PRIMARY(ci)	((ci) == cpu_info_primary)
145 #define cpu_number()		(curcpu()->ci_cpuid)
146 
147 #define CPU_INFO_UNIT(ci)	((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
148 #define CPU_INFO_FOREACH(cii, ci) \
149 	for (cii = 0, ci = &cpu_info[0]; cii < ncpus; cii++, ci++)
150 
151 void	cpu_kick(struct cpu_info *);
152 void	cpu_unidle(struct cpu_info *);
153 void	cpu_boot_secondary_processors(void);
154 void	cpu_startclock(void);
155 
156 extern void (*ul_setperf)(int);
157 void	mp_setperf(int);
158 
159 #endif
160 
161 #define clockframe trapframe
162 
163 #define CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
164 #define CLKF_USERMODE(frame)	(frame->srr1 & PSL_PR)
165 #define CLKF_PC(frame)		(frame->srr0)
166 
167 #define aston(p)		((p)->p_md.md_astpending = 1)
168 #define need_proftick(p)	aston(p)
169 
170 void signotify(struct proc *);
171 
172 #define CPU_BUSY_CYCLE()	do {} while (0)
173 
174 #define curpcb			curcpu()->ci_curpcb
175 
176 extern uint32_t cpu_features;
177 extern uint32_t cpu_features2;
178 
179 #define PPC_FEATURE2_ARCH_3_00	0x00800000
180 #define PPC_FEATURE2_DARN	0x00200000
181 
182 void cpu_init_features(void);
183 void cpu_init(void);
184 
185 extern uint64_t cpu_idle_state_psscr;
186 extern void (*cpu_idle_cycle_fcn)(void);
187 
188 static inline unsigned int
189 cpu_rnd_messybits(void)
190 {
191 	uint64_t tb;
192 
193 	__asm volatile("mftb %0" : "=r" (tb));
194 	return ((tb >> 32) ^ tb);
195 }
196 
197 void need_resched(struct cpu_info *);
198 #define clear_resched(ci)	((ci)->ci_want_resched = 0)
199 
200 void delay(u_int);
201 #define DELAY(x)	delay(x)
202 
203 #define PROC_STACK(p)		((p)->p_md.md_regs->fixreg[1])
204 #define PROC_PC(p)		((p)->p_md.md_regs->srr0)
205 
206 void	proc_trampoline(void);
207 
208 static inline void
209 intr_enable(void)
210 {
211 	mtmsr(mfmsr() | PSL_EE);
212 }
213 
214 static inline u_long
215 intr_disable(void)
216 {
217 	u_long msr;
218 
219 	msr = mfmsr();
220 	mtmsr(msr & ~PSL_EE);
221 	return msr;
222 }
223 
224 static inline void
225 intr_restore(u_long msr)
226 {
227 	mtmsr(msr);
228 }
229 
230 #endif /* _KERNEL */
231 
232 #ifdef MULTIPROCESSOR
233 #include <sys/mplock.h>
234 #endif /* MULTIPROCESSOR */
235 
236 #endif /* _MACHINE_CPU_H_ */
237