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 55 struct 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 116 extern struct cpu_info cpu_info[]; 117 extern struct cpu_info *cpu_info_primary; 118 119 static __inline struct cpu_info * 120 curcpu(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 154 void cpu_kick(struct cpu_info *); 155 void cpu_unidle(struct cpu_info *); 156 void cpu_boot_secondary_processors(void); 157 158 extern void (*ul_setperf)(int); 159 void 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 172 void signotify(struct proc *); 173 174 #define CPU_BUSY_CYCLE() __asm volatile ("" ::: "memory") 175 176 #define curpcb curcpu()->ci_curpcb 177 178 void cpu_init_features(void); 179 void cpu_init(void); 180 181 #define cpu_idle_enter() do { /* nothing */ } while (0) 182 #define cpu_idle_leave() do { /* nothing */ } while (0) 183 extern uint64_t cpu_idle_state_psscr; 184 extern void (*cpu_idle_cycle_fcn)(void); 185 186 static inline unsigned int 187 cpu_rnd_messybits(void) 188 { 189 uint64_t tb; 190 191 __asm volatile("mftb %0" : "=r" (tb)); 192 return ((tb >> 32) ^ tb); 193 } 194 195 void need_resched(struct cpu_info *); 196 #define clear_resched(ci) ((ci)->ci_want_resched = 0) 197 198 void 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 204 void proc_trampoline(void); 205 206 static inline void 207 intr_enable(void) 208 { 209 mtmsr(mfmsr() | PSL_EE); 210 } 211 212 static inline u_long 213 intr_disable(void) 214 { 215 u_long msr; 216 217 msr = mfmsr(); 218 mtmsr(msr & ~PSL_EE); 219 return msr; 220 } 221 222 static inline void 223 intr_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_ */ 235