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