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