1 /* $OpenBSD: cpu.h,v 1.78 2011/07/06 22:26:44 kettenis 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 #endif 122 int ci_node; 123 u_int32_t ci_randseed; 124 struct schedstate_percpu ci_schedstate; /* scheduler state */ 125 126 int ci_want_resched; 127 int ci_handled_intr_level; 128 void *ci_intrpending[16][8]; 129 u_int64_t ci_tick; 130 struct intrhand ci_tickintr; 131 132 /* DEBUG/DIAGNOSTIC stuff */ 133 u_long ci_spin_locks; /* # of spin locks held */ 134 u_long ci_simple_locks;/* # of simple locks held */ 135 136 /* Spinning up the CPU */ 137 void (*ci_spinup)(void); /* spinup routine */ 138 void *ci_initstack; 139 paddr_t ci_paddr; /* Phys addr of this structure. */ 140 141 #ifdef SUN4V 142 struct rwindow64 ci_rw; 143 u_int64_t ci_rwsp; 144 145 paddr_t ci_mmfsa; 146 paddr_t ci_cpumq; 147 paddr_t ci_devmq; 148 149 paddr_t ci_cpuset; 150 paddr_t ci_mondo; 151 #endif 152 153 int ci_pci_probe; 154 int ci_pci_fault; 155 156 #ifdef DIAGNOSTIC 157 int ci_mutex_level; 158 #endif 159 }; 160 161 #define CPUF_RUNNING 0x0001 /* CPU is running */ 162 163 extern struct cpu_info *cpus; 164 165 #define curpcb curcpu()->ci_cpcb 166 #define fpproc curcpu()->ci_fpproc 167 168 #ifdef MULTIPROCESSOR 169 170 #define cpu_number() (curcpu()->ci_number) 171 172 extern __inline struct cpu_info *curcpu(void); 173 extern __inline struct cpu_info * 174 curcpu(void) 175 { 176 struct cpu_info *ci; 177 178 __asm __volatile("mov %%g7, %0" : "=r"(ci)); 179 return (ci->ci_self); 180 } 181 182 #define CPU_IS_PRIMARY(ci) ((ci)->ci_number == 0) 183 #define CPU_INFO_ITERATOR int 184 #define CPU_INFO_FOREACH(cii, ci) \ 185 for (cii = 0, ci = cpus; ci != NULL; ci = ci->ci_next) 186 #define CPU_INFO_UNIT(ci) ((ci)->ci_number) 187 #define MAXCPUS 256 188 189 void cpu_boot_secondary_processors(void); 190 191 void sparc64_send_ipi(int, void (*)(void), u_int64_t, u_int64_t); 192 void sparc64_broadcast_ipi(void (*)(void), u_int64_t, u_int64_t); 193 194 void cpu_unidle(struct cpu_info *); 195 196 #else 197 198 #define cpu_number() 0 199 #define curcpu() ((struct cpu_info *)CPUINFO_VA) 200 201 #define CPU_IS_PRIMARY(ci) 1 202 #define CPU_INFO_ITERATOR int 203 #define CPU_INFO_FOREACH(cii, ci) \ 204 for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL) 205 #define CPU_INFO_UNIT(ci) 0 206 #define MAXCPUS 1 207 208 #define cpu_unidle(ci) 209 210 #endif 211 212 /* 213 * Arguments to hardclock, softclock and gatherstats encapsulate the 214 * previous machine state in an opaque clockframe. The ipl is here 215 * as well for strayintr (see locore.s:interrupt and intr.c:strayintr). 216 */ 217 struct clockframe { 218 struct trapframe64 t; 219 int saved_intr_level; 220 }; 221 222 #define CLKF_USERMODE(framep) (((framep)->t.tf_tstate & TSTATE_PRIV) == 0) 223 #define CLKF_PC(framep) ((framep)->t.tf_pc) 224 #define CLKF_INTR(framep) ((framep)->saved_intr_level != 0) 225 226 extern void (*cpu_start_clock)(void); 227 228 #define aston(p) ((p)->p_md.md_astpending = 1) 229 230 /* 231 * Preempt the current process if in interrupt from user mode, 232 * or after the current trap/syscall if in system mode. 233 */ 234 extern void need_resched(struct cpu_info *); 235 #define clear_resched(ci) (ci)->ci_want_resched = 0 236 237 /* 238 * This is used during profiling to integrate system time. 239 */ 240 #define PROC_PC(p) ((p)->p_md.md_tf->tf_pc) 241 242 /* 243 * Give a profiling tick to the current process when the user profiling 244 * buffer pages are invalid. On the sparc, request an ast to send us 245 * through trap(), marking the proc as needing a profiling tick. 246 */ 247 #define need_proftick(p) aston(p) 248 249 void signotify(struct proc *); 250 251 /* cpu.c */ 252 int cpu_myid(void); 253 /* machdep.c */ 254 int ldcontrolb(caddr_t); 255 void dumpconf(void); 256 caddr_t reserve_dumppages(caddr_t); 257 /* clock.c */ 258 struct timeval; 259 int clockintr(void *);/* level 10 (clock) interrupt code */ 260 int statintr(void *); /* level 14 (statclock) interrupt code */ 261 /* locore.s */ 262 struct fpstate64; 263 void savefpstate(struct fpstate64 *); 264 void loadfpstate(struct fpstate64 *); 265 void clearfpstate(void); 266 u_int64_t probeget(paddr_t, int, int); 267 #define write_all_windows() __asm __volatile("flushw" : : ) 268 void write_user_windows(void); 269 void proc_trampoline(void); 270 struct pcb; 271 void snapshot(struct pcb *); 272 struct frame *getfp(void); 273 int xldcontrolb(caddr_t, struct pcb *); 274 void copywords(const void *, void *, size_t); 275 void qcopy(const void *, void *, size_t); 276 void qzero(void *, size_t); 277 void switchtoctx(int); 278 /* trap.c */ 279 void pmap_unuse_final(struct proc *); 280 int rwindow_save(struct proc *); 281 /* vm_machdep.c */ 282 void fpusave_cpu(struct cpu_info *, int); 283 void fpusave_proc(struct proc *, int); 284 /* cons.c */ 285 int cnrom(void); 286 /* zs.c */ 287 void zsconsole(struct tty *, int, int, void (**)(struct tty *, int)); 288 /* fb.c */ 289 void fb_unblank(void); 290 /* tda.c */ 291 void tda_full_blast(void); 292 /* emul.c */ 293 int emulinstr(vaddr_t, struct trapframe64 *); 294 int emul_qf(int32_t, struct proc *, union sigval, struct trapframe64 *); 295 int emul_popc(int32_t, struct proc *, union sigval, struct trapframe64 *); 296 297 /* 298 * 299 * The SPARC has a Trap Base Register (TBR) which holds the upper 20 bits 300 * of the trap vector table. The next eight bits are supplied by the 301 * hardware when the trap occurs, and the bottom four bits are always 302 * zero (so that we can shove up to 16 bytes of executable code---exactly 303 * four instructions---into each trap vector). 304 * 305 * The hardware allocates half the trap vectors to hardware and half to 306 * software. 307 * 308 * Traps have priorities assigned (lower number => higher priority). 309 */ 310 311 struct trapvec { 312 int tv_instr[8]; /* the eight instructions */ 313 }; 314 extern struct trapvec trapbase[]; /* the 256 vectors */ 315 316 extern void wzero(void *, u_int); 317 extern void wcopy(const void *, void *, u_int); 318 319 struct blink_led { 320 void (*bl_func)(void *, int); 321 void *bl_arg; 322 SLIST_ENTRY(blink_led) bl_next; 323 }; 324 325 extern void blink_led_register(struct blink_led *); 326 327 #ifdef MULTIPROCESSOR 328 #include <sys/mplock.h> 329 #endif 330 331 #endif /* _KERNEL */ 332 #endif /* _MACHINE_CPU_H_ */ 333