1 /* $OpenBSD: cpu.h,v 1.77 2024/10/25 08:08:24 mpi Exp $ */ 2 /* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */ 3 4 /*- 5 * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1988 University of Utah. 36 * Copyright (c) 1982, 1990, 1993 37 * The Regents of the University of California. All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * the Systems Programming Group of the University of Utah Computer 41 * Science Department. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. Neither the name of the University nor the names of its contributors 52 * may be used to endorse or promote products derived from this software 53 * without specific prior written permission. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 * SUCH DAMAGE. 66 * 67 * from: Utah $Hdr: cpu.h 1.16 91/03/25$ 68 * 69 * @(#)cpu.h 8.4 (Berkeley) 1/5/94 70 */ 71 72 #ifndef _MACHINE_CPU_H_ 73 #define _MACHINE_CPU_H_ 74 75 #ifndef NO_IEEE 76 typedef union alpha_s_float { 77 u_int32_t i; 78 u_int32_t frac: 23, 79 exp: 8, 80 sign: 1; 81 } s_float; 82 83 typedef union alpha_t_float { 84 u_int64_t i; 85 u_int64_t frac: 52, 86 exp: 11, 87 sign: 1; 88 } t_float; 89 #endif 90 91 /* 92 * Exported definitions unique to Alpha cpu support. 93 */ 94 95 #ifdef _KERNEL 96 97 #include <machine/alpha_cpu.h> 98 #include <machine/frame.h> 99 #include <machine/bus.h> 100 #include <machine/intr.h> 101 #include <sys/cdefs.h> 102 #include <sys/clockintr.h> 103 #include <sys/device.h> 104 #include <sys/sched.h> 105 #include <sys/srp.h> 106 #include <uvm/uvm_percpu.h> 107 108 struct pcb; 109 struct proc; 110 struct reg; 111 struct rpb; 112 struct trapframe; 113 114 extern u_long cpu_implver; /* from IMPLVER instruction */ 115 extern u_long cpu_amask; /* from AMASK instruction */ 116 extern int bootdev_debug; 117 extern int alpha_fp_sync_complete; 118 119 void XentArith(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ 120 void XentIF(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ 121 void XentInt(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ 122 void XentMM(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ 123 void XentRestart(void); /* MAGIC */ 124 void XentSys(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ 125 void XentUna(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ 126 void alpha_init(u_long, u_long, u_long, u_long, u_long); 127 int alpha_pa_access(u_long); 128 void ast(struct trapframe *); 129 int badaddr(void *, size_t); 130 int badaddr_read(void *, size_t, void *); 131 u_int64_t console_restart(struct trapframe *); 132 void do_sir(void); 133 void dumpconf(void); 134 void exception_return(void); /* MAGIC */ 135 void frametoreg(struct trapframe *, struct reg *); 136 long fswintrberr(void); /* MAGIC */ 137 void init_bootstrap_console(void); 138 void init_prom_interface(struct rpb *); 139 void interrupt(unsigned long, unsigned long, unsigned long, 140 struct trapframe *); 141 void machine_check(unsigned long, struct trapframe *, unsigned long, 142 unsigned long); 143 u_int64_t hwrpb_checksum(void); 144 void hwrpb_restart_setup(void); 145 void proc_trampoline(void); /* MAGIC */ 146 void regdump(struct trapframe *); 147 void regtoframe(struct reg *, struct trapframe *); 148 void savectx(struct pcb *); 149 void syscall(u_int64_t, struct trapframe *); 150 void trap(unsigned long, unsigned long, unsigned long, unsigned long, 151 struct trapframe *); 152 void trap_init(void); 153 void enable_nsio_ide(bus_space_tag_t); 154 155 /* Multiprocessor glue; cpu.c */ 156 struct cpu_info; 157 int cpu_iccb_send(cpuid_t, const char *); 158 void cpu_iccb_receive(void); 159 void cpu_hatch(struct cpu_info *); 160 __dead 161 void cpu_halt(void); 162 void cpu_halt_secondary(unsigned long); 163 void cpu_spinup_trampoline(void); /* MAGIC */ 164 void cpu_pause(unsigned long); 165 void cpu_resume(unsigned long); 166 167 /* 168 * Machine check information. 169 */ 170 struct mchkinfo { 171 volatile int mc_expected; /* machine check is expected */ 172 volatile int mc_received; /* machine check was received */ 173 }; 174 175 struct cpu_info { 176 /* 177 * Private members accessed in assembly with 8 bit offsets. 178 */ 179 struct proc *ci_curproc; /* current owner of the processor */ 180 paddr_t ci_curpcb; /* PA of current HW PCB */ 181 182 /* 183 * Public members. 184 */ 185 struct schedstate_percpu ci_schedstate; /* scheduler state */ 186 #ifdef DIAGNOSTIC 187 int ci_mutex_level; 188 #endif 189 cpuid_t ci_cpuid; /* our CPU ID */ 190 struct cpu_info *ci_next; 191 u_int32_t ci_randseed; 192 193 #if defined(MULTIPROCESSOR) 194 struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; 195 #define __HAVE_UVM_PERCPU 196 struct uvm_pmr_cache ci_uvm; 197 #endif 198 199 /* 200 * Private members. 201 */ 202 struct mchkinfo ci_mcinfo; /* machine check info */ 203 struct proc *ci_fpcurproc; /* current owner of the FPU */ 204 struct pcb *ci_idle_pcb; /* our idle PCB */ 205 paddr_t ci_idle_pcb_paddr; /* PA of idle PCB */ 206 struct device *ci_dev; /* pointer to our device */ 207 u_long ci_want_resched; /* preempt current process */ 208 u_long ci_idepth; /* interrupt trap depth */ 209 struct trapframe *ci_db_regs; /* registers for debuggers */ 210 211 #if defined(MULTIPROCESSOR) 212 volatile u_long ci_flags; /* flags; see below */ 213 volatile u_long ci_ipis; /* interprocessor interrupts pending */ 214 #endif 215 #ifdef GPROF 216 struct gmonparam *ci_gmon; 217 struct clockintr ci_gmonclock; 218 #endif 219 struct clockqueue ci_queue; 220 char ci_panicbuf[512]; 221 }; 222 223 #define CPUF_PRIMARY 0x01 /* CPU is primary CPU */ 224 #define CPUF_RUNNING 0x02 /* CPU is running */ 225 #define CPUF_PAUSED 0x04 /* CPU is paused */ 226 #define CPUF_FPUSAVE 0x08 /* CPU is currently in fpusave_cpu() */ 227 228 void fpusave_cpu(struct cpu_info *, int); 229 void fpusave_proc(struct proc *, int); 230 231 extern struct cpu_info cpu_info_primary; 232 extern struct cpu_info *cpu_info_list; 233 234 #define CPU_INFO_UNIT(ci) ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0) 235 #define CPU_INFO_ITERATOR int 236 #define CPU_INFO_FOREACH(cii, ci) for (cii = 0, ci = cpu_info_list; \ 237 ci != NULL; ci = ci->ci_next) 238 239 #define MAXCPUS ALPHA_MAXPROCS 240 241 #if defined(MULTIPROCESSOR) 242 extern volatile u_long cpus_running; 243 extern volatile u_long cpus_paused; 244 extern struct cpu_info *cpu_info[]; 245 246 #define curcpu() ((struct cpu_info *)alpha_pal_rdval()) 247 #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY) 248 #define CPU_IS_RUNNING(ci) ((ci)->ci_flags & CPUF_RUNNING) 249 250 void cpu_boot_secondary_processors(void); 251 252 void cpu_pause_resume(unsigned long, int); 253 void cpu_pause_resume_all(int); 254 void cpu_unidle(struct cpu_info *); 255 256 /* 257 * On the Alpha, interprocessor interrupts come in at device priority 258 * level. This can cause some problems while waiting for r/w spinlocks 259 * from a high'ish priority level: IPIs that come in will not be processed. 260 * This can lead to deadlock. 261 * 262 * This hook allows IPIs to be processed while a spinlock's interlock 263 * is released. 264 */ 265 #define CPU_BUSY_CYCLE() \ 266 do { \ 267 struct cpu_info *__ci = curcpu(); \ 268 int __s; \ 269 \ 270 __asm volatile ("" ::: "memory"); \ 271 \ 272 if (__ci->ci_ipis != 0) { \ 273 __s = splipi(); \ 274 alpha_ipi_process_with_frame(__ci); \ 275 splx(__s); \ 276 } \ 277 } while (0) 278 279 #else /* ! MULTIPROCESSOR */ 280 281 #define curcpu() (&cpu_info_primary) 282 #define CPU_IS_PRIMARY(ci) 1 283 #define CPU_IS_RUNNING(ci) 1 284 #define cpu_unidle(ci) do { /* nothing */ } while (0) 285 #define CPU_BUSY_CYCLE() __asm volatile ("" ::: "memory") 286 287 #endif /* MULTIPROCESSOR */ 288 289 290 #define curproc curcpu()->ci_curproc 291 #define fpcurproc curcpu()->ci_fpcurproc 292 #define curpcb curcpu()->ci_curpcb 293 294 /* 295 * definitions of cpu-dependent requirements 296 * referenced in generic code 297 */ 298 #define cpu_number() alpha_pal_whami() 299 300 static inline unsigned int 301 cpu_rnd_messybits(void) 302 { 303 return alpha_rpcc(); 304 } 305 306 /* 307 * Arguments to clockintr_dispatch encapsulate the previous 308 * machine state in an opaque clockframe. On the Alpha, we use 309 * what we push on an interrupt (a trapframe). 310 */ 311 struct clockframe { 312 struct trapframe cf_tf; 313 }; 314 #define CLKF_USERMODE(framep) \ 315 (((framep)->cf_tf.tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0) 316 #define CLKF_PC(framep) ((framep)->cf_tf.tf_regs[FRAME_PC]) 317 318 /* 319 * This isn't perfect; if the clock interrupt comes in before the 320 * r/m/w cycle is complete, we won't be counted... but it's not 321 * like this statistic has to be extremely accurate. 322 */ 323 #define CLKF_INTR(framep) (curcpu()->ci_idepth) 324 325 /* 326 * This is used during profiling to integrate system time. 327 */ 328 #define PROC_PC(p) ((p)->p_md.md_tf->tf_regs[FRAME_PC]) 329 #define PROC_STACK(p) ((p)->p_md.md_tf->tf_regs[FRAME_SP]) 330 331 /* 332 * Preempt the current process if in interrupt from user mode, 333 * or after the current trap/syscall if in system mode. 334 */ 335 #define need_resched(ci) \ 336 do { \ 337 (ci)->ci_want_resched = 1; \ 338 if ((ci)->ci_curproc != NULL) \ 339 aston((ci)->ci_curproc); \ 340 } while (/*CONSTCOND*/0) 341 #define clear_resched(ci) (ci)->ci_want_resched = 0 342 343 /* 344 * Give a profiling tick to the current process when the user profiling 345 * buffer pages are invalid. On the Alpha, request an AST to send us 346 * through trap, marking the proc as needing a profiling tick. 347 */ 348 #define need_proftick(p) aston(p) 349 350 /* 351 * Notify the current process (p) that it has a signal pending, 352 * process as soon as possible. 353 */ 354 #ifdef MULTIPROCESSOR 355 #define signotify(p) do { aston(p); cpu_unidle((p)->p_cpu); } while (0) 356 #else 357 #define signotify(p) aston(p) 358 #endif 359 360 #define aston(p) ((p)->p_md.md_astpending = 1) 361 #endif /* _KERNEL */ 362 363 /* 364 * CTL_MACHDEP definitions. 365 */ 366 #define CPU_CONSDEV 1 /* dev_t: console terminal device */ 367 #define CPU_BOOTED_KERNEL 6 /* string: booted kernel name */ 368 #define CPU_FP_SYNC_COMPLETE 7 /* int: always fixup sync fp traps */ 369 #define CPU_CHIPSET 8 /* chipset information */ 370 #define CPU_ALLOWAPERTURE 9 371 #define CPU_LED_BLINK 10 /* int: blink leds on DEC 3000 */ 372 373 #define CPU_MAXID 11 /* valid machdep IDs */ 374 375 #define CPU_CHIPSET_MEM 1 /* PCI memory address */ 376 #define CPU_CHIPSET_BWX 2 /* PCI supports BWX */ 377 #define CPU_CHIPSET_TYPE 3 /* PCI chipset name */ 378 #define CPU_CHIPSET_DENSE 4 /* PCI chipset dense memory addr */ 379 #define CPU_CHIPSET_PORTS 5 /* PCI port address */ 380 #define CPU_CHIPSET_HAE_MASK 6 /* PCI chipset mask for HAE register */ 381 #define CPU_CHIPSET_MAXID 7 382 383 #define CTL_MACHDEP_NAMES { \ 384 { 0, 0 }, \ 385 { "console_device", CTLTYPE_STRUCT }, \ 386 { 0, 0 }, \ 387 { 0, 0 }, \ 388 { 0, 0 }, \ 389 { 0, 0 }, \ 390 { "booted_kernel", CTLTYPE_STRING }, \ 391 { "fp_sync_complete", CTLTYPE_INT }, \ 392 { "chipset", CTLTYPE_NODE }, \ 393 { "allowaperture", CTLTYPE_INT }, \ 394 { "led_blink", CTLTYPE_INT } \ 395 } 396 397 #define CTL_CHIPSET_NAMES { \ 398 { 0, 0 }, \ 399 { "memory", CTLTYPE_QUAD }, \ 400 { "bwx", CTLTYPE_INT }, \ 401 { "type", CTLTYPE_STRING }, \ 402 { "dense_base", CTLTYPE_QUAD }, \ 403 { "ports_base", CTLTYPE_QUAD }, \ 404 { "hae_mask", CTLTYPE_QUAD }, \ 405 } 406 407 #ifdef _KERNEL 408 409 struct pcb; 410 struct proc; 411 struct reg; 412 struct rpb; 413 struct trapframe; 414 415 /* IEEE and VAX FP completion */ 416 417 #ifndef NO_IEEE 418 void alpha_sts(int, s_float *); /* MAGIC */ 419 void alpha_stt(int, t_float *); /* MAGIC */ 420 void alpha_lds(int, s_float *); /* MAGIC */ 421 void alpha_ldt(int, t_float *); /* MAGIC */ 422 423 uint64_t alpha_read_fpcr(void); /* MAGIC */ 424 void alpha_write_fpcr(u_int64_t); /* MAGIC */ 425 426 u_int64_t alpha_read_fp_c(struct proc *); 427 void alpha_write_fp_c(struct proc *, u_int64_t); 428 429 int alpha_fp_complete(u_long, u_long, struct proc *, u_int64_t *); 430 int alpha_fp_complete_at(u_long, struct proc *, u_int64_t *); 431 #endif 432 433 void alpha_enable_fp(struct proc *, int); 434 435 #ifdef MULTIPROCESSOR 436 #include <sys/mplock.h> 437 #endif 438 439 static inline u_long 440 intr_disable(void) 441 { 442 return (u_long)splhigh(); 443 } 444 445 static inline void 446 intr_restore(u_long s) 447 { 448 splx((int)s); 449 } 450 451 #define copyinsn(p, v, ip) copyin32((v), (ip)) 452 453 #endif /* _KERNEL */ 454 #endif /* _MACHINE_CPU_H_ */ 455