1 /* $NetBSD: cpu.h,v 1.13 2023/02/23 14:55:36 riastradh Exp $ */ 2 3 /* $OpenBSD: cpu.h,v 1.55 2008/07/23 17:39:35 kettenis Exp $ */ 4 5 /* 6 * Copyright (c) 2000-2004 Michael Shalayeff 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 /* 31 * Copyright (c) 1988-1994, The University of Utah and 32 * the Computer Systems Laboratory at the University of Utah (CSL). 33 * All rights reserved. 34 * 35 * Permission to use, copy, modify and distribute this software is hereby 36 * granted provided that (1) source code retains these copyright, permission, 37 * and disclaimer notices, and (2) redistributions including binaries 38 * reproduce the notices in supporting documentation, and (3) all advertising 39 * materials mentioning features or use of this software display the following 40 * acknowledgement: ``This product includes software developed by the 41 * Computer Systems Laboratory at the University of Utah.'' 42 * 43 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS 44 * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF 45 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 46 * 47 * CSL requests users of this software to return to csl-dist@cs.utah.edu any 48 * improvements that they make and grant CSL redistribution rights. 49 * 50 * Utah $Hdr: cpu.h 1.19 94/12/16$ 51 */ 52 53 #ifndef _MACHINE_CPU_H_ 54 #define _MACHINE_CPU_H_ 55 56 #ifdef _KERNEL_OPT 57 #include "opt_cputype.h" 58 #include "opt_gprof.h" 59 #include "opt_multiprocessor.h" 60 #endif 61 62 #include <machine/trap.h> 63 #include <machine/frame.h> 64 #include <machine/reg.h> 65 #include <machine/intrdefs.h> 66 67 #ifndef __ASSEMBLER__ 68 #include <machine/intr.h> 69 #endif 70 71 #ifndef _LOCORE 72 73 /* types */ 74 enum hppa_cpu_type { 75 hpc_unknown, 76 hpcx, /* PA7000 (x) PA 1.0 */ 77 hpcxs, /* PA7000 (s) PA 1.1a */ 78 hpcxt, /* PA7100 (t) PA 1.1b */ 79 hpcxl, /* PA7100LC (l) PA 1.1c */ 80 hpcxtp, /* PA7200 (t') PA 1.1d */ 81 hpcxl2, /* PA7300LC (l2) PA 1.1e */ 82 hpcxu, /* PA8000 (u) PA 2.0 */ 83 hpcxup, /* PA8200 (u+) PA 2.0 */ 84 hpcxw, /* PA8500 (w) PA 2.0 */ 85 hpcxwp, /* PA8600 (w+) PA 2.0 */ 86 hpcxw2, /* PA8700 (piranha) PA 2.0 */ 87 mako /* PA8800 (mako) PA 2.0 */ 88 }; 89 90 #ifdef _KERNEL 91 /* 92 * A CPU description. 93 */ 94 struct hppa_cpu_info { 95 /* The official name of the chip. */ 96 const char *hci_chip_name; 97 98 /* The nickname for the chip. */ 99 const char *hci_chip_nickname; 100 101 /* The type and PA-RISC specification of the chip. */ 102 const char hci_chip_type[8]; 103 enum hppa_cpu_type hci_cputype; 104 int hci_cpuversion; 105 int hci_features; /* CPU types and features */ 106 #define HPPA_FTRS_TLBU 0x00000001 107 #define HPPA_FTRS_BTLBU 0x00000002 108 #define HPPA_FTRS_HVT 0x00000004 109 #define HPPA_FTRS_W32B 0x00000008 110 111 const char *hci_chip_spec; 112 113 int (*desidhash)(void); 114 const u_int *itlbh, *dtlbh, *itlbnah, *dtlbnah, *tlbdh; 115 int (*dbtlbins)(int, pa_space_t, vaddr_t, paddr_t, vsize_t, u_int); 116 int (*ibtlbins)(int, pa_space_t, vaddr_t, paddr_t, vsize_t, u_int); 117 int (*btlbprg)(int); 118 int (*hptinit)(vaddr_t, vsize_t); 119 }; 120 121 extern const struct hppa_cpu_info *hppa_cpu_info; 122 extern int cpu_modelno; 123 extern int cpu_revision; 124 #endif 125 #endif 126 127 /* 128 * COPR/SFUs 129 */ 130 #define HPPA_FPUS 0xc0 131 #define HPPA_PMSFUS 0x20 /* ??? */ 132 133 /* 134 * Exported definitions unique to hppa/PA-RISC cpu support. 135 */ 136 137 /* 138 * COPR/SFUs 139 */ 140 #define HPPA_FPUVER(w) (((w) & 0x003ff800) >> 11) 141 #define HPPA_FPU_OP(w) ((w) >> 26) 142 #define HPPA_FPU_UNMPL 0x01 /* exception reg, the rest is << 1 */ 143 #define HPPA_FPU_ILL 0x80 /* software-only */ 144 #define HPPA_FPU_I 0x01 145 #define HPPA_FPU_U 0x02 146 #define HPPA_FPU_O 0x04 147 #define HPPA_FPU_Z 0x08 148 #define HPPA_FPU_V 0x10 149 #define HPPA_FPU_D 0x20 150 #define HPPA_FPU_T 0x40 151 #define HPPA_FPU_XMASK 0x7f 152 #define HPPA_FPU_T_POS 25 153 #define HPPA_FPU_RM 0x00000600 154 #define HPPA_FPU_CQ 0x00fff800 155 #define HPPA_FPU_C 0x04000000 156 #define HPPA_FPU_FLSH 27 157 #define HPPA_FPU_INIT (0) 158 #define HPPA_FPU_FORK(s) ((s) & ~((uint64_t)(HPPA_FPU_XMASK) << 32)) 159 160 /* 161 * definitions of cpu-dependent requirements 162 * referenced in generic code 163 */ 164 #if defined(HP8000_CPU) || defined(HP8200_CPU) || \ 165 defined(HP8500_CPU) || defined(HP8600_CPU) 166 167 /* PA2.0 aliases */ 168 #define HPPA_PGALIAS 0x00400000 169 #define HPPA_PGAMASK 0xffc00000 /* PA bits 0-9 not used in index */ 170 #define HPPA_PGAOFF 0x003fffff 171 172 #else 173 174 /* PA1.x aliases */ 175 #define HPPA_PGALIAS 0x00100000 176 #define HPPA_PGAMASK 0xfff00000 /* PA bits 0-11 not used in index */ 177 #define HPPA_PGAOFF 0x000fffff 178 179 #endif 180 181 #define HPPA_SPAMASK 0xf0f0f000 /* PA bits 0-3,8-11,16-19 not used */ 182 183 #define HPPA_IOSPACE 0xf0000000 184 #define HPPA_IOLEN 0x10000000 185 #define HPPA_PDC_LOW 0xef000000 186 #define HPPA_PDC_HIGH 0xf1000000 187 #define HPPA_IOBCAST 0xfffc0000 188 #define HPPA_LBCAST 0xfffc0000 189 #define HPPA_GBCAST 0xfffe0000 190 #define HPPA_FPA 0xfff80000 191 #define HPPA_FLEX_DATA 0xfff80001 192 #define HPPA_DMA_ENABLE 0x00000001 193 #define HPPA_SPA_ENABLE 0x00000020 194 #define HPPA_NMODSPBUS 64 195 196 #ifdef MULTIPROCESSOR 197 198 #define GET_CURCPU(r) mfctl CR_CURCPU, r 199 #define GET_CURCPU_SPACE(s, r) GET_CURCPU(r) 200 #define GET_CURLWP(r) mfctl CR_CURCPU, r ! ldw CI_CURLWP(r), r 201 #define GET_CURLWP_SPACE(s, r) mfctl CR_CURCPU, r ! ldw CI_CURLWP(s, r), r 202 203 /* 204 * Issue barriers to coordinate mutex_exit on this CPU with 205 * mutex_vector_enter on another CPU. 206 * 207 * 1. Any prior mutex_exit by oldlwp must be visible to other 208 * CPUs before we set ci_curlwp := newlwp on this one, 209 * requiring a store-before-store barrier. 210 * 211 * 2. ci_curlwp := newlwp must be visible on all other CPUs 212 * before any subsequent mutex_exit by newlwp can even test 213 * whether there might be waiters, requiring a 214 * store-before-load barrier. 215 * 216 * See kern_mutex.c for details -- this is necessary for 217 * adaptive mutexes to detect whether the lwp is on the CPU in 218 * order to safely block without requiring atomic r/m/w in 219 * mutex_exit. 220 */ 221 #define SET_CURLWP(r,t) \ 222 sync ! mfctl CR_CURCPU, t ! stw r, CI_CURLWP(t) ! sync 223 224 #else /* MULTIPROCESSOR */ 225 226 #define GET_CURCPU(r) mfctl CR_CURLWP, r ! ldw L_CPU(r), r 227 #define GET_CURCPU_SPACE(s, r) mfctl CR_CURLWP, r ! ldw L_CPU(s, r), r 228 #define GET_CURLWP(r) mfctl CR_CURLWP, r 229 #define GET_CURLWP_SPACE(s, r) GET_CURLWP(r) 230 231 #define SET_CURLWP(r,t) mtctl r, CR_CURLWP 232 233 #endif /* MULTIPROCESSOR */ 234 235 #ifndef _LOCORE 236 #ifdef _KERNEL 237 238 /* 239 * External definitions unique to PA-RISC cpu support. 240 * These are the "public" declarations - those needed in 241 * machine-independent source code. The "private" ones 242 * are in machdep.h. 243 * 244 * Note that the name of this file is NOT meant to imply 245 * that it has anything to do with PA-RISC CPU stuff. 246 * The name "cpu" is historical, and used in the common 247 * code to identify machine-dependent functions, etc. 248 */ 249 250 /* clockframe describes the system before we took an interrupt. */ 251 struct clockframe { 252 int cf_flags; 253 int cf_spl; 254 u_int cf_pc; 255 }; 256 #define CLKF_PC(framep) ((framep)->cf_pc) 257 #define CLKF_INTR(framep) ((framep)->cf_flags & TFF_INTR) 258 #define CLKF_USERMODE(framep) ((framep)->cf_flags & T_USER) 259 260 int clock_intr(void *); 261 262 /* 263 * LWP_PC: the program counter for the given lwp. 264 */ 265 #define LWP_PC(l) ((l)->l_md.md_regs->tf_iioq_head) 266 267 #define cpu_signotify(l) (setsoftast(l)) 268 #define cpu_need_proftick(l) ((l)->l_pflag |= LP_OWEUPC, setsoftast(l)) 269 270 #endif /* _KERNEL */ 271 272 #ifndef __ASSEMBLER__ 273 #if defined(_KERNEL) || defined(_KMEMUSER) 274 275 #include <sys/cpu_data.h> 276 #include <sys/evcnt.h> 277 278 /* 279 * Note that the alignment of ci_trap_save is important since we want to keep 280 * it within a single cache line. As a result, it must be kept as the first 281 * entry within the cpu_info struct. 282 */ 283 struct cpu_info { 284 /* Keep this first to simplify the trap handlers */ 285 register_t ci_trapsave[16];/* the "phys" part of frame */ 286 287 struct cpu_data ci_data; /* MI per-cpu data */ 288 289 #ifndef _KMEMUSER 290 hppa_hpa_t ci_hpa; 291 register_t ci_psw; /* Processor Status Word. */ 292 paddr_t ci_fpu_state; /* LWP FPU state address, or zero. */ 293 u_long ci_itmr; 294 295 int ci_cpuid; /* CPU index (see cpus[] array) */ 296 int ci_mtx_count; 297 int ci_mtx_oldspl; 298 int ci_want_resched; 299 300 volatile int ci_cpl; 301 volatile int ci_ipending; /* The pending interrupts. */ 302 u_int ci_intr_depth; /* Nonzero iff running an interrupt. */ 303 u_int ci_ishared; 304 u_int ci_eiem; 305 306 u_int ci_imask[NIPL]; 307 308 struct hppa_interrupt_register ci_ir; 309 struct hppa_interrupt_bit ci_ib[HPPA_INTERRUPT_BITS]; 310 311 struct lwp *ci_onproc; /* current user LWP / kthread */ 312 #if defined(MULTIPROCESSOR) 313 struct lwp *ci_curlwp; /* CPU owner */ 314 paddr_t ci_stack; /* stack for spin up */ 315 volatile int ci_flags; /* CPU status flags */ 316 #define CPUF_PRIMARY 0x0001 /* ... is monarch/primary */ 317 #define CPUF_RUNNING 0x0002 /* ... is running. */ 318 319 volatile u_long ci_ipi; /* IPIs pending */ 320 321 struct cpu_softc *ci_softc; 322 #endif 323 #if defined(GPROF) && defined(MULTIPROCESSOR) 324 struct gmonparam *ci_gmon; /* MI per-cpu GPROF */ 325 #endif 326 #endif /* !_KMEMUSER */ 327 } __aligned(64); 328 329 #endif /* _KERNEL || _KMEMUSER */ 330 #endif /* __ASSEMBLER__ */ 331 332 #if defined(_KERNEL) 333 334 /* 335 * definitions of cpu-dependent requirements 336 * referenced in generic code 337 */ 338 339 void cpu_proc_fork(struct proc *, struct proc *); 340 341 struct lwp *hppa_curlwp(void); 342 struct cpu_info *hppa_curcpu(void); 343 344 #if defined(_MODULE) 345 #define curcpu() hppa_curcpu() 346 #define curlwp hppa_curlwp() 347 #endif 348 349 #if defined(MULTIPROCESSOR) || defined(_MODULE) 350 /* Number of CPUs in the system */ 351 extern int hppa_ncpu; 352 353 #define HPPA_MAXCPUS 4 354 355 #define cpu_number() (curcpu()->ci_cpuid) 356 357 #define CPU_IS_PRIMARY(ci) ((ci)->ci_cpuid == 0) 358 #define CPU_INFO_ITERATOR int 359 #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = &cpus[0]; cii < hppa_ncpu; cii++, ci++ 360 361 void cpu_boot_secondary_processors(void); 362 363 #if !defined(_MODULE) 364 static __inline __always_inline struct cpu_info * 365 _hppa_curcpu(void) 366 { 367 struct cpu_info *ci; 368 369 __asm volatile("mfctl %1, %0" : "=r" (ci): "i" (CR_CURCPU)); 370 371 return ci; 372 } 373 374 #define curcpu() _hppa_curcpu() 375 #endif 376 377 #else /* MULTIPROCESSOR */ 378 379 #define HPPA_MAXCPUS 1 380 #define curcpu() (&cpus[0]) 381 #define cpu_number() 0 382 383 static __inline struct lwp * 384 _hppa_curlwp(void) 385 { 386 struct lwp *l; 387 388 __asm volatile("mfctl %1, %0" : "=r" (l): "i" (CR_CURLWP)); 389 390 return l; 391 } 392 393 #define curlwp _hppa_curlwp() 394 395 #endif /* MULTIPROCESSOR */ 396 397 extern struct cpu_info cpus[HPPA_MAXCPUS]; 398 399 #define DELAY(x) delay(x) 400 401 static __inline paddr_t 402 kvtop(const void *va) 403 { 404 paddr_t pa; 405 406 __asm volatile ("lpa %%r0(%1), %0" : "=r" (pa) : "r" (va)); 407 return pa; 408 } 409 410 extern int (*cpu_desidhash)(void); 411 412 static __inline bool 413 hppa_cpu_ispa20_p(void) 414 { 415 416 return (hppa_cpu_info->hci_features & HPPA_FTRS_W32B) != 0; 417 } 418 419 static __inline bool 420 hppa_cpu_hastlbu_p(void) 421 { 422 423 return (hppa_cpu_info->hci_features & HPPA_FTRS_TLBU) != 0; 424 } 425 426 void delay(u_int); 427 void hppa_init(paddr_t, void *); 428 void trap(int, struct trapframe *); 429 void hppa_ras(struct lwp *); 430 int spcopy(pa_space_t, const void *, pa_space_t, void *, size_t); 431 int spstrcpy(pa_space_t, const void *, pa_space_t, void *, size_t, 432 size_t *); 433 int copy_on_fault(void); 434 void lwp_trampoline(void); 435 int cpu_dumpsize(void); 436 int cpu_dump(void); 437 438 #ifdef MULTIPROCESSOR 439 void cpu_boot_secondary_processors(void); 440 void cpu_hw_init(void); 441 void cpu_hatch(void); 442 #endif 443 #endif /* _KERNEL */ 444 445 /* 446 * Boot arguments stuff 447 */ 448 449 #define BOOTARG_LEN (PAGE_SIZE) 450 #define BOOTARG_OFF (0x10000) 451 452 /* 453 * CTL_MACHDEP definitions. 454 */ 455 #define CPU_CONSDEV 1 /* dev_t: console terminal device */ 456 #define CPU_BOOTED_KERNEL 2 /* string: booted kernel name */ 457 #define CPU_LCD_BLINK 3 /* int: twiddle heartbeat LED/LCD */ 458 459 #ifdef _KERNEL 460 #include <sys/queue.h> 461 462 struct blink_lcd { 463 void (*bl_func)(void *, int); 464 void *bl_arg; 465 SLIST_ENTRY(blink_lcd) bl_next; 466 }; 467 468 extern void blink_lcd_register(struct blink_lcd *); 469 #endif /* _KERNEL */ 470 #endif /* !_LOCORE */ 471 472 #endif /* _MACHINE_CPU_H_ */ 473