machdep.c revision 112888
180708Sjake/*- 280708Sjake * Copyright (c) 2001 Jake Burkholder. 382902Sjake * Copyright (c) 1992 Terrence R. Lambert. 482902Sjake * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 580708Sjake * All rights reserved. 680708Sjake * 782902Sjake * This code is derived from software contributed to Berkeley by 882902Sjake * William Jolitz. 982902Sjake * 1080708Sjake * Redistribution and use in source and binary forms, with or without 1180708Sjake * modification, are permitted provided that the following conditions 1280708Sjake * are met: 1380708Sjake * 1. Redistributions of source code must retain the above copyright 1480708Sjake * notice, this list of conditions and the following disclaimer. 1580708Sjake * 2. Redistributions in binary form must reproduce the above copyright 1680708Sjake * notice, this list of conditions and the following disclaimer in the 1780708Sjake * documentation and/or other materials provided with the distribution. 1882902Sjake * 3. All advertising materials mentioning features or use of this software 1982902Sjake * must display the following acknowledgement: 2082902Sjake * This product includes software developed by the University of 2182902Sjake * California, Berkeley and its contributors. 2282902Sjake * 4. Neither the name of the University nor the names of its contributors 2382902Sjake * may be used to endorse or promote products derived from this software 2482902Sjake * without specific prior written permission. 2580708Sjake * 2682902Sjake * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2780708Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2880708Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2982902Sjake * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3080708Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3180708Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3280708Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3380708Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3480708Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3580708Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3680708Sjake * SUCH DAMAGE. 3780708Sjake * 3882902Sjake * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 3982902Sjake * from: FreeBSD: src/sys/i386/i386/machdep.c,v 1.477 2001/08/27 4080708Sjake * $FreeBSD: head/sys/sparc64/sparc64/machdep.c 112888 2003-03-31 22:49:17Z jeff $ 4180708Sjake */ 4280708Sjake 43105950Speter#include "opt_compat.h" 4480709Sjake#include "opt_ddb.h" 4585242Sjake#include "opt_msgbuf.h" 4680709Sjake 4780708Sjake#include <sys/param.h> 4880708Sjake#include <sys/systm.h> 4980709Sjake#include <sys/cons.h> 50102561Sjake#include <sys/imgact.h> 5180709Sjake#include <sys/kernel.h> 5285262Sjake#include <sys/ktr.h> 5380709Sjake#include <sys/linker.h> 5480709Sjake#include <sys/lock.h> 5588782Sjake#include <sys/malloc.h> 5685242Sjake#include <sys/msgbuf.h> 5780708Sjake#include <sys/mutex.h> 5880709Sjake#include <sys/pcpu.h> 5980708Sjake#include <sys/proc.h> 6085242Sjake#include <sys/reboot.h> 6180709Sjake#include <sys/bio.h> 6280709Sjake#include <sys/buf.h> 6384849Stmm#include <sys/bus.h> 6486147Stmm#include <sys/eventhandler.h> 6584849Stmm#include <sys/interrupt.h> 6680708Sjake#include <sys/ptrace.h> 6780708Sjake#include <sys/signalvar.h> 6891616Sjake#include <sys/smp.h> 6982902Sjake#include <sys/sysent.h> 7080708Sjake#include <sys/sysproto.h> 7180709Sjake#include <sys/timetc.h> 7291783Sjake#include <sys/user.h> 7391156Sjake#include <sys/ucontext.h> 7480709Sjake#include <sys/user.h> 7591616Sjake#include <sys/ucontext.h> 7682902Sjake#include <sys/exec.h> 7780708Sjake 7880708Sjake#include <dev/ofw/openfirm.h> 7980708Sjake 8080709Sjake#include <vm/vm.h> 8180709Sjake#include <vm/vm_param.h> 8280709Sjake#include <vm/vm_kern.h> 8380709Sjake#include <vm/vm_object.h> 8480709Sjake#include <vm/vm_page.h> 8580709Sjake#include <vm/vm_map.h> 8680709Sjake#include <vm/vm_pager.h> 8780709Sjake#include <vm/vm_extern.h> 8880709Sjake 8980709Sjake#include <ddb/ddb.h> 9080709Sjake 9186521Sjake#include <machine/cache.h> 9281383Sjake#include <machine/clock.h> 9382902Sjake#include <machine/cpu.h> 9483366Sjulian#include <machine/fp.h> 9581383Sjake#include <machine/intr_machdep.h> 9680708Sjake#include <machine/md_var.h> 9788436Sjake#include <machine/metadata.h> 9886147Stmm#include <machine/ofw_machdep.h> 9991783Sjake#include <machine/smp.h> 10080709Sjake#include <machine/pmap.h> 10180709Sjake#include <machine/pstate.h> 10280708Sjake#include <machine/reg.h> 10382902Sjake#include <machine/sigframe.h> 10481383Sjake#include <machine/tick.h> 10591613Sjake#include <machine/tlb.h> 10682016Sjake#include <machine/tstate.h> 10791616Sjake#include <machine/upa.h> 10882902Sjake#include <machine/ver.h> 10980708Sjake 11080709Sjaketypedef int ofw_vec_t(void *); 11180708Sjake 11297445Sjakestruct tlb_entry *kernel_tlbs; 11391616Sjakeint kernel_tlb_slots; 11491616Sjake 11580708Sjakeint cold = 1; 116102600Speterlong Maxmem; 11780708Sjake 11891360Sjakechar pcpu0[PCPU_PAGES * PAGE_SIZE]; 11989038Sjakechar uarea0[UAREA_PAGES * PAGE_SIZE]; 12089038Sjakestruct trapframe frame0; 12180708Sjake 12289038Sjakevm_offset_t kstack0; 12389038Sjakevm_offset_t kstack0_phys; 12488781Sjake 12582902Sjakestruct kva_md_info kmi; 12680709Sjake 12780709Sjakeu_long ofw_vec; 12880709Sjakeu_long ofw_tba; 12980709Sjake 13080709Sjakestatic struct timecounter tick_tc; 13180709Sjake 132106555Stmmchar sparc64_model[32]; 133106555Stmm 13480709Sjakestatic timecounter_get_t tick_get_timecount; 13591616Sjakevoid sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, 13689038Sjake ofw_vec_t *vec); 13786147Stmmvoid sparc64_shutdown_final(void *dummy, int howto); 13880709Sjake 13980709Sjakestatic void cpu_startup(void *); 14080709SjakeSYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 14180709Sjake 14291336SjakeCTASSERT((1 << INT_SHIFT) == sizeof(int)); 14391336SjakeCTASSERT((1 << PTR_SHIFT) == sizeof(char *)); 14491336Sjake 145105733SjakeCTASSERT(sizeof(struct reg) == 256); 146105733SjakeCTASSERT(sizeof(struct fpreg) == 272); 147105733SjakeCTASSERT(sizeof(struct __mcontext) == 512); 148105733Sjake 14991360SjakeCTASSERT(sizeof(struct pcpu) <= ((PCPU_PAGES * PAGE_SIZE) / 2)); 15089038Sjake 15180709Sjakestatic void 15280709Sjakecpu_startup(void *arg) 15380709Sjake{ 15480709Sjake 15580709Sjake tick_tc.tc_get_timecount = tick_get_timecount; 15680709Sjake tick_tc.tc_poll_pps = NULL; 15780709Sjake tick_tc.tc_counter_mask = ~0u; 158105946Stmm tick_tc.tc_frequency = tick_freq; 15980709Sjake tick_tc.tc_name = "tick"; 16080709Sjake tc_init(&tick_tc); 16180709Sjake 162105946Stmm cpu_identify(rdpr(ver), tick_freq, PCPU_GET(cpuid)); 163106555Stmm printf("Model: %s\n", sparc64_model); 16480709Sjake 16582902Sjake vm_ksubmap_init(&kmi); 16680709Sjake 16780709Sjake bufinit(); 16880709Sjake vm_pager_bufferinit(); 16980709Sjake 17086147Stmm EVENTHANDLER_REGISTER(shutdown_final, sparc64_shutdown_final, NULL, 17186147Stmm SHUTDOWN_PRI_LAST); 17280709Sjake} 17380709Sjake 17487702Sjhbvoid 17587702Sjhbcpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 17687702Sjhb{ 17797265Sjake struct intr_request *ir; 17897265Sjake int i; 17997265Sjake 18097265Sjake pcpu->pc_irtail = &pcpu->pc_irhead; 18197265Sjake for (i = 0; i < IR_FREE; i++) { 18297265Sjake ir = &pcpu->pc_irpool[i]; 18397265Sjake ir->ir_next = pcpu->pc_irfree; 18497265Sjake pcpu->pc_irfree = ir; 18597265Sjake } 18687702Sjhb} 18787702Sjhb 18880709Sjakeunsigned 18980709Sjaketick_get_timecount(struct timecounter *tc) 19080709Sjake{ 19180709Sjake return ((unsigned)rd(tick)); 19280709Sjake} 19380709Sjake 19480708Sjakevoid 19591616Sjakesparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) 19680708Sjake{ 197101898Sjake phandle_t child; 198101898Sjake phandle_t root; 19989038Sjake struct pcpu *pc; 20086521Sjake vm_offset_t end; 20186521Sjake caddr_t kmdp; 202105946Stmm u_int clock; 203105569Smux char *env; 204101898Sjake char type[8]; 20580709Sjake 20686521Sjake end = 0; 20786521Sjake kmdp = NULL; 20886521Sjake 20980709Sjake /* 210112398Sjake * Find out what kind of cpu we have first, for anything that changes 211112398Sjake * behaviour. 212112398Sjake */ 213112398Sjake cpu_impl = VER_IMPL(rdpr(ver)); 214112398Sjake 215112398Sjake /* 21680709Sjake * Initialize openfirmware (needed for console). 21780709Sjake */ 21880709Sjake OF_init(vec); 21980709Sjake 22080709Sjake /* 22186521Sjake * Parse metadata if present and fetch parameters. Must be before the 22286521Sjake * console is inited so cninit gets the right value of boothowto. 22386521Sjake */ 22486521Sjake if (mdp != NULL) { 22586521Sjake preload_metadata = mdp; 22686521Sjake kmdp = preload_search_by_type("elf kernel"); 22786521Sjake if (kmdp != NULL) { 22886521Sjake boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 22986521Sjake kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 23086521Sjake end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 23191616Sjake kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS, 23291616Sjake int); 23397445Sjake kernel_tlbs = (void *)preload_search_info(kmdp, 23491616Sjake MODINFO_METADATA | MODINFOMD_DTLB); 23586521Sjake } 23686521Sjake } 23786521Sjake 23886521Sjake /* 23980709Sjake * Initialize the console before printing anything. 24080709Sjake */ 24188639Sjake cninit(); 24280709Sjake 24380709Sjake /* 24486521Sjake * Panic is there is no metadata. Most likely the kernel was booted 24586521Sjake * directly, instead of through loader(8). 24680709Sjake */ 24786521Sjake if (mdp == NULL || kmdp == NULL) { 24886521Sjake printf("sparc64_init: no loader metadata.\n" 24986521Sjake "This probably means you are not using loader(8).\n"); 25086521Sjake panic("sparc64_init"); 25186521Sjake } 25280709Sjake 25381383Sjake /* 25486521Sjake * Sanity check the kernel end, which is important. 25586521Sjake */ 25686521Sjake if (end == 0) { 25786521Sjake printf("sparc64_init: warning, kernel end not specified.\n" 25886521Sjake "Attempting to continue anyway.\n"); 25986521Sjake end = (vm_offset_t)_end; 26086521Sjake } 26186521Sjake 262101898Sjake root = OF_peer(0); 263101898Sjake for (child = OF_child(root); child != 0; child = OF_peer(child)) { 264101898Sjake OF_getprop(child, "device_type", type, sizeof(type)); 265101898Sjake if (strcmp(type, "cpu") == 0) 266101898Sjake break; 267101898Sjake } 268101898Sjake if (child == 0) 269101898Sjake panic("cpu_startup: no cpu\n"); 270101898Sjake OF_getprop(child, "#dtlb-entries", &tlb_dtlb_entries, 271101898Sjake sizeof(tlb_dtlb_entries)); 272101898Sjake OF_getprop(child, "#itlb-entries", &tlb_itlb_entries, 273101898Sjake sizeof(tlb_itlb_entries)); 274101898Sjake 275101898Sjake cache_init(child); 276101898Sjake 27790625Stmm#ifdef DDB 27890625Stmm kdb_init(); 27990625Stmm#endif 28090625Stmm 28191616Sjake#ifdef SMP 28291616Sjake mp_tramp = mp_tramp_alloc(); 28391616Sjake#endif 28491616Sjake 28586521Sjake /* 28690625Stmm * Initialize virtual memory and calculate physmem. 28787546Sdillon */ 28890625Stmm pmap_bootstrap(end); 28987546Sdillon 29087546Sdillon /* 29181383Sjake * Initialize tunables. 29281383Sjake */ 29387546Sdillon init_param1(); 29487546Sdillon init_param2(physmem); 295105569Smux env = getenv("kernelname"); 296105569Smux if (env != NULL) { 297105569Smux strlcpy(kernelname, env, sizeof(kernelname)); 298105569Smux freeenv(env); 299105569Smux } 30081085Sjake 30180709Sjake /* 30281383Sjake * Disable tick for now. 30380709Sjake */ 30481383Sjake tick_stop(); 30580709Sjake 30689038Sjake /* 30789038Sjake * Initialize the interrupt tables. 30889038Sjake */ 30990624Stmm intr_init1(); 31080709Sjake 31180709Sjake /* 31280709Sjake * Initialize proc0 stuff (p_contested needs to be done early). 31380709Sjake */ 314103367Sjulian proc_linkup(&proc0, &ksegrp0, &kse0, &thread0); 31595744Sjake proc0.p_md.md_sigtramp = NULL; 31688822Stmm proc0.p_md.md_utrap = NULL; 31789038Sjake proc0.p_uarea = (struct user *)uarea0; 31883366Sjulian proc0.p_stats = &proc0.p_uarea->u_stats; 31990361Sjulian thread0.td_kstack = kstack0; 32090361Sjulian thread0.td_pcb = (struct pcb *) 32190361Sjulian (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 322105908Sjake frame0.tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_PRIV; 32390361Sjulian thread0.td_frame = &frame0; 32480709Sjake 32580709Sjake /* 32689038Sjake * Prime our per-cpu data page for use. Note, we are using it for our 32789038Sjake * stack, so don't pass the real size (PAGE_SIZE) to pcpu_init or 32889038Sjake * it'll zero it out from under us. 32980709Sjake */ 33091360Sjake pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; 33189038Sjake pcpu_init(pc, 0, sizeof(struct pcpu)); 33290361Sjulian pc->pc_curthread = &thread0; 33391156Sjake pc->pc_curpcb = thread0.td_pcb; 33491616Sjake pc->pc_mid = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); 33591616Sjake pc->pc_addr = (vm_offset_t)pcpu0; 336101898Sjake pc->pc_node = child; 33791613Sjake pc->pc_tlb_ctx = TLB_CTX_USER_MIN; 33891613Sjake pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; 33991613Sjake pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; 34088639Sjake 34180709Sjake /* 34289038Sjake * Initialize global registers. 34381383Sjake */ 34489038Sjake cpu_setregs(pc); 34588639Sjake 34688639Sjake /* 347108301Sjake * Initialize the message buffer (after setting trap table). 34888822Stmm */ 34988822Stmm msgbufinit(msgbufp, MSGBUF_SIZE); 35088822Stmm 35193702Sjhb mutex_init(); 35290624Stmm intr_init2(); 353105946Stmm 354105946Stmm OF_getprop(PCPU_GET(node), "clock-frequency", &clock, sizeof(clock)); 355105946Stmm tick_init(clock); 356106555Stmm 357106555Stmm OF_getprop(root, "name", sparc64_model, sizeof(sparc64_model) - 1); 35880708Sjake} 35980708Sjake 36080708Sjakevoid 36180709Sjakeset_openfirm_callback(ofw_vec_t *vec) 36280709Sjake{ 36380709Sjake ofw_tba = rdpr(tba); 36480709Sjake ofw_vec = (u_long)vec; 36580709Sjake} 36680709Sjake 36780709Sjakevoid 36880708Sjakesendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 36980708Sjake{ 37082902Sjake struct trapframe *tf; 37182902Sjake struct sigframe *sfp; 37282902Sjake struct sigacts *psp; 37382902Sjake struct sigframe sf; 37483366Sjulian struct thread *td; 37585242Sjake struct frame *fp; 37682902Sjake struct proc *p; 37785242Sjake int oonstack; 37882902Sjake u_long sp; 37982902Sjake 38082902Sjake oonstack = 0; 38183366Sjulian td = curthread; 38283366Sjulian p = td->td_proc; 38382902Sjake psp = p->p_sigacts; 38483366Sjulian tf = td->td_frame; 38582902Sjake sp = tf->tf_sp + SPOFF; 38682902Sjake oonstack = sigonstack(sp); 38782902Sjake 38883366Sjulian CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 38982902Sjake catcher, sig); 39082902Sjake 391102554Sjake /* Make sure we have a signal trampoline to return to. */ 392102554Sjake if (p->p_md.md_sigtramp == NULL) { 393102554Sjake /* 394102554Sjake * No signal tramoline... kill the process. 395102554Sjake */ 396102554Sjake CTR0(KTR_SIG, "sendsig: no sigtramp"); 397102873Sjake printf("sendsig: %s is too old, rebuild it\n", p->p_comm); 398102554Sjake sigexit(td, sig); 399102554Sjake /* NOTREACHED */ 400102554Sjake } 401102554Sjake 40282902Sjake /* Save user context. */ 40382902Sjake bzero(&sf, sizeof(sf)); 40482902Sjake sf.sf_uc.uc_sigmask = *mask; 40582902Sjake sf.sf_uc.uc_stack = p->p_sigstk; 40682902Sjake sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) 40782902Sjake ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 408105733Sjake bcopy(tf, &sf.sf_uc.uc_mcontext, sizeof(*tf)); 40982902Sjake 41082902Sjake /* Allocate and validate space for the signal handler context. */ 41182902Sjake if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && 41282902Sjake SIGISMEMBER(psp->ps_sigonstack, sig)) { 41382902Sjake sfp = (struct sigframe *)(p->p_sigstk.ss_sp + 41482902Sjake p->p_sigstk.ss_size - sizeof(struct sigframe)); 41582902Sjake } else 41682902Sjake sfp = (struct sigframe *)sp - 1; 41782902Sjake PROC_UNLOCK(p); 41882902Sjake 41985242Sjake fp = (struct frame *)sfp - 1; 42082902Sjake 42182902Sjake /* Translate the signal if appropriate. */ 42282902Sjake if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 42382902Sjake sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 42482902Sjake 42582902Sjake /* Build the argument list for the signal handler. */ 42682902Sjake tf->tf_out[0] = sig; 427105733Sjake tf->tf_out[1] = (register_t)&sfp->sf_si; 42882902Sjake tf->tf_out[2] = (register_t)&sfp->sf_uc; 42982902Sjake tf->tf_out[4] = (register_t)catcher; 430105733Sjake /* Fill siginfo structure. */ 431105733Sjake sf.sf_si.si_signo = sig; 432105733Sjake sf.sf_si.si_code = code; 433105733Sjake sf.sf_si.si_addr = (void *)tf->tf_sfar; 43482902Sjake 43582902Sjake /* Copy the sigframe out to the user's stack. */ 43685242Sjake if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 || 43794254Sjake suword(&fp->fr_in[6], tf->tf_out[6]) != 0) { 43882902Sjake /* 43982902Sjake * Something is wrong with the stack pointer. 44082902Sjake * ...Kill the process. 44182902Sjake */ 44283366Sjulian CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 44382902Sjake PROC_LOCK(p); 44483366Sjulian sigexit(td, SIGILL); 44582902Sjake /* NOTREACHED */ 44682902Sjake } 44782902Sjake 448102554Sjake tf->tf_tpc = (u_long)p->p_md.md_sigtramp; 44982902Sjake tf->tf_tnpc = tf->tf_tpc + 4; 45085242Sjake tf->tf_sp = (u_long)fp - SPOFF; 45182902Sjake 45283366Sjulian CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, 45382902Sjake tf->tf_sp); 45484178Sjake 45584178Sjake PROC_LOCK(p); 45680708Sjake} 45780708Sjake 45880708Sjake#ifndef _SYS_SYSPROTO_H_ 45983088Sobrienstruct sigreturn_args { 46080708Sjake ucontext_t *ucp; 46180708Sjake}; 46280708Sjake#endif 46380708Sjake 46494606Salc/* 46594606Salc * MPSAFE 46694606Salc */ 46780708Sjakeint 46883366Sjuliansigreturn(struct thread *td, struct sigreturn_args *uap) 46980708Sjake{ 470109036Sjake struct trapframe *tf; 47183366Sjulian struct proc *p; 472109036Sjake mcontext_t *mc; 47382902Sjake ucontext_t uc; 47482902Sjake 47583366Sjulian p = td->td_proc; 47683366Sjulian if (rwindow_save(td)) { 47782902Sjake PROC_LOCK(p); 47883366Sjulian sigexit(td, SIGILL); 47982902Sjake } 48082902Sjake 48183366Sjulian CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 48282902Sjake if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 48383366Sjulian CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 48482902Sjake return (EFAULT); 48582902Sjake } 48682902Sjake 487109036Sjake mc = &uc.uc_mcontext; 488109036Sjake tf = td->td_frame; 489109036Sjake if (!TSTATE_SECURE(mc->mc_tstate)) 49084178Sjake return (EINVAL); 491109036Sjake mc->mc_wstate = tf->tf_wstate; 492109036Sjake bcopy(mc, tf, sizeof(*tf)); 49382902Sjake 49482902Sjake PROC_LOCK(p); 495112888Sjeff td->td_sigmask = uc.uc_sigmask; 496112888Sjeff SIG_CANTMASK(td->td_sigmask); 497112888Sjeff signotify(td); 49882902Sjake PROC_UNLOCK(p); 499105733Sjake 50083366Sjulian CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", 501109036Sjake td, tf->tf_tpc, tf->tf_sp, tf->tf_tstate); 50282902Sjake return (EJUSTRETURN); 50380708Sjake} 50480708Sjake 505105950Speter#ifdef COMPAT_FREEBSD4 506105950Speterint 507105950Speterfreebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 508105950Speter{ 509105950Speter 510105950Speter return sigreturn(td, (struct sigreturn_args *)uap); 511105950Speter} 512105950Speter#endif 513105950Speter 514106977Sdeischenint 515106977Sdeischenget_mcontext(struct thread *td, mcontext_t *mcp) 516106977Sdeischen{ 517106977Sdeischen 518106977Sdeischen return (ENOSYS); 519106977Sdeischen} 520106977Sdeischen 521106977Sdeischenint 522106977Sdeischenset_mcontext(struct thread *td, const mcontext_t *mcp) 523106977Sdeischen{ 524106977Sdeischen 525106977Sdeischen return (ENOSYS); 526106977Sdeischen} 527106977Sdeischen 52886147Stmm/* 52992205Sjake * Exit the kernel and execute a firmware call that will not return, as 53092205Sjake * specified by the arguments. 53192205Sjake */ 53292205Sjakevoid 53392205Sjakecpu_shutdown(void *args) 53492205Sjake{ 53592205Sjake 53692205Sjake#ifdef SMP 53792205Sjake cpu_mp_shutdown(); 53892205Sjake#endif 53992205Sjake openfirmware_exit(args); 54092205Sjake} 54192205Sjake 54292205Sjake/* 54386147Stmm * Duplicate OF_exit() with a different firmware call function that restores 54486147Stmm * the trap table, otherwise a RED state exception is triggered in at least 54586147Stmm * some firmware versions. 54686147Stmm */ 54780708Sjakevoid 54880708Sjakecpu_halt(void) 54980708Sjake{ 55086147Stmm static struct { 55186147Stmm cell_t name; 55286147Stmm cell_t nargs; 55386147Stmm cell_t nreturns; 55486147Stmm } args = { 55586147Stmm (cell_t)"exit", 55686147Stmm 0, 55786147Stmm 0 55886147Stmm }; 55984178Sjake 56092205Sjake cpu_shutdown(&args); 56180708Sjake} 56280708Sjake 56386147Stmmvoid 56486147Stmmsparc64_shutdown_final(void *dummy, int howto) 56586147Stmm{ 56686147Stmm static struct { 56786147Stmm cell_t name; 56886147Stmm cell_t nargs; 56986147Stmm cell_t nreturns; 57086147Stmm } args = { 57186147Stmm (cell_t)"SUNW,power-off", 57286147Stmm 0, 57386147Stmm 0 57486147Stmm }; 57586147Stmm 57686147Stmm /* Turn the power off? */ 57786147Stmm if ((howto & RB_POWEROFF) != 0) 57892205Sjake cpu_shutdown(&args); 57986147Stmm /* In case of halt, return to the firmware */ 58086147Stmm if ((howto & RB_HALT) != 0) 58186147Stmm cpu_halt(); 58286147Stmm} 58386147Stmm 58480708Sjakeint 58583366Sjulianptrace_set_pc(struct thread *td, u_long addr) 58680708Sjake{ 58782016Sjake 58883366Sjulian td->td_frame->tf_tpc = addr; 58983366Sjulian td->td_frame->tf_tnpc = addr + 4; 59080708Sjake return (0); 59180708Sjake} 59280708Sjake 59380708Sjakeint 59483366Sjulianptrace_single_step(struct thread *td) 59580708Sjake{ 596104271Sjake /* TODO; */ 59780708Sjake return (0); 59880708Sjake} 59980708Sjake 60080708Sjakevoid 601102561Sjakeexec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 60280708Sjake{ 60388639Sjake struct trapframe *tf; 60488782Sjake struct md_utrap *ut; 60581135Stmm struct pcb *pcb; 606102557Sjake struct proc *p; 60784178Sjake u_long sp; 60881135Stmm 60988782Sjake /* XXX no cpu_exec */ 610102557Sjake p = td->td_proc; 611102557Sjake p->p_md.md_sigtramp = NULL; 612102557Sjake if ((ut = p->p_md.md_utrap) != NULL) { 61388782Sjake ut->ut_refcnt--; 61488782Sjake if (ut->ut_refcnt == 0) 61588782Sjake free(ut, M_SUBPROC); 616102557Sjake p->p_md.md_utrap = NULL; 61788782Sjake } 61888782Sjake 61983366Sjulian pcb = td->td_pcb; 620105908Sjake tf = td->td_frame; 62188639Sjake sp = rounddown(stack, 16); 62298032Sjake bzero(pcb, sizeof(*pcb)); 62398032Sjake bzero(tf, sizeof(*tf)); 62488639Sjake tf->tf_out[0] = stack; 625105908Sjake tf->tf_out[3] = p->p_sysent->sv_psstrings; 62688639Sjake tf->tf_out[6] = sp - SPOFF - sizeof(struct frame); 62788639Sjake tf->tf_tnpc = entry + 4; 62888639Sjake tf->tf_tpc = entry; 62988639Sjake tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO; 63088639Sjake 63188639Sjake td->td_retval[0] = tf->tf_out[0]; 63288639Sjake td->td_retval[1] = tf->tf_out[1]; 63380708Sjake} 63480708Sjake 63580708Sjakevoid 63680708SjakeDebugger(const char *msg) 63780708Sjake{ 63880709Sjake 63980709Sjake printf("Debugger(\"%s\")\n", msg); 64088436Sjake critical_enter(); 64180709Sjake breakpoint(); 64288436Sjake critical_exit(); 64380708Sjake} 64480708Sjake 64580708Sjakeint 64684178Sjakefill_regs(struct thread *td, struct reg *regs) 64780708Sjake{ 64880708Sjake 649105733Sjake bcopy(td->td_frame, regs, sizeof(*regs)); 65080708Sjake return (0); 65180708Sjake} 65280708Sjake 65380708Sjakeint 65484178Sjakeset_regs(struct thread *td, struct reg *regs) 65580708Sjake{ 65680708Sjake 65784178Sjake if (!TSTATE_SECURE(regs->r_tstate)) 65884178Sjake return (EINVAL); 659105733Sjake bcopy(regs, td->td_frame, sizeof(*regs)); 66080708Sjake return (0); 66180708Sjake} 66280708Sjake 66380708Sjakeint 66485294Sdesfill_dbregs(struct thread *td, struct dbreg *dbregs) 66585294Sdes{ 66685294Sdes 66785294Sdes return (ENOSYS); 66885294Sdes} 66985294Sdes 67085294Sdesint 67185294Sdesset_dbregs(struct thread *td, struct dbreg *dbregs) 67285294Sdes{ 67385294Sdes 67485294Sdes return (ENOSYS); 67585294Sdes} 67685294Sdes 67785294Sdesint 67883366Sjulianfill_fpregs(struct thread *td, struct fpreg *fpregs) 67980708Sjake{ 68088639Sjake struct trapframe *tf; 68184178Sjake struct pcb *pcb; 68284178Sjake 68384178Sjake pcb = td->td_pcb; 68488639Sjake tf = td->td_frame; 68584178Sjake bcopy(pcb->pcb_fpstate.fp_fb, fpregs->fr_regs, 68684178Sjake sizeof(pcb->pcb_fpstate.fp_fb)); 68788639Sjake fpregs->fr_fsr = tf->tf_fsr; 688105733Sjake fpregs->fr_gsr = tf->tf_gsr; 68980708Sjake return (0); 69080708Sjake} 69180708Sjake 69280708Sjakeint 69383366Sjulianset_fpregs(struct thread *td, struct fpreg *fpregs) 69480708Sjake{ 69588639Sjake struct trapframe *tf; 69684178Sjake struct pcb *pcb; 69784178Sjake 69884178Sjake pcb = td->td_pcb; 69988639Sjake tf = td->td_frame; 70084178Sjake bcopy(fpregs->fr_regs, pcb->pcb_fpstate.fp_fb, 70184178Sjake sizeof(fpregs->fr_regs)); 70288639Sjake tf->tf_fsr = fpregs->fr_fsr; 703105733Sjake tf->tf_gsr = fpregs->fr_gsr; 70480708Sjake return (0); 70580708Sjake} 706