machdep.c revision 228869
1/*- 2 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 3 * Copyright (C) 1995, 1996 TooLs GmbH. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by TooLs GmbH. 17 * 4. The name of TooLs GmbH may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31/*- 32 * Copyright (C) 2001 Benno Rice 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 55 */ 56 57#include <sys/cdefs.h> 58__FBSDID("$FreeBSD: head/sys/powerpc/aim/machdep.c 228869 2011-12-24 19:34:52Z jhibbits $"); 59 60#include "opt_compat.h" 61#include "opt_ddb.h" 62#include "opt_kstack_pages.h" 63 64#include <sys/param.h> 65#include <sys/proc.h> 66#include <sys/systm.h> 67#include <sys/bio.h> 68#include <sys/buf.h> 69#include <sys/bus.h> 70#include <sys/cons.h> 71#include <sys/cpu.h> 72#include <sys/eventhandler.h> 73#include <sys/exec.h> 74#include <sys/imgact.h> 75#include <sys/kdb.h> 76#include <sys/kernel.h> 77#include <sys/ktr.h> 78#include <sys/linker.h> 79#include <sys/lock.h> 80#include <sys/malloc.h> 81#include <sys/mbuf.h> 82#include <sys/msgbuf.h> 83#include <sys/mutex.h> 84#include <sys/ptrace.h> 85#include <sys/reboot.h> 86#include <sys/signalvar.h> 87#include <sys/syscallsubr.h> 88#include <sys/sysctl.h> 89#include <sys/sysent.h> 90#include <sys/sysproto.h> 91#include <sys/ucontext.h> 92#include <sys/uio.h> 93#include <sys/vmmeter.h> 94#include <sys/vnode.h> 95 96#include <net/netisr.h> 97 98#include <vm/vm.h> 99#include <vm/vm_extern.h> 100#include <vm/vm_kern.h> 101#include <vm/vm_page.h> 102#include <vm/vm_map.h> 103#include <vm/vm_object.h> 104#include <vm/vm_pager.h> 105 106#include <machine/altivec.h> 107#ifndef __powerpc64__ 108#include <machine/bat.h> 109#endif 110#include <machine/cpu.h> 111#include <machine/elf.h> 112#include <machine/fpu.h> 113#include <machine/hid.h> 114#include <machine/kdb.h> 115#include <machine/md_var.h> 116#include <machine/metadata.h> 117#include <machine/mmuvar.h> 118#include <machine/pcb.h> 119#include <machine/reg.h> 120#include <machine/sigframe.h> 121#include <machine/spr.h> 122#include <machine/trap.h> 123#include <machine/vmparam.h> 124 125#include <ddb/ddb.h> 126 127#include <dev/ofw/openfirm.h> 128 129#ifdef DDB 130extern vm_offset_t ksym_start, ksym_end; 131#endif 132 133int cold = 1; 134#ifdef __powerpc64__ 135extern int n_slbs; 136int cacheline_size = 128; 137#else 138int cacheline_size = 32; 139#endif 140int hw_direct_map = 1; 141 142struct pcpu __pcpu[MAXCPU]; 143 144static struct trapframe frame0; 145 146char machine[] = "powerpc"; 147SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 148 149static void cpu_startup(void *); 150SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 151 152SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 153 CTLFLAG_RD, &cacheline_size, 0, ""); 154 155uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *); 156 157int setfault(faultbuf); /* defined in locore.S */ 158 159long Maxmem = 0; 160long realmem = 0; 161 162#ifndef __powerpc64__ 163struct bat battable[16]; 164#endif 165 166struct kva_md_info kmi; 167 168static void 169cpu_startup(void *dummy) 170{ 171 172 /* 173 * Initialise the decrementer-based clock. 174 */ 175 decr_init(); 176 177 /* 178 * Good {morning,afternoon,evening,night}. 179 */ 180 cpu_setup(PCPU_GET(cpuid)); 181 182#ifdef PERFMON 183 perfmon_init(); 184#endif 185 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 186 ptoa(physmem) / 1048576); 187 realmem = physmem; 188 189 if (bootverbose) 190 printf("available KVA = %zd (%zd MB)\n", 191 virtual_end - virtual_avail, 192 (virtual_end - virtual_avail) / 1048576); 193 194 /* 195 * Display any holes after the first chunk of extended memory. 196 */ 197 if (bootverbose) { 198 int indx; 199 200 printf("Physical memory chunk(s):\n"); 201 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 202 vm_offset_t size1 = 203 phys_avail[indx + 1] - phys_avail[indx]; 204 205 #ifdef __powerpc64__ 206 printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n", 207 #else 208 printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n", 209 #endif 210 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 211 size1 / PAGE_SIZE); 212 } 213 } 214 215 vm_ksubmap_init(&kmi); 216 217 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count), 218 ptoa(cnt.v_free_count) / 1048576); 219 220 /* 221 * Set up buffers, so they can be used to read disk labels. 222 */ 223 bufinit(); 224 vm_pager_bufferinit(); 225} 226 227extern char kernel_text[], _end[]; 228 229#ifndef __powerpc64__ 230/* Bits for running on 64-bit systems in 32-bit mode. */ 231extern void *testppc64, *testppc64size; 232extern void *restorebridge, *restorebridgesize; 233extern void *rfid_patch, *rfi_patch1, *rfi_patch2; 234extern void *trapcode64; 235#endif 236 237#ifdef SMP 238extern void *rstcode, *rstsize; 239#endif 240extern void *trapcode, *trapsize; 241extern void *alitrap, *alisize; 242extern void *dsitrap, *dsisize; 243extern void *decrint, *decrsize; 244extern void *extint, *extsize; 245extern void *dblow, *dbsize; 246extern void *imisstrap, *imisssize; 247extern void *dlmisstrap, *dlmisssize; 248extern void *dsmisstrap, *dsmisssize; 249 250uintptr_t 251powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel, 252 vm_offset_t basekernel, void *mdp) 253{ 254 struct pcpu *pc; 255 void *generictrap; 256 size_t trap_offset; 257 void *kmdp; 258 char *env; 259 register_t msr, scratch; 260 uint8_t *cache_check; 261 int cacheline_warn; 262 #ifndef __powerpc64__ 263 int ppc64; 264 #endif 265 266 kmdp = NULL; 267 trap_offset = 0; 268 cacheline_warn = 0; 269 270 /* 271 * Parse metadata if present and fetch parameters. Must be done 272 * before console is inited so cninit gets the right value of 273 * boothowto. 274 */ 275 if (mdp != NULL) { 276 preload_metadata = mdp; 277 kmdp = preload_search_by_type("elf kernel"); 278 if (kmdp != NULL) { 279 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 280 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 281 endkernel = ulmax(endkernel, MD_FETCH(kmdp, 282 MODINFOMD_KERNEND, vm_offset_t)); 283#ifdef DDB 284 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 285 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 286#endif 287 } 288 } 289 290 /* 291 * Init params/tunables that can be overridden by the loader 292 */ 293 init_param1(); 294 295 /* 296 * Start initializing proc0 and thread0. 297 */ 298 proc_linkup0(&proc0, &thread0); 299 thread0.td_frame = &frame0; 300 301 /* 302 * Set up per-cpu data. 303 */ 304 pc = __pcpu; 305 pcpu_init(pc, 0, sizeof(struct pcpu)); 306 pc->pc_curthread = &thread0; 307#ifdef __powerpc64__ 308 __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread)); 309#else 310 __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread)); 311#endif 312 pc->pc_cpuid = 0; 313 314 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 315 316 /* 317 * Init mutexes, which we use heavily in PMAP 318 */ 319 320 mutex_init(); 321 322 /* 323 * Install the OF client interface 324 */ 325 326 OF_bootstrap(); 327 328 /* 329 * Initialize the console before printing anything. 330 */ 331 cninit(); 332 333 /* 334 * Complain if there is no metadata. 335 */ 336 if (mdp == NULL || kmdp == NULL) { 337 printf("powerpc_init: no loader metadata.\n"); 338 } 339 340 /* 341 * Init KDB 342 */ 343 344 kdb_init(); 345 346 /* Various very early CPU fix ups */ 347 switch (mfpvr() >> 16) { 348 /* 349 * PowerPC 970 CPUs have a misfeature requested by Apple that 350 * makes them pretend they have a 32-byte cacheline. Turn this 351 * off before we measure the cacheline size. 352 */ 353 case IBM970: 354 case IBM970FX: 355 case IBM970MP: 356 case IBM970GX: 357 scratch = mfspr(SPR_HID5); 358 scratch &= ~HID5_970_DCBZ_SIZE_HI; 359 mtspr(SPR_HID5, scratch); 360 break; 361 #ifdef __powerpc64__ 362 case IBMPOWER7: 363 /* XXX: get from ibm,slb-size in device tree */ 364 n_slbs = 32; 365 break; 366 #endif 367 } 368 369 /* 370 * Initialize the interrupt tables and figure out our cache line 371 * size and whether or not we need the 64-bit bridge code. 372 */ 373 374 /* 375 * Disable translation in case the vector area hasn't been 376 * mapped (G5). Note that no OFW calls can be made until 377 * translation is re-enabled. 378 */ 379 380 msr = mfmsr(); 381 mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI); 382 383 /* 384 * Measure the cacheline size using dcbz 385 * 386 * Use EXC_PGM as a playground. We are about to overwrite it 387 * anyway, we know it exists, and we know it is cache-aligned. 388 */ 389 390 cache_check = (void *)EXC_PGM; 391 392 for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) 393 cache_check[cacheline_size] = 0xff; 394 395 __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); 396 397 /* Find the first byte dcbz did not zero to get the cache line size */ 398 for (cacheline_size = 0; cacheline_size < 0x100 && 399 cache_check[cacheline_size] == 0; cacheline_size++); 400 401 /* Work around psim bug */ 402 if (cacheline_size == 0) { 403 cacheline_warn = 1; 404 cacheline_size = 32; 405 } 406 407 #ifndef __powerpc64__ 408 /* 409 * Figure out whether we need to use the 64 bit PMAP. This works by 410 * executing an instruction that is only legal on 64-bit PPC (mtmsrd), 411 * and setting ppc64 = 0 if that causes a trap. 412 */ 413 414 ppc64 = 1; 415 416 bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size); 417 __syncicache((void *)EXC_PGM, (size_t)&testppc64size); 418 419 __asm __volatile("\ 420 mfmsr %0; \ 421 mtsprg2 %1; \ 422 \ 423 mtmsrd %0; \ 424 mfsprg2 %1;" 425 : "=r"(scratch), "=r"(ppc64)); 426 427 if (ppc64) 428 cpu_features |= PPC_FEATURE_64; 429 430 /* 431 * Now copy restorebridge into all the handlers, if necessary, 432 * and set up the trap tables. 433 */ 434 435 if (cpu_features & PPC_FEATURE_64) { 436 /* Patch the two instances of rfi -> rfid */ 437 bcopy(&rfid_patch,&rfi_patch1,4); 438 #ifdef KDB 439 /* rfi_patch2 is at the end of dbleave */ 440 bcopy(&rfid_patch,&rfi_patch2,4); 441 #endif 442 443 /* 444 * Copy a code snippet to restore 32-bit bridge mode 445 * to the top of every non-generic trap handler 446 */ 447 448 trap_offset += (size_t)&restorebridgesize; 449 bcopy(&restorebridge, (void *)EXC_RST, trap_offset); 450 bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); 451 bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); 452 bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); 453 bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); 454 bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); 455 bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); 456 457 /* 458 * Set the common trap entry point to the one that 459 * knows to restore 32-bit operation on execution. 460 */ 461 462 generictrap = &trapcode64; 463 } else { 464 generictrap = &trapcode; 465 } 466 467 #else /* powerpc64 */ 468 cpu_features |= PPC_FEATURE_64; 469 generictrap = &trapcode; 470 #endif 471 472#ifdef SMP 473 bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize); 474#else 475 bcopy(generictrap, (void *)EXC_RST, (size_t)&trapsize); 476#endif 477 478#ifdef KDB 479 bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize); 480 bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbsize); 481 bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbsize); 482 bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbsize); 483#else 484 bcopy(generictrap, (void *)EXC_MCHK, (size_t)&trapsize); 485 bcopy(generictrap, (void *)EXC_PGM, (size_t)&trapsize); 486 bcopy(generictrap, (void *)EXC_TRC, (size_t)&trapsize); 487 bcopy(generictrap, (void *)EXC_BPT, (size_t)&trapsize); 488#endif 489 bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&alisize); 490 bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsisize); 491 bcopy(generictrap, (void *)EXC_ISI, (size_t)&trapsize); 492 #ifdef __powerpc64__ 493 bcopy(generictrap, (void *)EXC_DSE, (size_t)&trapsize); 494 bcopy(generictrap, (void *)EXC_ISE, (size_t)&trapsize); 495 #endif 496 bcopy(generictrap, (void *)EXC_EXI, (size_t)&trapsize); 497 bcopy(generictrap, (void *)EXC_FPU, (size_t)&trapsize); 498 bcopy(generictrap, (void *)EXC_DECR, (size_t)&trapsize); 499 bcopy(generictrap, (void *)EXC_SC, (size_t)&trapsize); 500 bcopy(generictrap, (void *)EXC_FPA, (size_t)&trapsize); 501 bcopy(generictrap, (void *)EXC_VEC, (size_t)&trapsize); 502 bcopy(generictrap, (void *)EXC_PERF, (size_t)&trapsize); 503 bcopy(generictrap, (void *)EXC_VECAST_G4, (size_t)&trapsize); 504 bcopy(generictrap, (void *)EXC_VECAST_G5, (size_t)&trapsize); 505 #ifndef __powerpc64__ 506 /* G2-specific TLB miss helper handlers */ 507 bcopy(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize); 508 bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize); 509 bcopy(&dsmisstrap, (void *)EXC_DSMISS, (size_t)&dsmisssize); 510 #endif 511 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 512 513 /* 514 * Restore MSR 515 */ 516 mtmsr(msr); 517 518 /* Warn if cachline size was not determined */ 519 if (cacheline_warn == 1) { 520 printf("WARNING: cacheline size undetermined, setting to 32\n"); 521 } 522 523 /* 524 * Choose a platform module so we can get the physical memory map. 525 */ 526 527 platform_probe_and_attach(); 528 529 /* 530 * Initialise virtual memory. Use BUS_PROBE_GENERIC priority 531 * in case the platform module had a better idea of what we 532 * should do. 533 */ 534 if (cpu_features & PPC_FEATURE_64) 535 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); 536 else 537 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); 538 539 pmap_bootstrap(startkernel, endkernel); 540 mtmsr(PSL_KERNSET & ~PSL_EE); 541 542 /* 543 * Initialize params/tunables that are derived from memsize 544 */ 545 init_param2(physmem); 546 547 /* 548 * Grab booted kernel's name 549 */ 550 env = getenv("kernelname"); 551 if (env != NULL) { 552 strlcpy(kernelname, env, sizeof(kernelname)); 553 freeenv(env); 554 } 555 556 /* 557 * Finish setting up thread0. 558 */ 559 thread0.td_pcb = (struct pcb *) 560 ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - 561 sizeof(struct pcb)) & ~15UL); 562 bzero((void *)thread0.td_pcb, sizeof(struct pcb)); 563 pc->pc_curpcb = thread0.td_pcb; 564 565 /* Initialise the message buffer. */ 566 msgbufinit(msgbufp, msgbufsize); 567 568#ifdef KDB 569 if (boothowto & RB_KDB) 570 kdb_enter(KDB_WHY_BOOTFLAGS, 571 "Boot flags requested debugger"); 572#endif 573 574 return (((uintptr_t)thread0.td_pcb - 575 (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL); 576} 577 578void 579bzero(void *buf, size_t len) 580{ 581 caddr_t p; 582 583 p = buf; 584 585 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 586 *p++ = 0; 587 len--; 588 } 589 590 while (len >= sizeof(u_long) * 8) { 591 *(u_long*) p = 0; 592 *((u_long*) p + 1) = 0; 593 *((u_long*) p + 2) = 0; 594 *((u_long*) p + 3) = 0; 595 len -= sizeof(u_long) * 8; 596 *((u_long*) p + 4) = 0; 597 *((u_long*) p + 5) = 0; 598 *((u_long*) p + 6) = 0; 599 *((u_long*) p + 7) = 0; 600 p += sizeof(u_long) * 8; 601 } 602 603 while (len >= sizeof(u_long)) { 604 *(u_long*) p = 0; 605 len -= sizeof(u_long); 606 p += sizeof(u_long); 607 } 608 609 while (len) { 610 *p++ = 0; 611 len--; 612 } 613} 614 615void 616cpu_boot(int howto) 617{ 618} 619 620/* 621 * Flush the D-cache for non-DMA I/O so that the I-cache can 622 * be made coherent later. 623 */ 624void 625cpu_flush_dcache(void *ptr, size_t len) 626{ 627 /* TBD */ 628} 629 630void 631cpu_initclocks(void) 632{ 633 634 decr_tc_init(); 635 cpu_initclocks_bsp(); 636} 637 638/* 639 * Shutdown the CPU as much as possible. 640 */ 641void 642cpu_halt(void) 643{ 644 645 OF_exit(); 646} 647 648int 649ptrace_set_pc(struct thread *td, unsigned long addr) 650{ 651 struct trapframe *tf; 652 653 tf = td->td_frame; 654 tf->srr0 = (register_t)addr; 655 656 return (0); 657} 658 659int 660ptrace_single_step(struct thread *td) 661{ 662 struct trapframe *tf; 663 664 tf = td->td_frame; 665 tf->srr1 |= PSL_SE; 666 667 return (0); 668} 669 670int 671ptrace_clear_single_step(struct thread *td) 672{ 673 struct trapframe *tf; 674 675 tf = td->td_frame; 676 tf->srr1 &= ~PSL_SE; 677 678 return (0); 679} 680 681void 682kdb_cpu_clear_singlestep(void) 683{ 684 685 kdb_frame->srr1 &= ~PSL_SE; 686} 687 688void 689kdb_cpu_set_singlestep(void) 690{ 691 692 kdb_frame->srr1 |= PSL_SE; 693} 694 695/* 696 * Initialise a struct pcpu. 697 */ 698void 699cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 700{ 701#ifdef __powerpc64__ 702/* Copy the SLB contents from the current CPU */ 703memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb)); 704#endif 705} 706 707void 708spinlock_enter(void) 709{ 710 struct thread *td; 711 register_t msr; 712 713 td = curthread; 714 if (td->td_md.md_spinlock_count == 0) { 715 msr = intr_disable(); 716 td->td_md.md_spinlock_count = 1; 717 td->td_md.md_saved_msr = msr; 718 } else 719 td->td_md.md_spinlock_count++; 720 critical_enter(); 721} 722 723void 724spinlock_exit(void) 725{ 726 struct thread *td; 727 register_t msr; 728 729 td = curthread; 730 critical_exit(); 731 msr = td->td_md.md_saved_msr; 732 td->td_md.md_spinlock_count--; 733 if (td->td_md.md_spinlock_count == 0) 734 intr_restore(msr); 735} 736 737/* 738 * kcopy(const void *src, void *dst, size_t len); 739 * 740 * Copy len bytes from src to dst, aborting if we encounter a fatal 741 * page fault. 742 * 743 * kcopy() _must_ save and restore the old fault handler since it is 744 * called by uiomove(), which may be in the path of servicing a non-fatal 745 * page fault. 746 */ 747int 748kcopy(const void *src, void *dst, size_t len) 749{ 750 struct thread *td; 751 faultbuf env, *oldfault; 752 int rv; 753 754 td = curthread; 755 oldfault = td->td_pcb->pcb_onfault; 756 if ((rv = setfault(env)) != 0) { 757 td->td_pcb->pcb_onfault = oldfault; 758 return rv; 759 } 760 761 memcpy(dst, src, len); 762 763 td->td_pcb->pcb_onfault = oldfault; 764 return (0); 765} 766 767int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */ 768 769int 770db_trap_glue(struct trapframe *frame) 771{ 772 if (!(frame->srr1 & PSL_PR) 773 && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC 774 || (frame->exc == EXC_PGM 775 && (frame->srr1 & 0x20000)) 776 || frame->exc == EXC_BPT 777 || frame->exc == EXC_DSI)) { 778 int type = frame->exc; 779 if (type == EXC_PGM && (frame->srr1 & 0x20000)) { 780 type = T_BREAKPOINT; 781 } 782 return (kdb_trap(type, 0, frame)); 783 } 784 785 return (0); 786} 787 788#ifndef __powerpc64__ 789 790uint64_t 791va_to_vsid(pmap_t pm, vm_offset_t va) 792{ 793 return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK); 794} 795 796#endif 797