1*d9a6171aSgkoehler /* $OpenBSD: cpu.h,v 1.39 2024/11/28 18:54:36 gkoehler Exp $ */ 212e5a6fbSkettenis 312e5a6fbSkettenis /* 412e5a6fbSkettenis * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> 512e5a6fbSkettenis * 612e5a6fbSkettenis * Permission to use, copy, modify, and distribute this software for any 712e5a6fbSkettenis * purpose with or without fee is hereby granted, provided that the above 812e5a6fbSkettenis * copyright notice and this permission notice appear in all copies. 912e5a6fbSkettenis * 1012e5a6fbSkettenis * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1112e5a6fbSkettenis * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1212e5a6fbSkettenis * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1312e5a6fbSkettenis * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1412e5a6fbSkettenis * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1512e5a6fbSkettenis * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1612e5a6fbSkettenis * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1712e5a6fbSkettenis */ 1812e5a6fbSkettenis 1913861200Skettenis #ifndef _MACHINE_CPU_H_ 2013861200Skettenis #define _MACHINE_CPU_H_ 2113861200Skettenis 2212e5a6fbSkettenis /* 2312e5a6fbSkettenis * User-visible definitions 2412e5a6fbSkettenis */ 2512e5a6fbSkettenis 260dc8bf2fSkettenis /* 270dc8bf2fSkettenis * CTL_MACHDEP definitions. 280dc8bf2fSkettenis */ 290dc8bf2fSkettenis #define CPU_ALTIVEC 1 /* altivec is present */ 300dc8bf2fSkettenis #define CPU_MAXID 2 /* number of valid machdep ids */ 310dc8bf2fSkettenis 320dc8bf2fSkettenis #define CTL_MACHDEP_NAMES { \ 330dc8bf2fSkettenis { 0, 0 }, \ 340dc8bf2fSkettenis { "altivec", CTLTYPE_INT }, \ 350dc8bf2fSkettenis } 3612e5a6fbSkettenis 3712e5a6fbSkettenis #ifdef _KERNEL 3812e5a6fbSkettenis 3912e5a6fbSkettenis /* 4012e5a6fbSkettenis * Kernel-only definitions 4112e5a6fbSkettenis */ 4212e5a6fbSkettenis 4312e5a6fbSkettenis #include <machine/cpufunc.h> 440b0568a1Sjca #include <machine/elf.h> 4513861200Skettenis #include <machine/frame.h> 4612e5a6fbSkettenis #include <machine/intr.h> 4712e5a6fbSkettenis #include <machine/psl.h> 48b079169dSkettenis #include <machine/pte.h> 4913861200Skettenis 50aca18452Scheloha #include <sys/clockintr.h> 5113861200Skettenis #include <sys/device.h> 5213861200Skettenis #include <sys/sched.h> 53ea057ba5Skettenis #include <sys/srp.h> 5413861200Skettenis 5513861200Skettenis struct cpu_info { 5613861200Skettenis struct device *ci_dev; 5713861200Skettenis struct cpu_info *ci_next; 5813861200Skettenis struct schedstate_percpu ci_schedstate; 5913861200Skettenis 60ea057ba5Skettenis uint32_t ci_cpuid; 61ea057ba5Skettenis uint32_t ci_pir; 62fcf94dc6Skettenis int ci_node; 63ea057ba5Skettenis 6413861200Skettenis struct proc *ci_curproc; 6545dd89a7Skettenis struct pcb *ci_curpcb; 6613861200Skettenis 67b079169dSkettenis struct slb ci_kernel_slb[32]; 6837d56e14Skettenis paddr_t ci_user_slb_pa; 6967fd21e2Skettenis register_t ci_slbsave[18]; 7067fd21e2Skettenis char ci_slbstack[1024]; 71b079169dSkettenis 72b0c94682Skettenis #define CPUSAVE_LEN 9 73b0c94682Skettenis register_t ci_tempsave[CPUSAVE_LEN]; 74196daab3Sgkoehler register_t ci_idle_sp_save; 75b0c94682Skettenis 76c737cf90Scheloha struct clockqueue ci_queue; 77ff56acc2Skettenis 78ff56acc2Skettenis volatile int ci_cpl; 79f27ca60cScheloha volatile int ci_dec_deferred; 8013861200Skettenis uint32_t ci_ipending; 811af8fcf9Skettenis uint32_t ci_idepth; 8213861200Skettenis #ifdef DIAGNOSTIC 8313861200Skettenis int ci_mutex_level; 8413861200Skettenis #endif 8513861200Skettenis int ci_want_resched; 8613861200Skettenis 8713861200Skettenis uint32_t ci_randseed; 88ea057ba5Skettenis 89ea057ba5Skettenis #ifdef MULTIPROCESSOR 90ea057ba5Skettenis struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; 91ea057ba5Skettenis void *ci_initstack_end; 92fcf94dc6Skettenis void *ci_ipi; 93284a504dSkettenis int ci_ipi_reason; 94284a504dSkettenis volatile int ci_flags; 95284a504dSkettenis #endif 96284a504dSkettenis 97284a504dSkettenis #ifdef DDB 98284a504dSkettenis volatile int ci_ddb_paused; 99284a504dSkettenis #define CI_DDB_RUNNING 0 100284a504dSkettenis #define CI_DDB_SHOULDSTOP 1 101284a504dSkettenis #define CI_DDB_STOPPED 2 102284a504dSkettenis #define CI_DDB_ENTERDDB 3 103284a504dSkettenis #define CI_DDB_INDDB 4 104ea057ba5Skettenis #endif 1051a4a9ab2Scheloha char ci_panicbuf[512]; 10613861200Skettenis }; 10713861200Skettenis 108ea057ba5Skettenis #define CPUF_PRIMARY (1 << 0) 109ea057ba5Skettenis #define CPUF_AP (1 << 1) 110ea057ba5Skettenis #define CPUF_IDENTIFY (1 << 2) 111ea057ba5Skettenis #define CPUF_IDENTIFIED (1 << 3) 112ea057ba5Skettenis #define CPUF_PRESENT (1 << 4) 113ea057ba5Skettenis #define CPUF_GO (1 << 5) 114ea057ba5Skettenis #define CPUF_RUNNING (1 << 6) 115ea057ba5Skettenis 116ea057ba5Skettenis extern struct cpu_info cpu_info[]; 117ea057ba5Skettenis extern struct cpu_info *cpu_info_primary; 11813861200Skettenis 11987c5ae51Skettenis static __inline struct cpu_info * 12087c5ae51Skettenis curcpu(void) 12187c5ae51Skettenis { 12287c5ae51Skettenis struct cpu_info *ci; 12387c5ae51Skettenis __asm volatile ("mfsprg0 %0" : "=r"(ci)); 12487c5ae51Skettenis return ci; 12587c5ae51Skettenis } 12613861200Skettenis 127ea057ba5Skettenis #define CPU_INFO_ITERATOR int 128ea057ba5Skettenis 129ea057ba5Skettenis #ifndef MULTIPROCESSOR 130ea057ba5Skettenis 13113861200Skettenis #define MAXCPUS 1 13213861200Skettenis #define CPU_IS_PRIMARY(ci) 1 133d73de46fSkettenis #define CPU_IS_RUNNING(ci) 1 134ea057ba5Skettenis #define cpu_number() 0 135ea057ba5Skettenis 13613861200Skettenis #define CPU_INFO_UNIT(ci) 0 13713861200Skettenis #define CPU_INFO_FOREACH(cii, ci) \ 13813861200Skettenis for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL) 139ea057ba5Skettenis 140fcf94dc6Skettenis #define cpu_kick(ci) 141196daab3Sgkoehler #define cpu_unidle(ci) 142fcf94dc6Skettenis 143ea057ba5Skettenis #else 144ea057ba5Skettenis 1455fc7d48aSkettenis #define MAXCPUS 48 146ea057ba5Skettenis #define CPU_IS_PRIMARY(ci) ((ci) == cpu_info_primary) 147d73de46fSkettenis #define CPU_IS_RUNNING(ci) ((ci)->ci_flags & CPUF_RUNNING) 148ea057ba5Skettenis #define cpu_number() (curcpu()->ci_cpuid) 149ea057ba5Skettenis 150ea057ba5Skettenis #define CPU_INFO_UNIT(ci) ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0) 151ea057ba5Skettenis #define CPU_INFO_FOREACH(cii, ci) \ 152ea057ba5Skettenis for (cii = 0, ci = &cpu_info[0]; cii < ncpus; cii++, ci++) 153ea057ba5Skettenis 154fcf94dc6Skettenis void cpu_kick(struct cpu_info *); 155196daab3Sgkoehler void cpu_unidle(struct cpu_info *); 156ea057ba5Skettenis void cpu_boot_secondary_processors(void); 157ea057ba5Skettenis 158c7966c0cSgkoehler extern void (*ul_setperf)(int); 159c7966c0cSgkoehler void mp_setperf(int); 160c7966c0cSgkoehler 161ea057ba5Skettenis #endif 16213861200Skettenis 163351f0751Skettenis #define clockframe trapframe 164351f0751Skettenis 165351f0751Skettenis #define CLKF_INTR(frame) (curcpu()->ci_idepth > 1) 166351f0751Skettenis #define CLKF_USERMODE(frame) (frame->srr1 & PSL_PR) 167351f0751Skettenis #define CLKF_PC(frame) (frame->srr0) 16813861200Skettenis 16913861200Skettenis #define aston(p) ((p)->p_md.md_astpending = 1) 17013861200Skettenis #define need_proftick(p) aston(p) 17113861200Skettenis 1729ae0232dSgkoehler void signotify(struct proc *); 1739ae0232dSgkoehler 174b43d7c27Sjca #define CPU_BUSY_CYCLE() __asm volatile ("" ::: "memory") 17513861200Skettenis 17645dd89a7Skettenis #define curpcb curcpu()->ci_curpcb 17745dd89a7Skettenis 178c2b3d03cSkettenis void cpu_init_features(void); 179c2b3d03cSkettenis void cpu_init(void); 180c2b3d03cSkettenis 1810e6cad35Sguenther #define cpu_idle_enter() do { /* nothing */ } while (0) 1820e6cad35Sguenther #define cpu_idle_leave() do { /* nothing */ } while (0) 183196daab3Sgkoehler extern uint64_t cpu_idle_state_psscr; 184196daab3Sgkoehler extern void (*cpu_idle_cycle_fcn)(void); 185196daab3Sgkoehler 186354e4bfbSkettenis static inline unsigned int 187354e4bfbSkettenis cpu_rnd_messybits(void) 188354e4bfbSkettenis { 189354e4bfbSkettenis uint64_t tb; 190354e4bfbSkettenis 191354e4bfbSkettenis __asm volatile("mftb %0" : "=r" (tb)); 192f585323aSnaddy return ((tb >> 32) ^ tb); 193354e4bfbSkettenis } 19401802d2cSdlg 19513861200Skettenis void need_resched(struct cpu_info *); 19613861200Skettenis #define clear_resched(ci) ((ci)->ci_want_resched = 0) 19713861200Skettenis 19813861200Skettenis void delay(u_int); 19913861200Skettenis #define DELAY(x) delay(x) 20013861200Skettenis 201717af3c7Skettenis #define PROC_STACK(p) ((p)->p_md.md_regs->fixreg[1]) 202717af3c7Skettenis #define PROC_PC(p) ((p)->p_md.md_regs->srr0) 20313861200Skettenis 2040d8e59b5Skettenis void proc_trampoline(void); 2050d8e59b5Skettenis 20612e5a6fbSkettenis static inline void 20712e5a6fbSkettenis intr_enable(void) 20812e5a6fbSkettenis { 20912e5a6fbSkettenis mtmsr(mfmsr() | PSL_EE); 21012e5a6fbSkettenis } 21112e5a6fbSkettenis 21212e5a6fbSkettenis static inline u_long 21312e5a6fbSkettenis intr_disable(void) 21412e5a6fbSkettenis { 21512e5a6fbSkettenis u_long msr; 21612e5a6fbSkettenis 21712e5a6fbSkettenis msr = mfmsr(); 21812e5a6fbSkettenis mtmsr(msr & ~PSL_EE); 21912e5a6fbSkettenis return msr; 22012e5a6fbSkettenis } 22112e5a6fbSkettenis 22212e5a6fbSkettenis static inline void 22312e5a6fbSkettenis intr_restore(u_long msr) 22412e5a6fbSkettenis { 22512e5a6fbSkettenis mtmsr(msr); 22612e5a6fbSkettenis } 22712e5a6fbSkettenis 22812e5a6fbSkettenis #endif /* _KERNEL */ 22906db26f9Sgkoehler 230ea057ba5Skettenis #ifdef MULTIPROCESSOR 231ea057ba5Skettenis #include <sys/mplock.h> 232ea057ba5Skettenis #endif /* MULTIPROCESSOR */ 233ea057ba5Skettenis 23413861200Skettenis #endif /* _MACHINE_CPU_H_ */ 235