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