machdep.c revision 209975
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 209975 2010-07-13 05:32:19Z nwhitehorn $"); 59 60#include "opt_compat.h" 61#include "opt_ddb.h" 62#include "opt_kstack_pages.h" 63#include "opt_msgbuf.h" 64 65#include <sys/param.h> 66#include <sys/proc.h> 67#include <sys/systm.h> 68#include <sys/bio.h> 69#include <sys/buf.h> 70#include <sys/bus.h> 71#include <sys/cons.h> 72#include <sys/cpu.h> 73#include <sys/eventhandler.h> 74#include <sys/exec.h> 75#include <sys/imgact.h> 76#include <sys/kdb.h> 77#include <sys/kernel.h> 78#include <sys/ktr.h> 79#include <sys/linker.h> 80#include <sys/lock.h> 81#include <sys/malloc.h> 82#include <sys/mbuf.h> 83#include <sys/msgbuf.h> 84#include <sys/mutex.h> 85#include <sys/ptrace.h> 86#include <sys/reboot.h> 87#include <sys/signalvar.h> 88#include <sys/syscallsubr.h> 89#include <sys/sysctl.h> 90#include <sys/sysent.h> 91#include <sys/sysproto.h> 92#include <sys/ucontext.h> 93#include <sys/uio.h> 94#include <sys/vmmeter.h> 95#include <sys/vnode.h> 96 97#include <net/netisr.h> 98 99#include <vm/vm.h> 100#include <vm/vm_extern.h> 101#include <vm/vm_kern.h> 102#include <vm/vm_page.h> 103#include <vm/vm_map.h> 104#include <vm/vm_object.h> 105#include <vm/vm_pager.h> 106 107#include <machine/altivec.h> 108#ifndef __powerpc64__ 109#include <machine/bat.h> 110#endif 111#include <machine/cpu.h> 112#include <machine/elf.h> 113#include <machine/fpu.h> 114#include <machine/hid.h> 115#include <machine/kdb.h> 116#include <machine/md_var.h> 117#include <machine/metadata.h> 118#include <machine/mmuvar.h> 119#include <machine/pcb.h> 120#include <machine/reg.h> 121#include <machine/sigframe.h> 122#include <machine/spr.h> 123#include <machine/trap.h> 124#include <machine/vmparam.h> 125 126#include <ddb/ddb.h> 127 128#include <dev/ofw/openfirm.h> 129 130#ifdef DDB 131extern vm_offset_t ksym_start, ksym_end; 132#endif 133 134int cold = 1; 135#ifdef __powerpc64__ 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 162struct pmap ofw_pmap; 163 164#ifndef __powerpc64__ 165struct bat battable[16]; 166#endif 167 168struct kva_md_info kmi; 169 170static void 171powerpc_ofw_shutdown(void *junk, int howto) 172{ 173 if (howto & RB_HALT) { 174 OF_halt(); 175 } 176 OF_reboot(); 177} 178 179static void 180cpu_startup(void *dummy) 181{ 182 183 /* 184 * Initialise the decrementer-based clock. 185 */ 186 decr_init(); 187 188 /* 189 * Good {morning,afternoon,evening,night}. 190 */ 191 cpu_setup(PCPU_GET(cpuid)); 192 193#ifdef PERFMON 194 perfmon_init(); 195#endif 196 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 197 ptoa(physmem) / 1048576); 198 realmem = physmem; 199 200 if (bootverbose) 201 printf("available KVA = %zd (%zd MB)\n", 202 virtual_end - virtual_avail, 203 (virtual_end - virtual_avail) / 1048576); 204 205 /* 206 * Display any holes after the first chunk of extended memory. 207 */ 208 if (bootverbose) { 209 int indx; 210 211 printf("Physical memory chunk(s):\n"); 212 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 213 vm_offset_t size1 = 214 phys_avail[indx + 1] - phys_avail[indx]; 215 216 #ifdef __powerpc64__ 217 printf("0x%16lx - 0x%16lx, %ld bytes (%ld pages)\n", 218 #else 219 printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n", 220 #endif 221 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 222 size1 / PAGE_SIZE); 223 } 224 } 225 226 vm_ksubmap_init(&kmi); 227 228 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count), 229 ptoa(cnt.v_free_count) / 1048576); 230 231 /* 232 * Set up buffers, so they can be used to read disk labels. 233 */ 234 bufinit(); 235 vm_pager_bufferinit(); 236 237 EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0, 238 SHUTDOWN_PRI_LAST); 239} 240 241extern char kernel_text[], _end[]; 242 243#ifndef __powerpc64__ 244/* Bits for running on 64-bit systems in 32-bit mode. */ 245extern void *testppc64, *testppc64size; 246extern void *restorebridge, *restorebridgesize; 247extern void *rfid_patch, *rfi_patch1, *rfi_patch2; 248extern void *trapcode64; 249#endif 250 251#ifdef SMP 252extern void *rstcode, *rstsize; 253#endif 254extern void *trapcode, *trapsize; 255extern void *alitrap, *alisize; 256extern void *dsitrap, *dsisize; 257extern void *decrint, *decrsize; 258extern void *extint, *extsize; 259extern void *dblow, *dbsize; 260 261uintptr_t 262powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel, 263 vm_offset_t basekernel, void *mdp) 264{ 265 struct pcpu *pc; 266 vm_offset_t end; 267 void *generictrap; 268 size_t trap_offset; 269 void *kmdp; 270 char *env; 271 register_t msr, scratch; 272 uint8_t *cache_check; 273 #ifndef __powerpc64__ 274 int ppc64; 275 #endif 276 277 end = 0; 278 kmdp = NULL; 279 trap_offset = 0; 280 281 /* 282 * Parse metadata if present and fetch parameters. Must be done 283 * before console is inited so cninit gets the right value of 284 * boothowto. 285 */ 286 if (mdp != NULL) { 287 preload_metadata = mdp; 288 kmdp = preload_search_by_type("elf kernel"); 289 if (kmdp != NULL) { 290 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 291 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 292 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 293#ifdef DDB 294 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 295 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 296#endif 297 } 298 } 299 300 /* 301 * Init params/tunables that can be overridden by the loader 302 */ 303 init_param1(); 304 305 /* 306 * Start initializing proc0 and thread0. 307 */ 308 proc_linkup0(&proc0, &thread0); 309 thread0.td_frame = &frame0; 310 311 /* 312 * Set up per-cpu data. 313 */ 314 pc = __pcpu; 315 pcpu_init(pc, 0, sizeof(struct pcpu)); 316 pc->pc_curthread = &thread0; 317 pc->pc_cpuid = 0; 318 319 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 320 321 /* 322 * Init mutexes, which we use heavily in PMAP 323 */ 324 325 mutex_init(); 326 327 /* 328 * Install the OF client interface 329 */ 330 331 OF_bootstrap(); 332 333 /* 334 * Initialize the console before printing anything. 335 */ 336 cninit(); 337 338 /* 339 * Complain if there is no metadata. 340 */ 341 if (mdp == NULL || kmdp == NULL) { 342 printf("powerpc_init: no loader metadata.\n"); 343 } 344 345 /* 346 * Init KDB 347 */ 348 349 kdb_init(); 350 351 /* 352 * PowerPC 970 CPUs have a misfeature requested by Apple that makes 353 * them pretend they have a 32-byte cacheline. Turn this off 354 * before we measure the cacheline size. 355 */ 356 357 switch (mfpvr() >> 16) { 358 case IBM970: 359 case IBM970FX: 360 case IBM970MP: 361 case IBM970GX: 362 scratch = mfspr(SPR_HID5); 363 scratch &= ~HID5_970_DCBZ_SIZE_HI; 364 mtspr(SPR_HID5, scratch); 365 break; 366 } 367 368 /* 369 * Initialize the interrupt tables and figure out our cache line 370 * size and whether or not we need the 64-bit bridge code. 371 */ 372 373 /* 374 * Disable translation in case the vector area hasn't been 375 * mapped (G5). 376 */ 377 378 msr = mfmsr(); 379 mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI); 380 isync(); 381 382 /* 383 * Measure the cacheline size using dcbz 384 * 385 * Use EXC_PGM as a playground. We are about to overwrite it 386 * anyway, we know it exists, and we know it is cache-aligned. 387 */ 388 389 cache_check = (void *)EXC_PGM; 390 391 for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) 392 cache_check[cacheline_size] = 0xff; 393 394 __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); 395 396 /* Find the first byte dcbz did not zero to get the cache line size */ 397 for (cacheline_size = 0; cacheline_size < 0x100 && 398 cache_check[cacheline_size] == 0; cacheline_size++); 399 400 /* Work around psim bug */ 401 if (cacheline_size == 0) { 402 printf("WARNING: cacheline size undetermined, setting to 32\n"); 403 cacheline_size = 32; 404 } 405 406 #ifndef __powerpc64__ 407 /* 408 * Figure out whether we need to use the 64 bit PMAP. This works by 409 * executing an instruction that is only legal on 64-bit PPC (mtmsrd), 410 * and setting ppc64 = 0 if that causes a trap. 411 */ 412 413 ppc64 = 1; 414 415 bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size); 416 __syncicache((void *)EXC_PGM, (size_t)&testppc64size); 417 418 __asm __volatile("\ 419 mfmsr %0; \ 420 mtsprg2 %1; \ 421 \ 422 mtmsrd %0; \ 423 mfsprg2 %1;" 424 : "=r"(scratch), "=r"(ppc64)); 425 426 if (ppc64) 427 cpu_features |= PPC_FEATURE_64; 428 429 /* 430 * Now copy restorebridge into all the handlers, if necessary, 431 * and set up the trap tables. 432 */ 433 434 if (cpu_features & PPC_FEATURE_64) { 435 /* Patch the two instances of rfi -> rfid */ 436 bcopy(&rfid_patch,&rfi_patch1,4); 437 #ifdef KDB 438 /* rfi_patch2 is at the end of dbleave */ 439 bcopy(&rfid_patch,&rfi_patch2,4); 440 #endif 441 442 /* 443 * Copy a code snippet to restore 32-bit bridge mode 444 * to the top of every non-generic trap handler 445 */ 446 447 trap_offset += (size_t)&restorebridgesize; 448 bcopy(&restorebridge, (void *)EXC_RST, trap_offset); 449 bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); 450 bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); 451 bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); 452 bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); 453 bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); 454 bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); 455 456 /* 457 * Set the common trap entry point to the one that 458 * knows to restore 32-bit operation on execution. 459 */ 460 461 generictrap = &trapcode64; 462 } else { 463 generictrap = &trapcode; 464 } 465 466 #else /* powerpc64 */ 467 cpu_features |= PPC_FEATURE_64; 468 generictrap = &trapcode; 469 #endif 470 471#ifdef SMP 472 bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize); 473#else 474 bcopy(generictrap, (void *)EXC_RST, (size_t)&trapsize); 475#endif 476 477#ifdef KDB 478 bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize); 479 bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbsize); 480 bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbsize); 481 bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbsize); 482#else 483 bcopy(generictrap, (void *)EXC_MCHK, (size_t)&trapsize); 484 bcopy(generictrap, (void *)EXC_PGM, (size_t)&trapsize); 485 bcopy(generictrap, (void *)EXC_TRC, (size_t)&trapsize); 486 bcopy(generictrap, (void *)EXC_BPT, (size_t)&trapsize); 487#endif 488 bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&alisize); 489 bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsisize); 490 bcopy(generictrap, (void *)EXC_ISI, (size_t)&trapsize); 491 #ifdef __powerpc64__ 492 bcopy(generictrap, (void *)EXC_DSE, (size_t)&trapsize); 493 bcopy(generictrap, (void *)EXC_ISE, (size_t)&trapsize); 494 #endif 495 bcopy(generictrap, (void *)EXC_EXI, (size_t)&trapsize); 496 bcopy(generictrap, (void *)EXC_FPU, (size_t)&trapsize); 497 bcopy(generictrap, (void *)EXC_DECR, (size_t)&trapsize); 498 bcopy(generictrap, (void *)EXC_SC, (size_t)&trapsize); 499 bcopy(generictrap, (void *)EXC_FPA, (size_t)&trapsize); 500 bcopy(generictrap, (void *)EXC_VEC, (size_t)&trapsize); 501 bcopy(generictrap, (void *)EXC_VECAST, (size_t)&trapsize); 502 bcopy(generictrap, (void *)EXC_THRM, (size_t)&trapsize); 503 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 504 505 /* 506 * Restore MSR 507 */ 508 mtmsr(msr); 509 isync(); 510 511 /* 512 * Choose a platform module so we can get the physical memory map. 513 */ 514 515 platform_probe_and_attach(); 516 517 /* 518 * Initialise virtual memory. Use BUS_PROBE_GENERIC priority 519 * in case the platform module had a better idea of what we 520 * should do. 521 */ 522 if (cpu_features & PPC_FEATURE_64) 523 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); 524 else 525 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); 526 527 pmap_bootstrap(startkernel, endkernel); 528 mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI); 529 isync(); 530 531 /* 532 * Initialize params/tunables that are derived from memsize 533 */ 534 init_param2(physmem); 535 536 /* 537 * Grab booted kernel's name 538 */ 539 env = getenv("kernelname"); 540 if (env != NULL) { 541 strlcpy(kernelname, env, sizeof(kernelname)); 542 freeenv(env); 543 } 544 545 /* 546 * Finish setting up thread0. 547 */ 548 thread0.td_pcb = (struct pcb *) 549 ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - 550 sizeof(struct pcb)) & ~15UL); 551 bzero((void *)thread0.td_pcb, sizeof(struct pcb)); 552 pc->pc_curpcb = thread0.td_pcb; 553 554 /* Initialise the message buffer. */ 555 msgbufinit(msgbufp, MSGBUF_SIZE); 556 557#ifdef KDB 558 if (boothowto & RB_KDB) 559 kdb_enter(KDB_WHY_BOOTFLAGS, 560 "Boot flags requested debugger"); 561#endif 562 563 return (((uintptr_t)thread0.td_pcb - 564 (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL); 565} 566 567void 568bzero(void *buf, size_t len) 569{ 570 caddr_t p; 571 572 p = buf; 573 574 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 575 *p++ = 0; 576 len--; 577 } 578 579 while (len >= sizeof(u_long) * 8) { 580 *(u_long*) p = 0; 581 *((u_long*) p + 1) = 0; 582 *((u_long*) p + 2) = 0; 583 *((u_long*) p + 3) = 0; 584 len -= sizeof(u_long) * 8; 585 *((u_long*) p + 4) = 0; 586 *((u_long*) p + 5) = 0; 587 *((u_long*) p + 6) = 0; 588 *((u_long*) p + 7) = 0; 589 p += sizeof(u_long) * 8; 590 } 591 592 while (len >= sizeof(u_long)) { 593 *(u_long*) p = 0; 594 len -= sizeof(u_long); 595 p += sizeof(u_long); 596 } 597 598 while (len) { 599 *p++ = 0; 600 len--; 601 } 602} 603 604void 605cpu_boot(int howto) 606{ 607} 608 609/* 610 * Flush the D-cache for non-DMA I/O so that the I-cache can 611 * be made coherent later. 612 */ 613void 614cpu_flush_dcache(void *ptr, size_t len) 615{ 616 /* TBD */ 617} 618 619void 620cpu_initclocks(void) 621{ 622 623 decr_tc_init(); 624 stathz = hz; 625 profhz = hz; 626} 627 628/* 629 * Shutdown the CPU as much as possible. 630 */ 631void 632cpu_halt(void) 633{ 634 635 OF_exit(); 636} 637 638void 639cpu_idle(int busy) 640{ 641 register_t msr; 642 uint16_t vers; 643 644 msr = mfmsr(); 645 vers = mfpvr() >> 16; 646 647#ifdef INVARIANTS 648 if ((msr & PSL_EE) != PSL_EE) { 649 struct thread *td = curthread; 650 printf("td msr %#lx\n", (u_long)td->td_md.md_saved_msr); 651 panic("ints disabled in idleproc!"); 652 } 653#endif 654 if (powerpc_pow_enabled) { 655 switch (vers) { 656 case IBM970: 657 case IBM970FX: 658 case IBM970MP: 659 case MPC7447A: 660 case MPC7448: 661 case MPC7450: 662 case MPC7455: 663 case MPC7457: 664 __asm __volatile("\ 665 dssall; sync; mtmsr %0; isync" 666 :: "r"(msr | PSL_POW)); 667 break; 668 default: 669 powerpc_sync(); 670 mtmsr(msr | PSL_POW); 671 isync(); 672 break; 673 } 674 } 675} 676 677int 678cpu_idle_wakeup(int cpu) 679{ 680 681 return (0); 682} 683 684int 685ptrace_set_pc(struct thread *td, unsigned long addr) 686{ 687 struct trapframe *tf; 688 689 tf = td->td_frame; 690 tf->srr0 = (register_t)addr; 691 692 return (0); 693} 694 695int 696ptrace_single_step(struct thread *td) 697{ 698 struct trapframe *tf; 699 700 tf = td->td_frame; 701 tf->srr1 |= PSL_SE; 702 703 return (0); 704} 705 706int 707ptrace_clear_single_step(struct thread *td) 708{ 709 struct trapframe *tf; 710 711 tf = td->td_frame; 712 tf->srr1 &= ~PSL_SE; 713 714 return (0); 715} 716 717void 718kdb_cpu_clear_singlestep(void) 719{ 720 721 kdb_frame->srr1 &= ~PSL_SE; 722} 723 724void 725kdb_cpu_set_singlestep(void) 726{ 727 728 kdb_frame->srr1 |= PSL_SE; 729} 730 731/* 732 * Initialise a struct pcpu. 733 */ 734void 735cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 736{ 737#ifdef __powerpc64__ 738/* Copy the SLB contents from the current CPU */ 739memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb)); 740#endif 741} 742 743void 744spinlock_enter(void) 745{ 746 struct thread *td; 747 748 td = curthread; 749 if (td->td_md.md_spinlock_count == 0) 750 td->td_md.md_saved_msr = intr_disable(); 751 td->td_md.md_spinlock_count++; 752 critical_enter(); 753} 754 755void 756spinlock_exit(void) 757{ 758 struct thread *td; 759 760 td = curthread; 761 critical_exit(); 762 td->td_md.md_spinlock_count--; 763 if (td->td_md.md_spinlock_count == 0) 764 intr_restore(td->td_md.md_saved_msr); 765} 766 767/* 768 * kcopy(const void *src, void *dst, size_t len); 769 * 770 * Copy len bytes from src to dst, aborting if we encounter a fatal 771 * page fault. 772 * 773 * kcopy() _must_ save and restore the old fault handler since it is 774 * called by uiomove(), which may be in the path of servicing a non-fatal 775 * page fault. 776 */ 777int 778kcopy(const void *src, void *dst, size_t len) 779{ 780 struct thread *td; 781 faultbuf env, *oldfault; 782 int rv; 783 784 td = PCPU_GET(curthread); 785 oldfault = td->td_pcb->pcb_onfault; 786 if ((rv = setfault(env)) != 0) { 787 td->td_pcb->pcb_onfault = oldfault; 788 return rv; 789 } 790 791 memcpy(dst, src, len); 792 793 td->td_pcb->pcb_onfault = oldfault; 794 return (0); 795} 796 797int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */ 798 799int 800db_trap_glue(struct trapframe *frame) 801{ 802 if (!(frame->srr1 & PSL_PR) 803 && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC 804 || (frame->exc == EXC_PGM 805 && (frame->srr1 & 0x20000)) 806 || frame->exc == EXC_BPT 807 || frame->exc == EXC_DSI)) { 808 int type = frame->exc; 809 if (type == EXC_PGM && (frame->srr1 & 0x20000)) { 810 type = T_BREAKPOINT; 811 } 812 return (kdb_trap(type, 0, frame)); 813 } 814 815 return (0); 816} 817 818#ifndef __powerpc64__ 819 820uint64_t 821va_to_vsid(pmap_t pm, vm_offset_t va) 822{ 823 return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK); 824} 825 826#endif 827