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