1/* $OpenBSD: cpu.h,v 1.39 2024/11/28 18:54:36 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/elf.h>
45#include <machine/frame.h>
46#include <machine/intr.h>
47#include <machine/psl.h>
48#include <machine/pte.h>
49
50#include <sys/clockintr.h>
51#include <sys/device.h>
52#include <sys/sched.h>
53#include <sys/srp.h>
54
55struct cpu_info {
56 struct device *ci_dev;
57 struct cpu_info *ci_next;
58 struct schedstate_percpu ci_schedstate;
59
60 uint32_t ci_cpuid;
61 uint32_t ci_pir;
62 int ci_node;
63
64 struct proc *ci_curproc;
65 struct pcb *ci_curpcb;
66
67 struct slb ci_kernel_slb[32];
68 paddr_t ci_user_slb_pa;
69 register_t ci_slbsave[18];
70 char ci_slbstack[1024];
71
72#define CPUSAVE_LEN 9
73 register_t ci_tempsave[CPUSAVE_LEN];
74 register_t ci_idle_sp_save;
75
76 struct clockqueue ci_queue;
77
78 volatile int ci_cpl;
79 volatile int ci_dec_deferred;
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 char ci_panicbuf[512];
106};
107
108#define CPUF_PRIMARY (1 << 0)
109#define CPUF_AP (1 << 1)
110#define CPUF_IDENTIFY (1 << 2)
111#define CPUF_IDENTIFIED (1 << 3)
112#define CPUF_PRESENT (1 << 4)
113#define CPUF_GO (1 << 5)
114#define CPUF_RUNNING (1 << 6)
115
116extern struct cpu_info cpu_info[];
117extern struct cpu_info *cpu_info_primary;
118
119static __inline struct cpu_info *
120curcpu(void)
121{
122 struct cpu_info *ci;
123 __asm volatile ("mfsprg0 %0" : "=r"(ci));
124 return ci;
125}
126
127#define CPU_INFO_ITERATOR int
128
129#ifndef MULTIPROCESSOR
130
131#define MAXCPUS 1
132#define CPU_IS_PRIMARY(ci) 1
133#define CPU_IS_RUNNING(ci) 1
134#define cpu_number() 0
135
136#define CPU_INFO_UNIT(ci) 0
137#define CPU_INFO_FOREACH(cii, ci) \
138 for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
139
140#define cpu_kick(ci)
141#define cpu_unidle(ci)
142
143#else
144
145#define MAXCPUS 48
146#define CPU_IS_PRIMARY(ci) ((ci) == cpu_info_primary)
147#define CPU_IS_RUNNING(ci) ((ci)->ci_flags & CPUF_RUNNING)
148#define cpu_number() (curcpu()->ci_cpuid)
149
150#define CPU_INFO_UNIT(ci) ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
151#define CPU_INFO_FOREACH(cii, ci) \
152 for (cii = 0, ci = &cpu_info[0]; cii < ncpus; cii++, ci++)
153
154void cpu_kick(struct cpu_info *);
155void cpu_unidle(struct cpu_info *);
156void cpu_boot_secondary_processors(void);
157
158extern void (*ul_setperf)(int);
159void mp_setperf(int);
160
161#endif
162
163#define clockframe trapframe
164
165#define CLKF_INTR(frame) (curcpu()->ci_idepth > 1)
166#define CLKF_USERMODE(frame) (frame->srr1 & PSL_PR)
167#define CLKF_PC(frame) (frame->srr0)
168
169#define aston(p) ((p)->p_md.md_astpending = 1)
170#define need_proftick(p) aston(p)
171
172void signotify(struct proc *);
173
174#define CPU_BUSY_CYCLE() __asm volatile ("" ::: "memory")
175
176#define curpcb curcpu()->ci_curpcb
177
178void cpu_init_features(void);
179void cpu_init(void);
180
181#define cpu_idle_enter() do { /* nothing */ } while (0)
182#define cpu_idle_leave() do { /* nothing */ } while (0)
183extern uint64_t cpu_idle_state_psscr;
184extern void (*cpu_idle_cycle_fcn)(void);
185
186static inline unsigned int
187cpu_rnd_messybits(void)
188{
189 uint64_t tb;
190
191 __asm volatile("mftb %0" : "=r" (tb));
192 return ((tb >> 32) ^ tb);
193}
194
195void need_resched(struct cpu_info *);
196#define clear_resched(ci) ((ci)->ci_want_resched = 0)
197
198void delay(u_int);
199#define DELAY(x) delay(x)
200
201#define PROC_STACK(p) ((p)->p_md.md_regs->fixreg[1])
202#define PROC_PC(p) ((p)->p_md.md_regs->srr0)
203
204void proc_trampoline(void);
205
206static inline void
207intr_enable(void)
208{
209 mtmsr(mfmsr() | PSL_EE);
210}
211
212static inline u_long
213intr_disable(void)
214{
215 u_long msr;
216
217 msr = mfmsr();
218 mtmsr(msr & ~PSL_EE);
219 return msr;
220}
221
222static inline void
223intr_restore(u_long msr)
224{
225 mtmsr(msr);
226}
227
228#endif /* _KERNEL */
229
230#ifdef MULTIPROCESSOR
231#include <sys/mplock.h>
232#endif /* MULTIPROCESSOR */
233
234#endif /* _MACHINE_CPU_H_ */