machdep.c revision 170170
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 * 4. Neither the name of the University nor the names of its contributors 1982902Sjake * may be used to endorse or promote products derived from this software 2082902Sjake * without specific prior written permission. 2180708Sjake * 2282902Sjake * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2380708Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2480708Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2582902Sjake * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2680708Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2780708Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2880708Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2980708Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3080708Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3180708Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3280708Sjake * SUCH DAMAGE. 3380708Sjake * 3482902Sjake * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 3582902Sjake * from: FreeBSD: src/sys/i386/i386/machdep.c,v 1.477 2001/08/27 3680708Sjake */ 3780708Sjake 38145151Smarius#include <sys/cdefs.h> 39145151Smarius__FBSDID("$FreeBSD: head/sys/sparc64/sparc64/machdep.c 170170 2007-05-31 22:52:15Z attilio $"); 40145151Smarius 41105950Speter#include "opt_compat.h" 4280709Sjake#include "opt_ddb.h" 43118239Speter#include "opt_kstack_pages.h" 4485242Sjake#include "opt_msgbuf.h" 4580709Sjake 4680708Sjake#include <sys/param.h> 47141378Snjl#include <sys/malloc.h> 48141378Snjl#include <sys/proc.h> 4980708Sjake#include <sys/systm.h> 50141249Snjl#include <sys/bio.h> 51141249Snjl#include <sys/buf.h> 52141249Snjl#include <sys/bus.h> 53141249Snjl#include <sys/cpu.h> 5480709Sjake#include <sys/cons.h> 55141378Snjl#include <sys/eventhandler.h> 56141378Snjl#include <sys/exec.h> 57102561Sjake#include <sys/imgact.h> 58141378Snjl#include <sys/interrupt.h> 59131950Smarcel#include <sys/kdb.h> 6080709Sjake#include <sys/kernel.h> 6185262Sjake#include <sys/ktr.h> 6280709Sjake#include <sys/linker.h> 6380709Sjake#include <sys/lock.h> 6485242Sjake#include <sys/msgbuf.h> 6580708Sjake#include <sys/mutex.h> 6680709Sjake#include <sys/pcpu.h> 67141378Snjl#include <sys/ptrace.h> 6885242Sjake#include <sys/reboot.h> 6980708Sjake#include <sys/signalvar.h> 7091616Sjake#include <sys/smp.h> 7182902Sjake#include <sys/sysent.h> 7280708Sjake#include <sys/sysproto.h> 7380709Sjake#include <sys/timetc.h> 7491156Sjake#include <sys/ucontext.h> 7580708Sjake 7680708Sjake#include <dev/ofw/openfirm.h> 7780708Sjake 7880709Sjake#include <vm/vm.h> 79141378Snjl#include <vm/vm_extern.h> 8080709Sjake#include <vm/vm_kern.h> 8180709Sjake#include <vm/vm_page.h> 8280709Sjake#include <vm/vm_map.h> 83141378Snjl#include <vm/vm_object.h> 8480709Sjake#include <vm/vm_pager.h> 85141378Snjl#include <vm/vm_param.h> 8680709Sjake 8780709Sjake#include <ddb/ddb.h> 8880709Sjake 89119696Smarcel#include <machine/bus.h> 9086521Sjake#include <machine/cache.h> 9181383Sjake#include <machine/clock.h> 9282902Sjake#include <machine/cpu.h> 9383366Sjulian#include <machine/fp.h> 94112922Sjake#include <machine/fsr.h> 9581383Sjake#include <machine/intr_machdep.h> 9680708Sjake#include <machine/md_var.h> 9788436Sjake#include <machine/metadata.h> 9886147Stmm#include <machine/ofw_machdep.h> 99115971Sjake#include <machine/ofw_mem.h> 100138129Sdas#include <machine/pcb.h> 10180709Sjake#include <machine/pmap.h> 10280709Sjake#include <machine/pstate.h> 10380708Sjake#include <machine/reg.h> 10482902Sjake#include <machine/sigframe.h> 105141378Snjl#include <machine/smp.h> 10681383Sjake#include <machine/tick.h> 10791613Sjake#include <machine/tlb.h> 10882016Sjake#include <machine/tstate.h> 10991616Sjake#include <machine/upa.h> 11082902Sjake#include <machine/ver.h> 11180708Sjake 11280709Sjaketypedef int ofw_vec_t(void *); 11380708Sjake 114131950Smarcel#ifdef DDB 115131950Smarcelextern vm_offset_t ksym_start, ksym_end; 116131950Smarcel#endif 117131950Smarcel 11897445Sjakestruct tlb_entry *kernel_tlbs; 11991616Sjakeint kernel_tlb_slots; 12091616Sjake 12180708Sjakeint cold = 1; 122102600Speterlong Maxmem; 123142956Sweslong realmem; 12480708Sjake 12591360Sjakechar pcpu0[PCPU_PAGES * PAGE_SIZE]; 12689038Sjakestruct trapframe frame0; 12780708Sjake 12889038Sjakevm_offset_t kstack0; 129113238Sjakevm_paddr_t kstack0_phys; 13088781Sjake 13182902Sjakestruct kva_md_info kmi; 13280709Sjake 13380709Sjakeu_long ofw_vec; 13480709Sjakeu_long ofw_tba; 13580709Sjake 136135972Skensmith/* 137135972Skensmith * Note: timer quality for CPU's is set low to try and prevent them from 138135972Skensmith * being chosen as the primary timecounter. The CPU counters are not 139135972Skensmith * synchronized among the CPU's so in MP machines this causes problems 140135972Skensmith * when calculating the time. With this value the CPU's should only be 141135972Skensmith * chosen as the primary timecounter as a last resort. 142135972Skensmith */ 143135972Skensmith 144135972Skensmith#define UP_TICK_QUALITY 1000 145135972Skensmith#define MP_TICK_QUALITY -100 14680709Sjakestatic struct timecounter tick_tc; 14780709Sjake 148106555Stmmchar sparc64_model[32]; 149106555Stmm 150113166Sjakestatic int cpu_use_vis = 1; 151113166Sjake 152113166Sjakecpu_block_copy_t *cpu_block_copy; 153113166Sjakecpu_block_zero_t *cpu_block_zero; 154113166Sjake 15580709Sjakestatic timecounter_get_t tick_get_timecount; 15691616Sjakevoid sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, 15789038Sjake ofw_vec_t *vec); 15886147Stmmvoid sparc64_shutdown_final(void *dummy, int howto); 15980709Sjake 16080709Sjakestatic void cpu_startup(void *); 16180709SjakeSYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 16280709Sjake 16391336SjakeCTASSERT((1 << INT_SHIFT) == sizeof(int)); 16491336SjakeCTASSERT((1 << PTR_SHIFT) == sizeof(char *)); 16591336Sjake 166105733SjakeCTASSERT(sizeof(struct reg) == 256); 167105733SjakeCTASSERT(sizeof(struct fpreg) == 272); 168105733SjakeCTASSERT(sizeof(struct __mcontext) == 512); 169105733Sjake 170113023SjakeCTASSERT((sizeof(struct pcb) & (64 - 1)) == 0); 171113023SjakeCTASSERT((offsetof(struct pcb, pcb_kfp) & (64 - 1)) == 0); 172113023SjakeCTASSERT((offsetof(struct pcb, pcb_ufp) & (64 - 1)) == 0); 173113023SjakeCTASSERT(sizeof(struct pcb) <= ((KSTACK_PAGES * PAGE_SIZE) / 8)); 174113023Sjake 17591360SjakeCTASSERT(sizeof(struct pcpu) <= ((PCPU_PAGES * PAGE_SIZE) / 2)); 17689038Sjake 17780709Sjakestatic void 17880709Sjakecpu_startup(void *arg) 17980709Sjake{ 180115971Sjake vm_paddr_t physsz; 181115971Sjake int i; 18280709Sjake 18380709Sjake tick_tc.tc_get_timecount = tick_get_timecount; 18480709Sjake tick_tc.tc_poll_pps = NULL; 18580709Sjake tick_tc.tc_counter_mask = ~0u; 186105946Stmm tick_tc.tc_frequency = tick_freq; 18780709Sjake tick_tc.tc_name = "tick"; 188135972Skensmith tick_tc.tc_quality = UP_TICK_QUALITY; 189135972Skensmith#ifdef SMP 190135972Skensmith /* 191135972Skensmith * We do not know if each CPU's tick counter is synchronized. 192135972Skensmith */ 193135972Skensmith if (cpu_mp_probe()) 194135972Skensmith tick_tc.tc_quality = MP_TICK_QUALITY; 195135972Skensmith#endif 196135972Skensmith 19780709Sjake tc_init(&tick_tc); 19880709Sjake 199115971Sjake physsz = 0; 200115971Sjake for (i = 0; i < sparc64_nmemreg; i++) 201115971Sjake physsz += sparc64_memreg[i].mr_size; 202115971Sjake printf("real memory = %lu (%lu MB)\n", physsz, 203115971Sjake physsz / (1024 * 1024)); 204155680Sjhb realmem = (long)physsz / PAGE_SIZE; 20580709Sjake 20682902Sjake vm_ksubmap_init(&kmi); 20780709Sjake 20880709Sjake bufinit(); 20980709Sjake vm_pager_bufferinit(); 21080709Sjake 21186147Stmm EVENTHANDLER_REGISTER(shutdown_final, sparc64_shutdown_final, NULL, 21286147Stmm SHUTDOWN_PRI_LAST); 213113338Sjake 214170170Sattilio printf("avail memory = %lu (%lu MB)\n", cnt.v_free_count * PAGE_SIZE, 215170170Sattilio cnt.v_free_count / ((1024 * 1024) / PAGE_SIZE)); 216113338Sjake 217113338Sjake if (bootverbose) 218113338Sjake printf("machine: %s\n", sparc64_model); 219113338Sjake 220113338Sjake cpu_identify(rdpr(ver), tick_freq, PCPU_GET(cpuid)); 22180709Sjake} 22280709Sjake 22387702Sjhbvoid 22487702Sjhbcpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 22587702Sjhb{ 22697265Sjake struct intr_request *ir; 22797265Sjake int i; 22897265Sjake 22997265Sjake pcpu->pc_irtail = &pcpu->pc_irhead; 23097265Sjake for (i = 0; i < IR_FREE; i++) { 23197265Sjake ir = &pcpu->pc_irpool[i]; 23297265Sjake ir->ir_next = pcpu->pc_irfree; 23397265Sjake pcpu->pc_irfree = ir; 23497265Sjake } 23587702Sjhb} 23687702Sjhb 237144637Sjhbvoid 238144637Sjhbspinlock_enter(void) 239144637Sjhb{ 240144637Sjhb struct thread *td; 241145085Sjhb register_t pil; 242144637Sjhb 243144637Sjhb td = curthread; 244144637Sjhb if (td->td_md.md_spinlock_count == 0) { 245145085Sjhb pil = rdpr(pil); 246145151Smarius wrpr(pil, 0, PIL_TICK); 247145085Sjhb td->td_md.md_saved_pil = pil; 248144637Sjhb } 249144637Sjhb td->td_md.md_spinlock_count++; 250144637Sjhb critical_enter(); 251144637Sjhb} 252144637Sjhb 253144637Sjhbvoid 254144637Sjhbspinlock_exit(void) 255144637Sjhb{ 256144637Sjhb struct thread *td; 257144637Sjhb 258144637Sjhb td = curthread; 259144637Sjhb critical_exit(); 260144637Sjhb td->td_md.md_spinlock_count--; 261144637Sjhb if (td->td_md.md_spinlock_count == 0) 262144637Sjhb wrpr(pil, td->td_md.md_saved_pil, 0); 263144637Sjhb} 264144637Sjhb 26580709Sjakeunsigned 26680709Sjaketick_get_timecount(struct timecounter *tc) 26780709Sjake{ 26880709Sjake return ((unsigned)rd(tick)); 26980709Sjake} 27080709Sjake 27180708Sjakevoid 27291616Sjakesparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) 27380708Sjake{ 274101898Sjake phandle_t child; 275101898Sjake phandle_t root; 27689038Sjake struct pcpu *pc; 27786521Sjake vm_offset_t end; 27886521Sjake caddr_t kmdp; 279105946Stmm u_int clock; 280105569Smux char *env; 281101898Sjake char type[8]; 28280709Sjake 28386521Sjake end = 0; 28486521Sjake kmdp = NULL; 28586521Sjake 28680709Sjake /* 287112398Sjake * Find out what kind of cpu we have first, for anything that changes 288112398Sjake * behaviour. 289112398Sjake */ 290112398Sjake cpu_impl = VER_IMPL(rdpr(ver)); 291112398Sjake 292112398Sjake /* 293133862Smarius * Initialize Open Firmware (needed for console). 29480709Sjake */ 29580709Sjake OF_init(vec); 29680709Sjake 29780709Sjake /* 29886521Sjake * Parse metadata if present and fetch parameters. Must be before the 29986521Sjake * console is inited so cninit gets the right value of boothowto. 30086521Sjake */ 30186521Sjake if (mdp != NULL) { 30286521Sjake preload_metadata = mdp; 303114374Speter kmdp = preload_search_by_type("elf kernel"); 30486521Sjake if (kmdp != NULL) { 30586521Sjake boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 30686521Sjake kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 30786521Sjake end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 30891616Sjake kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS, 30991616Sjake int); 31097445Sjake kernel_tlbs = (void *)preload_search_info(kmdp, 31191616Sjake MODINFO_METADATA | MODINFOMD_DTLB); 31286521Sjake } 31386521Sjake } 31486521Sjake 315122462Sjake init_param1(); 316122462Sjake 317122462Sjake root = OF_peer(0); 318122462Sjake for (child = OF_child(root); child != 0; child = OF_peer(child)) { 319122462Sjake OF_getprop(child, "device_type", type, sizeof(type)); 320122462Sjake if (strcmp(type, "cpu") == 0) 321122462Sjake break; 322122462Sjake } 323122462Sjake 324157227Smarius /* 325157227Smarius * Initialize the tick counter. Must be before the console is inited 326157227Smarius * in order to provide the low-level console drivers with a working 327157227Smarius * DELAY(). 328157227Smarius */ 329122462Sjake OF_getprop(child, "clock-frequency", &clock, sizeof(clock)); 330122462Sjake tick_init(clock); 331122462Sjake 33286521Sjake /* 33380709Sjake * Initialize the console before printing anything. 33480709Sjake */ 33588639Sjake cninit(); 33680709Sjake 33780709Sjake /* 338157227Smarius * Panic if there is no metadata. Most likely the kernel was booted 33986521Sjake * directly, instead of through loader(8). 34080709Sjake */ 34186521Sjake if (mdp == NULL || kmdp == NULL) { 34286521Sjake printf("sparc64_init: no loader metadata.\n" 34386521Sjake "This probably means you are not using loader(8).\n"); 34486521Sjake panic("sparc64_init"); 34586521Sjake } 34680709Sjake 34781383Sjake /* 34886521Sjake * Sanity check the kernel end, which is important. 34986521Sjake */ 35086521Sjake if (end == 0) { 35186521Sjake printf("sparc64_init: warning, kernel end not specified.\n" 35286521Sjake "Attempting to continue anyway.\n"); 35386521Sjake end = (vm_offset_t)_end; 35486521Sjake } 35586521Sjake 356101898Sjake cache_init(child); 357166968Smarius uma_set_align(cache.dc_linesize - 1); 358101898Sjake 359169178Smarius cpu_block_copy = bcopy; 360169178Smarius cpu_block_zero = bzero; 361113166Sjake getenv_int("machdep.use_vis", &cpu_use_vis); 362113166Sjake if (cpu_use_vis) { 363169178Smarius switch (cpu_impl) { 364169178Smarius case CPU_IMPL_SPARC64: 365169178Smarius case CPU_IMPL_ULTRASPARCI: 366169178Smarius case CPU_IMPL_ULTRASPARCII: 367169178Smarius case CPU_IMPL_ULTRASPARCIIi: 368169178Smarius case CPU_IMPL_ULTRASPARCIIe: 369169178Smarius cpu_block_copy = spitfire_block_copy; 370169178Smarius cpu_block_zero = spitfire_block_zero; 371169178Smarius break; 372169178Smarius } 373113166Sjake } 374113166Sjake 37591616Sjake#ifdef SMP 37691616Sjake mp_tramp = mp_tramp_alloc(); 37791616Sjake#endif 37891616Sjake 37986521Sjake /* 38090625Stmm * Initialize virtual memory and calculate physmem. 38187546Sdillon */ 38290625Stmm pmap_bootstrap(end); 38387546Sdillon 38487546Sdillon /* 38581383Sjake * Initialize tunables. 38681383Sjake */ 38787546Sdillon init_param2(physmem); 388105569Smux env = getenv("kernelname"); 389105569Smux if (env != NULL) { 390105569Smux strlcpy(kernelname, env, sizeof(kernelname)); 391105569Smux freeenv(env); 392105569Smux } 39381085Sjake 39480709Sjake /* 39589038Sjake * Initialize the interrupt tables. 39689038Sjake */ 39790624Stmm intr_init1(); 39880709Sjake 39980709Sjake /* 40080709Sjake * Initialize proc0 stuff (p_contested needs to be done early). 40180709Sjake */ 402163709Sjb proc_linkup(&proc0, &thread0); 40395744Sjake proc0.p_md.md_sigtramp = NULL; 40488822Stmm proc0.p_md.md_utrap = NULL; 40590361Sjulian thread0.td_kstack = kstack0; 40690361Sjulian thread0.td_pcb = (struct pcb *) 40790361Sjulian (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 408105908Sjake frame0.tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_PRIV; 40990361Sjulian thread0.td_frame = &frame0; 41080709Sjake 41180709Sjake /* 41289038Sjake * Prime our per-cpu data page for use. Note, we are using it for our 41389038Sjake * stack, so don't pass the real size (PAGE_SIZE) to pcpu_init or 41489038Sjake * it'll zero it out from under us. 41580709Sjake */ 416163973Sjb pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; 41789038Sjake pcpu_init(pc, 0, sizeof(struct pcpu)); 41890361Sjulian pc->pc_curthread = &thread0; 41991156Sjake pc->pc_curpcb = thread0.td_pcb; 42091616Sjake pc->pc_mid = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); 42191616Sjake pc->pc_addr = (vm_offset_t)pcpu0; 422101898Sjake pc->pc_node = child; 42391613Sjake pc->pc_tlb_ctx = TLB_CTX_USER_MIN; 42491613Sjake pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; 42591613Sjake pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; 42688639Sjake 42780709Sjake /* 428163973Sjb * Initialize global registers. 429163973Sjb */ 430163973Sjb cpu_setregs(pc); 431163973Sjb 432163973Sjb /* 433108301Sjake * Initialize the message buffer (after setting trap table). 43488822Stmm */ 43588822Stmm msgbufinit(msgbufp, MSGBUF_SIZE); 43688822Stmm 43793702Sjhb mutex_init(); 43890624Stmm intr_init2(); 439105946Stmm 440133451Salc /* 441133451Salc * Finish pmap initialization now that we're ready for mutexes. 442133451Salc */ 443133451Salc PMAP_LOCK_INIT(kernel_pmap); 444133451Salc 445106555Stmm OF_getprop(root, "name", sparc64_model, sizeof(sparc64_model) - 1); 446122604Ssimokawa 447131950Smarcel kdb_init(); 448131950Smarcel 449131950Smarcel#ifdef KDB 450122604Ssimokawa if (boothowto & RB_KDB) 451131950Smarcel kdb_enter("Boot flags requested debugger"); 452122604Ssimokawa#endif 45380708Sjake} 45480708Sjake 45580708Sjakevoid 45680709Sjakeset_openfirm_callback(ofw_vec_t *vec) 45780709Sjake{ 45880709Sjake ofw_tba = rdpr(tba); 45980709Sjake ofw_vec = (u_long)vec; 46080709Sjake} 46180709Sjake 46280709Sjakevoid 463151316Sdavidxusendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 46480708Sjake{ 46582902Sjake struct trapframe *tf; 46682902Sjake struct sigframe *sfp; 46782902Sjake struct sigacts *psp; 46882902Sjake struct sigframe sf; 46983366Sjulian struct thread *td; 47085242Sjake struct frame *fp; 47182902Sjake struct proc *p; 47285242Sjake int oonstack; 47382902Sjake u_long sp; 474151316Sdavidxu int sig; 47582902Sjake 47682902Sjake oonstack = 0; 47783366Sjulian td = curthread; 47883366Sjulian p = td->td_proc; 479114983Sjhb PROC_LOCK_ASSERT(p, MA_OWNED); 480151316Sdavidxu sig = ksi->ksi_signo; 48182902Sjake psp = p->p_sigacts; 482114983Sjhb mtx_assert(&psp->ps_mtx, MA_OWNED); 48383366Sjulian tf = td->td_frame; 48482902Sjake sp = tf->tf_sp + SPOFF; 48582902Sjake oonstack = sigonstack(sp); 48682902Sjake 48783366Sjulian CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 48882902Sjake catcher, sig); 48982902Sjake 490102554Sjake /* Make sure we have a signal trampoline to return to. */ 491102554Sjake if (p->p_md.md_sigtramp == NULL) { 492102554Sjake /* 493157445Smarius * No signal trampoline... kill the process. 494102554Sjake */ 495102554Sjake CTR0(KTR_SIG, "sendsig: no sigtramp"); 496102873Sjake printf("sendsig: %s is too old, rebuild it\n", p->p_comm); 497102554Sjake sigexit(td, sig); 498102554Sjake /* NOTREACHED */ 499102554Sjake } 500102554Sjake 50182902Sjake /* Save user context. */ 50282902Sjake bzero(&sf, sizeof(sf)); 503118708Sjake get_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 50482902Sjake sf.sf_uc.uc_sigmask = *mask; 505124092Sdavidxu sf.sf_uc.uc_stack = td->td_sigstk; 506124092Sdavidxu sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 50782902Sjake ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 50882902Sjake 50982902Sjake /* Allocate and validate space for the signal handler context. */ 510124092Sdavidxu if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 51182902Sjake SIGISMEMBER(psp->ps_sigonstack, sig)) { 512124092Sdavidxu sfp = (struct sigframe *)(td->td_sigstk.ss_sp + 513124092Sdavidxu td->td_sigstk.ss_size - sizeof(struct sigframe)); 51482902Sjake } else 51582902Sjake sfp = (struct sigframe *)sp - 1; 516114983Sjhb mtx_unlock(&psp->ps_mtx); 51782902Sjake PROC_UNLOCK(p); 51882902Sjake 51985242Sjake fp = (struct frame *)sfp - 1; 52082902Sjake 52182902Sjake /* Translate the signal if appropriate. */ 52282902Sjake if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 52382902Sjake sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 52482902Sjake 52582902Sjake /* Build the argument list for the signal handler. */ 52682902Sjake tf->tf_out[0] = sig; 52782902Sjake tf->tf_out[2] = (register_t)&sfp->sf_uc; 52882902Sjake tf->tf_out[4] = (register_t)catcher; 529157445Smarius if (SIGISMEMBER(psp->ps_siginfo, sig)) { 530157445Smarius /* Signal handler installed with SA_SIGINFO. */ 531157445Smarius tf->tf_out[1] = (register_t)&sfp->sf_si; 53282902Sjake 533157445Smarius /* Fill in POSIX parts. */ 534157445Smarius sf.sf_si = ksi->ksi_info; 535157445Smarius sf.sf_si.si_signo = sig; /* maybe a translated signal */ 536157445Smarius } else { 537157445Smarius /* Old FreeBSD-style arguments. */ 538157445Smarius tf->tf_out[1] = ksi->ksi_code; 539157445Smarius tf->tf_out[3] = (register_t)ksi->ksi_addr; 540157445Smarius } 541157445Smarius 54282902Sjake /* Copy the sigframe out to the user's stack. */ 54385242Sjake if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 || 54494254Sjake suword(&fp->fr_in[6], tf->tf_out[6]) != 0) { 54582902Sjake /* 54682902Sjake * Something is wrong with the stack pointer. 54782902Sjake * ...Kill the process. 54882902Sjake */ 54983366Sjulian CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 55082902Sjake PROC_LOCK(p); 55183366Sjulian sigexit(td, SIGILL); 55282902Sjake /* NOTREACHED */ 55382902Sjake } 55482902Sjake 555102554Sjake tf->tf_tpc = (u_long)p->p_md.md_sigtramp; 55682902Sjake tf->tf_tnpc = tf->tf_tpc + 4; 55785242Sjake tf->tf_sp = (u_long)fp - SPOFF; 55882902Sjake 55983366Sjulian CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, 56082902Sjake tf->tf_sp); 56184178Sjake 56284178Sjake PROC_LOCK(p); 563114983Sjhb mtx_lock(&psp->ps_mtx); 56480708Sjake} 56580708Sjake 56680708Sjake#ifndef _SYS_SYSPROTO_H_ 56783088Sobrienstruct sigreturn_args { 56880708Sjake ucontext_t *ucp; 56980708Sjake}; 57080708Sjake#endif 57180708Sjake 57294606Salc/* 57394606Salc * MPSAFE 57494606Salc */ 57580708Sjakeint 57683366Sjuliansigreturn(struct thread *td, struct sigreturn_args *uap) 57780708Sjake{ 57883366Sjulian struct proc *p; 579118768Sjake mcontext_t *mc; 58082902Sjake ucontext_t uc; 581118708Sjake int error; 58282902Sjake 58383366Sjulian p = td->td_proc; 58483366Sjulian if (rwindow_save(td)) { 58582902Sjake PROC_LOCK(p); 58683366Sjulian sigexit(td, SIGILL); 58782902Sjake } 58882902Sjake 58983366Sjulian CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 59082902Sjake if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 59183366Sjulian CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 59282902Sjake return (EFAULT); 59382902Sjake } 59482902Sjake 595118768Sjake mc = &uc.uc_mcontext; 596118768Sjake error = set_mcontext(td, mc); 597118708Sjake if (error != 0) 598118708Sjake return (error); 59982902Sjake 60082902Sjake PROC_LOCK(p); 601112888Sjeff td->td_sigmask = uc.uc_sigmask; 602112888Sjeff SIG_CANTMASK(td->td_sigmask); 603112888Sjeff signotify(td); 60482902Sjake PROC_UNLOCK(p); 605105733Sjake 60683366Sjulian CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", 607118768Sjake td, mc->mc_tpc, mc->mc_sp, mc->mc_tstate); 60882902Sjake return (EJUSTRETURN); 60980708Sjake} 61080708Sjake 611105950Speter#ifdef COMPAT_FREEBSD4 612105950Speterint 613105950Speterfreebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 614105950Speter{ 615105950Speter 616105950Speter return sigreturn(td, (struct sigreturn_args *)uap); 617105950Speter} 618105950Speter#endif 619105950Speter 620131905Smarcel/* 621131905Smarcel * Construct a PCB from a trapframe. This is called from kdb_trap() where 622131905Smarcel * we want to start a backtrace from the function that caused us to enter 623131905Smarcel * the debugger. We have the context in the trapframe, but base the trace 624131905Smarcel * on the PCB. The PCB doesn't have to be perfect, as long as it contains 625131905Smarcel * enough for a backtrace. 626131905Smarcel */ 627131905Smarcelvoid 628131905Smarcelmakectx(struct trapframe *tf, struct pcb *pcb) 629131905Smarcel{ 630131905Smarcel 631131905Smarcel pcb->pcb_pc = tf->tf_tpc; 632131905Smarcel pcb->pcb_sp = tf->tf_sp; 633131905Smarcel} 634131905Smarcel 635106977Sdeischenint 636122364Smarcelget_mcontext(struct thread *td, mcontext_t *mc, int flags) 637106977Sdeischen{ 638112924Sjake struct trapframe *tf; 639112924Sjake struct pcb *pcb; 640106977Sdeischen 641112924Sjake tf = td->td_frame; 642112924Sjake pcb = td->td_pcb; 643112924Sjake bcopy(tf, mc, sizeof(*tf)); 644122364Smarcel if (flags & GET_MC_CLEAR_RET) { 645113998Sdeischen mc->mc_out[0] = 0; 646113998Sdeischen mc->mc_out[1] = 0; 647113998Sdeischen } 648112961Sjake mc->mc_flags = _MC_VERSION; 649112924Sjake critical_enter(); 650112961Sjake if ((tf->tf_fprs & FPRS_FEF) != 0) { 651112961Sjake savefpctx(pcb->pcb_ufp); 652112961Sjake tf->tf_fprs &= ~FPRS_FEF; 653112961Sjake pcb->pcb_flags |= PCB_FEF; 654112961Sjake } 655112961Sjake if ((pcb->pcb_flags & PCB_FEF) != 0) { 656113018Sjake bcopy(pcb->pcb_ufp, mc->mc_fp, sizeof(mc->mc_fp)); 657112924Sjake mc->mc_fprs |= FPRS_FEF; 658112924Sjake } 659112924Sjake critical_exit(); 660112924Sjake return (0); 661106977Sdeischen} 662106977Sdeischen 663106977Sdeischenint 664112924Sjakeset_mcontext(struct thread *td, const mcontext_t *mc) 665106977Sdeischen{ 666112924Sjake struct trapframe *tf; 667112924Sjake struct pcb *pcb; 668112924Sjake uint64_t wstate; 669106977Sdeischen 670112961Sjake if (!TSTATE_SECURE(mc->mc_tstate) || 671112961Sjake (mc->mc_flags & ((1L << _MC_VERSION_BITS) - 1)) != _MC_VERSION) 672112924Sjake return (EINVAL); 673112924Sjake tf = td->td_frame; 674112924Sjake pcb = td->td_pcb; 675136325Skensmith /* Make sure the windows are spilled first. */ 676136325Skensmith flushw(); 677112924Sjake wstate = tf->tf_wstate; 678112924Sjake bcopy(mc, tf, sizeof(*tf)); 679112924Sjake tf->tf_wstate = wstate; 680112924Sjake if ((mc->mc_fprs & FPRS_FEF) != 0) { 681112924Sjake tf->tf_fprs = 0; 682113018Sjake bcopy(mc->mc_fp, pcb->pcb_ufp, sizeof(pcb->pcb_ufp)); 683112924Sjake pcb->pcb_flags |= PCB_FEF; 684112924Sjake } 685112924Sjake return (0); 686106977Sdeischen} 687106977Sdeischen 68886147Stmm/* 68992205Sjake * Exit the kernel and execute a firmware call that will not return, as 69092205Sjake * specified by the arguments. 69192205Sjake */ 69292205Sjakevoid 69392205Sjakecpu_shutdown(void *args) 69492205Sjake{ 69592205Sjake 69692205Sjake#ifdef SMP 69792205Sjake cpu_mp_shutdown(); 69892205Sjake#endif 69992205Sjake openfirmware_exit(args); 70092205Sjake} 70192205Sjake 702141237Snjl/* Get current clock frequency for the given cpu id. */ 703141237Snjlint 704141237Snjlcpu_est_clockrate(int cpu_id, uint64_t *rate) 705141237Snjl{ 706141237Snjl 707141237Snjl return (ENXIO); 708141237Snjl} 709141237Snjl 71092205Sjake/* 71186147Stmm * Duplicate OF_exit() with a different firmware call function that restores 71286147Stmm * the trap table, otherwise a RED state exception is triggered in at least 71386147Stmm * some firmware versions. 71486147Stmm */ 71580708Sjakevoid 71680708Sjakecpu_halt(void) 71780708Sjake{ 71886147Stmm static struct { 71986147Stmm cell_t name; 72086147Stmm cell_t nargs; 72186147Stmm cell_t nreturns; 72286147Stmm } args = { 72386147Stmm (cell_t)"exit", 72486147Stmm 0, 72586147Stmm 0 72686147Stmm }; 72784178Sjake 72892205Sjake cpu_shutdown(&args); 72980708Sjake} 73080708Sjake 73186147Stmmvoid 73286147Stmmsparc64_shutdown_final(void *dummy, int howto) 73386147Stmm{ 73486147Stmm static struct { 73586147Stmm cell_t name; 73686147Stmm cell_t nargs; 73786147Stmm cell_t nreturns; 73886147Stmm } args = { 73986147Stmm (cell_t)"SUNW,power-off", 74086147Stmm 0, 74186147Stmm 0 74286147Stmm }; 74386147Stmm 74486147Stmm /* Turn the power off? */ 74586147Stmm if ((howto & RB_POWEROFF) != 0) 74692205Sjake cpu_shutdown(&args); 74786147Stmm /* In case of halt, return to the firmware */ 74886147Stmm if ((howto & RB_HALT) != 0) 74986147Stmm cpu_halt(); 75086147Stmm} 75186147Stmm 752121237Spetervoid 753121237Spetercpu_idle(void) 754121237Speter{ 755121237Speter /* Insert code to halt (until next interrupt) for the idle loop */ 756121237Speter} 757121237Speter 75880708Sjakeint 75983366Sjulianptrace_set_pc(struct thread *td, u_long addr) 76080708Sjake{ 76182016Sjake 76283366Sjulian td->td_frame->tf_tpc = addr; 76383366Sjulian td->td_frame->tf_tnpc = addr + 4; 76480708Sjake return (0); 76580708Sjake} 76680708Sjake 76780708Sjakeint 76883366Sjulianptrace_single_step(struct thread *td) 76980708Sjake{ 770104271Sjake /* TODO; */ 77180708Sjake return (0); 77280708Sjake} 77380708Sjake 774132088Sdavidxuint 775132088Sdavidxuptrace_clear_single_step(struct thread *td) 776132088Sdavidxu{ 777132088Sdavidxu /* TODO; */ 778132088Sdavidxu return (0); 779132088Sdavidxu} 780132088Sdavidxu 78180708Sjakevoid 782102561Sjakeexec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 78380708Sjake{ 78488639Sjake struct trapframe *tf; 78581135Stmm struct pcb *pcb; 786102557Sjake struct proc *p; 78784178Sjake u_long sp; 78881135Stmm 78988782Sjake /* XXX no cpu_exec */ 790102557Sjake p = td->td_proc; 791102557Sjake p->p_md.md_sigtramp = NULL; 792140485Sjhb if (p->p_md.md_utrap != NULL) { 793140485Sjhb utrap_free(p->p_md.md_utrap); 794102557Sjake p->p_md.md_utrap = NULL; 79588782Sjake } 79688782Sjake 79783366Sjulian pcb = td->td_pcb; 798105908Sjake tf = td->td_frame; 79988639Sjake sp = rounddown(stack, 16); 80098032Sjake bzero(pcb, sizeof(*pcb)); 80198032Sjake bzero(tf, sizeof(*tf)); 80288639Sjake tf->tf_out[0] = stack; 803105908Sjake tf->tf_out[3] = p->p_sysent->sv_psstrings; 80488639Sjake tf->tf_out[6] = sp - SPOFF - sizeof(struct frame); 80588639Sjake tf->tf_tnpc = entry + 4; 80688639Sjake tf->tf_tpc = entry; 80788639Sjake tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO; 80888639Sjake 80988639Sjake td->td_retval[0] = tf->tf_out[0]; 81088639Sjake td->td_retval[1] = tf->tf_out[1]; 81180708Sjake} 81280708Sjake 81380708Sjakeint 81484178Sjakefill_regs(struct thread *td, struct reg *regs) 81580708Sjake{ 81680708Sjake 817105733Sjake bcopy(td->td_frame, regs, sizeof(*regs)); 81880708Sjake return (0); 81980708Sjake} 82080708Sjake 82180708Sjakeint 82284178Sjakeset_regs(struct thread *td, struct reg *regs) 82380708Sjake{ 824112922Sjake struct trapframe *tf; 82580708Sjake 82684178Sjake if (!TSTATE_SECURE(regs->r_tstate)) 82784178Sjake return (EINVAL); 828112922Sjake tf = td->td_frame; 829112922Sjake regs->r_wstate = tf->tf_wstate; 830112922Sjake bcopy(regs, tf, sizeof(*regs)); 83180708Sjake return (0); 83280708Sjake} 83380708Sjake 83480708Sjakeint 83585294Sdesfill_dbregs(struct thread *td, struct dbreg *dbregs) 83685294Sdes{ 83785294Sdes 83885294Sdes return (ENOSYS); 83985294Sdes} 84085294Sdes 84185294Sdesint 84285294Sdesset_dbregs(struct thread *td, struct dbreg *dbregs) 84385294Sdes{ 84485294Sdes 84585294Sdes return (ENOSYS); 84685294Sdes} 84785294Sdes 84885294Sdesint 84983366Sjulianfill_fpregs(struct thread *td, struct fpreg *fpregs) 85080708Sjake{ 85188639Sjake struct trapframe *tf; 85284178Sjake struct pcb *pcb; 85384178Sjake 85484178Sjake pcb = td->td_pcb; 85588639Sjake tf = td->td_frame; 856112920Sjake bcopy(pcb->pcb_ufp, fpregs->fr_regs, sizeof(fpregs->fr_regs)); 85788639Sjake fpregs->fr_fsr = tf->tf_fsr; 858105733Sjake fpregs->fr_gsr = tf->tf_gsr; 85980708Sjake return (0); 86080708Sjake} 86180708Sjake 86280708Sjakeint 86383366Sjulianset_fpregs(struct thread *td, struct fpreg *fpregs) 86480708Sjake{ 86588639Sjake struct trapframe *tf; 86684178Sjake struct pcb *pcb; 86784178Sjake 86884178Sjake pcb = td->td_pcb; 86988639Sjake tf = td->td_frame; 870112922Sjake tf->tf_fprs &= ~FPRS_FEF; 871112920Sjake bcopy(fpregs->fr_regs, pcb->pcb_ufp, sizeof(pcb->pcb_ufp)); 87288639Sjake tf->tf_fsr = fpregs->fr_fsr; 873105733Sjake tf->tf_gsr = fpregs->fr_gsr; 87480708Sjake return (0); 87580708Sjake} 876140485Sjhb 877140485Sjhbstruct md_utrap * 878140485Sjhbutrap_alloc(void) 879140485Sjhb{ 880140485Sjhb struct md_utrap *ut; 881140485Sjhb 882140485Sjhb ut = malloc(sizeof(struct md_utrap), M_SUBPROC, M_WAITOK | M_ZERO); 883140485Sjhb ut->ut_refcnt = 1; 884140485Sjhb return (ut); 885140485Sjhb} 886140485Sjhb 887140485Sjhbvoid 888140485Sjhbutrap_free(struct md_utrap *ut) 889140485Sjhb{ 890140485Sjhb int refcnt; 891140485Sjhb 892140485Sjhb if (ut == NULL) 893140485Sjhb return; 894140485Sjhb mtx_pool_lock(mtxpool_sleep, ut); 895140485Sjhb ut->ut_refcnt--; 896140485Sjhb refcnt = ut->ut_refcnt; 897140485Sjhb mtx_pool_unlock(mtxpool_sleep, ut); 898140485Sjhb if (refcnt == 0) 899140485Sjhb free(ut, M_SUBPROC); 900140485Sjhb} 901140485Sjhb 902140485Sjhbstruct md_utrap * 903140485Sjhbutrap_hold(struct md_utrap *ut) 904140485Sjhb{ 905140485Sjhb 906140485Sjhb if (ut == NULL) 907140485Sjhb return (NULL); 908140485Sjhb mtx_pool_lock(mtxpool_sleep, ut); 909140485Sjhb ut->ut_refcnt++; 910140485Sjhb mtx_pool_unlock(mtxpool_sleep, ut); 911140485Sjhb return (ut); 912140485Sjhb} 913