machdep.c revision 105733
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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 39 * from: FreeBSD: src/sys/i386/i386/machdep.c,v 1.477 2001/08/27 40 * $FreeBSD: head/sys/sparc64/sparc64/machdep.c 105733 2002-10-22 18:03:15Z jake $ 41 */ 42 43#include "opt_ddb.h" 44#include "opt_msgbuf.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/cons.h> 49#include <sys/imgact.h> 50#include <sys/kernel.h> 51#include <sys/ktr.h> 52#include <sys/linker.h> 53#include <sys/lock.h> 54#include <sys/malloc.h> 55#include <sys/msgbuf.h> 56#include <sys/mutex.h> 57#include <sys/pcpu.h> 58#include <sys/proc.h> 59#include <sys/reboot.h> 60#include <sys/bio.h> 61#include <sys/buf.h> 62#include <sys/bus.h> 63#include <sys/eventhandler.h> 64#include <sys/interrupt.h> 65#include <sys/ptrace.h> 66#include <sys/signalvar.h> 67#include <sys/smp.h> 68#include <sys/sysent.h> 69#include <sys/sysproto.h> 70#include <sys/timetc.h> 71#include <sys/user.h> 72#include <sys/ucontext.h> 73#include <sys/user.h> 74#include <sys/ucontext.h> 75#include <sys/exec.h> 76 77#include <dev/ofw/openfirm.h> 78 79#include <vm/vm.h> 80#include <vm/vm_param.h> 81#include <vm/vm_kern.h> 82#include <vm/vm_object.h> 83#include <vm/vm_page.h> 84#include <vm/vm_map.h> 85#include <vm/vm_pager.h> 86#include <vm/vm_extern.h> 87 88#include <ddb/ddb.h> 89 90#include <machine/cache.h> 91#include <machine/clock.h> 92#include <machine/cpu.h> 93#include <machine/fp.h> 94#include <machine/intr_machdep.h> 95#include <machine/md_var.h> 96#include <machine/metadata.h> 97#include <machine/ofw_machdep.h> 98#include <machine/smp.h> 99#include <machine/pmap.h> 100#include <machine/pstate.h> 101#include <machine/reg.h> 102#include <machine/sigframe.h> 103#include <machine/tick.h> 104#include <machine/tlb.h> 105#include <machine/tstate.h> 106#include <machine/upa.h> 107#include <machine/ver.h> 108 109typedef int ofw_vec_t(void *); 110 111struct tlb_entry *kernel_tlbs; 112int kernel_tlb_slots; 113 114long physmem; 115int cold = 1; 116long Maxmem; 117 118char pcpu0[PCPU_PAGES * PAGE_SIZE]; 119char uarea0[UAREA_PAGES * PAGE_SIZE]; 120struct trapframe frame0; 121 122vm_offset_t kstack0; 123vm_offset_t kstack0_phys; 124 125struct kva_md_info kmi; 126 127u_long ofw_vec; 128u_long ofw_tba; 129 130static struct timecounter tick_tc; 131 132static timecounter_get_t tick_get_timecount; 133void sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, 134 ofw_vec_t *vec); 135void sparc64_shutdown_final(void *dummy, int howto); 136 137static void cpu_startup(void *); 138SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 139 140CTASSERT((1 << INT_SHIFT) == sizeof(int)); 141CTASSERT((1 << PTR_SHIFT) == sizeof(char *)); 142 143CTASSERT(sizeof(struct reg) == 256); 144CTASSERT(sizeof(struct fpreg) == 272); 145CTASSERT(sizeof(struct __mcontext) == 512); 146 147CTASSERT(sizeof(struct pcpu) <= ((PCPU_PAGES * PAGE_SIZE) / 2)); 148 149static void 150cpu_startup(void *arg) 151{ 152 u_int clock; 153 154 OF_getprop(PCPU_GET(node), "clock-frequency", &clock, sizeof(clock)); 155 156 tick_tc.tc_get_timecount = tick_get_timecount; 157 tick_tc.tc_poll_pps = NULL; 158 tick_tc.tc_counter_mask = ~0u; 159 tick_tc.tc_frequency = clock; 160 tick_tc.tc_name = "tick"; 161 tc_init(&tick_tc); 162 163 cpu_identify(rdpr(ver), clock, PCPU_GET(cpuid)); 164 165 vm_ksubmap_init(&kmi); 166 167 bufinit(); 168 vm_pager_bufferinit(); 169 170 EVENTHANDLER_REGISTER(shutdown_final, sparc64_shutdown_final, NULL, 171 SHUTDOWN_PRI_LAST); 172} 173 174void 175cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 176{ 177 struct intr_request *ir; 178 int i; 179 180 pcpu->pc_irtail = &pcpu->pc_irhead; 181 for (i = 0; i < IR_FREE; i++) { 182 ir = &pcpu->pc_irpool[i]; 183 ir->ir_next = pcpu->pc_irfree; 184 pcpu->pc_irfree = ir; 185 } 186} 187 188unsigned 189tick_get_timecount(struct timecounter *tc) 190{ 191 return ((unsigned)rd(tick)); 192} 193 194void 195sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) 196{ 197 phandle_t child; 198 phandle_t root; 199 struct pcpu *pc; 200 vm_offset_t end; 201 vm_offset_t va; 202 caddr_t kmdp; 203 char *env; 204 char type[8]; 205 206 end = 0; 207 kmdp = NULL; 208 209 /* 210 * Initialize openfirmware (needed for console). 211 */ 212 OF_init(vec); 213 214 /* 215 * Parse metadata if present and fetch parameters. Must be before the 216 * console is inited so cninit gets the right value of boothowto. 217 */ 218 if (mdp != NULL) { 219 preload_metadata = mdp; 220 kmdp = preload_search_by_type("elf kernel"); 221 if (kmdp != NULL) { 222 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 223 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 224 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 225 kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS, 226 int); 227 kernel_tlbs = (void *)preload_search_info(kmdp, 228 MODINFO_METADATA | MODINFOMD_DTLB); 229 } 230 } 231 232 /* 233 * Initialize the console before printing anything. 234 */ 235 cninit(); 236 237 /* 238 * Panic is there is no metadata. Most likely the kernel was booted 239 * directly, instead of through loader(8). 240 */ 241 if (mdp == NULL || kmdp == NULL) { 242 printf("sparc64_init: no loader metadata.\n" 243 "This probably means you are not using loader(8).\n"); 244 panic("sparc64_init"); 245 } 246 247 /* 248 * Sanity check the kernel end, which is important. 249 */ 250 if (end == 0) { 251 printf("sparc64_init: warning, kernel end not specified.\n" 252 "Attempting to continue anyway.\n"); 253 end = (vm_offset_t)_end; 254 } 255 256 root = OF_peer(0); 257 for (child = OF_child(root); child != 0; child = OF_peer(child)) { 258 OF_getprop(child, "device_type", type, sizeof(type)); 259 if (strcmp(type, "cpu") == 0) 260 break; 261 } 262 if (child == 0) 263 panic("cpu_startup: no cpu\n"); 264 OF_getprop(child, "#dtlb-entries", &tlb_dtlb_entries, 265 sizeof(tlb_dtlb_entries)); 266 OF_getprop(child, "#itlb-entries", &tlb_itlb_entries, 267 sizeof(tlb_itlb_entries)); 268 269 cache_init(child); 270 271#ifdef DDB 272 kdb_init(); 273#endif 274 275#ifdef SMP 276 mp_tramp = mp_tramp_alloc(); 277#endif 278 279 /* 280 * Initialize virtual memory and calculate physmem. 281 */ 282 pmap_bootstrap(end); 283 284 /* 285 * Initialize tunables. 286 */ 287 init_param1(); 288 init_param2(physmem); 289 env = getenv("kernelname"); 290 if (env != NULL) { 291 strlcpy(kernelname, env, sizeof(kernelname)); 292 freeenv(env); 293 } 294 295 /* 296 * Disable tick for now. 297 */ 298 tick_stop(); 299 300 /* 301 * Initialize the interrupt tables. 302 */ 303 intr_init1(); 304 305 /* 306 * Initialize proc0 stuff (p_contested needs to be done early). 307 */ 308 proc_linkup(&proc0, &ksegrp0, &kse0, &thread0); 309 proc0.p_md.md_sigtramp = NULL; 310 proc0.p_md.md_utrap = NULL; 311 proc0.p_uarea = (struct user *)uarea0; 312 proc0.p_stats = &proc0.p_uarea->u_stats; 313 thread0.td_kstack = kstack0; 314 thread0.td_pcb = (struct pcb *) 315 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 316 frame0.tf_tstate = TSTATE_IE | TSTATE_PEF; 317 thread0.td_frame = &frame0; 318 319 /* 320 * Prime our per-cpu data page for use. Note, we are using it for our 321 * stack, so don't pass the real size (PAGE_SIZE) to pcpu_init or 322 * it'll zero it out from under us. 323 */ 324 pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; 325 pcpu_init(pc, 0, sizeof(struct pcpu)); 326 pc->pc_curthread = &thread0; 327 pc->pc_curpcb = thread0.td_pcb; 328 pc->pc_mid = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); 329 pc->pc_addr = (vm_offset_t)pcpu0; 330 pc->pc_node = child; 331 pc->pc_tlb_ctx = TLB_CTX_USER_MIN; 332 pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; 333 pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; 334 335 /* 336 * Initialize global registers. 337 */ 338 cpu_setregs(pc); 339 340 /* 341 * Map and initialize the message buffer (after setting trap table). 342 */ 343 va = (vm_offset_t)msgbufp; 344 pmap_map(&va, msgbuf_phys, msgbuf_phys + MSGBUF_SIZE, 0); 345 msgbufinit(msgbufp, MSGBUF_SIZE); 346 347 mutex_init(); 348 intr_init2(); 349} 350 351void 352set_openfirm_callback(ofw_vec_t *vec) 353{ 354 ofw_tba = rdpr(tba); 355 ofw_vec = (u_long)vec; 356} 357 358void 359sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 360{ 361 struct trapframe *tf; 362 struct sigframe *sfp; 363 struct sigacts *psp; 364 struct sigframe sf; 365 struct thread *td; 366 struct frame *fp; 367 struct proc *p; 368 int oonstack; 369 u_long sp; 370 371 oonstack = 0; 372 td = curthread; 373 p = td->td_proc; 374 psp = p->p_sigacts; 375 tf = td->td_frame; 376 sp = tf->tf_sp + SPOFF; 377 oonstack = sigonstack(sp); 378 379 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 380 catcher, sig); 381 382 /* Make sure we have a signal trampoline to return to. */ 383 if (p->p_md.md_sigtramp == NULL) { 384 /* 385 * No signal tramoline... kill the process. 386 */ 387 CTR0(KTR_SIG, "sendsig: no sigtramp"); 388 printf("sendsig: %s is too old, rebuild it\n", p->p_comm); 389 sigexit(td, sig); 390 /* NOTREACHED */ 391 } 392 393 /* Save user context. */ 394 bzero(&sf, sizeof(sf)); 395 sf.sf_uc.uc_sigmask = *mask; 396 sf.sf_uc.uc_stack = p->p_sigstk; 397 sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) 398 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 399 bcopy(tf, &sf.sf_uc.uc_mcontext, sizeof(*tf)); 400 401 /* Allocate and validate space for the signal handler context. */ 402 if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && 403 SIGISMEMBER(psp->ps_sigonstack, sig)) { 404 sfp = (struct sigframe *)(p->p_sigstk.ss_sp + 405 p->p_sigstk.ss_size - sizeof(struct sigframe)); 406 } else 407 sfp = (struct sigframe *)sp - 1; 408 PROC_UNLOCK(p); 409 410 fp = (struct frame *)sfp - 1; 411 412 /* Translate the signal if appropriate. */ 413 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 414 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 415 416 /* Build the argument list for the signal handler. */ 417 tf->tf_out[0] = sig; 418 tf->tf_out[1] = (register_t)&sfp->sf_si; 419 tf->tf_out[2] = (register_t)&sfp->sf_uc; 420 tf->tf_out[4] = (register_t)catcher; 421 /* Fill siginfo structure. */ 422 sf.sf_si.si_signo = sig; 423 sf.sf_si.si_code = code; 424 sf.sf_si.si_addr = (void *)tf->tf_sfar; 425 sf.sf_si.si_pid = p->p_pid; 426 sf.sf_si.si_uid = td->td_ucred->cr_uid; 427 428 /* Copy the sigframe out to the user's stack. */ 429 if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 || 430 suword(&fp->fr_in[6], tf->tf_out[6]) != 0) { 431 /* 432 * Something is wrong with the stack pointer. 433 * ...Kill the process. 434 */ 435 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 436 PROC_LOCK(p); 437 sigexit(td, SIGILL); 438 /* NOTREACHED */ 439 } 440 441 tf->tf_tpc = (u_long)p->p_md.md_sigtramp; 442 tf->tf_tnpc = tf->tf_tpc + 4; 443 tf->tf_sp = (u_long)fp - SPOFF; 444 445 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, 446 tf->tf_sp); 447 448 PROC_LOCK(p); 449} 450 451/* 452 * Stub to satisfy the reference to osigreturn in the syscall table. This 453 * is needed even for newer arches that don't support old signals because 454 * the syscall table is machine-independent. 455 * 456 * MPSAFE 457 */ 458int 459osigreturn(struct thread *td, struct osigreturn_args *uap) 460{ 461 462 return (nosys(td, (struct nosys_args *)uap)); 463} 464 465#ifndef _SYS_SYSPROTO_H_ 466struct sigreturn_args { 467 ucontext_t *ucp; 468}; 469#endif 470 471/* 472 * MPSAFE 473 */ 474int 475sigreturn(struct thread *td, struct sigreturn_args *uap) 476{ 477 struct proc *p; 478 ucontext_t uc; 479 480 p = td->td_proc; 481 if (rwindow_save(td)) { 482 PROC_LOCK(p); 483 sigexit(td, SIGILL); 484 } 485 486 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 487 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 488 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 489 return (EFAULT); 490 } 491 492 if (!TSTATE_SECURE(uc.uc_mcontext.mc_tstate)) 493 return (EINVAL); 494 bcopy(&uc.uc_mcontext, td->td_frame, sizeof(*td->td_frame)); 495 496 PROC_LOCK(p); 497 p->p_sigmask = uc.uc_sigmask; 498 SIG_CANTMASK(p->p_sigmask); 499 signotify(p); 500 PROC_UNLOCK(p); 501 502 CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", 503 td, td->td_frame->tf_tpc, td->td_frame->tf_sp, 504 td->td_frame->tf_tstate); 505 return (EJUSTRETURN); 506} 507 508/* 509 * Exit the kernel and execute a firmware call that will not return, as 510 * specified by the arguments. 511 */ 512void 513cpu_shutdown(void *args) 514{ 515 516#ifdef SMP 517 cpu_mp_shutdown(); 518#endif 519 openfirmware_exit(args); 520} 521 522/* 523 * Duplicate OF_exit() with a different firmware call function that restores 524 * the trap table, otherwise a RED state exception is triggered in at least 525 * some firmware versions. 526 */ 527void 528cpu_halt(void) 529{ 530 static struct { 531 cell_t name; 532 cell_t nargs; 533 cell_t nreturns; 534 } args = { 535 (cell_t)"exit", 536 0, 537 0 538 }; 539 540 cpu_shutdown(&args); 541} 542 543void 544sparc64_shutdown_final(void *dummy, int howto) 545{ 546 static struct { 547 cell_t name; 548 cell_t nargs; 549 cell_t nreturns; 550 } args = { 551 (cell_t)"SUNW,power-off", 552 0, 553 0 554 }; 555 556 /* Turn the power off? */ 557 if ((howto & RB_POWEROFF) != 0) 558 cpu_shutdown(&args); 559 /* In case of halt, return to the firmware */ 560 if ((howto & RB_HALT) != 0) 561 cpu_halt(); 562} 563 564int 565ptrace_set_pc(struct thread *td, u_long addr) 566{ 567 568 td->td_frame->tf_tpc = addr; 569 td->td_frame->tf_tnpc = addr + 4; 570 return (0); 571} 572 573int 574ptrace_single_step(struct thread *td) 575{ 576 /* TODO; */ 577 return (0); 578} 579 580void 581exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 582{ 583 struct trapframe *tf; 584 struct md_utrap *ut; 585 struct pcb *pcb; 586 struct proc *p; 587 u_long sp; 588 589 /* XXX no cpu_exec */ 590 p = td->td_proc; 591 p->p_md.md_sigtramp = NULL; 592 if ((ut = p->p_md.md_utrap) != NULL) { 593 ut->ut_refcnt--; 594 if (ut->ut_refcnt == 0) 595 free(ut, M_SUBPROC); 596 p->p_md.md_utrap = NULL; 597 } 598 599 pcb = td->td_pcb; 600 sp = rounddown(stack, 16); 601 tf = td->td_frame; 602 bzero(pcb, sizeof(*pcb)); 603 bzero(tf, sizeof(*tf)); 604 tf->tf_out[0] = stack; 605 tf->tf_out[3] = PS_STRINGS; 606 tf->tf_out[6] = sp - SPOFF - sizeof(struct frame); 607 tf->tf_tnpc = entry + 4; 608 tf->tf_tpc = entry; 609 tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO; 610 611 td->td_retval[0] = tf->tf_out[0]; 612 td->td_retval[1] = tf->tf_out[1]; 613} 614 615void 616Debugger(const char *msg) 617{ 618 619 printf("Debugger(\"%s\")\n", msg); 620 critical_enter(); 621 breakpoint(); 622 critical_exit(); 623} 624 625int 626fill_regs(struct thread *td, struct reg *regs) 627{ 628 629 bcopy(td->td_frame, regs, sizeof(*regs)); 630 return (0); 631} 632 633int 634set_regs(struct thread *td, struct reg *regs) 635{ 636 637 if (!TSTATE_SECURE(regs->r_tstate)) 638 return (EINVAL); 639 bcopy(regs, td->td_frame, sizeof(*regs)); 640 return (0); 641} 642 643int 644fill_dbregs(struct thread *td, struct dbreg *dbregs) 645{ 646 647 return (ENOSYS); 648} 649 650int 651set_dbregs(struct thread *td, struct dbreg *dbregs) 652{ 653 654 return (ENOSYS); 655} 656 657int 658fill_fpregs(struct thread *td, struct fpreg *fpregs) 659{ 660 struct trapframe *tf; 661 struct pcb *pcb; 662 663 pcb = td->td_pcb; 664 tf = td->td_frame; 665 bcopy(pcb->pcb_fpstate.fp_fb, fpregs->fr_regs, 666 sizeof(pcb->pcb_fpstate.fp_fb)); 667 fpregs->fr_fsr = tf->tf_fsr; 668 fpregs->fr_gsr = tf->tf_gsr; 669 return (0); 670} 671 672int 673set_fpregs(struct thread *td, struct fpreg *fpregs) 674{ 675 struct trapframe *tf; 676 struct pcb *pcb; 677 678 pcb = td->td_pcb; 679 tf = td->td_frame; 680 bcopy(fpregs->fr_regs, pcb->pcb_fpstate.fp_fb, 681 sizeof(fpregs->fr_regs)); 682 tf->tf_fsr = fpregs->fr_fsr; 683 tf->tf_gsr = fpregs->fr_gsr; 684 return (0); 685} 686