machdep.c revision 108301
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 108301 2002-12-27 01:50:29Z jake $ 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 /* 21080709Sjake * Initialize openfirmware (needed for console). 21180709Sjake */ 21280709Sjake OF_init(vec); 21380709Sjake 21480709Sjake /* 21586521Sjake * Parse metadata if present and fetch parameters. Must be before the 21686521Sjake * console is inited so cninit gets the right value of boothowto. 21786521Sjake */ 21886521Sjake if (mdp != NULL) { 21986521Sjake preload_metadata = mdp; 22086521Sjake kmdp = preload_search_by_type("elf kernel"); 22186521Sjake if (kmdp != NULL) { 22286521Sjake boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 22386521Sjake kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 22486521Sjake end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 22591616Sjake kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS, 22691616Sjake int); 22797445Sjake kernel_tlbs = (void *)preload_search_info(kmdp, 22891616Sjake MODINFO_METADATA | MODINFOMD_DTLB); 22986521Sjake } 23086521Sjake } 23186521Sjake 23286521Sjake /* 23380709Sjake * Initialize the console before printing anything. 23480709Sjake */ 23588639Sjake cninit(); 23680709Sjake 23780709Sjake /* 23886521Sjake * Panic is there is no metadata. Most likely the kernel was booted 23986521Sjake * directly, instead of through loader(8). 24080709Sjake */ 24186521Sjake if (mdp == NULL || kmdp == NULL) { 24286521Sjake printf("sparc64_init: no loader metadata.\n" 24386521Sjake "This probably means you are not using loader(8).\n"); 24486521Sjake panic("sparc64_init"); 24586521Sjake } 24680709Sjake 24781383Sjake /* 24886521Sjake * Sanity check the kernel end, which is important. 24986521Sjake */ 25086521Sjake if (end == 0) { 25186521Sjake printf("sparc64_init: warning, kernel end not specified.\n" 25286521Sjake "Attempting to continue anyway.\n"); 25386521Sjake end = (vm_offset_t)_end; 25486521Sjake } 25586521Sjake 256101898Sjake root = OF_peer(0); 257101898Sjake for (child = OF_child(root); child != 0; child = OF_peer(child)) { 258101898Sjake OF_getprop(child, "device_type", type, sizeof(type)); 259101898Sjake if (strcmp(type, "cpu") == 0) 260101898Sjake break; 261101898Sjake } 262101898Sjake if (child == 0) 263101898Sjake panic("cpu_startup: no cpu\n"); 264101898Sjake OF_getprop(child, "#dtlb-entries", &tlb_dtlb_entries, 265101898Sjake sizeof(tlb_dtlb_entries)); 266101898Sjake OF_getprop(child, "#itlb-entries", &tlb_itlb_entries, 267101898Sjake sizeof(tlb_itlb_entries)); 268101898Sjake 269101898Sjake cache_init(child); 270101898Sjake 27190625Stmm#ifdef DDB 27290625Stmm kdb_init(); 27390625Stmm#endif 27490625Stmm 27591616Sjake#ifdef SMP 27691616Sjake mp_tramp = mp_tramp_alloc(); 27791616Sjake#endif 27891616Sjake 27986521Sjake /* 28090625Stmm * Initialize virtual memory and calculate physmem. 28187546Sdillon */ 28290625Stmm pmap_bootstrap(end); 28387546Sdillon 28487546Sdillon /* 28581383Sjake * Initialize tunables. 28681383Sjake */ 28787546Sdillon init_param1(); 28887546Sdillon init_param2(physmem); 289105569Smux env = getenv("kernelname"); 290105569Smux if (env != NULL) { 291105569Smux strlcpy(kernelname, env, sizeof(kernelname)); 292105569Smux freeenv(env); 293105569Smux } 29481085Sjake 29580709Sjake /* 29681383Sjake * Disable tick for now. 29780709Sjake */ 29881383Sjake tick_stop(); 29980709Sjake 30089038Sjake /* 30189038Sjake * Initialize the interrupt tables. 30289038Sjake */ 30390624Stmm intr_init1(); 30480709Sjake 30580709Sjake /* 30680709Sjake * Initialize proc0 stuff (p_contested needs to be done early). 30780709Sjake */ 308103367Sjulian proc_linkup(&proc0, &ksegrp0, &kse0, &thread0); 30995744Sjake proc0.p_md.md_sigtramp = NULL; 31088822Stmm proc0.p_md.md_utrap = NULL; 31189038Sjake proc0.p_uarea = (struct user *)uarea0; 31283366Sjulian proc0.p_stats = &proc0.p_uarea->u_stats; 31390361Sjulian thread0.td_kstack = kstack0; 31490361Sjulian thread0.td_pcb = (struct pcb *) 31590361Sjulian (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 316105908Sjake frame0.tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_PRIV; 31790361Sjulian thread0.td_frame = &frame0; 31880709Sjake 31980709Sjake /* 32089038Sjake * Prime our per-cpu data page for use. Note, we are using it for our 32189038Sjake * stack, so don't pass the real size (PAGE_SIZE) to pcpu_init or 32289038Sjake * it'll zero it out from under us. 32380709Sjake */ 32491360Sjake pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; 32589038Sjake pcpu_init(pc, 0, sizeof(struct pcpu)); 32690361Sjulian pc->pc_curthread = &thread0; 32791156Sjake pc->pc_curpcb = thread0.td_pcb; 32891616Sjake pc->pc_mid = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); 32991616Sjake pc->pc_addr = (vm_offset_t)pcpu0; 330101898Sjake pc->pc_node = child; 33191613Sjake pc->pc_tlb_ctx = TLB_CTX_USER_MIN; 33291613Sjake pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; 33391613Sjake pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; 33488639Sjake 33580709Sjake /* 33689038Sjake * Initialize global registers. 33781383Sjake */ 33889038Sjake cpu_setregs(pc); 33988639Sjake 34088639Sjake /* 341108301Sjake * Initialize the message buffer (after setting trap table). 34288822Stmm */ 34388822Stmm msgbufinit(msgbufp, MSGBUF_SIZE); 34488822Stmm 34593702Sjhb mutex_init(); 34690624Stmm intr_init2(); 347105946Stmm 348105946Stmm OF_getprop(PCPU_GET(node), "clock-frequency", &clock, sizeof(clock)); 349105946Stmm tick_init(clock); 350106555Stmm 351106555Stmm OF_getprop(root, "name", sparc64_model, sizeof(sparc64_model) - 1); 35280708Sjake} 35380708Sjake 35480708Sjakevoid 35580709Sjakeset_openfirm_callback(ofw_vec_t *vec) 35680709Sjake{ 35780709Sjake ofw_tba = rdpr(tba); 35880709Sjake ofw_vec = (u_long)vec; 35980709Sjake} 36080709Sjake 36180709Sjakevoid 36280708Sjakesendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 36380708Sjake{ 36482902Sjake struct trapframe *tf; 36582902Sjake struct sigframe *sfp; 36682902Sjake struct sigacts *psp; 36782902Sjake struct sigframe sf; 36883366Sjulian struct thread *td; 36985242Sjake struct frame *fp; 37082902Sjake struct proc *p; 37185242Sjake int oonstack; 37282902Sjake u_long sp; 37382902Sjake 37482902Sjake oonstack = 0; 37583366Sjulian td = curthread; 37683366Sjulian p = td->td_proc; 37782902Sjake psp = p->p_sigacts; 37883366Sjulian tf = td->td_frame; 37982902Sjake sp = tf->tf_sp + SPOFF; 38082902Sjake oonstack = sigonstack(sp); 38182902Sjake 38283366Sjulian CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 38382902Sjake catcher, sig); 38482902Sjake 385102554Sjake /* Make sure we have a signal trampoline to return to. */ 386102554Sjake if (p->p_md.md_sigtramp == NULL) { 387102554Sjake /* 388102554Sjake * No signal tramoline... kill the process. 389102554Sjake */ 390102554Sjake CTR0(KTR_SIG, "sendsig: no sigtramp"); 391102873Sjake printf("sendsig: %s is too old, rebuild it\n", p->p_comm); 392102554Sjake sigexit(td, sig); 393102554Sjake /* NOTREACHED */ 394102554Sjake } 395102554Sjake 39682902Sjake /* Save user context. */ 39782902Sjake bzero(&sf, sizeof(sf)); 39882902Sjake sf.sf_uc.uc_sigmask = *mask; 39982902Sjake sf.sf_uc.uc_stack = p->p_sigstk; 40082902Sjake sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) 40182902Sjake ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 402105733Sjake bcopy(tf, &sf.sf_uc.uc_mcontext, sizeof(*tf)); 40382902Sjake 40482902Sjake /* Allocate and validate space for the signal handler context. */ 40582902Sjake if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && 40682902Sjake SIGISMEMBER(psp->ps_sigonstack, sig)) { 40782902Sjake sfp = (struct sigframe *)(p->p_sigstk.ss_sp + 40882902Sjake p->p_sigstk.ss_size - sizeof(struct sigframe)); 40982902Sjake } else 41082902Sjake sfp = (struct sigframe *)sp - 1; 41182902Sjake PROC_UNLOCK(p); 41282902Sjake 41385242Sjake fp = (struct frame *)sfp - 1; 41482902Sjake 41582902Sjake /* Translate the signal if appropriate. */ 41682902Sjake if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 41782902Sjake sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 41882902Sjake 41982902Sjake /* Build the argument list for the signal handler. */ 42082902Sjake tf->tf_out[0] = sig; 421105733Sjake tf->tf_out[1] = (register_t)&sfp->sf_si; 42282902Sjake tf->tf_out[2] = (register_t)&sfp->sf_uc; 42382902Sjake tf->tf_out[4] = (register_t)catcher; 424105733Sjake /* Fill siginfo structure. */ 425105733Sjake sf.sf_si.si_signo = sig; 426105733Sjake sf.sf_si.si_code = code; 427105733Sjake sf.sf_si.si_addr = (void *)tf->tf_sfar; 42882902Sjake 42982902Sjake /* Copy the sigframe out to the user's stack. */ 43085242Sjake if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 || 43194254Sjake suword(&fp->fr_in[6], tf->tf_out[6]) != 0) { 43282902Sjake /* 43382902Sjake * Something is wrong with the stack pointer. 43482902Sjake * ...Kill the process. 43582902Sjake */ 43683366Sjulian CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 43782902Sjake PROC_LOCK(p); 43883366Sjulian sigexit(td, SIGILL); 43982902Sjake /* NOTREACHED */ 44082902Sjake } 44182902Sjake 442102554Sjake tf->tf_tpc = (u_long)p->p_md.md_sigtramp; 44382902Sjake tf->tf_tnpc = tf->tf_tpc + 4; 44485242Sjake tf->tf_sp = (u_long)fp - SPOFF; 44582902Sjake 44683366Sjulian CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, 44782902Sjake tf->tf_sp); 44884178Sjake 44984178Sjake PROC_LOCK(p); 45080708Sjake} 45180708Sjake 45280708Sjake#ifndef _SYS_SYSPROTO_H_ 45383088Sobrienstruct sigreturn_args { 45480708Sjake ucontext_t *ucp; 45580708Sjake}; 45680708Sjake#endif 45780708Sjake 45894606Salc/* 45994606Salc * MPSAFE 46094606Salc */ 46180708Sjakeint 46283366Sjuliansigreturn(struct thread *td, struct sigreturn_args *uap) 46380708Sjake{ 46483366Sjulian struct proc *p; 46582902Sjake ucontext_t uc; 46682902Sjake 46783366Sjulian p = td->td_proc; 46883366Sjulian if (rwindow_save(td)) { 46982902Sjake PROC_LOCK(p); 47083366Sjulian sigexit(td, SIGILL); 47182902Sjake } 47282902Sjake 47383366Sjulian CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 47482902Sjake if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 47583366Sjulian CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 47682902Sjake return (EFAULT); 47782902Sjake } 47882902Sjake 47984178Sjake if (!TSTATE_SECURE(uc.uc_mcontext.mc_tstate)) 48084178Sjake return (EINVAL); 481105733Sjake bcopy(&uc.uc_mcontext, td->td_frame, sizeof(*td->td_frame)); 48282902Sjake 48382902Sjake PROC_LOCK(p); 48482902Sjake p->p_sigmask = uc.uc_sigmask; 48582902Sjake SIG_CANTMASK(p->p_sigmask); 48693793Sbde signotify(p); 48782902Sjake PROC_UNLOCK(p); 488105733Sjake 48983366Sjulian CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", 490105733Sjake td, td->td_frame->tf_tpc, td->td_frame->tf_sp, 491105733Sjake td->td_frame->tf_tstate); 49282902Sjake return (EJUSTRETURN); 49380708Sjake} 49480708Sjake 495105950Speter#ifdef COMPAT_FREEBSD4 496105950Speterint 497105950Speterfreebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 498105950Speter{ 499105950Speter 500105950Speter return sigreturn(td, (struct sigreturn_args *)uap); 501105950Speter} 502105950Speter#endif 503105950Speter 504106977Sdeischenint 505106977Sdeischenget_mcontext(struct thread *td, mcontext_t *mcp) 506106977Sdeischen{ 507106977Sdeischen 508106977Sdeischen return (ENOSYS); 509106977Sdeischen} 510106977Sdeischen 511106977Sdeischenint 512106977Sdeischenset_mcontext(struct thread *td, const mcontext_t *mcp) 513106977Sdeischen{ 514106977Sdeischen 515106977Sdeischen return (ENOSYS); 516106977Sdeischen} 517106977Sdeischen 51886147Stmm/* 51992205Sjake * Exit the kernel and execute a firmware call that will not return, as 52092205Sjake * specified by the arguments. 52192205Sjake */ 52292205Sjakevoid 52392205Sjakecpu_shutdown(void *args) 52492205Sjake{ 52592205Sjake 52692205Sjake#ifdef SMP 52792205Sjake cpu_mp_shutdown(); 52892205Sjake#endif 52992205Sjake openfirmware_exit(args); 53092205Sjake} 53192205Sjake 53292205Sjake/* 53386147Stmm * Duplicate OF_exit() with a different firmware call function that restores 53486147Stmm * the trap table, otherwise a RED state exception is triggered in at least 53586147Stmm * some firmware versions. 53686147Stmm */ 53780708Sjakevoid 53880708Sjakecpu_halt(void) 53980708Sjake{ 54086147Stmm static struct { 54186147Stmm cell_t name; 54286147Stmm cell_t nargs; 54386147Stmm cell_t nreturns; 54486147Stmm } args = { 54586147Stmm (cell_t)"exit", 54686147Stmm 0, 54786147Stmm 0 54886147Stmm }; 54984178Sjake 55092205Sjake cpu_shutdown(&args); 55180708Sjake} 55280708Sjake 55386147Stmmvoid 55486147Stmmsparc64_shutdown_final(void *dummy, int howto) 55586147Stmm{ 55686147Stmm static struct { 55786147Stmm cell_t name; 55886147Stmm cell_t nargs; 55986147Stmm cell_t nreturns; 56086147Stmm } args = { 56186147Stmm (cell_t)"SUNW,power-off", 56286147Stmm 0, 56386147Stmm 0 56486147Stmm }; 56586147Stmm 56686147Stmm /* Turn the power off? */ 56786147Stmm if ((howto & RB_POWEROFF) != 0) 56892205Sjake cpu_shutdown(&args); 56986147Stmm /* In case of halt, return to the firmware */ 57086147Stmm if ((howto & RB_HALT) != 0) 57186147Stmm cpu_halt(); 57286147Stmm} 57386147Stmm 57480708Sjakeint 57583366Sjulianptrace_set_pc(struct thread *td, u_long addr) 57680708Sjake{ 57782016Sjake 57883366Sjulian td->td_frame->tf_tpc = addr; 57983366Sjulian td->td_frame->tf_tnpc = addr + 4; 58080708Sjake return (0); 58180708Sjake} 58280708Sjake 58380708Sjakeint 58483366Sjulianptrace_single_step(struct thread *td) 58580708Sjake{ 586104271Sjake /* TODO; */ 58780708Sjake return (0); 58880708Sjake} 58980708Sjake 59080708Sjakevoid 591102561Sjakeexec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 59280708Sjake{ 59388639Sjake struct trapframe *tf; 59488782Sjake struct md_utrap *ut; 59581135Stmm struct pcb *pcb; 596102557Sjake struct proc *p; 59784178Sjake u_long sp; 59881135Stmm 59988782Sjake /* XXX no cpu_exec */ 600102557Sjake p = td->td_proc; 601102557Sjake p->p_md.md_sigtramp = NULL; 602102557Sjake if ((ut = p->p_md.md_utrap) != NULL) { 60388782Sjake ut->ut_refcnt--; 60488782Sjake if (ut->ut_refcnt == 0) 60588782Sjake free(ut, M_SUBPROC); 606102557Sjake p->p_md.md_utrap = NULL; 60788782Sjake } 60888782Sjake 60983366Sjulian pcb = td->td_pcb; 610105908Sjake tf = td->td_frame; 61188639Sjake sp = rounddown(stack, 16); 61298032Sjake bzero(pcb, sizeof(*pcb)); 61398032Sjake bzero(tf, sizeof(*tf)); 61488639Sjake tf->tf_out[0] = stack; 615105908Sjake tf->tf_out[3] = p->p_sysent->sv_psstrings; 61688639Sjake tf->tf_out[6] = sp - SPOFF - sizeof(struct frame); 61788639Sjake tf->tf_tnpc = entry + 4; 61888639Sjake tf->tf_tpc = entry; 61988639Sjake tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO; 62088639Sjake 62188639Sjake td->td_retval[0] = tf->tf_out[0]; 62288639Sjake td->td_retval[1] = tf->tf_out[1]; 62380708Sjake} 62480708Sjake 62580708Sjakevoid 62680708SjakeDebugger(const char *msg) 62780708Sjake{ 62880709Sjake 62980709Sjake printf("Debugger(\"%s\")\n", msg); 63088436Sjake critical_enter(); 63180709Sjake breakpoint(); 63288436Sjake critical_exit(); 63380708Sjake} 63480708Sjake 63580708Sjakeint 63684178Sjakefill_regs(struct thread *td, struct reg *regs) 63780708Sjake{ 63880708Sjake 639105733Sjake bcopy(td->td_frame, regs, sizeof(*regs)); 64080708Sjake return (0); 64180708Sjake} 64280708Sjake 64380708Sjakeint 64484178Sjakeset_regs(struct thread *td, struct reg *regs) 64580708Sjake{ 64680708Sjake 64784178Sjake if (!TSTATE_SECURE(regs->r_tstate)) 64884178Sjake return (EINVAL); 649105733Sjake bcopy(regs, td->td_frame, sizeof(*regs)); 65080708Sjake return (0); 65180708Sjake} 65280708Sjake 65380708Sjakeint 65485294Sdesfill_dbregs(struct thread *td, struct dbreg *dbregs) 65585294Sdes{ 65685294Sdes 65785294Sdes return (ENOSYS); 65885294Sdes} 65985294Sdes 66085294Sdesint 66185294Sdesset_dbregs(struct thread *td, struct dbreg *dbregs) 66285294Sdes{ 66385294Sdes 66485294Sdes return (ENOSYS); 66585294Sdes} 66685294Sdes 66785294Sdesint 66883366Sjulianfill_fpregs(struct thread *td, struct fpreg *fpregs) 66980708Sjake{ 67088639Sjake struct trapframe *tf; 67184178Sjake struct pcb *pcb; 67284178Sjake 67384178Sjake pcb = td->td_pcb; 67488639Sjake tf = td->td_frame; 67584178Sjake bcopy(pcb->pcb_fpstate.fp_fb, fpregs->fr_regs, 67684178Sjake sizeof(pcb->pcb_fpstate.fp_fb)); 67788639Sjake fpregs->fr_fsr = tf->tf_fsr; 678105733Sjake fpregs->fr_gsr = tf->tf_gsr; 67980708Sjake return (0); 68080708Sjake} 68180708Sjake 68280708Sjakeint 68383366Sjulianset_fpregs(struct thread *td, struct fpreg *fpregs) 68480708Sjake{ 68588639Sjake struct trapframe *tf; 68684178Sjake struct pcb *pcb; 68784178Sjake 68884178Sjake pcb = td->td_pcb; 68988639Sjake tf = td->td_frame; 69084178Sjake bcopy(fpregs->fr_regs, pcb->pcb_fpstate.fp_fb, 69184178Sjake sizeof(fpregs->fr_regs)); 69288639Sjake tf->tf_fsr = fpregs->fr_fsr; 693105733Sjake tf->tf_gsr = fpregs->fr_gsr; 69480708Sjake return (0); 69580708Sjake} 696