1 /* $OpenBSD: cpu.h,v 1.89 2016/08/17 11:09:01 dlg Exp $ */ 2 /* $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This software was developed by the Computer Systems Engineering group 9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 * contributed to Berkeley. 11 * 12 * All advertising materials mentioning features or use of this software 13 * must display the following acknowledgement: 14 * This product includes software developed by the University of 15 * California, Lawrence Berkeley Laboratory. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 3. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * @(#)cpu.h 8.4 (Berkeley) 1/5/94 42 */ 43 44 #ifndef _MACHINE_CPU_H_ 45 #define _MACHINE_CPU_H_ 46 47 /* 48 * CTL_MACHDEP definitions. 49 */ 50 /* 1 formerly: booted kernel name */ 51 #define CPU_LED_BLINK 2 /* int: blink leds? */ 52 #define CPU_ALLOWAPERTURE 3 /* allow xf86 operations */ 53 #define CPU_CPUTYPE 4 /* cpu type */ 54 #define CPU_CECCERRORS 5 /* Correctable ECC errors */ 55 #define CPU_CECCLAST 6 /* Correctable ECC last fault addr */ 56 /* 7 formerly: soft reset via keyboard */ 57 #define CPU_MAXID 8 /* number of valid machdep ids */ 58 59 #define CTL_MACHDEP_NAMES { \ 60 { 0, 0 }, \ 61 { 0, 0 }, \ 62 { "led_blink", CTLTYPE_INT }, \ 63 { "allowaperture", CTLTYPE_INT }, \ 64 { "cputype", CTLTYPE_INT }, \ 65 { "ceccerrs", CTLTYPE_INT }, \ 66 { "cecclast", CTLTYPE_QUAD }, \ 67 { 0, 0 }, \ 68 } 69 70 #ifdef _KERNEL 71 /* 72 * Exported definitions unique to SPARC cpu support. 73 */ 74 75 #include <machine/ctlreg.h> 76 #include <machine/psl.h> 77 #include <machine/reg.h> 78 #include <machine/intr.h> 79 80 #include <sys/sched.h> 81 82 /* 83 * The cpu_info structure is part of a 64KB structure mapped both the kernel 84 * pmap and a single locked TTE a CPUINFO_VA for that particular processor. 85 * Each processor's cpu_info is accessible at CPUINFO_VA only for that 86 * processor. Other processors can access that through an additional mapping 87 * in the kernel pmap. 88 * 89 * The 64KB page contains: 90 * 91 * cpu_info 92 * interrupt stack (all remaining space) 93 * idle PCB 94 * idle stack (STACKSPACE - sizeof(PCB)) 95 * 32KB TSB 96 */ 97 98 struct cpu_info { 99 /* 100 * SPARC cpu_info structures live at two VAs: one global 101 * VA (so each CPU can access any other CPU's cpu_info) 102 * and an alias VA CPUINFO_VA which is the same on each 103 * CPU and maps to that CPU's cpu_info. Since the alias 104 * CPUINFO_VA is how we locate our cpu_info, we have to 105 * self-reference the global VA so that we can return it 106 * in the curcpu() macro. 107 */ 108 struct cpu_info * volatile ci_self; 109 110 /* Most important fields first */ 111 struct proc *ci_curproc; 112 struct pcb *ci_cpcb; /* also initial stack */ 113 struct cpu_info *ci_next; 114 115 struct proc *ci_fpproc; 116 int ci_number; 117 int ci_flags; 118 int ci_upaid; 119 #ifdef MULTIPROCESSOR 120 int ci_itid; 121 struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; 122 #endif 123 int ci_node; 124 u_int32_t ci_randseed; 125 struct schedstate_percpu ci_schedstate; /* scheduler state */ 126 127 int ci_want_resched; 128 int ci_handled_intr_level; 129 void *ci_intrpending[16][8]; 130 u_int64_t ci_tick; 131 struct intrhand ci_tickintr; 132 133 volatile int ci_ddb_paused; 134 #define CI_DDB_RUNNING 0 135 #define CI_DDB_SHOULDSTOP 1 136 #define CI_DDB_STOPPED 2 137 #define CI_DDB_ENTERDDB 3 138 #define CI_DDB_INDDB 4 139 140 /* Spinning up the CPU */ 141 void (*ci_spinup)(void); /* spinup routine */ 142 void *ci_initstack; 143 paddr_t ci_paddr; /* Phys addr of this structure. */ 144 145 #ifdef SUN4V 146 struct rwindow64 ci_rw; 147 u_int64_t ci_rwsp; 148 149 paddr_t ci_mmfsa; 150 paddr_t ci_cpumq; 151 paddr_t ci_devmq; 152 153 paddr_t ci_cpuset; 154 paddr_t ci_mondo; 155 #endif 156 157 int ci_pci_probe; 158 int ci_pci_fault; 159 160 #ifdef DIAGNOSTIC 161 int ci_mutex_level; 162 #endif 163 #ifdef GPROF 164 struct gmonparam *ci_gmon; 165 #endif 166 }; 167 168 #define CPUF_RUNNING 0x0001 /* CPU is running */ 169 170 extern struct cpu_info *cpus; 171 172 #ifdef MULTIPROCESSOR 173 174 register struct cpu_info *__curcpu asm ("%g7"); 175 176 #define curcpu() (__curcpu->ci_self) 177 #define cpu_number() (__curcpu->ci_number) 178 179 #define CPU_IS_PRIMARY(ci) ((ci)->ci_number == 0) 180 #define CPU_INFO_ITERATOR int 181 #define CPU_INFO_FOREACH(cii, ci) \ 182 for (cii = 0, ci = cpus; ci != NULL; ci = ci->ci_next) 183 #define CPU_INFO_UNIT(ci) ((ci)->ci_number) 184 #define MAXCPUS 256 185 186 void cpu_boot_secondary_processors(void); 187 188 void sparc64_send_ipi(int, void (*)(void), u_int64_t, u_int64_t); 189 void sparc64_broadcast_ipi(void (*)(void), u_int64_t, u_int64_t); 190 191 void cpu_unidle(struct cpu_info *); 192 193 #else /* MULTIPROCESSOR */ 194 195 #define __curcpu ((struct cpu_info *)CPUINFO_VA) 196 #define curcpu() __curcpu 197 #define cpu_number() 0 198 199 #define CPU_IS_PRIMARY(ci) 1 200 #define CPU_INFO_ITERATOR int 201 #define CPU_INFO_FOREACH(cii, ci) \ 202 for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL) 203 #define CPU_INFO_UNIT(ci) 0 204 #define MAXCPUS 1 205 206 #define cpu_unidle(ci) 207 208 #endif /* MULTIPROCESSOR */ 209 210 #define curpcb __curcpu->ci_cpcb 211 #define fpproc __curcpu->ci_fpproc 212 213 #define CPU_BUSY_CYCLE() do {} while (0) 214 215 /* 216 * Arguments to hardclock, softclock and gatherstats encapsulate the 217 * previous machine state in an opaque clockframe. The ipl is here 218 * as well for strayintr (see locore.s:interrupt and intr.c:strayintr). 219 */ 220 struct clockframe { 221 struct trapframe64 t; 222 int saved_intr_level; 223 }; 224 225 #define CLKF_USERMODE(framep) (((framep)->t.tf_tstate & TSTATE_PRIV) == 0) 226 #define CLKF_PC(framep) ((framep)->t.tf_pc) 227 #define CLKF_INTR(framep) ((framep)->saved_intr_level != 0) 228 229 extern void (*cpu_start_clock)(void); 230 231 #define aston(p) ((p)->p_md.md_astpending = 1) 232 233 /* 234 * Preempt the current process if in interrupt from user mode, 235 * or after the current trap/syscall if in system mode. 236 */ 237 extern void need_resched(struct cpu_info *); 238 #define clear_resched(ci) (ci)->ci_want_resched = 0 239 240 /* 241 * This is used during profiling to integrate system time. 242 */ 243 #define PROC_PC(p) ((p)->p_md.md_tf->tf_pc) 244 #define PROC_STACK(p) ((p)->p_md.md_tf->tf_out[6] + (2048-1)) /* BIAS */ 245 246 /* 247 * Give a profiling tick to the current process when the user profiling 248 * buffer pages are invalid. On the sparc, request an ast to send us 249 * through trap(), marking the proc as needing a profiling tick. 250 */ 251 #define need_proftick(p) aston(p) 252 253 void signotify(struct proc *); 254 255 /* cpu.c */ 256 int cpu_myid(void); 257 /* machdep.c */ 258 int ldcontrolb(caddr_t); 259 void dumpconf(void); 260 caddr_t reserve_dumppages(caddr_t); 261 /* clock.c */ 262 struct timeval; 263 int clockintr(void *);/* level 10 (clock) interrupt code */ 264 int statintr(void *); /* level 14 (statclock) interrupt code */ 265 /* locore.s */ 266 struct fpstate64; 267 void savefpstate(struct fpstate64 *); 268 void loadfpstate(struct fpstate64 *); 269 void clearfpstate(void); 270 u_int64_t probeget(paddr_t, int, int); 271 #define write_all_windows() __asm volatile("flushw" : : ) 272 void write_user_windows(void); 273 void proc_trampoline(void); 274 struct pcb; 275 void snapshot(struct pcb *); 276 struct frame *getfp(void); 277 int xldcontrolb(caddr_t, struct pcb *); 278 void copywords(const void *, void *, size_t); 279 void qcopy(const void *, void *, size_t); 280 void qzero(void *, size_t); 281 void switchtoctx(int); 282 /* trap.c */ 283 void pmap_unuse_final(struct proc *); 284 int rwindow_save(struct proc *); 285 /* vm_machdep.c */ 286 void fpusave_cpu(struct cpu_info *, int); 287 void fpusave_proc(struct proc *, int); 288 /* cons.c */ 289 int cnrom(void); 290 /* zs.c */ 291 void zsconsole(struct tty *, int, int, void (**)(struct tty *, int)); 292 /* fb.c */ 293 void fb_unblank(void); 294 /* tda.c */ 295 void tda_full_blast(void); 296 /* emul.c */ 297 int emulinstr(vaddr_t, struct trapframe64 *); 298 int emul_qf(int32_t, struct proc *, union sigval, struct trapframe64 *); 299 int emul_popc(int32_t, struct proc *, union sigval, struct trapframe64 *); 300 301 /* 302 * 303 * The SPARC has a Trap Base Register (TBR) which holds the upper 20 bits 304 * of the trap vector table. The next eight bits are supplied by the 305 * hardware when the trap occurs, and the bottom four bits are always 306 * zero (so that we can shove up to 16 bytes of executable code---exactly 307 * four instructions---into each trap vector). 308 * 309 * The hardware allocates half the trap vectors to hardware and half to 310 * software. 311 * 312 * Traps have priorities assigned (lower number => higher priority). 313 */ 314 315 struct trapvec { 316 int tv_instr[8]; /* the eight instructions */ 317 }; 318 extern struct trapvec trapbase[]; /* the 256 vectors */ 319 320 extern void wzero(void *, u_int); 321 extern void wcopy(const void *, void *, u_int); 322 323 struct blink_led { 324 void (*bl_func)(void *, int); 325 void *bl_arg; 326 SLIST_ENTRY(blink_led) bl_next; 327 }; 328 329 extern void blink_led_register(struct blink_led *); 330 331 #ifdef MULTIPROCESSOR 332 #include <sys/mplock.h> 333 #endif 334 335 #endif /* _KERNEL */ 336 #endif /* _MACHINE_CPU_H_ */ 337