machdep.c revision 144637
1/*- 2 * Copyright (c) 2001 Jake Burkholder. 3 * Copyright (c) 1992 Terrence R. Lambert. 4 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * William Jolitz. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 35 * from: FreeBSD: src/sys/i386/i386/machdep.c,v 1.477 2001/08/27 36 * $FreeBSD: head/sys/sparc64/sparc64/machdep.c 144637 2005-04-04 21:53:56Z jhb $ 37 */ 38 39#include "opt_compat.h" 40#include "opt_ddb.h" 41#include "opt_kstack_pages.h" 42#include "opt_msgbuf.h" 43 44#include <sys/param.h> 45#include <sys/malloc.h> 46#include <sys/proc.h> 47#include <sys/systm.h> 48#include <sys/bio.h> 49#include <sys/buf.h> 50#include <sys/bus.h> 51#include <sys/cpu.h> 52#include <sys/cons.h> 53#include <sys/eventhandler.h> 54#include <sys/exec.h> 55#include <sys/imgact.h> 56#include <sys/interrupt.h> 57#include <sys/kdb.h> 58#include <sys/kernel.h> 59#include <sys/ktr.h> 60#include <sys/linker.h> 61#include <sys/lock.h> 62#include <sys/msgbuf.h> 63#include <sys/mutex.h> 64#include <sys/pcpu.h> 65#include <sys/ptrace.h> 66#include <sys/reboot.h> 67#include <sys/signalvar.h> 68#include <sys/smp.h> 69#include <sys/sysent.h> 70#include <sys/sysproto.h> 71#include <sys/timetc.h> 72#include <sys/ucontext.h> 73 74#include <dev/ofw/openfirm.h> 75 76#include <vm/vm.h> 77#include <vm/vm_extern.h> 78#include <vm/vm_kern.h> 79#include <vm/vm_page.h> 80#include <vm/vm_map.h> 81#include <vm/vm_object.h> 82#include <vm/vm_pager.h> 83#include <vm/vm_param.h> 84 85#include <ddb/ddb.h> 86 87#include <machine/bus.h> 88#include <machine/cache.h> 89#include <machine/clock.h> 90#include <machine/cpu.h> 91#include <machine/fp.h> 92#include <machine/fsr.h> 93#include <machine/intr_machdep.h> 94#include <machine/md_var.h> 95#include <machine/metadata.h> 96#include <machine/ofw_machdep.h> 97#include <machine/ofw_mem.h> 98#include <machine/pcb.h> 99#include <machine/pmap.h> 100#include <machine/pstate.h> 101#include <machine/reg.h> 102#include <machine/sigframe.h> 103#include <machine/smp.h> 104#include <machine/tick.h> 105#include <machine/tlb.h> 106#include <machine/tstate.h> 107#include <machine/upa.h> 108#include <machine/ver.h> 109 110typedef int ofw_vec_t(void *); 111 112#ifdef DDB 113extern vm_offset_t ksym_start, ksym_end; 114#endif 115 116struct tlb_entry *kernel_tlbs; 117int kernel_tlb_slots; 118 119int cold = 1; 120long Maxmem; 121long realmem; 122 123char pcpu0[PCPU_PAGES * PAGE_SIZE]; 124struct trapframe frame0; 125 126vm_offset_t kstack0; 127vm_paddr_t kstack0_phys; 128 129struct kva_md_info kmi; 130 131u_long ofw_vec; 132u_long ofw_tba; 133 134/* 135 * Note: timer quality for CPU's is set low to try and prevent them from 136 * being chosen as the primary timecounter. The CPU counters are not 137 * synchronized among the CPU's so in MP machines this causes problems 138 * when calculating the time. With this value the CPU's should only be 139 * chosen as the primary timecounter as a last resort. 140 */ 141 142#define UP_TICK_QUALITY 1000 143#define MP_TICK_QUALITY -100 144static struct timecounter tick_tc; 145 146char sparc64_model[32]; 147 148static int cpu_use_vis = 1; 149 150cpu_block_copy_t *cpu_block_copy; 151cpu_block_zero_t *cpu_block_zero; 152 153static timecounter_get_t tick_get_timecount; 154void sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, 155 ofw_vec_t *vec); 156void sparc64_shutdown_final(void *dummy, int howto); 157 158static void cpu_startup(void *); 159SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 160 161CTASSERT((1 << INT_SHIFT) == sizeof(int)); 162CTASSERT((1 << PTR_SHIFT) == sizeof(char *)); 163 164CTASSERT(sizeof(struct reg) == 256); 165CTASSERT(sizeof(struct fpreg) == 272); 166CTASSERT(sizeof(struct __mcontext) == 512); 167 168CTASSERT((sizeof(struct pcb) & (64 - 1)) == 0); 169CTASSERT((offsetof(struct pcb, pcb_kfp) & (64 - 1)) == 0); 170CTASSERT((offsetof(struct pcb, pcb_ufp) & (64 - 1)) == 0); 171CTASSERT(sizeof(struct pcb) <= ((KSTACK_PAGES * PAGE_SIZE) / 8)); 172 173CTASSERT(sizeof(struct pcpu) <= ((PCPU_PAGES * PAGE_SIZE) / 2)); 174 175static void 176cpu_startup(void *arg) 177{ 178 vm_paddr_t physsz; 179 int i; 180 181 tick_tc.tc_get_timecount = tick_get_timecount; 182 tick_tc.tc_poll_pps = NULL; 183 tick_tc.tc_counter_mask = ~0u; 184 tick_tc.tc_frequency = tick_freq; 185 tick_tc.tc_name = "tick"; 186 tick_tc.tc_quality = UP_TICK_QUALITY; 187#ifdef SMP 188 /* 189 * We do not know if each CPU's tick counter is synchronized. 190 */ 191 if (cpu_mp_probe()) 192 tick_tc.tc_quality = MP_TICK_QUALITY; 193#endif 194 195 tc_init(&tick_tc); 196 197 physsz = 0; 198 for (i = 0; i < sparc64_nmemreg; i++) 199 physsz += sparc64_memreg[i].mr_size; 200 printf("real memory = %lu (%lu MB)\n", physsz, 201 physsz / (1024 * 1024)); 202 realmem = (long)physsz; 203 204 vm_ksubmap_init(&kmi); 205 206 bufinit(); 207 vm_pager_bufferinit(); 208 209 EVENTHANDLER_REGISTER(shutdown_final, sparc64_shutdown_final, NULL, 210 SHUTDOWN_PRI_LAST); 211 212 printf("avail memory = %lu (%lu MB)\n", cnt.v_free_count * PAGE_SIZE, 213 cnt.v_free_count / ((1024 * 1024) / PAGE_SIZE)); 214 215 if (bootverbose) 216 printf("machine: %s\n", sparc64_model); 217 218 cpu_identify(rdpr(ver), tick_freq, PCPU_GET(cpuid)); 219} 220 221void 222cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 223{ 224 struct intr_request *ir; 225 int i; 226 227 pcpu->pc_irtail = &pcpu->pc_irhead; 228 for (i = 0; i < IR_FREE; i++) { 229 ir = &pcpu->pc_irpool[i]; 230 ir->ir_next = pcpu->pc_irfree; 231 pcpu->pc_irfree = ir; 232 } 233} 234 235void 236spinlock_enter(void) 237{ 238 struct thread *td; 239 240 td = curthread; 241 if (td->td_md.md_spinlock_count == 0) { 242 td->td_md.md_saved_pil = rdpr(pil); 243 wrpr(pil, 0, 14); 244 } 245 td->td_md.md_spinlock_count++; 246 critical_enter(); 247} 248 249void 250spinlock_exit(void) 251{ 252 struct thread *td; 253 254 td = curthread; 255 critical_exit(); 256 td->td_md.md_spinlock_count--; 257 if (td->td_md.md_spinlock_count == 0) 258 wrpr(pil, td->td_md.md_saved_pil, 0); 259} 260 261unsigned 262tick_get_timecount(struct timecounter *tc) 263{ 264 return ((unsigned)rd(tick)); 265} 266 267void 268sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) 269{ 270 phandle_t child; 271 phandle_t root; 272 struct pcpu *pc; 273 vm_offset_t end; 274 caddr_t kmdp; 275 u_int clock; 276 char *env; 277 char type[8]; 278 279 end = 0; 280 kmdp = NULL; 281 282 /* 283 * Find out what kind of cpu we have first, for anything that changes 284 * behaviour. 285 */ 286 cpu_impl = VER_IMPL(rdpr(ver)); 287 288 /* 289 * Initialize Open Firmware (needed for console). 290 */ 291 OF_init(vec); 292 293 /* 294 * Parse metadata if present and fetch parameters. Must be before the 295 * console is inited so cninit gets the right value of boothowto. 296 */ 297 if (mdp != NULL) { 298 preload_metadata = mdp; 299 kmdp = preload_search_by_type("elf kernel"); 300 if (kmdp != NULL) { 301 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 302 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 303 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 304 kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS, 305 int); 306 kernel_tlbs = (void *)preload_search_info(kmdp, 307 MODINFO_METADATA | MODINFOMD_DTLB); 308 } 309 } 310 311 init_param1(); 312 313 root = OF_peer(0); 314 for (child = OF_child(root); child != 0; child = OF_peer(child)) { 315 OF_getprop(child, "device_type", type, sizeof(type)); 316 if (strcmp(type, "cpu") == 0) 317 break; 318 } 319 320 OF_getprop(child, "clock-frequency", &clock, sizeof(clock)); 321 tick_init(clock); 322 323 /* 324 * Initialize the console before printing anything. 325 */ 326 cninit(); 327 328 /* 329 * Panic is there is no metadata. Most likely the kernel was booted 330 * directly, instead of through loader(8). 331 */ 332 if (mdp == NULL || kmdp == NULL) { 333 printf("sparc64_init: no loader metadata.\n" 334 "This probably means you are not using loader(8).\n"); 335 panic("sparc64_init"); 336 } 337 338 /* 339 * Sanity check the kernel end, which is important. 340 */ 341 if (end == 0) { 342 printf("sparc64_init: warning, kernel end not specified.\n" 343 "Attempting to continue anyway.\n"); 344 end = (vm_offset_t)_end; 345 } 346 347 cache_init(child); 348 349 getenv_int("machdep.use_vis", &cpu_use_vis); 350 if (cpu_use_vis) { 351 cpu_block_copy = spitfire_block_copy; 352 cpu_block_zero = spitfire_block_zero; 353 } else { 354 cpu_block_copy = bcopy; 355 cpu_block_zero = bzero; 356 } 357 358#ifdef SMP 359 mp_tramp = mp_tramp_alloc(); 360#endif 361 362 /* 363 * Initialize virtual memory and calculate physmem. 364 */ 365 pmap_bootstrap(end); 366 367 /* 368 * Initialize tunables. 369 */ 370 init_param2(physmem); 371 env = getenv("kernelname"); 372 if (env != NULL) { 373 strlcpy(kernelname, env, sizeof(kernelname)); 374 freeenv(env); 375 } 376 377 /* 378 * Disable tick for now. 379 */ 380 tick_stop(); 381 382 /* 383 * Initialize the interrupt tables. 384 */ 385 intr_init1(); 386 387 /* 388 * Initialize proc0 stuff (p_contested needs to be done early). 389 */ 390 proc_linkup(&proc0, &ksegrp0, &thread0); 391 proc0.p_md.md_sigtramp = NULL; 392 proc0.p_md.md_utrap = NULL; 393 thread0.td_kstack = kstack0; 394 thread0.td_pcb = (struct pcb *) 395 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 396 frame0.tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_PRIV; 397 thread0.td_frame = &frame0; 398 399 /* 400 * Prime our per-cpu data page for use. Note, we are using it for our 401 * stack, so don't pass the real size (PAGE_SIZE) to pcpu_init or 402 * it'll zero it out from under us. 403 */ 404 pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; 405 pcpu_init(pc, 0, sizeof(struct pcpu)); 406 pc->pc_curthread = &thread0; 407 pc->pc_curpcb = thread0.td_pcb; 408 pc->pc_mid = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); 409 pc->pc_addr = (vm_offset_t)pcpu0; 410 pc->pc_node = child; 411 pc->pc_tlb_ctx = TLB_CTX_USER_MIN; 412 pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; 413 pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; 414 415 /* 416 * Initialize global registers. 417 */ 418 cpu_setregs(pc); 419 420 /* 421 * Initialize the message buffer (after setting trap table). 422 */ 423 msgbufinit(msgbufp, MSGBUF_SIZE); 424 425 mutex_init(); 426 intr_init2(); 427 428 /* 429 * Finish pmap initialization now that we're ready for mutexes. 430 */ 431 PMAP_LOCK_INIT(kernel_pmap); 432 433 OF_getprop(root, "name", sparc64_model, sizeof(sparc64_model) - 1); 434 435 kdb_init(); 436 437#ifdef KDB 438 if (boothowto & RB_KDB) 439 kdb_enter("Boot flags requested debugger"); 440#endif 441} 442 443void 444set_openfirm_callback(ofw_vec_t *vec) 445{ 446 ofw_tba = rdpr(tba); 447 ofw_vec = (u_long)vec; 448} 449 450void 451sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 452{ 453 struct trapframe *tf; 454 struct sigframe *sfp; 455 struct sigacts *psp; 456 struct sigframe sf; 457 struct thread *td; 458 struct frame *fp; 459 struct proc *p; 460 int oonstack; 461 u_long sp; 462 463 oonstack = 0; 464 td = curthread; 465 p = td->td_proc; 466 PROC_LOCK_ASSERT(p, MA_OWNED); 467 psp = p->p_sigacts; 468 mtx_assert(&psp->ps_mtx, MA_OWNED); 469 tf = td->td_frame; 470 sp = tf->tf_sp + SPOFF; 471 oonstack = sigonstack(sp); 472 473 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 474 catcher, sig); 475 476 /* Make sure we have a signal trampoline to return to. */ 477 if (p->p_md.md_sigtramp == NULL) { 478 /* 479 * No signal tramoline... kill the process. 480 */ 481 CTR0(KTR_SIG, "sendsig: no sigtramp"); 482 printf("sendsig: %s is too old, rebuild it\n", p->p_comm); 483 sigexit(td, sig); 484 /* NOTREACHED */ 485 } 486 487 /* Save user context. */ 488 bzero(&sf, sizeof(sf)); 489 get_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 490 sf.sf_uc.uc_sigmask = *mask; 491 sf.sf_uc.uc_stack = td->td_sigstk; 492 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 493 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 494 495 /* Allocate and validate space for the signal handler context. */ 496 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 497 SIGISMEMBER(psp->ps_sigonstack, sig)) { 498 sfp = (struct sigframe *)(td->td_sigstk.ss_sp + 499 td->td_sigstk.ss_size - sizeof(struct sigframe)); 500 } else 501 sfp = (struct sigframe *)sp - 1; 502 mtx_unlock(&psp->ps_mtx); 503 PROC_UNLOCK(p); 504 505 fp = (struct frame *)sfp - 1; 506 507 /* Translate the signal if appropriate. */ 508 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 509 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 510 511 /* Build the argument list for the signal handler. */ 512 tf->tf_out[0] = sig; 513 tf->tf_out[1] = (register_t)&sfp->sf_si; 514 tf->tf_out[2] = (register_t)&sfp->sf_uc; 515 tf->tf_out[4] = (register_t)catcher; 516 /* Fill siginfo structure. */ 517 sf.sf_si.si_signo = sig; 518 sf.sf_si.si_code = code; 519 sf.sf_si.si_addr = (void *)tf->tf_sfar; 520 521 /* Copy the sigframe out to the user's stack. */ 522 if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 || 523 suword(&fp->fr_in[6], tf->tf_out[6]) != 0) { 524 /* 525 * Something is wrong with the stack pointer. 526 * ...Kill the process. 527 */ 528 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 529 PROC_LOCK(p); 530 sigexit(td, SIGILL); 531 /* NOTREACHED */ 532 } 533 534 tf->tf_tpc = (u_long)p->p_md.md_sigtramp; 535 tf->tf_tnpc = tf->tf_tpc + 4; 536 tf->tf_sp = (u_long)fp - SPOFF; 537 538 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, 539 tf->tf_sp); 540 541 PROC_LOCK(p); 542 mtx_lock(&psp->ps_mtx); 543} 544 545/* 546 * Build siginfo_t for SA thread 547 */ 548void 549cpu_thread_siginfo(int sig, u_long code, siginfo_t *si) 550{ 551 struct proc *p; 552 struct thread *td; 553 554 td = curthread; 555 p = td->td_proc; 556 PROC_LOCK_ASSERT(p, MA_OWNED); 557 558 bzero(si, sizeof(*si)); 559 si->si_signo = sig; 560 si->si_code = code; 561 /* XXXKSE fill other fields */ 562} 563 564#ifndef _SYS_SYSPROTO_H_ 565struct sigreturn_args { 566 ucontext_t *ucp; 567}; 568#endif 569 570/* 571 * MPSAFE 572 */ 573int 574sigreturn(struct thread *td, struct sigreturn_args *uap) 575{ 576 struct proc *p; 577 mcontext_t *mc; 578 ucontext_t uc; 579 int error; 580 581 p = td->td_proc; 582 if (rwindow_save(td)) { 583 PROC_LOCK(p); 584 sigexit(td, SIGILL); 585 } 586 587 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 588 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 589 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 590 return (EFAULT); 591 } 592 593 mc = &uc.uc_mcontext; 594 error = set_mcontext(td, mc); 595 if (error != 0) 596 return (error); 597 598 PROC_LOCK(p); 599 td->td_sigmask = uc.uc_sigmask; 600 SIG_CANTMASK(td->td_sigmask); 601 signotify(td); 602 PROC_UNLOCK(p); 603 604 CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", 605 td, mc->mc_tpc, mc->mc_sp, mc->mc_tstate); 606 return (EJUSTRETURN); 607} 608 609#ifdef COMPAT_FREEBSD4 610int 611freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 612{ 613 614 return sigreturn(td, (struct sigreturn_args *)uap); 615} 616#endif 617 618/* 619 * Construct a PCB from a trapframe. This is called from kdb_trap() where 620 * we want to start a backtrace from the function that caused us to enter 621 * the debugger. We have the context in the trapframe, but base the trace 622 * on the PCB. The PCB doesn't have to be perfect, as long as it contains 623 * enough for a backtrace. 624 */ 625void 626makectx(struct trapframe *tf, struct pcb *pcb) 627{ 628 629 pcb->pcb_pc = tf->tf_tpc; 630 pcb->pcb_sp = tf->tf_sp; 631} 632 633int 634get_mcontext(struct thread *td, mcontext_t *mc, int flags) 635{ 636 struct trapframe *tf; 637 struct pcb *pcb; 638 639 tf = td->td_frame; 640 pcb = td->td_pcb; 641 bcopy(tf, mc, sizeof(*tf)); 642 if (flags & GET_MC_CLEAR_RET) { 643 mc->mc_out[0] = 0; 644 mc->mc_out[1] = 0; 645 } 646 mc->mc_flags = _MC_VERSION; 647 critical_enter(); 648 if ((tf->tf_fprs & FPRS_FEF) != 0) { 649 savefpctx(pcb->pcb_ufp); 650 tf->tf_fprs &= ~FPRS_FEF; 651 pcb->pcb_flags |= PCB_FEF; 652 } 653 if ((pcb->pcb_flags & PCB_FEF) != 0) { 654 bcopy(pcb->pcb_ufp, mc->mc_fp, sizeof(mc->mc_fp)); 655 mc->mc_fprs |= FPRS_FEF; 656 } 657 critical_exit(); 658 return (0); 659} 660 661int 662set_mcontext(struct thread *td, const mcontext_t *mc) 663{ 664 struct trapframe *tf; 665 struct pcb *pcb; 666 uint64_t wstate; 667 668 if (!TSTATE_SECURE(mc->mc_tstate) || 669 (mc->mc_flags & ((1L << _MC_VERSION_BITS) - 1)) != _MC_VERSION) 670 return (EINVAL); 671 tf = td->td_frame; 672 pcb = td->td_pcb; 673 /* Make sure the windows are spilled first. */ 674 flushw(); 675 wstate = tf->tf_wstate; 676 bcopy(mc, tf, sizeof(*tf)); 677 tf->tf_wstate = wstate; 678 if ((mc->mc_fprs & FPRS_FEF) != 0) { 679 tf->tf_fprs = 0; 680 bcopy(mc->mc_fp, pcb->pcb_ufp, sizeof(pcb->pcb_ufp)); 681 pcb->pcb_flags |= PCB_FEF; 682 } 683 return (0); 684} 685 686/* 687 * Exit the kernel and execute a firmware call that will not return, as 688 * specified by the arguments. 689 */ 690void 691cpu_shutdown(void *args) 692{ 693 694#ifdef SMP 695 cpu_mp_shutdown(); 696#endif 697 openfirmware_exit(args); 698} 699 700/* Get current clock frequency for the given cpu id. */ 701int 702cpu_est_clockrate(int cpu_id, uint64_t *rate) 703{ 704 705 return (ENXIO); 706} 707 708/* 709 * Duplicate OF_exit() with a different firmware call function that restores 710 * the trap table, otherwise a RED state exception is triggered in at least 711 * some firmware versions. 712 */ 713void 714cpu_halt(void) 715{ 716 static struct { 717 cell_t name; 718 cell_t nargs; 719 cell_t nreturns; 720 } args = { 721 (cell_t)"exit", 722 0, 723 0 724 }; 725 726 cpu_shutdown(&args); 727} 728 729void 730sparc64_shutdown_final(void *dummy, int howto) 731{ 732 static struct { 733 cell_t name; 734 cell_t nargs; 735 cell_t nreturns; 736 } args = { 737 (cell_t)"SUNW,power-off", 738 0, 739 0 740 }; 741 742 /* Turn the power off? */ 743 if ((howto & RB_POWEROFF) != 0) 744 cpu_shutdown(&args); 745 /* In case of halt, return to the firmware */ 746 if ((howto & RB_HALT) != 0) 747 cpu_halt(); 748} 749 750void 751cpu_idle(void) 752{ 753 /* Insert code to halt (until next interrupt) for the idle loop */ 754} 755 756int 757ptrace_set_pc(struct thread *td, u_long addr) 758{ 759 760 td->td_frame->tf_tpc = addr; 761 td->td_frame->tf_tnpc = addr + 4; 762 return (0); 763} 764 765int 766ptrace_single_step(struct thread *td) 767{ 768 /* TODO; */ 769 return (0); 770} 771 772int 773ptrace_clear_single_step(struct thread *td) 774{ 775 /* TODO; */ 776 return (0); 777} 778 779void 780exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 781{ 782 struct trapframe *tf; 783 struct pcb *pcb; 784 struct proc *p; 785 u_long sp; 786 787 /* XXX no cpu_exec */ 788 p = td->td_proc; 789 p->p_md.md_sigtramp = NULL; 790 if (p->p_md.md_utrap != NULL) { 791 utrap_free(p->p_md.md_utrap); 792 p->p_md.md_utrap = NULL; 793 } 794 795 pcb = td->td_pcb; 796 tf = td->td_frame; 797 sp = rounddown(stack, 16); 798 bzero(pcb, sizeof(*pcb)); 799 bzero(tf, sizeof(*tf)); 800 tf->tf_out[0] = stack; 801 tf->tf_out[3] = p->p_sysent->sv_psstrings; 802 tf->tf_out[6] = sp - SPOFF - sizeof(struct frame); 803 tf->tf_tnpc = entry + 4; 804 tf->tf_tpc = entry; 805 tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO; 806 807 td->td_retval[0] = tf->tf_out[0]; 808 td->td_retval[1] = tf->tf_out[1]; 809} 810 811int 812fill_regs(struct thread *td, struct reg *regs) 813{ 814 815 bcopy(td->td_frame, regs, sizeof(*regs)); 816 return (0); 817} 818 819int 820set_regs(struct thread *td, struct reg *regs) 821{ 822 struct trapframe *tf; 823 824 if (!TSTATE_SECURE(regs->r_tstate)) 825 return (EINVAL); 826 tf = td->td_frame; 827 regs->r_wstate = tf->tf_wstate; 828 bcopy(regs, tf, sizeof(*regs)); 829 return (0); 830} 831 832int 833fill_dbregs(struct thread *td, struct dbreg *dbregs) 834{ 835 836 return (ENOSYS); 837} 838 839int 840set_dbregs(struct thread *td, struct dbreg *dbregs) 841{ 842 843 return (ENOSYS); 844} 845 846int 847fill_fpregs(struct thread *td, struct fpreg *fpregs) 848{ 849 struct trapframe *tf; 850 struct pcb *pcb; 851 852 pcb = td->td_pcb; 853 tf = td->td_frame; 854 bcopy(pcb->pcb_ufp, fpregs->fr_regs, sizeof(fpregs->fr_regs)); 855 fpregs->fr_fsr = tf->tf_fsr; 856 fpregs->fr_gsr = tf->tf_gsr; 857 return (0); 858} 859 860int 861set_fpregs(struct thread *td, struct fpreg *fpregs) 862{ 863 struct trapframe *tf; 864 struct pcb *pcb; 865 866 pcb = td->td_pcb; 867 tf = td->td_frame; 868 tf->tf_fprs &= ~FPRS_FEF; 869 bcopy(fpregs->fr_regs, pcb->pcb_ufp, sizeof(pcb->pcb_ufp)); 870 tf->tf_fsr = fpregs->fr_fsr; 871 tf->tf_gsr = fpregs->fr_gsr; 872 return (0); 873} 874 875struct md_utrap * 876utrap_alloc(void) 877{ 878 struct md_utrap *ut; 879 880 ut = malloc(sizeof(struct md_utrap), M_SUBPROC, M_WAITOK | M_ZERO); 881 ut->ut_refcnt = 1; 882 return (ut); 883} 884 885void 886utrap_free(struct md_utrap *ut) 887{ 888 int refcnt; 889 890 if (ut == NULL) 891 return; 892 mtx_pool_lock(mtxpool_sleep, ut); 893 ut->ut_refcnt--; 894 refcnt = ut->ut_refcnt; 895 mtx_pool_unlock(mtxpool_sleep, ut); 896 if (refcnt == 0) 897 free(ut, M_SUBPROC); 898} 899 900struct md_utrap * 901utrap_hold(struct md_utrap *ut) 902{ 903 904 if (ut == NULL) 905 return (NULL); 906 mtx_pool_lock(mtxpool_sleep, ut); 907 ut->ut_refcnt++; 908 mtx_pool_unlock(mtxpool_sleep, ut); 909 return (ut); 910} 911