xref: /openbsd-src/sys/arch/powerpc64/include/cpu.h (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /*	$OpenBSD: cpu.h,v 1.28 2020/09/23 03:03:12 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 
73 	uint64_t	ci_lasttb;
74 	uint64_t	ci_nexttimerevent;
75 	uint64_t	ci_nextstatevent;
76 	int		ci_statspending;
77 
78 	volatile int 	ci_cpl;
79 	uint32_t	ci_ipending;
80 	uint32_t	ci_idepth;
81 #ifdef DIAGNOSTIC
82 	int		ci_mutex_level;
83 #endif
84 	int		ci_want_resched;
85 
86 	uint32_t	ci_randseed;
87 
88 #ifdef MULTIPROCESSOR
89 	struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM];
90 	void		*ci_initstack_end;
91 	void		*ci_ipi;
92 	int		ci_ipi_reason;
93 	volatile int	ci_flags;
94 #endif
95 
96 #ifdef DDB
97 	volatile int    ci_ddb_paused;
98 #define	CI_DDB_RUNNING	0
99 #define	CI_DDB_SHOULDSTOP	1
100 #define	CI_DDB_STOPPED		2
101 #define	CI_DDB_ENTERDDB		3
102 #define	CI_DDB_INDDB		4
103 #endif
104 };
105 
106 #define CPUF_PRIMARY 		(1 << 0)
107 #define CPUF_AP	 		(1 << 1)
108 #define CPUF_IDENTIFY		(1 << 2)
109 #define CPUF_IDENTIFIED		(1 << 3)
110 #define CPUF_PRESENT		(1 << 4)
111 #define CPUF_GO			(1 << 5)
112 #define CPUF_RUNNING		(1 << 6)
113 
114 extern struct cpu_info cpu_info[];
115 extern struct cpu_info *cpu_info_primary;
116 
117 static __inline struct cpu_info *
118 curcpu(void)
119 {
120 	struct cpu_info *ci;
121 	__asm volatile ("mfsprg0 %0" : "=r"(ci));
122 	return ci;
123 }
124 
125 #define CPU_INFO_ITERATOR	int
126 
127 #ifndef MULTIPROCESSOR
128 
129 #define MAXCPUS			1
130 #define CPU_IS_PRIMARY(ci)	1
131 #define cpu_number()		0
132 
133 #define CPU_INFO_UNIT(ci)	0
134 #define CPU_INFO_FOREACH(cii, ci) \
135 	for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
136 
137 #define cpu_kick(ci)
138 
139 #else
140 
141 #define MAXCPUS			48
142 #define CPU_IS_PRIMARY(ci)	((ci) == cpu_info_primary)
143 #define cpu_number()		(curcpu()->ci_cpuid)
144 
145 #define CPU_INFO_UNIT(ci)	((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
146 #define CPU_INFO_FOREACH(cii, ci) \
147 	for (cii = 0, ci = &cpu_info[0]; cii < ncpus; cii++, ci++)
148 
149 void	cpu_kick(struct cpu_info *);
150 void	cpu_boot_secondary_processors(void);
151 void	cpu_startclock(void);
152 
153 extern void (*ul_setperf)(int);
154 void	mp_setperf(int);
155 
156 #endif
157 
158 #define clockframe trapframe
159 
160 #define CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
161 #define CLKF_USERMODE(frame)	(frame->srr1 & PSL_PR)
162 #define CLKF_PC(frame)		(frame->srr0)
163 
164 #define aston(p)		((p)->p_md.md_astpending = 1)
165 #define need_proftick(p)	aston(p)
166 
167 void signotify(struct proc *);
168 
169 #define cpu_unidle(ci)
170 #define CPU_BUSY_CYCLE()	do {} while (0)
171 
172 #define curpcb			curcpu()->ci_curpcb
173 
174 extern uint32_t cpu_features;
175 extern uint32_t cpu_features2;
176 
177 #define PPC_FEATURE2_ARCH_3_00	0x00800000
178 #define PPC_FEATURE2_DARN	0x00200000
179 
180 void cpu_init_features(void);
181 void cpu_init(void);
182 
183 static inline unsigned int
184 cpu_rnd_messybits(void)
185 {
186 	uint64_t tb;
187 
188 	__asm volatile("mftb %0" : "=r" (tb));
189 	return ((tb >> 32) ^ tb);
190 }
191 
192 void need_resched(struct cpu_info *);
193 #define clear_resched(ci)	((ci)->ci_want_resched = 0)
194 
195 void delay(u_int);
196 #define DELAY(x)	delay(x)
197 
198 #define PROC_STACK(p)		((p)->p_md.md_regs->fixreg[1])
199 #define PROC_PC(p)		((p)->p_md.md_regs->srr0)
200 
201 void	proc_trampoline(void);
202 
203 static inline void
204 intr_enable(void)
205 {
206 	mtmsr(mfmsr() | PSL_EE);
207 }
208 
209 static inline u_long
210 intr_disable(void)
211 {
212 	u_long msr;
213 
214 	msr = mfmsr();
215 	mtmsr(msr & ~PSL_EE);
216 	return msr;
217 }
218 
219 static inline void
220 intr_restore(u_long msr)
221 {
222 	mtmsr(msr);
223 }
224 
225 #endif /* _KERNEL */
226 
227 #ifdef MULTIPROCESSOR
228 #include <sys/mplock.h>
229 #endif /* MULTIPROCESSOR */
230 
231 #endif /* _MACHINE_CPU_H_ */
232