1 /* $NetBSD: machdep.c,v 1.328 2010/11/10 09:27:21 uebayasi Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center and by Chris G. Demetriou. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 35 * All rights reserved. 36 * 37 * Author: Chris G. Demetriou 38 * 39 * Permission to use, copy, modify and distribute this software and 40 * its documentation is hereby granted, provided that both the copyright 41 * notice and this permission notice appear in all copies of the 42 * software, derivative works or modified versions, and any portions 43 * thereof, and that both notices appear in supporting documentation. 44 * 45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 * 49 * Carnegie Mellon requests users of this software to return to 50 * 51 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 52 * School of Computer Science 53 * Carnegie Mellon University 54 * Pittsburgh PA 15213-3890 55 * 56 * any improvements or extensions that they make and grant Carnegie the 57 * rights to redistribute these changes. 58 */ 59 60 #include "opt_ddb.h" 61 #include "opt_kgdb.h" 62 #include "opt_modular.h" 63 #include "opt_multiprocessor.h" 64 #include "opt_dec_3000_300.h" 65 #include "opt_dec_3000_500.h" 66 #include "opt_compat_osf1.h" 67 #include "opt_execfmt.h" 68 69 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 70 71 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.328 2010/11/10 09:27:21 uebayasi Exp $"); 72 73 #include <sys/param.h> 74 #include <sys/systm.h> 75 #include <sys/signalvar.h> 76 #include <sys/kernel.h> 77 #include <sys/cpu.h> 78 #include <sys/proc.h> 79 #include <sys/ras.h> 80 #include <sys/sa.h> 81 #include <sys/savar.h> 82 #include <sys/sched.h> 83 #include <sys/reboot.h> 84 #include <sys/device.h> 85 #include <sys/malloc.h> 86 #include <sys/mman.h> 87 #include <sys/msgbuf.h> 88 #include <sys/ioctl.h> 89 #include <sys/tty.h> 90 #include <sys/exec.h> 91 #include <sys/exec_aout.h> /* for MID_* */ 92 #include <sys/exec_ecoff.h> 93 #include <sys/core.h> 94 #include <sys/kcore.h> 95 #include <sys/ucontext.h> 96 #include <sys/conf.h> 97 #include <sys/ksyms.h> 98 #include <sys/kauth.h> 99 #include <sys/atomic.h> 100 #include <sys/cpu.h> 101 102 #include <machine/kcore.h> 103 #include <machine/fpu.h> 104 105 #include <sys/mount.h> 106 #include <sys/syscallargs.h> 107 108 #include <uvm/uvm.h> 109 #include <sys/sysctl.h> 110 111 #include <dev/cons.h> 112 113 #include <machine/autoconf.h> 114 #include <machine/reg.h> 115 #include <machine/rpb.h> 116 #include <machine/prom.h> 117 #include <machine/cpuconf.h> 118 #include <machine/ieeefp.h> 119 120 #ifdef DDB 121 #include <machine/db_machdep.h> 122 #include <ddb/db_access.h> 123 #include <ddb/db_sym.h> 124 #include <ddb/db_extern.h> 125 #include <ddb/db_interface.h> 126 #endif 127 128 #ifdef KGDB 129 #include <sys/kgdb.h> 130 #endif 131 132 #ifdef DEBUG 133 #include <machine/sigdebug.h> 134 #endif 135 136 #include <machine/alpha.h> 137 138 #include "ksyms.h" 139 140 struct vm_map *phys_map = NULL; 141 142 void *msgbufaddr; 143 144 int maxmem; /* max memory per process */ 145 146 int totalphysmem; /* total amount of physical memory in system */ 147 int physmem; /* physical memory used by NetBSD + some rsvd */ 148 int resvmem; /* amount of memory reserved for PROM */ 149 int unusedmem; /* amount of memory for OS that we don't use */ 150 int unknownmem; /* amount of memory with an unknown use */ 151 152 int cputype; /* system type, from the RPB */ 153 154 int bootdev_debug = 0; /* patchable, or from DDB */ 155 156 /* 157 * XXX We need an address to which we can assign things so that they 158 * won't be optimized away because we didn't use the value. 159 */ 160 u_int32_t no_optimize; 161 162 /* the following is used externally (sysctl_hw) */ 163 char machine[] = MACHINE; /* from <machine/param.h> */ 164 char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */ 165 char cpu_model[128]; 166 167 /* Number of machine cycles per microsecond */ 168 u_int64_t cycles_per_usec; 169 170 /* number of CPUs in the box. really! */ 171 int ncpus; 172 173 struct bootinfo_kernel bootinfo; 174 175 /* For built-in TCDS */ 176 #if defined(DEC_3000_300) || defined(DEC_3000_500) 177 u_int8_t dec_3000_scsiid[2], dec_3000_scsifast[2]; 178 #endif 179 180 struct platform platform; 181 182 #if NKSYMS || defined(DDB) || defined(MODULAR) 183 /* start and end of kernel symbol table */ 184 void *ksym_start, *ksym_end; 185 #endif 186 187 /* for cpu_sysctl() */ 188 int alpha_unaligned_print = 1; /* warn about unaligned accesses */ 189 int alpha_unaligned_fix = 1; /* fix up unaligned accesses */ 190 int alpha_unaligned_sigbus = 0; /* don't SIGBUS on fixed-up accesses */ 191 int alpha_fp_sync_complete = 0; /* fp fixup if sync even without /s */ 192 193 /* 194 * XXX This should be dynamically sized, but we have the chicken-egg problem! 195 * XXX it should also be larger than it is, because not all of the mddt 196 * XXX clusters end up being used for VM. 197 */ 198 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; /* low size bits overloaded */ 199 int mem_cluster_cnt; 200 201 int cpu_dump(void); 202 int cpu_dumpsize(void); 203 u_long cpu_dump_mempagecnt(void); 204 void dumpsys(void); 205 void identifycpu(void); 206 void printregs(struct reg *); 207 208 void 209 alpha_init(u_long pfn, u_long ptb, u_long bim, u_long bip, u_long biv) 210 /* pfn: first free PFN number */ 211 /* ptb: PFN of current level 1 page table */ 212 /* bim: bootinfo magic */ 213 /* bip: bootinfo pointer */ 214 /* biv: bootinfo version */ 215 { 216 extern char kernel_text[], _end[]; 217 struct mddt *mddtp; 218 struct mddt_cluster *memc; 219 int i, mddtweird; 220 struct vm_physseg *vps; 221 struct pcb *pcb0; 222 vaddr_t kernstart, kernend, v; 223 paddr_t kernstartpfn, kernendpfn, pfn0, pfn1; 224 cpuid_t cpu_id; 225 struct cpu_info *ci; 226 char *p; 227 const char *bootinfo_msg; 228 const struct cpuinit *c; 229 230 /* NO OUTPUT ALLOWED UNTIL FURTHER NOTICE */ 231 232 /* 233 * Turn off interrupts (not mchecks) and floating point. 234 * Make sure the instruction and data streams are consistent. 235 */ 236 (void)alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH); 237 alpha_pal_wrfen(0); 238 ALPHA_TBIA(); 239 alpha_pal_imb(); 240 241 /* Initialize the SCB. */ 242 scb_init(); 243 244 cpu_id = cpu_number(); 245 246 #if defined(MULTIPROCESSOR) 247 /* 248 * Set our SysValue to the address of our cpu_info structure. 249 * Secondary processors do this in their spinup trampoline. 250 */ 251 alpha_pal_wrval((u_long)&cpu_info_primary); 252 cpu_info[cpu_id] = &cpu_info_primary; 253 #endif 254 255 ci = curcpu(); 256 ci->ci_cpuid = cpu_id; 257 258 /* 259 * Get critical system information (if possible, from the 260 * information provided by the boot program). 261 */ 262 bootinfo_msg = NULL; 263 if (bim == BOOTINFO_MAGIC) { 264 if (biv == 0) { /* backward compat */ 265 biv = *(u_long *)bip; 266 bip += 8; 267 } 268 switch (biv) { 269 case 1: { 270 struct bootinfo_v1 *v1p = (struct bootinfo_v1 *)bip; 271 272 bootinfo.ssym = v1p->ssym; 273 bootinfo.esym = v1p->esym; 274 /* hwrpb may not be provided by boot block in v1 */ 275 if (v1p->hwrpb != NULL) { 276 bootinfo.hwrpb_phys = 277 ((struct rpb *)v1p->hwrpb)->rpb_phys; 278 bootinfo.hwrpb_size = v1p->hwrpbsize; 279 } else { 280 bootinfo.hwrpb_phys = 281 ((struct rpb *)HWRPB_ADDR)->rpb_phys; 282 bootinfo.hwrpb_size = 283 ((struct rpb *)HWRPB_ADDR)->rpb_size; 284 } 285 memcpy(bootinfo.boot_flags, v1p->boot_flags, 286 min(sizeof v1p->boot_flags, 287 sizeof bootinfo.boot_flags)); 288 memcpy(bootinfo.booted_kernel, v1p->booted_kernel, 289 min(sizeof v1p->booted_kernel, 290 sizeof bootinfo.booted_kernel)); 291 /* booted dev not provided in bootinfo */ 292 init_prom_interface((struct rpb *) 293 ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys)); 294 prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev, 295 sizeof bootinfo.booted_dev); 296 break; 297 } 298 default: 299 bootinfo_msg = "unknown bootinfo version"; 300 goto nobootinfo; 301 } 302 } else { 303 bootinfo_msg = "boot program did not pass bootinfo"; 304 nobootinfo: 305 bootinfo.ssym = (u_long)_end; 306 bootinfo.esym = (u_long)_end; 307 bootinfo.hwrpb_phys = ((struct rpb *)HWRPB_ADDR)->rpb_phys; 308 bootinfo.hwrpb_size = ((struct rpb *)HWRPB_ADDR)->rpb_size; 309 init_prom_interface((struct rpb *)HWRPB_ADDR); 310 prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo.boot_flags, 311 sizeof bootinfo.boot_flags); 312 prom_getenv(PROM_E_BOOTED_FILE, bootinfo.booted_kernel, 313 sizeof bootinfo.booted_kernel); 314 prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev, 315 sizeof bootinfo.booted_dev); 316 } 317 318 /* 319 * Initialize the kernel's mapping of the RPB. It's needed for 320 * lots of things. 321 */ 322 hwrpb = (struct rpb *)ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys); 323 324 #if defined(DEC_3000_300) || defined(DEC_3000_500) 325 if (hwrpb->rpb_type == ST_DEC_3000_300 || 326 hwrpb->rpb_type == ST_DEC_3000_500) { 327 prom_getenv(PROM_E_SCSIID, dec_3000_scsiid, 328 sizeof(dec_3000_scsiid)); 329 prom_getenv(PROM_E_SCSIFAST, dec_3000_scsifast, 330 sizeof(dec_3000_scsifast)); 331 } 332 #endif 333 334 /* 335 * Remember how many cycles there are per microsecond, 336 * so that we can use delay(). Round up, for safety. 337 */ 338 cycles_per_usec = (hwrpb->rpb_cc_freq + 999999) / 1000000; 339 340 /* 341 * Initialize the (temporary) bootstrap console interface, so 342 * we can use printf until the VM system starts being setup. 343 * The real console is initialized before then. 344 */ 345 init_bootstrap_console(); 346 347 /* OUTPUT NOW ALLOWED */ 348 349 /* delayed from above */ 350 if (bootinfo_msg) 351 printf("WARNING: %s (0x%lx, 0x%lx, 0x%lx)\n", 352 bootinfo_msg, bim, bip, biv); 353 354 /* Initialize the trap vectors on the primary processor. */ 355 trap_init(); 356 357 /* 358 * Find out this system's page size, and initialize 359 * PAGE_SIZE-dependent variables. 360 */ 361 if (hwrpb->rpb_page_size != ALPHA_PGBYTES) 362 panic("page size %lu != %d?!", hwrpb->rpb_page_size, 363 ALPHA_PGBYTES); 364 uvmexp.pagesize = hwrpb->rpb_page_size; 365 uvm_setpagesize(); 366 367 /* 368 * Find out what hardware we're on, and do basic initialization. 369 */ 370 cputype = hwrpb->rpb_type; 371 if (cputype < 0) { 372 /* 373 * At least some white-box systems have SRM which 374 * reports a systype that's the negative of their 375 * blue-box counterpart. 376 */ 377 cputype = -cputype; 378 } 379 c = platform_lookup(cputype); 380 if (c == NULL) { 381 platform_not_supported(); 382 /* NOTREACHED */ 383 } 384 (*c->init)(); 385 strcpy(cpu_model, platform.model); 386 387 /* 388 * Initialize the real console, so that the bootstrap console is 389 * no longer necessary. 390 */ 391 (*platform.cons_init)(); 392 393 #ifdef DIAGNOSTIC 394 /* Paranoid sanity checking */ 395 396 /* We should always be running on the primary. */ 397 assert(hwrpb->rpb_primary_cpu_id == cpu_id); 398 399 /* 400 * On single-CPU systypes, the primary should always be CPU 0, 401 * except on Alpha 8200 systems where the CPU id is related 402 * to the VID, which is related to the Turbo Laser node id. 403 */ 404 if (cputype != ST_DEC_21000) 405 assert(hwrpb->rpb_primary_cpu_id == 0); 406 #endif 407 408 /* NO MORE FIRMWARE ACCESS ALLOWED */ 409 #ifdef _PMAP_MAY_USE_PROM_CONSOLE 410 /* 411 * XXX (unless _PMAP_MAY_USE_PROM_CONSOLE is defined and 412 * XXX pmap_uses_prom_console() evaluates to non-zero.) 413 */ 414 #endif 415 416 /* 417 * Find the beginning and end of the kernel (and leave a 418 * bit of space before the beginning for the bootstrap 419 * stack). 420 */ 421 kernstart = trunc_page((vaddr_t)kernel_text) - 2 * PAGE_SIZE; 422 #if NKSYMS || defined(DDB) || defined(MODULAR) 423 ksym_start = (void *)bootinfo.ssym; 424 ksym_end = (void *)bootinfo.esym; 425 kernend = (vaddr_t)round_page((vaddr_t)ksym_end); 426 #else 427 kernend = (vaddr_t)round_page((vaddr_t)_end); 428 #endif 429 430 kernstartpfn = atop(ALPHA_K0SEG_TO_PHYS(kernstart)); 431 kernendpfn = atop(ALPHA_K0SEG_TO_PHYS(kernend)); 432 433 /* 434 * Find out how much memory is available, by looking at 435 * the memory cluster descriptors. This also tries to do 436 * its best to detect things things that have never been seen 437 * before... 438 */ 439 mddtp = (struct mddt *)(((char *)hwrpb) + hwrpb->rpb_memdat_off); 440 441 /* MDDT SANITY CHECKING */ 442 mddtweird = 0; 443 if (mddtp->mddt_cluster_cnt < 2) { 444 mddtweird = 1; 445 printf("WARNING: weird number of mem clusters: %lu\n", 446 mddtp->mddt_cluster_cnt); 447 } 448 449 #if 0 450 printf("Memory cluster count: %d\n", mddtp->mddt_cluster_cnt); 451 #endif 452 453 for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { 454 memc = &mddtp->mddt_clusters[i]; 455 #if 0 456 printf("MEMC %d: pfn 0x%lx cnt 0x%lx usage 0x%lx\n", i, 457 memc->mddt_pfn, memc->mddt_pg_cnt, memc->mddt_usage); 458 #endif 459 totalphysmem += memc->mddt_pg_cnt; 460 if (mem_cluster_cnt < VM_PHYSSEG_MAX) { /* XXX */ 461 mem_clusters[mem_cluster_cnt].start = 462 ptoa(memc->mddt_pfn); 463 mem_clusters[mem_cluster_cnt].size = 464 ptoa(memc->mddt_pg_cnt); 465 if (memc->mddt_usage & MDDT_mbz || 466 memc->mddt_usage & MDDT_NONVOLATILE || /* XXX */ 467 memc->mddt_usage & MDDT_PALCODE) 468 mem_clusters[mem_cluster_cnt].size |= 469 PROT_READ; 470 else 471 mem_clusters[mem_cluster_cnt].size |= 472 PROT_READ | PROT_WRITE | PROT_EXEC; 473 mem_cluster_cnt++; 474 } 475 476 if (memc->mddt_usage & MDDT_mbz) { 477 mddtweird = 1; 478 printf("WARNING: mem cluster %d has weird " 479 "usage 0x%lx\n", i, memc->mddt_usage); 480 unknownmem += memc->mddt_pg_cnt; 481 continue; 482 } 483 if (memc->mddt_usage & MDDT_NONVOLATILE) { 484 /* XXX should handle these... */ 485 printf("WARNING: skipping non-volatile mem " 486 "cluster %d\n", i); 487 unusedmem += memc->mddt_pg_cnt; 488 continue; 489 } 490 if (memc->mddt_usage & MDDT_PALCODE) { 491 resvmem += memc->mddt_pg_cnt; 492 continue; 493 } 494 495 /* 496 * We have a memory cluster available for system 497 * software use. We must determine if this cluster 498 * holds the kernel. 499 */ 500 #ifdef _PMAP_MAY_USE_PROM_CONSOLE 501 /* 502 * XXX If the kernel uses the PROM console, we only use the 503 * XXX memory after the kernel in the first system segment, 504 * XXX to avoid clobbering prom mapping, data, etc. 505 */ 506 if (!pmap_uses_prom_console() || physmem == 0) { 507 #endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 508 physmem += memc->mddt_pg_cnt; 509 pfn0 = memc->mddt_pfn; 510 pfn1 = memc->mddt_pfn + memc->mddt_pg_cnt; 511 if (pfn0 <= kernstartpfn && kernendpfn <= pfn1) { 512 /* 513 * Must compute the location of the kernel 514 * within the segment. 515 */ 516 #if 0 517 printf("Cluster %d contains kernel\n", i); 518 #endif 519 #ifdef _PMAP_MAY_USE_PROM_CONSOLE 520 if (!pmap_uses_prom_console()) { 521 #endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 522 if (pfn0 < kernstartpfn) { 523 /* 524 * There is a chunk before the kernel. 525 */ 526 #if 0 527 printf("Loading chunk before kernel: " 528 "0x%lx / 0x%lx\n", pfn0, kernstartpfn); 529 #endif 530 uvm_page_physload(pfn0, kernstartpfn, 531 pfn0, kernstartpfn, VM_FREELIST_DEFAULT); 532 } 533 #ifdef _PMAP_MAY_USE_PROM_CONSOLE 534 } 535 #endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 536 if (kernendpfn < pfn1) { 537 /* 538 * There is a chunk after the kernel. 539 */ 540 #if 0 541 printf("Loading chunk after kernel: " 542 "0x%lx / 0x%lx\n", kernendpfn, pfn1); 543 #endif 544 uvm_page_physload(kernendpfn, pfn1, 545 kernendpfn, pfn1, VM_FREELIST_DEFAULT); 546 } 547 } else { 548 /* 549 * Just load this cluster as one chunk. 550 */ 551 #if 0 552 printf("Loading cluster %d: 0x%lx / 0x%lx\n", i, 553 pfn0, pfn1); 554 #endif 555 uvm_page_physload(pfn0, pfn1, pfn0, pfn1, 556 VM_FREELIST_DEFAULT); 557 } 558 #ifdef _PMAP_MAY_USE_PROM_CONSOLE 559 } 560 #endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 561 } 562 563 /* 564 * Dump out the MDDT if it looks odd... 565 */ 566 if (mddtweird) { 567 printf("\n"); 568 printf("complete memory cluster information:\n"); 569 for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { 570 printf("mddt %d:\n", i); 571 printf("\tpfn %lx\n", 572 mddtp->mddt_clusters[i].mddt_pfn); 573 printf("\tcnt %lx\n", 574 mddtp->mddt_clusters[i].mddt_pg_cnt); 575 printf("\ttest %lx\n", 576 mddtp->mddt_clusters[i].mddt_pg_test); 577 printf("\tbva %lx\n", 578 mddtp->mddt_clusters[i].mddt_v_bitaddr); 579 printf("\tbpa %lx\n", 580 mddtp->mddt_clusters[i].mddt_p_bitaddr); 581 printf("\tbcksum %lx\n", 582 mddtp->mddt_clusters[i].mddt_bit_cksum); 583 printf("\tusage %lx\n", 584 mddtp->mddt_clusters[i].mddt_usage); 585 } 586 printf("\n"); 587 } 588 589 if (totalphysmem == 0) 590 panic("can't happen: system seems to have no memory!"); 591 maxmem = physmem; 592 #if 0 593 printf("totalphysmem = %d\n", totalphysmem); 594 printf("physmem = %d\n", physmem); 595 printf("resvmem = %d\n", resvmem); 596 printf("unusedmem = %d\n", unusedmem); 597 printf("unknownmem = %d\n", unknownmem); 598 #endif 599 600 /* 601 * Initialize error message buffer (at end of core). 602 */ 603 { 604 vsize_t sz = (vsize_t)round_page(MSGBUFSIZE); 605 vsize_t reqsz = sz; 606 607 vps = VM_PHYSMEM_PTR(vm_nphysseg - 1); 608 609 /* shrink so that it'll fit in the last segment */ 610 if ((vps->avail_end - vps->avail_start) < atop(sz)) 611 sz = ptoa(vps->avail_end - vps->avail_start); 612 613 vps->end -= atop(sz); 614 vps->avail_end -= atop(sz); 615 msgbufaddr = (void *) ALPHA_PHYS_TO_K0SEG(ptoa(vps->end)); 616 initmsgbuf(msgbufaddr, sz); 617 618 /* Remove the last segment if it now has no pages. */ 619 if (vps->start == vps->end) 620 vm_nphysseg--; 621 622 /* warn if the message buffer had to be shrunk */ 623 if (sz != reqsz) 624 printf("WARNING: %ld bytes not available for msgbuf " 625 "in last cluster (%ld used)\n", reqsz, sz); 626 627 } 628 629 /* 630 * NOTE: It is safe to use uvm_pageboot_alloc() before 631 * pmap_bootstrap() because our pmap_virtual_space() 632 * returns compile-time constants. 633 */ 634 635 /* 636 * Allocate uarea page for lwp0 and set it. 637 */ 638 v = uvm_pageboot_alloc(UPAGES * PAGE_SIZE); 639 uvm_lwp_setuarea(&lwp0, v); 640 641 /* 642 * Initialize the virtual memory system, and set the 643 * page table base register in proc 0's PCB. 644 */ 645 pmap_bootstrap(ALPHA_PHYS_TO_K0SEG(ptb << PGSHIFT), 646 hwrpb->rpb_max_asn, hwrpb->rpb_pcs_cnt); 647 648 /* 649 * Initialize the rest of lwp0's PCB and cache its physical address. 650 */ 651 pcb0 = lwp_getpcb(&lwp0); 652 lwp0.l_md.md_pcbpaddr = (void *)ALPHA_K0SEG_TO_PHYS((vaddr_t)pcb0); 653 654 /* 655 * Set the kernel sp, reserving space for an (empty) trapframe, 656 * and make lwp0's trapframe pointer point to it for sanity. 657 */ 658 pcb0->pcb_hw.apcb_ksp = v + USPACE - sizeof(struct trapframe); 659 lwp0.l_md.md_tf = (struct trapframe *)pcb0->pcb_hw.apcb_ksp; 660 simple_lock_init(&pcb0->pcb_fpcpu_slock); 661 662 /* Indicate that lwp0 has a CPU. */ 663 lwp0.l_cpu = ci; 664 665 /* 666 * Look at arguments passed to us and compute boothowto. 667 */ 668 669 boothowto = RB_SINGLE; 670 #ifdef KADB 671 boothowto |= RB_KDB; 672 #endif 673 for (p = bootinfo.boot_flags; p && *p != '\0'; p++) { 674 /* 675 * Note that we'd really like to differentiate case here, 676 * but the Alpha AXP Architecture Reference Manual 677 * says that we shouldn't. 678 */ 679 switch (*p) { 680 case 'a': /* autoboot */ 681 case 'A': 682 boothowto &= ~RB_SINGLE; 683 break; 684 685 #ifdef DEBUG 686 case 'c': /* crash dump immediately after autoconfig */ 687 case 'C': 688 boothowto |= RB_DUMP; 689 break; 690 #endif 691 692 #if defined(KGDB) || defined(DDB) 693 case 'd': /* break into the kernel debugger ASAP */ 694 case 'D': 695 boothowto |= RB_KDB; 696 break; 697 #endif 698 699 case 'h': /* always halt, never reboot */ 700 case 'H': 701 boothowto |= RB_HALT; 702 break; 703 704 #if 0 705 case 'm': /* mini root present in memory */ 706 case 'M': 707 boothowto |= RB_MINIROOT; 708 break; 709 #endif 710 711 case 'n': /* askname */ 712 case 'N': 713 boothowto |= RB_ASKNAME; 714 break; 715 716 case 's': /* single-user (default, supported for sanity) */ 717 case 'S': 718 boothowto |= RB_SINGLE; 719 break; 720 721 case 'q': /* quiet boot */ 722 case 'Q': 723 boothowto |= AB_QUIET; 724 break; 725 726 case 'v': /* verbose boot */ 727 case 'V': 728 boothowto |= AB_VERBOSE; 729 break; 730 731 case '-': 732 /* 733 * Just ignore this. It's not required, but it's 734 * common for it to be passed regardless. 735 */ 736 break; 737 738 default: 739 printf("Unrecognized boot flag '%c'.\n", *p); 740 break; 741 } 742 } 743 744 /* 745 * Perform any initial kernel patches based on the running system. 746 * We may perform more later if we attach additional CPUs. 747 */ 748 alpha_patch(false); 749 750 /* 751 * Figure out the number of CPUs in the box, from RPB fields. 752 * Really. We mean it. 753 */ 754 for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { 755 struct pcs *pcsp; 756 757 pcsp = LOCATE_PCS(hwrpb, i); 758 if ((pcsp->pcs_flags & PCS_PP) != 0) 759 ncpus++; 760 } 761 762 /* 763 * Initialize debuggers, and break into them if appropriate. 764 */ 765 #if NKSYMS || defined(DDB) || defined(MODULAR) 766 ksyms_addsyms_elf((int)((u_int64_t)ksym_end - (u_int64_t)ksym_start), 767 ksym_start, ksym_end); 768 #endif 769 770 if (boothowto & RB_KDB) { 771 #if defined(KGDB) 772 kgdb_debug_init = 1; 773 kgdb_connect(1); 774 #elif defined(DDB) 775 Debugger(); 776 #endif 777 } 778 779 #ifdef DIAGNOSTIC 780 /* 781 * Check our clock frequency, from RPB fields. 782 */ 783 if ((hwrpb->rpb_intr_freq >> 12) != 1024) 784 printf("WARNING: unbelievable rpb_intr_freq: %ld (%d hz)\n", 785 hwrpb->rpb_intr_freq, hz); 786 #endif 787 } 788 789 void 790 consinit(void) 791 { 792 793 /* 794 * Everything related to console initialization is done 795 * in alpha_init(). 796 */ 797 #if defined(DIAGNOSTIC) && defined(_PMAP_MAY_USE_PROM_CONSOLE) 798 printf("consinit: %susing prom console\n", 799 pmap_uses_prom_console() ? "" : "not "); 800 #endif 801 } 802 803 void 804 cpu_startup(void) 805 { 806 vaddr_t minaddr, maxaddr; 807 char pbuf[9]; 808 #if defined(DEBUG) 809 extern int pmapdebug; 810 int opmapdebug = pmapdebug; 811 812 pmapdebug = 0; 813 #endif 814 815 /* 816 * Good {morning,afternoon,evening,night}. 817 */ 818 printf("%s%s", copyright, version); 819 identifycpu(); 820 format_bytes(pbuf, sizeof(pbuf), ptoa(totalphysmem)); 821 printf("total memory = %s\n", pbuf); 822 format_bytes(pbuf, sizeof(pbuf), ptoa(resvmem)); 823 printf("(%s reserved for PROM, ", pbuf); 824 format_bytes(pbuf, sizeof(pbuf), ptoa(physmem)); 825 printf("%s used by NetBSD)\n", pbuf); 826 if (unusedmem) { 827 format_bytes(pbuf, sizeof(pbuf), ptoa(unusedmem)); 828 printf("WARNING: unused memory = %s\n", pbuf); 829 } 830 if (unknownmem) { 831 format_bytes(pbuf, sizeof(pbuf), ptoa(unknownmem)); 832 printf("WARNING: %s of memory with unknown purpose\n", pbuf); 833 } 834 835 minaddr = 0; 836 837 /* 838 * Allocate a submap for physio 839 */ 840 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 841 VM_PHYS_SIZE, 0, false, NULL); 842 843 /* 844 * No need to allocate an mbuf cluster submap. Mbuf clusters 845 * are allocated via the pool allocator, and we use K0SEG to 846 * map those pages. 847 */ 848 849 #if defined(DEBUG) 850 pmapdebug = opmapdebug; 851 #endif 852 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 853 printf("avail memory = %s\n", pbuf); 854 #if 0 855 { 856 extern u_long pmap_pages_stolen; 857 858 format_bytes(pbuf, sizeof(pbuf), pmap_pages_stolen * PAGE_SIZE); 859 printf("stolen memory for VM structures = %s\n", pbuf); 860 } 861 #endif 862 863 /* 864 * Set up the HWPCB so that it's safe to configure secondary 865 * CPUs. 866 */ 867 hwrpb_primary_init(); 868 } 869 870 /* 871 * Retrieve the platform name from the DSR. 872 */ 873 const char * 874 alpha_dsr_sysname(void) 875 { 876 struct dsrdb *dsr; 877 const char *sysname; 878 879 /* 880 * DSR does not exist on early HWRPB versions. 881 */ 882 if (hwrpb->rpb_version < HWRPB_DSRDB_MINVERS) 883 return (NULL); 884 885 dsr = (struct dsrdb *)(((char *)hwrpb) + hwrpb->rpb_dsrdb_off); 886 sysname = (const char *)((char *)dsr + (dsr->dsr_sysname_off + 887 sizeof(u_int64_t))); 888 return (sysname); 889 } 890 891 /* 892 * Lookup the system specified system variation in the provided table, 893 * returning the model string on match. 894 */ 895 const char * 896 alpha_variation_name(u_int64_t variation, const struct alpha_variation_table *avtp) 897 { 898 int i; 899 900 for (i = 0; avtp[i].avt_model != NULL; i++) 901 if (avtp[i].avt_variation == variation) 902 return (avtp[i].avt_model); 903 return (NULL); 904 } 905 906 /* 907 * Generate a default platform name based for unknown system variations. 908 */ 909 const char * 910 alpha_unknown_sysname(void) 911 { 912 static char s[128]; /* safe size */ 913 914 sprintf(s, "%s family, unknown model variation 0x%lx", 915 platform.family, hwrpb->rpb_variation & SV_ST_MASK); 916 return ((const char *)s); 917 } 918 919 void 920 identifycpu(void) 921 { 922 char *s; 923 int i; 924 925 /* 926 * print out CPU identification information. 927 */ 928 printf("%s", cpu_model); 929 for(s = cpu_model; *s; ++s) 930 if(strncasecmp(s, "MHz", 3) == 0) 931 goto skipMHz; 932 printf(", %ldMHz", hwrpb->rpb_cc_freq / 1000000); 933 skipMHz: 934 printf(", s/n "); 935 for (i = 0; i < 10; i++) 936 printf("%c", hwrpb->rpb_ssn[i]); 937 printf("\n"); 938 printf("%ld byte page size, %d processor%s.\n", 939 hwrpb->rpb_page_size, ncpus, ncpus == 1 ? "" : "s"); 940 #if 0 941 /* this isn't defined for any systems that we run on? */ 942 printf("serial number 0x%lx 0x%lx\n", 943 ((long *)hwrpb->rpb_ssn)[0], ((long *)hwrpb->rpb_ssn)[1]); 944 945 /* and these aren't particularly useful! */ 946 printf("variation: 0x%lx, revision 0x%lx\n", 947 hwrpb->rpb_variation, *(long *)hwrpb->rpb_revision); 948 #endif 949 } 950 951 int waittime = -1; 952 struct pcb dumppcb; 953 954 void 955 cpu_reboot(int howto, char *bootstr) 956 { 957 #if defined(MULTIPROCESSOR) 958 u_long cpu_id = cpu_number(); 959 u_long wait_mask; 960 int i; 961 #endif 962 963 /* If "always halt" was specified as a boot flag, obey. */ 964 if ((boothowto & RB_HALT) != 0) 965 howto |= RB_HALT; 966 967 boothowto = howto; 968 969 /* If system is cold, just halt. */ 970 if (cold) { 971 boothowto |= RB_HALT; 972 goto haltsys; 973 } 974 975 if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 976 waittime = 0; 977 vfs_shutdown(); 978 /* 979 * If we've been adjusting the clock, the todr 980 * will be out of synch; adjust it now. 981 */ 982 resettodr(); 983 } 984 985 /* Disable interrupts. */ 986 splhigh(); 987 988 #if defined(MULTIPROCESSOR) 989 /* 990 * Halt all other CPUs. If we're not the primary, the 991 * primary will spin, waiting for us to halt. 992 */ 993 cpu_id = cpu_number(); /* may have changed cpu */ 994 wait_mask = (1UL << cpu_id) | (1UL << hwrpb->rpb_primary_cpu_id); 995 996 alpha_broadcast_ipi(ALPHA_IPI_HALT); 997 998 /* Ensure any CPUs paused by DDB resume execution so they can halt */ 999 cpus_paused = 0; 1000 1001 for (i = 0; i < 10000; i++) { 1002 alpha_mb(); 1003 if (cpus_running == wait_mask) 1004 break; 1005 delay(1000); 1006 } 1007 alpha_mb(); 1008 if (cpus_running != wait_mask) 1009 printf("WARNING: Unable to halt secondary CPUs (0x%lx)\n", 1010 cpus_running); 1011 #endif /* MULTIPROCESSOR */ 1012 1013 /* If rebooting and a dump is requested do it. */ 1014 #if 0 1015 if ((boothowto & (RB_DUMP | RB_HALT)) == RB_DUMP) 1016 #else 1017 if (boothowto & RB_DUMP) 1018 #endif 1019 dumpsys(); 1020 1021 haltsys: 1022 1023 /* run any shutdown hooks */ 1024 doshutdownhooks(); 1025 1026 pmf_system_shutdown(boothowto); 1027 1028 #ifdef BOOTKEY 1029 printf("hit any key to %s...\n", howto & RB_HALT ? "halt" : "reboot"); 1030 cnpollc(1); /* for proper keyboard command handling */ 1031 cngetc(); 1032 cnpollc(0); 1033 printf("\n"); 1034 #endif 1035 1036 /* Finally, powerdown/halt/reboot the system. */ 1037 if ((boothowto & RB_POWERDOWN) == RB_POWERDOWN && 1038 platform.powerdown != NULL) { 1039 (*platform.powerdown)(); 1040 printf("WARNING: powerdown failed!\n"); 1041 } 1042 printf("%s\n\n", (boothowto & RB_HALT) ? "halted." : "rebooting..."); 1043 #if defined(MULTIPROCESSOR) 1044 if (cpu_id != hwrpb->rpb_primary_cpu_id) 1045 cpu_halt(); 1046 else 1047 #endif 1048 prom_halt(boothowto & RB_HALT); 1049 /*NOTREACHED*/ 1050 } 1051 1052 /* 1053 * These variables are needed by /sbin/savecore 1054 */ 1055 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 1056 int dumpsize = 0; /* pages */ 1057 long dumplo = 0; /* blocks */ 1058 1059 /* 1060 * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers. 1061 */ 1062 int 1063 cpu_dumpsize(void) 1064 { 1065 int size; 1066 1067 size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) + 1068 ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t)); 1069 if (roundup(size, dbtob(1)) != dbtob(1)) 1070 return -1; 1071 1072 return (1); 1073 } 1074 1075 /* 1076 * cpu_dump_mempagecnt: calculate size of RAM (in pages) to be dumped. 1077 */ 1078 u_long 1079 cpu_dump_mempagecnt(void) 1080 { 1081 u_long i, n; 1082 1083 n = 0; 1084 for (i = 0; i < mem_cluster_cnt; i++) 1085 n += atop(mem_clusters[i].size); 1086 return (n); 1087 } 1088 1089 /* 1090 * cpu_dump: dump machine-dependent kernel core dump headers. 1091 */ 1092 int 1093 cpu_dump(void) 1094 { 1095 int (*dump)(dev_t, daddr_t, void *, size_t); 1096 char buf[dbtob(1)]; 1097 kcore_seg_t *segp; 1098 cpu_kcore_hdr_t *cpuhdrp; 1099 phys_ram_seg_t *memsegp; 1100 const struct bdevsw *bdev; 1101 int i; 1102 1103 bdev = bdevsw_lookup(dumpdev); 1104 if (bdev == NULL) 1105 return (ENXIO); 1106 dump = bdev->d_dump; 1107 1108 memset(buf, 0, sizeof buf); 1109 segp = (kcore_seg_t *)buf; 1110 cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))]; 1111 memsegp = (phys_ram_seg_t *)&buf[ ALIGN(sizeof(*segp)) + 1112 ALIGN(sizeof(*cpuhdrp))]; 1113 1114 /* 1115 * Generate a segment header. 1116 */ 1117 CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 1118 segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); 1119 1120 /* 1121 * Add the machine-dependent header info. 1122 */ 1123 cpuhdrp->lev1map_pa = ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map); 1124 cpuhdrp->page_size = PAGE_SIZE; 1125 cpuhdrp->nmemsegs = mem_cluster_cnt; 1126 1127 /* 1128 * Fill in the memory segment descriptors. 1129 */ 1130 for (i = 0; i < mem_cluster_cnt; i++) { 1131 memsegp[i].start = mem_clusters[i].start; 1132 memsegp[i].size = mem_clusters[i].size & ~PAGE_MASK; 1133 } 1134 1135 return (dump(dumpdev, dumplo, (void *)buf, dbtob(1))); 1136 } 1137 1138 /* 1139 * This is called by main to set dumplo and dumpsize. 1140 * Dumps always skip the first PAGE_SIZE of disk space 1141 * in case there might be a disk label stored there. 1142 * If there is extra space, put dump at the end to 1143 * reduce the chance that swapping trashes it. 1144 */ 1145 void 1146 cpu_dumpconf(void) 1147 { 1148 const struct bdevsw *bdev; 1149 int nblks, dumpblks; /* size of dump area */ 1150 1151 if (dumpdev == NODEV) 1152 goto bad; 1153 bdev = bdevsw_lookup(dumpdev); 1154 if (bdev == NULL) { 1155 dumpdev = NODEV; 1156 goto bad; 1157 } 1158 if (bdev->d_psize == NULL) 1159 goto bad; 1160 nblks = (*bdev->d_psize)(dumpdev); 1161 if (nblks <= ctod(1)) 1162 goto bad; 1163 1164 dumpblks = cpu_dumpsize(); 1165 if (dumpblks < 0) 1166 goto bad; 1167 dumpblks += ctod(cpu_dump_mempagecnt()); 1168 1169 /* If dump won't fit (incl. room for possible label), punt. */ 1170 if (dumpblks > (nblks - ctod(1))) 1171 goto bad; 1172 1173 /* Put dump at end of partition */ 1174 dumplo = nblks - dumpblks; 1175 1176 /* dumpsize is in page units, and doesn't include headers. */ 1177 dumpsize = cpu_dump_mempagecnt(); 1178 return; 1179 1180 bad: 1181 dumpsize = 0; 1182 return; 1183 } 1184 1185 /* 1186 * Dump the kernel's image to the swap partition. 1187 */ 1188 #define BYTES_PER_DUMP PAGE_SIZE 1189 1190 void 1191 dumpsys(void) 1192 { 1193 const struct bdevsw *bdev; 1194 u_long totalbytesleft, bytes, i, n, memcl; 1195 u_long maddr; 1196 int psize; 1197 daddr_t blkno; 1198 int (*dump)(dev_t, daddr_t, void *, size_t); 1199 int error; 1200 1201 /* Save registers. */ 1202 savectx(&dumppcb); 1203 1204 if (dumpdev == NODEV) 1205 return; 1206 bdev = bdevsw_lookup(dumpdev); 1207 if (bdev == NULL || bdev->d_psize == NULL) 1208 return; 1209 1210 /* 1211 * For dumps during autoconfiguration, 1212 * if dump device has already configured... 1213 */ 1214 if (dumpsize == 0) 1215 cpu_dumpconf(); 1216 if (dumplo <= 0) { 1217 printf("\ndump to dev %u,%u not possible\n", 1218 major(dumpdev), minor(dumpdev)); 1219 return; 1220 } 1221 printf("\ndumping to dev %u,%u offset %ld\n", 1222 major(dumpdev), minor(dumpdev), dumplo); 1223 1224 psize = (*bdev->d_psize)(dumpdev); 1225 printf("dump "); 1226 if (psize == -1) { 1227 printf("area unavailable\n"); 1228 return; 1229 } 1230 1231 /* XXX should purge all outstanding keystrokes. */ 1232 1233 if ((error = cpu_dump()) != 0) 1234 goto err; 1235 1236 totalbytesleft = ptoa(cpu_dump_mempagecnt()); 1237 blkno = dumplo + cpu_dumpsize(); 1238 dump = bdev->d_dump; 1239 error = 0; 1240 1241 for (memcl = 0; memcl < mem_cluster_cnt; memcl++) { 1242 maddr = mem_clusters[memcl].start; 1243 bytes = mem_clusters[memcl].size & ~PAGE_MASK; 1244 1245 for (i = 0; i < bytes; i += n, totalbytesleft -= n) { 1246 1247 /* Print out how many MBs we to go. */ 1248 if ((totalbytesleft % (1024*1024)) == 0) 1249 printf_nolog("%ld ", 1250 totalbytesleft / (1024 * 1024)); 1251 1252 /* Limit size for next transfer. */ 1253 n = bytes - i; 1254 if (n > BYTES_PER_DUMP) 1255 n = BYTES_PER_DUMP; 1256 1257 error = (*dump)(dumpdev, blkno, 1258 (void *)ALPHA_PHYS_TO_K0SEG(maddr), n); 1259 if (error) 1260 goto err; 1261 maddr += n; 1262 blkno += btodb(n); /* XXX? */ 1263 1264 /* XXX should look for keystrokes, to cancel. */ 1265 } 1266 } 1267 1268 err: 1269 switch (error) { 1270 1271 case ENXIO: 1272 printf("device bad\n"); 1273 break; 1274 1275 case EFAULT: 1276 printf("device not ready\n"); 1277 break; 1278 1279 case EINVAL: 1280 printf("area improper\n"); 1281 break; 1282 1283 case EIO: 1284 printf("i/o error\n"); 1285 break; 1286 1287 case EINTR: 1288 printf("aborted from console\n"); 1289 break; 1290 1291 case 0: 1292 printf("succeeded\n"); 1293 break; 1294 1295 default: 1296 printf("error %d\n", error); 1297 break; 1298 } 1299 printf("\n\n"); 1300 delay(1000); 1301 } 1302 1303 void 1304 frametoreg(const struct trapframe *framep, struct reg *regp) 1305 { 1306 1307 regp->r_regs[R_V0] = framep->tf_regs[FRAME_V0]; 1308 regp->r_regs[R_T0] = framep->tf_regs[FRAME_T0]; 1309 regp->r_regs[R_T1] = framep->tf_regs[FRAME_T1]; 1310 regp->r_regs[R_T2] = framep->tf_regs[FRAME_T2]; 1311 regp->r_regs[R_T3] = framep->tf_regs[FRAME_T3]; 1312 regp->r_regs[R_T4] = framep->tf_regs[FRAME_T4]; 1313 regp->r_regs[R_T5] = framep->tf_regs[FRAME_T5]; 1314 regp->r_regs[R_T6] = framep->tf_regs[FRAME_T6]; 1315 regp->r_regs[R_T7] = framep->tf_regs[FRAME_T7]; 1316 regp->r_regs[R_S0] = framep->tf_regs[FRAME_S0]; 1317 regp->r_regs[R_S1] = framep->tf_regs[FRAME_S1]; 1318 regp->r_regs[R_S2] = framep->tf_regs[FRAME_S2]; 1319 regp->r_regs[R_S3] = framep->tf_regs[FRAME_S3]; 1320 regp->r_regs[R_S4] = framep->tf_regs[FRAME_S4]; 1321 regp->r_regs[R_S5] = framep->tf_regs[FRAME_S5]; 1322 regp->r_regs[R_S6] = framep->tf_regs[FRAME_S6]; 1323 regp->r_regs[R_A0] = framep->tf_regs[FRAME_A0]; 1324 regp->r_regs[R_A1] = framep->tf_regs[FRAME_A1]; 1325 regp->r_regs[R_A2] = framep->tf_regs[FRAME_A2]; 1326 regp->r_regs[R_A3] = framep->tf_regs[FRAME_A3]; 1327 regp->r_regs[R_A4] = framep->tf_regs[FRAME_A4]; 1328 regp->r_regs[R_A5] = framep->tf_regs[FRAME_A5]; 1329 regp->r_regs[R_T8] = framep->tf_regs[FRAME_T8]; 1330 regp->r_regs[R_T9] = framep->tf_regs[FRAME_T9]; 1331 regp->r_regs[R_T10] = framep->tf_regs[FRAME_T10]; 1332 regp->r_regs[R_T11] = framep->tf_regs[FRAME_T11]; 1333 regp->r_regs[R_RA] = framep->tf_regs[FRAME_RA]; 1334 regp->r_regs[R_T12] = framep->tf_regs[FRAME_T12]; 1335 regp->r_regs[R_AT] = framep->tf_regs[FRAME_AT]; 1336 regp->r_regs[R_GP] = framep->tf_regs[FRAME_GP]; 1337 /* regp->r_regs[R_SP] = framep->tf_regs[FRAME_SP]; XXX */ 1338 regp->r_regs[R_ZERO] = 0; 1339 } 1340 1341 void 1342 regtoframe(const struct reg *regp, struct trapframe *framep) 1343 { 1344 1345 framep->tf_regs[FRAME_V0] = regp->r_regs[R_V0]; 1346 framep->tf_regs[FRAME_T0] = regp->r_regs[R_T0]; 1347 framep->tf_regs[FRAME_T1] = regp->r_regs[R_T1]; 1348 framep->tf_regs[FRAME_T2] = regp->r_regs[R_T2]; 1349 framep->tf_regs[FRAME_T3] = regp->r_regs[R_T3]; 1350 framep->tf_regs[FRAME_T4] = regp->r_regs[R_T4]; 1351 framep->tf_regs[FRAME_T5] = regp->r_regs[R_T5]; 1352 framep->tf_regs[FRAME_T6] = regp->r_regs[R_T6]; 1353 framep->tf_regs[FRAME_T7] = regp->r_regs[R_T7]; 1354 framep->tf_regs[FRAME_S0] = regp->r_regs[R_S0]; 1355 framep->tf_regs[FRAME_S1] = regp->r_regs[R_S1]; 1356 framep->tf_regs[FRAME_S2] = regp->r_regs[R_S2]; 1357 framep->tf_regs[FRAME_S3] = regp->r_regs[R_S3]; 1358 framep->tf_regs[FRAME_S4] = regp->r_regs[R_S4]; 1359 framep->tf_regs[FRAME_S5] = regp->r_regs[R_S5]; 1360 framep->tf_regs[FRAME_S6] = regp->r_regs[R_S6]; 1361 framep->tf_regs[FRAME_A0] = regp->r_regs[R_A0]; 1362 framep->tf_regs[FRAME_A1] = regp->r_regs[R_A1]; 1363 framep->tf_regs[FRAME_A2] = regp->r_regs[R_A2]; 1364 framep->tf_regs[FRAME_A3] = regp->r_regs[R_A3]; 1365 framep->tf_regs[FRAME_A4] = regp->r_regs[R_A4]; 1366 framep->tf_regs[FRAME_A5] = regp->r_regs[R_A5]; 1367 framep->tf_regs[FRAME_T8] = regp->r_regs[R_T8]; 1368 framep->tf_regs[FRAME_T9] = regp->r_regs[R_T9]; 1369 framep->tf_regs[FRAME_T10] = regp->r_regs[R_T10]; 1370 framep->tf_regs[FRAME_T11] = regp->r_regs[R_T11]; 1371 framep->tf_regs[FRAME_RA] = regp->r_regs[R_RA]; 1372 framep->tf_regs[FRAME_T12] = regp->r_regs[R_T12]; 1373 framep->tf_regs[FRAME_AT] = regp->r_regs[R_AT]; 1374 framep->tf_regs[FRAME_GP] = regp->r_regs[R_GP]; 1375 /* framep->tf_regs[FRAME_SP] = regp->r_regs[R_SP]; XXX */ 1376 /* ??? = regp->r_regs[R_ZERO]; */ 1377 } 1378 1379 void 1380 printregs(struct reg *regp) 1381 { 1382 int i; 1383 1384 for (i = 0; i < 32; i++) 1385 printf("R%d:\t0x%016lx%s", i, regp->r_regs[i], 1386 i & 1 ? "\n" : "\t"); 1387 } 1388 1389 void 1390 regdump(struct trapframe *framep) 1391 { 1392 struct reg reg; 1393 1394 frametoreg(framep, ®); 1395 reg.r_regs[R_SP] = alpha_pal_rdusp(); 1396 1397 printf("REGISTERS:\n"); 1398 printregs(®); 1399 } 1400 1401 1402 1403 void * 1404 getframe(const struct lwp *l, int sig, int *onstack) 1405 { 1406 void *frame; 1407 1408 /* Do we need to jump onto the signal stack? */ 1409 *onstack = 1410 (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 1411 (SIGACTION(l->l_proc, sig).sa_flags & SA_ONSTACK) != 0; 1412 1413 if (*onstack) 1414 frame = (void *)((char *)l->l_sigstk.ss_sp + 1415 l->l_sigstk.ss_size); 1416 else 1417 frame = (void *)(alpha_pal_rdusp()); 1418 return (frame); 1419 } 1420 1421 void 1422 buildcontext(struct lwp *l, const void *catcher, const void *tramp, const void *fp) 1423 { 1424 struct trapframe *tf = l->l_md.md_tf; 1425 1426 tf->tf_regs[FRAME_RA] = (u_int64_t)tramp; 1427 tf->tf_regs[FRAME_PC] = (u_int64_t)catcher; 1428 tf->tf_regs[FRAME_T12] = (u_int64_t)catcher; 1429 alpha_pal_wrusp((unsigned long)fp); 1430 } 1431 1432 1433 /* 1434 * Send an interrupt to process, new style 1435 */ 1436 void 1437 sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) 1438 { 1439 struct lwp *l = curlwp; 1440 struct proc *p = l->l_proc; 1441 struct sigacts *ps = p->p_sigacts; 1442 int onstack, sig = ksi->ksi_signo, error; 1443 struct sigframe_siginfo *fp, frame; 1444 struct trapframe *tf; 1445 sig_t catcher = SIGACTION(p, ksi->ksi_signo).sa_handler; 1446 1447 fp = (struct sigframe_siginfo *)getframe(l,ksi->ksi_signo,&onstack); 1448 tf = l->l_md.md_tf; 1449 1450 /* Allocate space for the signal handler context. */ 1451 fp--; 1452 1453 #ifdef DEBUG 1454 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1455 printf("sendsig_siginfo(%d): sig %d ssp %p usp %p\n", p->p_pid, 1456 sig, &onstack, fp); 1457 #endif 1458 1459 /* Build stack frame for signal trampoline. */ 1460 1461 frame.sf_si._info = ksi->ksi_info; 1462 frame.sf_uc.uc_flags = _UC_SIGMASK; 1463 frame.sf_uc.uc_sigmask = *mask; 1464 frame.sf_uc.uc_link = l->l_ctxlink; 1465 memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack)); 1466 sendsig_reset(l, sig); 1467 mutex_exit(p->p_lock); 1468 cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags); 1469 error = copyout(&frame, fp, sizeof(frame)); 1470 mutex_enter(p->p_lock); 1471 1472 if (error != 0) { 1473 /* 1474 * Process has trashed its stack; give it an illegal 1475 * instruction to halt it in its tracks. 1476 */ 1477 #ifdef DEBUG 1478 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1479 printf("sendsig_siginfo(%d): copyout failed on sig %d\n", 1480 p->p_pid, sig); 1481 #endif 1482 sigexit(l, SIGILL); 1483 /* NOTREACHED */ 1484 } 1485 1486 #ifdef DEBUG 1487 if (sigdebug & SDB_FOLLOW) 1488 printf("sendsig_siginfo(%d): sig %d usp %p code %x\n", 1489 p->p_pid, sig, fp, ksi->ksi_code); 1490 #endif 1491 1492 /* 1493 * Set up the registers to directly invoke the signal handler. The 1494 * signal trampoline is then used to return from the signal. Note 1495 * the trampoline version numbers are coordinated with machine- 1496 * dependent code in libc. 1497 */ 1498 1499 tf->tf_regs[FRAME_A0] = sig; 1500 tf->tf_regs[FRAME_A1] = (u_int64_t)&fp->sf_si; 1501 tf->tf_regs[FRAME_A2] = (u_int64_t)&fp->sf_uc; 1502 1503 buildcontext(l,catcher,ps->sa_sigdesc[sig].sd_tramp,fp); 1504 1505 /* Remember that we're now on the signal stack. */ 1506 if (onstack) 1507 l->l_sigstk.ss_flags |= SS_ONSTACK; 1508 1509 #ifdef DEBUG 1510 if (sigdebug & SDB_FOLLOW) 1511 printf("sendsig_siginfo(%d): pc %lx, catcher %lx\n", p->p_pid, 1512 tf->tf_regs[FRAME_PC], tf->tf_regs[FRAME_A3]); 1513 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1514 printf("sendsig_siginfo(%d): sig %d returns\n", 1515 p->p_pid, sig); 1516 #endif 1517 } 1518 1519 1520 void 1521 cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, void *sas, void *ap, void *sp, sa_upcall_t upcall) 1522 { 1523 struct trapframe *tf; 1524 1525 tf = l->l_md.md_tf; 1526 1527 tf->tf_regs[FRAME_PC] = (u_int64_t)upcall; 1528 tf->tf_regs[FRAME_RA] = 0; 1529 tf->tf_regs[FRAME_A0] = type; 1530 tf->tf_regs[FRAME_A1] = (u_int64_t)sas; 1531 tf->tf_regs[FRAME_A2] = nevents; 1532 tf->tf_regs[FRAME_A3] = ninterrupted; 1533 tf->tf_regs[FRAME_A4] = (u_int64_t)ap; 1534 tf->tf_regs[FRAME_T12] = (u_int64_t)upcall; /* t12 is pv */ 1535 alpha_pal_wrusp((unsigned long)sp); 1536 } 1537 1538 /* 1539 * machine dependent system variables. 1540 */ 1541 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 1542 { 1543 1544 sysctl_createv(clog, 0, NULL, NULL, 1545 CTLFLAG_PERMANENT, 1546 CTLTYPE_NODE, "machdep", NULL, 1547 NULL, 0, NULL, 0, 1548 CTL_MACHDEP, CTL_EOL); 1549 1550 sysctl_createv(clog, 0, NULL, NULL, 1551 CTLFLAG_PERMANENT, 1552 CTLTYPE_STRUCT, "console_device", NULL, 1553 sysctl_consdev, 0, NULL, sizeof(dev_t), 1554 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 1555 sysctl_createv(clog, 0, NULL, NULL, 1556 CTLFLAG_PERMANENT, 1557 CTLTYPE_STRING, "root_device", NULL, 1558 sysctl_root_device, 0, NULL, 0, 1559 CTL_MACHDEP, CPU_ROOT_DEVICE, CTL_EOL); 1560 sysctl_createv(clog, 0, NULL, NULL, 1561 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1562 CTLTYPE_INT, "unaligned_print", NULL, 1563 NULL, 0, &alpha_unaligned_print, 0, 1564 CTL_MACHDEP, CPU_UNALIGNED_PRINT, CTL_EOL); 1565 sysctl_createv(clog, 0, NULL, NULL, 1566 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1567 CTLTYPE_INT, "unaligned_fix", NULL, 1568 NULL, 0, &alpha_unaligned_fix, 0, 1569 CTL_MACHDEP, CPU_UNALIGNED_FIX, CTL_EOL); 1570 sysctl_createv(clog, 0, NULL, NULL, 1571 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1572 CTLTYPE_INT, "unaligned_sigbus", NULL, 1573 NULL, 0, &alpha_unaligned_sigbus, 0, 1574 CTL_MACHDEP, CPU_UNALIGNED_SIGBUS, CTL_EOL); 1575 sysctl_createv(clog, 0, NULL, NULL, 1576 CTLFLAG_PERMANENT, 1577 CTLTYPE_STRING, "booted_kernel", NULL, 1578 NULL, 0, bootinfo.booted_kernel, 0, 1579 CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL); 1580 sysctl_createv(clog, 0, NULL, NULL, 1581 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1582 CTLTYPE_INT, "fp_sync_complete", NULL, 1583 NULL, 0, &alpha_fp_sync_complete, 0, 1584 CTL_MACHDEP, CPU_FP_SYNC_COMPLETE, CTL_EOL); 1585 } 1586 1587 /* 1588 * Set registers on exec. 1589 */ 1590 void 1591 setregs(register struct lwp *l, struct exec_package *pack, vaddr_t stack) 1592 { 1593 struct trapframe *tfp = l->l_md.md_tf; 1594 struct pcb *pcb; 1595 #ifdef DEBUG 1596 int i; 1597 #endif 1598 1599 #ifdef DEBUG 1600 /* 1601 * Crash and dump, if the user requested it. 1602 */ 1603 if (boothowto & RB_DUMP) 1604 panic("crash requested by boot flags"); 1605 #endif 1606 1607 #ifdef DEBUG 1608 for (i = 0; i < FRAME_SIZE; i++) 1609 tfp->tf_regs[i] = 0xbabefacedeadbeef; 1610 #else 1611 memset(tfp->tf_regs, 0, FRAME_SIZE * sizeof tfp->tf_regs[0]); 1612 #endif 1613 pcb = lwp_getpcb(l); 1614 memset(&pcb->pcb_fp, 0, sizeof(pcb->pcb_fp)); 1615 alpha_pal_wrusp(stack); 1616 tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET; 1617 tfp->tf_regs[FRAME_PC] = pack->ep_entry & ~3; 1618 1619 tfp->tf_regs[FRAME_A0] = stack; /* a0 = sp */ 1620 tfp->tf_regs[FRAME_A1] = 0; /* a1 = rtld cleanup */ 1621 tfp->tf_regs[FRAME_A2] = 0; /* a2 = rtld object */ 1622 tfp->tf_regs[FRAME_A3] = (u_int64_t)l->l_proc->p_psstr; /* a3 = ps_strings */ 1623 tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */ 1624 1625 l->l_md.md_flags &= ~MDP_FPUSED; 1626 if (__predict_true((l->l_md.md_flags & IEEE_INHERIT) == 0)) { 1627 l->l_md.md_flags &= ~MDP_FP_C; 1628 pcb->pcb_fp.fpr_cr = FPCR_DYN(FP_RN); 1629 } 1630 if (pcb->pcb_fpcpu != NULL) 1631 fpusave_proc(l, 0); 1632 } 1633 1634 /* 1635 * Release the FPU. 1636 */ 1637 void 1638 fpusave_cpu(struct cpu_info *ci, int save) 1639 { 1640 struct lwp *l; 1641 struct pcb *pcb; 1642 #if defined(MULTIPROCESSOR) 1643 int s; 1644 #endif 1645 1646 KDASSERT(ci == curcpu()); 1647 1648 #if defined(MULTIPROCESSOR) 1649 s = splhigh(); /* block IPIs for the duration */ 1650 atomic_or_ulong(&ci->ci_flags, CPUF_FPUSAVE); 1651 #endif 1652 1653 l = ci->ci_fpcurlwp; 1654 if (l == NULL) 1655 goto out; 1656 1657 pcb = lwp_getpcb(l); 1658 if (save) { 1659 alpha_pal_wrfen(1); 1660 savefpstate(&pcb->pcb_fp); 1661 } 1662 1663 alpha_pal_wrfen(0); 1664 1665 FPCPU_LOCK(pcb); 1666 1667 pcb->pcb_fpcpu = NULL; 1668 ci->ci_fpcurlwp = NULL; 1669 1670 FPCPU_UNLOCK(pcb); 1671 1672 out: 1673 #if defined(MULTIPROCESSOR) 1674 atomic_and_ulong(&ci->ci_flags, ~CPUF_FPUSAVE); 1675 splx(s); 1676 #endif 1677 return; 1678 } 1679 1680 /* 1681 * Synchronize FP state for this process. 1682 */ 1683 void 1684 fpusave_proc(struct lwp *l, int save) 1685 { 1686 struct cpu_info *ci = curcpu(); 1687 struct cpu_info *oci; 1688 struct pcb *pcb; 1689 #if defined(MULTIPROCESSOR) 1690 u_long ipi = save ? ALPHA_IPI_SYNCH_FPU : ALPHA_IPI_DISCARD_FPU; 1691 int s, spincount; 1692 #endif 1693 1694 pcb = lwp_getpcb(l); 1695 KDASSERT(pcb != NULL); 1696 1697 #if defined(MULTIPROCESSOR) 1698 s = splhigh(); /* block IPIs for the duration */ 1699 #endif 1700 FPCPU_LOCK(pcb); 1701 1702 oci = pcb->pcb_fpcpu; 1703 if (oci == NULL) { 1704 FPCPU_UNLOCK(pcb); 1705 #if defined(MULTIPROCESSOR) 1706 splx(s); 1707 #endif 1708 return; 1709 } 1710 1711 #if defined(MULTIPROCESSOR) 1712 if (oci == ci) { 1713 KASSERT(ci->ci_fpcurlwp == l); 1714 FPCPU_UNLOCK(pcb); 1715 splx(s); 1716 fpusave_cpu(ci, save); 1717 return; 1718 } 1719 1720 KASSERT(oci->ci_fpcurlwp == l); 1721 alpha_send_ipi(oci->ci_cpuid, ipi); 1722 FPCPU_UNLOCK(pcb); 1723 1724 spincount = 0; 1725 while (pcb->pcb_fpcpu != NULL) { 1726 spincount++; 1727 delay(1000); /* XXX */ 1728 if (spincount > 10000) 1729 panic("fpsave ipi didn't"); 1730 } 1731 #else 1732 KASSERT(ci->ci_fpcurlwp == l); 1733 FPCPU_UNLOCK(pcb); 1734 fpusave_cpu(ci, save); 1735 #endif /* MULTIPROCESSOR */ 1736 } 1737 1738 /* 1739 * Wait "n" microseconds. 1740 */ 1741 void 1742 delay(unsigned long n) 1743 { 1744 unsigned long pcc0, pcc1, curcycle, cycles, usec; 1745 1746 if (n == 0) 1747 return; 1748 1749 pcc0 = alpha_rpcc() & 0xffffffffUL; 1750 cycles = 0; 1751 usec = 0; 1752 1753 while (usec <= n) { 1754 /* 1755 * Get the next CPU cycle count- assumes that we cannot 1756 * have had more than one 32 bit overflow. 1757 */ 1758 pcc1 = alpha_rpcc() & 0xffffffffUL; 1759 if (pcc1 < pcc0) 1760 curcycle = (pcc1 + 0x100000000UL) - pcc0; 1761 else 1762 curcycle = pcc1 - pcc0; 1763 1764 /* 1765 * We now have the number of processor cycles since we 1766 * last checked. Add the current cycle count to the 1767 * running total. If it's over cycles_per_usec, increment 1768 * the usec counter. 1769 */ 1770 cycles += curcycle; 1771 while (cycles > cycles_per_usec) { 1772 usec++; 1773 cycles -= cycles_per_usec; 1774 } 1775 pcc0 = pcc1; 1776 } 1777 } 1778 1779 #ifdef EXEC_ECOFF 1780 void 1781 cpu_exec_ecoff_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) 1782 { 1783 struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; 1784 1785 l->l_md.md_tf->tf_regs[FRAME_GP] = execp->a.gp_value; 1786 } 1787 1788 /* 1789 * cpu_exec_ecoff_hook(): 1790 * cpu-dependent ECOFF format hook for execve(). 1791 * 1792 * Do any machine-dependent diddling of the exec package when doing ECOFF. 1793 * 1794 */ 1795 int 1796 cpu_exec_ecoff_probe(struct lwp *l, struct exec_package *epp) 1797 { 1798 struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; 1799 int error; 1800 1801 if (execp->f.f_magic == ECOFF_MAGIC_NETBSD_ALPHA) 1802 error = 0; 1803 else 1804 error = ENOEXEC; 1805 1806 return (error); 1807 } 1808 #endif /* EXEC_ECOFF */ 1809 1810 int 1811 alpha_pa_access(u_long pa) 1812 { 1813 int i; 1814 1815 for (i = 0; i < mem_cluster_cnt; i++) { 1816 if (pa < mem_clusters[i].start) 1817 continue; 1818 if ((pa - mem_clusters[i].start) >= 1819 (mem_clusters[i].size & ~PAGE_MASK)) 1820 continue; 1821 return (mem_clusters[i].size & PAGE_MASK); /* prot */ 1822 } 1823 1824 /* 1825 * Address is not a memory address. If we're secure, disallow 1826 * access. Otherwise, grant read/write. 1827 */ 1828 if (kauth_authorize_machdep(kauth_cred_get(), 1829 KAUTH_MACHDEP_UNMANAGEDMEM, NULL, NULL, NULL, NULL) != 0) 1830 return (PROT_NONE); 1831 else 1832 return (PROT_READ | PROT_WRITE); 1833 } 1834 1835 /* XXX XXX BEGIN XXX XXX */ 1836 paddr_t alpha_XXX_dmamap_or; /* XXX */ 1837 /* XXX */ 1838 paddr_t /* XXX */ 1839 alpha_XXX_dmamap(v) /* XXX */ 1840 vaddr_t v; /* XXX */ 1841 { /* XXX */ 1842 /* XXX */ 1843 return (vtophys(v) | alpha_XXX_dmamap_or); /* XXX */ 1844 } /* XXX */ 1845 /* XXX XXX END XXX XXX */ 1846 1847 char * 1848 dot_conv(unsigned long x) 1849 { 1850 int i; 1851 char *xc; 1852 static int next; 1853 static char space[2][20]; 1854 1855 xc = space[next ^= 1] + sizeof space[0]; 1856 *--xc = '\0'; 1857 for (i = 0;; ++i) { 1858 if (i && (i & 3) == 0) 1859 *--xc = '.'; 1860 *--xc = hexdigits[x & 0xf]; 1861 x >>= 4; 1862 if (x == 0) 1863 break; 1864 } 1865 return xc; 1866 } 1867 1868 void 1869 cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags) 1870 { 1871 struct trapframe *frame = l->l_md.md_tf; 1872 struct pcb *pcb = lwp_getpcb(l); 1873 __greg_t *gr = mcp->__gregs; 1874 __greg_t ras_pc; 1875 1876 /* Save register context. */ 1877 frametoreg(frame, (struct reg *)gr); 1878 /* XXX if there's a better, general way to get the USP of 1879 * an LWP that might or might not be curlwp, I'd like to know 1880 * about it. 1881 */ 1882 if (l == curlwp) { 1883 gr[_REG_SP] = alpha_pal_rdusp(); 1884 gr[_REG_UNIQUE] = alpha_pal_rdunique(); 1885 } else { 1886 gr[_REG_SP] = pcb->pcb_hw.apcb_usp; 1887 gr[_REG_UNIQUE] = pcb->pcb_hw.apcb_unique; 1888 } 1889 gr[_REG_PC] = frame->tf_regs[FRAME_PC]; 1890 gr[_REG_PS] = frame->tf_regs[FRAME_PS]; 1891 1892 if ((ras_pc = (__greg_t)ras_lookup(l->l_proc, 1893 (void *) gr[_REG_PC])) != -1) 1894 gr[_REG_PC] = ras_pc; 1895 1896 *flags |= _UC_CPU | _UC_UNIQUE; 1897 1898 /* Save floating point register context, if any, and copy it. */ 1899 if (l->l_md.md_flags & MDP_FPUSED) { 1900 fpusave_proc(l, 1); 1901 (void)memcpy(&mcp->__fpregs, &pcb->pcb_fp, 1902 sizeof (mcp->__fpregs)); 1903 mcp->__fpregs.__fp_fpcr = alpha_read_fp_c(l); 1904 *flags |= _UC_FPU; 1905 } 1906 } 1907 1908 1909 int 1910 cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags) 1911 { 1912 struct trapframe *frame = l->l_md.md_tf; 1913 struct pcb *pcb = lwp_getpcb(l); 1914 const __greg_t *gr = mcp->__gregs; 1915 1916 /* Restore register context, if any. */ 1917 if (flags & _UC_CPU) { 1918 /* Check for security violations first. */ 1919 if ((gr[_REG_PS] & ALPHA_PSL_USERSET) != ALPHA_PSL_USERSET || 1920 (gr[_REG_PS] & ALPHA_PSL_USERCLR) != 0) 1921 return (EINVAL); 1922 1923 regtoframe((const struct reg *)gr, l->l_md.md_tf); 1924 if (l == curlwp) 1925 alpha_pal_wrusp(gr[_REG_SP]); 1926 else 1927 pcb->pcb_hw.apcb_usp = gr[_REG_SP]; 1928 frame->tf_regs[FRAME_PC] = gr[_REG_PC]; 1929 frame->tf_regs[FRAME_PS] = gr[_REG_PS]; 1930 } 1931 if (flags & _UC_UNIQUE) { 1932 if (l == curlwp) 1933 alpha_pal_wrunique(gr[_REG_UNIQUE]); 1934 else 1935 pcb->pcb_hw.apcb_unique = gr[_REG_UNIQUE]; 1936 } 1937 /* Restore floating point register context, if any. */ 1938 if (flags & _UC_FPU) { 1939 /* If we have an FP register context, get rid of it. */ 1940 if (pcb->pcb_fpcpu != NULL) 1941 fpusave_proc(l, 0); 1942 (void)memcpy(&pcb->pcb_fp, &mcp->__fpregs, 1943 sizeof (pcb->pcb_fp)); 1944 l->l_md.md_flags = mcp->__fpregs.__fp_fpcr & MDP_FP_C; 1945 l->l_md.md_flags |= MDP_FPUSED; 1946 } 1947 1948 return (0); 1949 } 1950 1951 /* 1952 * Preempt the current process if in interrupt from user mode, 1953 * or after the current trap/syscall if in system mode. 1954 */ 1955 void 1956 cpu_need_resched(struct cpu_info *ci, int flags) 1957 { 1958 #if defined(MULTIPROCESSOR) 1959 bool immed = (flags & RESCHED_IMMED) != 0; 1960 #endif /* defined(MULTIPROCESSOR) */ 1961 1962 aston(ci->ci_data.cpu_onproc); 1963 ci->ci_want_resched = 1; 1964 if (ci->ci_data.cpu_onproc != ci->ci_data.cpu_idlelwp) { 1965 #if defined(MULTIPROCESSOR) 1966 if (immed && ci != curcpu()) { 1967 alpha_send_ipi(ci->ci_cpuid, 0); 1968 } 1969 #endif /* defined(MULTIPROCESSOR) */ 1970 } 1971 } 1972