machdep.c revision 214835
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 35181701Smarius * 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 214835 2010-11-05 13:42:58Z jhb $"); 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> 71209613Sjhb#include <sys/syscallsubr.h> 7282902Sjake#include <sys/sysent.h> 7380708Sjake#include <sys/sysproto.h> 7480709Sjake#include <sys/timetc.h> 7591156Sjake#include <sys/ucontext.h> 7680708Sjake 7780708Sjake#include <dev/ofw/openfirm.h> 7880708Sjake 7980709Sjake#include <vm/vm.h> 80141378Snjl#include <vm/vm_extern.h> 8180709Sjake#include <vm/vm_kern.h> 8280709Sjake#include <vm/vm_page.h> 8380709Sjake#include <vm/vm_map.h> 84141378Snjl#include <vm/vm_object.h> 8580709Sjake#include <vm/vm_pager.h> 86141378Snjl#include <vm/vm_param.h> 8780709Sjake 8880709Sjake#include <ddb/ddb.h> 8980709Sjake 90119696Smarcel#include <machine/bus.h> 9186521Sjake#include <machine/cache.h> 9281383Sjake#include <machine/clock.h> 93203838Smarius#include <machine/cmt.h> 9482902Sjake#include <machine/cpu.h> 95203838Smarius#include <machine/fireplane.h> 9683366Sjulian#include <machine/fp.h> 97112922Sjake#include <machine/fsr.h> 9881383Sjake#include <machine/intr_machdep.h> 99203838Smarius#include <machine/jbus.h> 10080708Sjake#include <machine/md_var.h> 10188436Sjake#include <machine/metadata.h> 10286147Stmm#include <machine/ofw_machdep.h> 103115971Sjake#include <machine/ofw_mem.h> 104138129Sdas#include <machine/pcb.h> 10580709Sjake#include <machine/pmap.h> 10680709Sjake#include <machine/pstate.h> 10780708Sjake#include <machine/reg.h> 10882902Sjake#include <machine/sigframe.h> 109141378Snjl#include <machine/smp.h> 11081383Sjake#include <machine/tick.h> 11191613Sjake#include <machine/tlb.h> 11282016Sjake#include <machine/tstate.h> 11391616Sjake#include <machine/upa.h> 11482902Sjake#include <machine/ver.h> 11580708Sjake 11680709Sjaketypedef int ofw_vec_t(void *); 11780708Sjake 118131950Smarcel#ifdef DDB 119131950Smarcelextern vm_offset_t ksym_start, ksym_end; 120131950Smarcel#endif 121131950Smarcel 122186682Smariusint dtlb_slots; 123186682Smariusint itlb_slots; 12497445Sjakestruct tlb_entry *kernel_tlbs; 12591616Sjakeint kernel_tlb_slots; 12691616Sjake 12780708Sjakeint cold = 1; 128102600Speterlong Maxmem; 129142956Sweslong realmem; 13080708Sjake 131194784Sjeffvoid *dpcpu0; 13291360Sjakechar pcpu0[PCPU_PAGES * PAGE_SIZE]; 13389038Sjakestruct trapframe frame0; 13480708Sjake 13589038Sjakevm_offset_t kstack0; 136113238Sjakevm_paddr_t kstack0_phys; 13788781Sjake 13882902Sjakestruct kva_md_info kmi; 13980709Sjake 14080709Sjakeu_long ofw_vec; 14180709Sjakeu_long ofw_tba; 142205409Smariusu_int tba_taken_over; 14380709Sjake 144106555Stmmchar sparc64_model[32]; 145106555Stmm 146113166Sjakestatic int cpu_use_vis = 1; 147113166Sjake 148113166Sjakecpu_block_copy_t *cpu_block_copy; 149113166Sjakecpu_block_zero_t *cpu_block_zero; 150113166Sjake 151204152Smariusstatic phandle_t find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl); 15291616Sjakevoid sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, 153181701Smarius ofw_vec_t *vec); 154203838Smariusstatic void sparc64_shutdown_final(void *dummy, int howto); 15580709Sjake 156203838Smariusstatic void cpu_startup(void *arg); 15780709SjakeSYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 15880709Sjake 15991336SjakeCTASSERT((1 << INT_SHIFT) == sizeof(int)); 16091336SjakeCTASSERT((1 << PTR_SHIFT) == sizeof(char *)); 16191336Sjake 162105733SjakeCTASSERT(sizeof(struct reg) == 256); 163105733SjakeCTASSERT(sizeof(struct fpreg) == 272); 164105733SjakeCTASSERT(sizeof(struct __mcontext) == 512); 165105733Sjake 166113023SjakeCTASSERT((sizeof(struct pcb) & (64 - 1)) == 0); 167113023SjakeCTASSERT((offsetof(struct pcb, pcb_kfp) & (64 - 1)) == 0); 168113023SjakeCTASSERT((offsetof(struct pcb, pcb_ufp) & (64 - 1)) == 0); 169113023SjakeCTASSERT(sizeof(struct pcb) <= ((KSTACK_PAGES * PAGE_SIZE) / 8)); 170113023Sjake 17191360SjakeCTASSERT(sizeof(struct pcpu) <= ((PCPU_PAGES * PAGE_SIZE) / 2)); 17289038Sjake 17380709Sjakestatic void 17480709Sjakecpu_startup(void *arg) 17580709Sjake{ 176115971Sjake vm_paddr_t physsz; 177115971Sjake int i; 17880709Sjake 179115971Sjake physsz = 0; 180115971Sjake for (i = 0; i < sparc64_nmemreg; i++) 181115971Sjake physsz += sparc64_memreg[i].mr_size; 182115971Sjake printf("real memory = %lu (%lu MB)\n", physsz, 183115971Sjake physsz / (1024 * 1024)); 184155680Sjhb realmem = (long)physsz / PAGE_SIZE; 18580709Sjake 18682902Sjake vm_ksubmap_init(&kmi); 18780709Sjake 18880709Sjake bufinit(); 18980709Sjake vm_pager_bufferinit(); 19080709Sjake 19186147Stmm EVENTHANDLER_REGISTER(shutdown_final, sparc64_shutdown_final, NULL, 19286147Stmm SHUTDOWN_PRI_LAST); 193113338Sjake 194170170Sattilio printf("avail memory = %lu (%lu MB)\n", cnt.v_free_count * PAGE_SIZE, 195170170Sattilio cnt.v_free_count / ((1024 * 1024) / PAGE_SIZE)); 196113338Sjake 197113338Sjake if (bootverbose) 198113338Sjake printf("machine: %s\n", sparc64_model); 199113338Sjake 200182730Smarius cpu_identify(rdpr(ver), PCPU_GET(clock), curcpu); 20180709Sjake} 20280709Sjake 20387702Sjhbvoid 20487702Sjhbcpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 20587702Sjhb{ 20697265Sjake struct intr_request *ir; 20797265Sjake int i; 20897265Sjake 20997265Sjake pcpu->pc_irtail = &pcpu->pc_irhead; 21097265Sjake for (i = 0; i < IR_FREE; i++) { 21197265Sjake ir = &pcpu->pc_irpool[i]; 21297265Sjake ir->ir_next = pcpu->pc_irfree; 21397265Sjake pcpu->pc_irfree = ir; 21497265Sjake } 21587702Sjhb} 21687702Sjhb 217144637Sjhbvoid 218144637Sjhbspinlock_enter(void) 219144637Sjhb{ 220144637Sjhb struct thread *td; 221145085Sjhb register_t pil; 222144637Sjhb 223144637Sjhb td = curthread; 224144637Sjhb if (td->td_md.md_spinlock_count == 0) { 225145085Sjhb pil = rdpr(pil); 226145151Smarius wrpr(pil, 0, PIL_TICK); 227214835Sjhb td->td_md.md_spinlock_count = 1; 228145085Sjhb td->td_md.md_saved_pil = pil; 229214835Sjhb } else 230214835Sjhb td->td_md.md_spinlock_count++; 231144637Sjhb critical_enter(); 232144637Sjhb} 233144637Sjhb 234144637Sjhbvoid 235144637Sjhbspinlock_exit(void) 236144637Sjhb{ 237144637Sjhb struct thread *td; 238214835Sjhb register_t pil; 239144637Sjhb 240144637Sjhb td = curthread; 241144637Sjhb critical_exit(); 242214835Sjhb pil = td->td_md.md_saved_pil; 243144637Sjhb td->td_md.md_spinlock_count--; 244144637Sjhb if (td->td_md.md_spinlock_count == 0) 245214835Sjhb wrpr(pil, pil, 0); 246144637Sjhb} 247144637Sjhb 248203838Smariusstatic phandle_t 249204152Smariusfind_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl) 250203838Smarius{ 251203838Smarius char type[sizeof("cpu")]; 252203838Smarius phandle_t child; 253203838Smarius uint32_t cpuid; 254203838Smarius 255203838Smarius for (; node != 0; node = OF_peer(node)) { 256203838Smarius child = OF_child(node); 257203838Smarius if (child > 0) { 258204152Smarius child = find_bsp(child, bspid, cpu_impl); 259203838Smarius if (child > 0) 260203838Smarius return (child); 261203838Smarius } else { 262203838Smarius if (OF_getprop(node, "device_type", type, 263203838Smarius sizeof(type)) <= 0) 264203838Smarius continue; 265203838Smarius if (strcmp(type, "cpu") != 0) 266203838Smarius continue; 267204152Smarius if (OF_getprop(node, cpu_cpuid_prop(cpu_impl), &cpuid, 268203838Smarius sizeof(cpuid)) <= 0) 269203838Smarius continue; 270203838Smarius if (cpuid == bspid) 271203838Smarius return (node); 272203838Smarius } 273203838Smarius } 274203838Smarius return (0); 275203838Smarius} 276203838Smarius 277203838Smariusconst char * 278204152Smariuscpu_cpuid_prop(u_int cpu_impl) 279203838Smarius{ 280203838Smarius 281203838Smarius switch (cpu_impl) { 282203838Smarius case CPU_IMPL_SPARC64: 283207537Smarius case CPU_IMPL_SPARC64V: 284203838Smarius case CPU_IMPL_ULTRASPARCI: 285203838Smarius case CPU_IMPL_ULTRASPARCII: 286203838Smarius case CPU_IMPL_ULTRASPARCIIi: 287203838Smarius case CPU_IMPL_ULTRASPARCIIe: 288203838Smarius return ("upa-portid"); 289203838Smarius case CPU_IMPL_ULTRASPARCIII: 290203838Smarius case CPU_IMPL_ULTRASPARCIIIp: 291203838Smarius case CPU_IMPL_ULTRASPARCIIIi: 292203838Smarius case CPU_IMPL_ULTRASPARCIIIip: 293203838Smarius return ("portid"); 294203838Smarius case CPU_IMPL_ULTRASPARCIV: 295203838Smarius case CPU_IMPL_ULTRASPARCIVp: 296203838Smarius return ("cpuid"); 297203838Smarius default: 298203838Smarius return (""); 299203838Smarius } 300203838Smarius} 301203838Smarius 302203838Smariusuint32_t 303204152Smariuscpu_get_mid(u_int cpu_impl) 304203838Smarius{ 305203838Smarius 306203838Smarius switch (cpu_impl) { 307203838Smarius case CPU_IMPL_SPARC64: 308207537Smarius case CPU_IMPL_SPARC64V: 309203838Smarius case CPU_IMPL_ULTRASPARCI: 310203838Smarius case CPU_IMPL_ULTRASPARCII: 311203838Smarius case CPU_IMPL_ULTRASPARCIIi: 312203838Smarius case CPU_IMPL_ULTRASPARCIIe: 313203838Smarius return (UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG))); 314203838Smarius case CPU_IMPL_ULTRASPARCIII: 315203838Smarius case CPU_IMPL_ULTRASPARCIIIp: 316203838Smarius return (FIREPLANE_CR_GET_AID(ldxa(AA_FIREPLANE_CONFIG, 317203838Smarius ASI_FIREPLANE_CONFIG_REG))); 318203838Smarius case CPU_IMPL_ULTRASPARCIIIi: 319203838Smarius case CPU_IMPL_ULTRASPARCIIIip: 320203838Smarius return (JBUS_CR_GET_JID(ldxa(0, ASI_JBUS_CONFIG_REG))); 321203838Smarius case CPU_IMPL_ULTRASPARCIV: 322203838Smarius case CPU_IMPL_ULTRASPARCIVp: 323203838Smarius return (INTR_ID_GET_ID(ldxa(AA_INTR_ID, ASI_INTR_ID))); 324203838Smarius default: 325203838Smarius return (0); 326203838Smarius } 327203838Smarius} 328203838Smarius 32980708Sjakevoid 33091616Sjakesparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec) 33180708Sjake{ 332181701Smarius char *env; 33389038Sjake struct pcpu *pc; 33486521Sjake vm_offset_t end; 335195149Smarius vm_offset_t va; 33686521Sjake caddr_t kmdp; 337181701Smarius phandle_t root; 338204152Smarius u_int cpu_impl; 33980709Sjake 34086521Sjake end = 0; 34186521Sjake kmdp = NULL; 34286521Sjake 34380709Sjake /* 344181701Smarius * Find out what kind of CPU we have first, for anything that changes 345112398Sjake * behaviour. 346112398Sjake */ 347112398Sjake cpu_impl = VER_IMPL(rdpr(ver)); 348112398Sjake 349112398Sjake /* 350207248Smarius * Do CPU-specific initialization. 351182768Smarius */ 352207537Smarius if (cpu_impl == CPU_IMPL_SPARC64V || 353207537Smarius cpu_impl >= CPU_IMPL_ULTRASPARCIII) 354204152Smarius cheetah_init(cpu_impl); 355182768Smarius 356182768Smarius /* 357182730Smarius * Clear (S)TICK timer (including NPT). 358182730Smarius */ 359204152Smarius tick_clear(cpu_impl); 360182730Smarius 361182730Smarius /* 362182730Smarius * UltraSparc II[e,i] based systems come up with the tick interrupt 363182730Smarius * enabled and a handler that resets the tick counter, causing DELAY() 364182730Smarius * to not work properly when used early in boot. 365182730Smarius * UltraSPARC III based systems come up with the system tick interrupt 366182730Smarius * enabled, causing an interrupt storm on startup since they are not 367182730Smarius * handled. 368182730Smarius */ 369204152Smarius tick_stop(cpu_impl); 370182730Smarius 371182730Smarius /* 372186682Smarius * Set up Open Firmware entry points. 37380709Sjake */ 374186347Snwhitehorn ofw_tba = rdpr(tba); 375186347Snwhitehorn ofw_vec = (u_long)vec; 37680709Sjake 37780709Sjake /* 37886521Sjake * Parse metadata if present and fetch parameters. Must be before the 37986521Sjake * console is inited so cninit gets the right value of boothowto. 38086521Sjake */ 38186521Sjake if (mdp != NULL) { 38286521Sjake preload_metadata = mdp; 383114374Speter kmdp = preload_search_by_type("elf kernel"); 38486521Sjake if (kmdp != NULL) { 38586521Sjake boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 38686521Sjake kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 38786521Sjake end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 38891616Sjake kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS, 38991616Sjake int); 39097445Sjake kernel_tlbs = (void *)preload_search_info(kmdp, 39191616Sjake MODINFO_METADATA | MODINFOMD_DTLB); 39286521Sjake } 39386521Sjake } 39486521Sjake 395122462Sjake init_param1(); 396122462Sjake 397182689Smarius /* 398186347Snwhitehorn * Initialize Open Firmware (needed for console). 399186347Snwhitehorn */ 400186347Snwhitehorn OF_install(OFW_STD_DIRECT, 0); 401186347Snwhitehorn OF_init(ofw_entry); 402186347Snwhitehorn 403186347Snwhitehorn /* 404182689Smarius * Prime our per-CPU data page for use. Note, we are using it for 405182689Smarius * our stack, so don't pass the real size (PAGE_SIZE) to pcpu_init 406182689Smarius * or it'll zero it out from under us. 407182689Smarius */ 408182689Smarius pc = (struct pcpu *)(pcpu0 + (PCPU_PAGES * PAGE_SIZE)) - 1; 409182689Smarius pcpu_init(pc, 0, sizeof(struct pcpu)); 410182689Smarius pc->pc_addr = (vm_offset_t)pcpu0; 411204152Smarius pc->pc_impl = cpu_impl; 412204152Smarius pc->pc_mid = cpu_get_mid(cpu_impl); 413182689Smarius pc->pc_tlb_ctx = TLB_CTX_USER_MIN; 414182689Smarius pc->pc_tlb_ctx_min = TLB_CTX_USER_MIN; 415182689Smarius pc->pc_tlb_ctx_max = TLB_CTX_USER_MAX; 416182689Smarius 417182689Smarius /* 418182730Smarius * Determine the OFW node and frequency of the BSP (and ensure the 419182689Smarius * BSP is in the device tree in the first place). 420182689Smarius */ 421122462Sjake root = OF_peer(0); 422204152Smarius pc->pc_node = find_bsp(root, pc->pc_mid, cpu_impl); 423182689Smarius if (pc->pc_node == 0) 424182689Smarius OF_exit(); 425203838Smarius if (OF_getprop(pc->pc_node, "clock-frequency", &pc->pc_clock, 426182730Smarius sizeof(pc->pc_clock)) <= 0) 427182730Smarius OF_exit(); 428122462Sjake 429157227Smarius /* 430182730Smarius * Provide a DELAY() that works before PCPU_REG is set. We can't 431182730Smarius * set PCPU_REG without also taking over the trap table or the 432182730Smarius * firmware will overwrite it. Unfortunately, it's way to early 433182730Smarius * to also take over the trap table at this point. 434157227Smarius */ 435182730Smarius clock_boot = pc->pc_clock; 436182730Smarius delay_func = delay_boot; 437122462Sjake 43886521Sjake /* 43980709Sjake * Initialize the console before printing anything. 440182730Smarius * NB: the low-level console drivers require a working DELAY() at 441182730Smarius * this point. 44280709Sjake */ 44388639Sjake cninit(); 44480709Sjake 44580709Sjake /* 446157227Smarius * Panic if there is no metadata. Most likely the kernel was booted 44786521Sjake * directly, instead of through loader(8). 44880709Sjake */ 449195149Smarius if (mdp == NULL || kmdp == NULL || end == 0 || 450195149Smarius kernel_tlb_slots == 0 || kernel_tlbs == NULL) { 451195149Smarius printf("sparc64_init: missing loader metadata.\n" 452181701Smarius "This probably means you are not using loader(8).\n"); 45386521Sjake panic("sparc64_init"); 45486521Sjake } 45580709Sjake 45681383Sjake /* 457195149Smarius * Work around the broken loader behavior of not demapping no 458195149Smarius * longer used kernel TLB slots when unloading the kernel or 459195149Smarius * modules. 46086521Sjake */ 461195149Smarius for (va = KERNBASE + (kernel_tlb_slots - 1) * PAGE_SIZE_4M; 462195149Smarius va >= roundup2(end, PAGE_SIZE_4M); va -= PAGE_SIZE_4M) { 463201396Smarius if (bootverbose) 464201396Smarius printf("demapping unused kernel TLB slot " 465201396Smarius "(va %#lx - %#lx)\n", va, va + PAGE_SIZE_4M - 1); 466195149Smarius stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, 467195149Smarius ASI_DMMU_DEMAP, 0); 468195149Smarius stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, 469195149Smarius ASI_IMMU_DEMAP, 0); 470195149Smarius flush(KERNBASE); 471195149Smarius kernel_tlb_slots--; 47286521Sjake } 47386521Sjake 474186682Smarius /* 475186682Smarius * Determine the TLB slot maxima, which are expected to be 476186682Smarius * equal across all CPUs. 477205409Smarius * NB: for cheetah-class CPUs, these properties only refer 478186682Smarius * to the t16s. 479186682Smarius */ 480186682Smarius if (OF_getprop(pc->pc_node, "#dtlb-entries", &dtlb_slots, 481186682Smarius sizeof(dtlb_slots)) == -1) 482186682Smarius panic("sparc64_init: cannot determine number of dTLB slots"); 483186682Smarius if (OF_getprop(pc->pc_node, "#itlb-entries", &itlb_slots, 484186682Smarius sizeof(itlb_slots)) == -1) 485186682Smarius panic("sparc64_init: cannot determine number of iTLB slots"); 486186682Smarius 487207248Smarius /* 488207248Smarius * Initialize and enable the caches. Note that his may include 489207248Smarius * applying workarounds. 490207248Smarius */ 491182689Smarius cache_init(pc); 492204152Smarius cache_enable(cpu_impl); 493182689Smarius uma_set_align(pc->pc_cache.dc_linesize - 1); 494101898Sjake 495169178Smarius cpu_block_copy = bcopy; 496169178Smarius cpu_block_zero = bzero; 497113166Sjake getenv_int("machdep.use_vis", &cpu_use_vis); 498113166Sjake if (cpu_use_vis) { 499169178Smarius switch (cpu_impl) { 500169178Smarius case CPU_IMPL_SPARC64: 501169178Smarius case CPU_IMPL_ULTRASPARCI: 502169178Smarius case CPU_IMPL_ULTRASPARCII: 503169178Smarius case CPU_IMPL_ULTRASPARCIIi: 504169178Smarius case CPU_IMPL_ULTRASPARCIIe: 505185007Smarius case CPU_IMPL_ULTRASPARCIII: /* NB: we've disabled P$. */ 506185007Smarius case CPU_IMPL_ULTRASPARCIIIp: 507185007Smarius case CPU_IMPL_ULTRASPARCIIIi: 508185007Smarius case CPU_IMPL_ULTRASPARCIV: 509185007Smarius case CPU_IMPL_ULTRASPARCIVp: 510185007Smarius case CPU_IMPL_ULTRASPARCIIIip: 511169178Smarius cpu_block_copy = spitfire_block_copy; 512169178Smarius cpu_block_zero = spitfire_block_zero; 513169178Smarius break; 514212709Smarius case CPU_IMPL_SPARC64V: 515212709Smarius cpu_block_copy = zeus_block_copy; 516212709Smarius cpu_block_zero = zeus_block_zero; 517212709Smarius break; 518169178Smarius } 519113166Sjake } 520113166Sjake 52191616Sjake#ifdef SMP 522204152Smarius mp_init(cpu_impl); 52391616Sjake#endif 52491616Sjake 52586521Sjake /* 52690625Stmm * Initialize virtual memory and calculate physmem. 52787546Sdillon */ 528204152Smarius pmap_bootstrap(cpu_impl); 52987546Sdillon 53087546Sdillon /* 53181383Sjake * Initialize tunables. 53281383Sjake */ 53387546Sdillon init_param2(physmem); 534105569Smux env = getenv("kernelname"); 535105569Smux if (env != NULL) { 536105569Smux strlcpy(kernelname, env, sizeof(kernelname)); 537105569Smux freeenv(env); 538105569Smux } 53981085Sjake 54080709Sjake /* 54189038Sjake * Initialize the interrupt tables. 54289038Sjake */ 54390624Stmm intr_init1(); 54480709Sjake 54580709Sjake /* 546182689Smarius * Initialize proc0, set kstack0, frame0, curthread and curpcb. 54780709Sjake */ 548173361Skib proc_linkup0(&proc0, &thread0); 54995744Sjake proc0.p_md.md_sigtramp = NULL; 55088822Stmm proc0.p_md.md_utrap = NULL; 55190361Sjulian thread0.td_kstack = kstack0; 55290361Sjulian thread0.td_pcb = (struct pcb *) 55390361Sjulian (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 554105908Sjake frame0.tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_PRIV; 55590361Sjulian thread0.td_frame = &frame0; 55690361Sjulian pc->pc_curthread = &thread0; 55791156Sjake pc->pc_curpcb = thread0.td_pcb; 55888639Sjake 55980709Sjake /* 560163973Sjb * Initialize global registers. 561163973Sjb */ 562163973Sjb cpu_setregs(pc); 563163973Sjb 564163973Sjb /* 565182773Smarius * Take over the trap table via the PROM. Using the PROM for this 566182773Smarius * is necessary in order to set obp-control-relinquished to true 567182773Smarius * within the PROM so obtaining /virtual-memory/translations doesn't 568182773Smarius * trigger a fatal reset error or worse things further down the road. 569182773Smarius * XXX it should be possible to use this soley instead of writing 570182773Smarius * %tba in cpu_setregs(). Doing so causes a hang however. 571182773Smarius */ 572182773Smarius sun4u_set_traptable(tl0_base); 573182773Smarius 574182773Smarius /* 575182730Smarius * It's now safe to use the real DELAY(). 576182730Smarius */ 577182730Smarius delay_func = delay_tick; 578182730Smarius 579182730Smarius /* 580194784Sjeff * Initialize the dynamic per-CPU area for the BSP and the message 581194784Sjeff * buffer (after setting the trap table). 58288822Stmm */ 583194784Sjeff dpcpu_init(dpcpu0, 0); 58488822Stmm msgbufinit(msgbufp, MSGBUF_SIZE); 58588822Stmm 586207248Smarius /* 587207248Smarius * Initialize mutexes. 588207248Smarius */ 58993702Sjhb mutex_init(); 590207248Smarius 591207248Smarius /* 592207248Smarius * Finish the interrupt initialization now that mutexes work and 593207248Smarius * enable them. 594207248Smarius */ 59590624Stmm intr_init2(); 596213873Smarius wrpr(pil, 0, 0); 597207248Smarius wrpr(pstate, 0, PSTATE_KERNEL); 598105946Stmm 599133451Salc /* 600133451Salc * Finish pmap initialization now that we're ready for mutexes. 601133451Salc */ 602133451Salc PMAP_LOCK_INIT(kernel_pmap); 603133451Salc 604106555Stmm OF_getprop(root, "name", sparc64_model, sizeof(sparc64_model) - 1); 605122604Ssimokawa 606131950Smarcel kdb_init(); 607131950Smarcel 608190161Smarius#ifdef KDB 609122604Ssimokawa if (boothowto & RB_KDB) 610174898Srwatson kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 611190161Smarius#endif 61280708Sjake} 61380708Sjake 61480708Sjakevoid 615151316Sdavidxusendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 61680708Sjake{ 61782902Sjake struct trapframe *tf; 61882902Sjake struct sigframe *sfp; 61982902Sjake struct sigacts *psp; 62082902Sjake struct sigframe sf; 62183366Sjulian struct thread *td; 62285242Sjake struct frame *fp; 62382902Sjake struct proc *p; 624181701Smarius u_long sp; 62585242Sjake int oonstack; 626151316Sdavidxu int sig; 62782902Sjake 62882902Sjake oonstack = 0; 62983366Sjulian td = curthread; 63083366Sjulian p = td->td_proc; 631114983Sjhb PROC_LOCK_ASSERT(p, MA_OWNED); 632151316Sdavidxu sig = ksi->ksi_signo; 63382902Sjake psp = p->p_sigacts; 634114983Sjhb mtx_assert(&psp->ps_mtx, MA_OWNED); 63583366Sjulian tf = td->td_frame; 63682902Sjake sp = tf->tf_sp + SPOFF; 63782902Sjake oonstack = sigonstack(sp); 63882902Sjake 63983366Sjulian CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 64082902Sjake catcher, sig); 64182902Sjake 642102554Sjake /* Make sure we have a signal trampoline to return to. */ 643102554Sjake if (p->p_md.md_sigtramp == NULL) { 644102554Sjake /* 645157445Smarius * No signal trampoline... kill the process. 646102554Sjake */ 647102554Sjake CTR0(KTR_SIG, "sendsig: no sigtramp"); 648102873Sjake printf("sendsig: %s is too old, rebuild it\n", p->p_comm); 649102554Sjake sigexit(td, sig); 650102554Sjake /* NOTREACHED */ 651102554Sjake } 652102554Sjake 65382902Sjake /* Save user context. */ 65482902Sjake bzero(&sf, sizeof(sf)); 655118708Sjake get_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 65682902Sjake sf.sf_uc.uc_sigmask = *mask; 657124092Sdavidxu sf.sf_uc.uc_stack = td->td_sigstk; 658181701Smarius sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) ? 659181701Smarius ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 66082902Sjake 66182902Sjake /* Allocate and validate space for the signal handler context. */ 662124092Sdavidxu if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 66382902Sjake SIGISMEMBER(psp->ps_sigonstack, sig)) { 664124092Sdavidxu sfp = (struct sigframe *)(td->td_sigstk.ss_sp + 665124092Sdavidxu td->td_sigstk.ss_size - sizeof(struct sigframe)); 66682902Sjake } else 66782902Sjake sfp = (struct sigframe *)sp - 1; 668114983Sjhb mtx_unlock(&psp->ps_mtx); 66982902Sjake PROC_UNLOCK(p); 67082902Sjake 67185242Sjake fp = (struct frame *)sfp - 1; 67282902Sjake 67382902Sjake /* Translate the signal if appropriate. */ 67482902Sjake if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 67582902Sjake sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 67682902Sjake 67782902Sjake /* Build the argument list for the signal handler. */ 67882902Sjake tf->tf_out[0] = sig; 67982902Sjake tf->tf_out[2] = (register_t)&sfp->sf_uc; 68082902Sjake tf->tf_out[4] = (register_t)catcher; 681157445Smarius if (SIGISMEMBER(psp->ps_siginfo, sig)) { 682157445Smarius /* Signal handler installed with SA_SIGINFO. */ 683157445Smarius tf->tf_out[1] = (register_t)&sfp->sf_si; 68482902Sjake 685157445Smarius /* Fill in POSIX parts. */ 686157445Smarius sf.sf_si = ksi->ksi_info; 687157445Smarius sf.sf_si.si_signo = sig; /* maybe a translated signal */ 688157445Smarius } else { 689157445Smarius /* Old FreeBSD-style arguments. */ 690157445Smarius tf->tf_out[1] = ksi->ksi_code; 691157445Smarius tf->tf_out[3] = (register_t)ksi->ksi_addr; 692157445Smarius } 693157445Smarius 69482902Sjake /* Copy the sigframe out to the user's stack. */ 69585242Sjake if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 || 69694254Sjake suword(&fp->fr_in[6], tf->tf_out[6]) != 0) { 69782902Sjake /* 69882902Sjake * Something is wrong with the stack pointer. 69982902Sjake * ...Kill the process. 70082902Sjake */ 70183366Sjulian CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 70282902Sjake PROC_LOCK(p); 70383366Sjulian sigexit(td, SIGILL); 70482902Sjake /* NOTREACHED */ 70582902Sjake } 70682902Sjake 707102554Sjake tf->tf_tpc = (u_long)p->p_md.md_sigtramp; 70882902Sjake tf->tf_tnpc = tf->tf_tpc + 4; 70985242Sjake tf->tf_sp = (u_long)fp - SPOFF; 71082902Sjake 71183366Sjulian CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, 71282902Sjake tf->tf_sp); 71384178Sjake 71484178Sjake PROC_LOCK(p); 715114983Sjhb mtx_lock(&psp->ps_mtx); 71680708Sjake} 71780708Sjake 71880708Sjake#ifndef _SYS_SYSPROTO_H_ 71983088Sobrienstruct sigreturn_args { 72080708Sjake ucontext_t *ucp; 72180708Sjake}; 72280708Sjake#endif 72380708Sjake 72494606Salc/* 72594606Salc * MPSAFE 72694606Salc */ 72780708Sjakeint 72883366Sjuliansigreturn(struct thread *td, struct sigreturn_args *uap) 72980708Sjake{ 73083366Sjulian struct proc *p; 731118768Sjake mcontext_t *mc; 73282902Sjake ucontext_t uc; 733118708Sjake int error; 73482902Sjake 73583366Sjulian p = td->td_proc; 73683366Sjulian if (rwindow_save(td)) { 73782902Sjake PROC_LOCK(p); 73883366Sjulian sigexit(td, SIGILL); 73982902Sjake } 74082902Sjake 74183366Sjulian CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 74282902Sjake if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 74383366Sjulian CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 74482902Sjake return (EFAULT); 74582902Sjake } 74682902Sjake 747118768Sjake mc = &uc.uc_mcontext; 748118768Sjake error = set_mcontext(td, mc); 749118708Sjake if (error != 0) 750118708Sjake return (error); 75182902Sjake 752198507Skib kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); 753105733Sjake 75483366Sjulian CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", 755118768Sjake td, mc->mc_tpc, mc->mc_sp, mc->mc_tstate); 75682902Sjake return (EJUSTRETURN); 75780708Sjake} 75880708Sjake 759131905Smarcel/* 760131905Smarcel * Construct a PCB from a trapframe. This is called from kdb_trap() where 761131905Smarcel * we want to start a backtrace from the function that caused us to enter 762131905Smarcel * the debugger. We have the context in the trapframe, but base the trace 763131905Smarcel * on the PCB. The PCB doesn't have to be perfect, as long as it contains 764131905Smarcel * enough for a backtrace. 765131905Smarcel */ 766131905Smarcelvoid 767131905Smarcelmakectx(struct trapframe *tf, struct pcb *pcb) 768131905Smarcel{ 769131905Smarcel 770131905Smarcel pcb->pcb_pc = tf->tf_tpc; 771131905Smarcel pcb->pcb_sp = tf->tf_sp; 772131905Smarcel} 773131905Smarcel 774106977Sdeischenint 775122364Smarcelget_mcontext(struct thread *td, mcontext_t *mc, int flags) 776106977Sdeischen{ 777112924Sjake struct trapframe *tf; 778112924Sjake struct pcb *pcb; 779106977Sdeischen 780112924Sjake tf = td->td_frame; 781112924Sjake pcb = td->td_pcb; 782199442Smarius /* 783199442Smarius * Copy the registers which will be restored by tl0_ret() from the 784199442Smarius * trapframe. 785199442Smarius * Note that we skip %g7 which is used as the userland TLS register 786199442Smarius * and %wstate. 787199442Smarius */ 788199442Smarius mc->mc_flags = _MC_VERSION; 789199442Smarius mc->mc_global[1] = tf->tf_global[1]; 790199442Smarius mc->mc_global[2] = tf->tf_global[2]; 791199442Smarius mc->mc_global[3] = tf->tf_global[3]; 792199442Smarius mc->mc_global[4] = tf->tf_global[4]; 793199442Smarius mc->mc_global[5] = tf->tf_global[5]; 794199442Smarius mc->mc_global[6] = tf->tf_global[6]; 795122364Smarcel if (flags & GET_MC_CLEAR_RET) { 796113998Sdeischen mc->mc_out[0] = 0; 797113998Sdeischen mc->mc_out[1] = 0; 798199442Smarius } else { 799199442Smarius mc->mc_out[0] = tf->tf_out[0]; 800199442Smarius mc->mc_out[1] = tf->tf_out[1]; 801113998Sdeischen } 802199442Smarius mc->mc_out[2] = tf->tf_out[2]; 803199442Smarius mc->mc_out[3] = tf->tf_out[3]; 804199442Smarius mc->mc_out[4] = tf->tf_out[4]; 805199442Smarius mc->mc_out[5] = tf->tf_out[5]; 806199442Smarius mc->mc_out[6] = tf->tf_out[6]; 807199442Smarius mc->mc_out[7] = tf->tf_out[7]; 808199442Smarius mc->mc_fprs = tf->tf_fprs; 809199442Smarius mc->mc_fsr = tf->tf_fsr; 810199442Smarius mc->mc_gsr = tf->tf_gsr; 811199442Smarius mc->mc_tnpc = tf->tf_tnpc; 812199442Smarius mc->mc_tpc = tf->tf_tpc; 813199442Smarius mc->mc_tstate = tf->tf_tstate; 814199442Smarius mc->mc_y = tf->tf_y; 815112924Sjake critical_enter(); 816112961Sjake if ((tf->tf_fprs & FPRS_FEF) != 0) { 817112961Sjake savefpctx(pcb->pcb_ufp); 818112961Sjake tf->tf_fprs &= ~FPRS_FEF; 819112961Sjake pcb->pcb_flags |= PCB_FEF; 820112961Sjake } 821112961Sjake if ((pcb->pcb_flags & PCB_FEF) != 0) { 822113018Sjake bcopy(pcb->pcb_ufp, mc->mc_fp, sizeof(mc->mc_fp)); 823112924Sjake mc->mc_fprs |= FPRS_FEF; 824112924Sjake } 825112924Sjake critical_exit(); 826112924Sjake return (0); 827106977Sdeischen} 828106977Sdeischen 829106977Sdeischenint 830112924Sjakeset_mcontext(struct thread *td, const mcontext_t *mc) 831106977Sdeischen{ 832112924Sjake struct trapframe *tf; 833112924Sjake struct pcb *pcb; 834106977Sdeischen 835112961Sjake if (!TSTATE_SECURE(mc->mc_tstate) || 836112961Sjake (mc->mc_flags & ((1L << _MC_VERSION_BITS) - 1)) != _MC_VERSION) 837112924Sjake return (EINVAL); 838112924Sjake tf = td->td_frame; 839112924Sjake pcb = td->td_pcb; 840136325Skensmith /* Make sure the windows are spilled first. */ 841136325Skensmith flushw(); 842199442Smarius /* 843199442Smarius * Copy the registers which will be restored by tl0_ret() to the 844199442Smarius * trapframe. 845199442Smarius * Note that we skip %g7 which is used as the userland TLS register 846199442Smarius * and %wstate. 847199442Smarius */ 848199442Smarius tf->tf_global[1] = mc->mc_global[1]; 849199442Smarius tf->tf_global[2] = mc->mc_global[2]; 850199442Smarius tf->tf_global[3] = mc->mc_global[3]; 851199442Smarius tf->tf_global[4] = mc->mc_global[4]; 852199442Smarius tf->tf_global[5] = mc->mc_global[5]; 853199442Smarius tf->tf_global[6] = mc->mc_global[6]; 854199442Smarius tf->tf_out[0] = mc->mc_out[0]; 855199442Smarius tf->tf_out[1] = mc->mc_out[1]; 856199442Smarius tf->tf_out[2] = mc->mc_out[2]; 857199442Smarius tf->tf_out[3] = mc->mc_out[3]; 858199442Smarius tf->tf_out[4] = mc->mc_out[4]; 859199442Smarius tf->tf_out[5] = mc->mc_out[5]; 860199442Smarius tf->tf_out[6] = mc->mc_out[6]; 861199442Smarius tf->tf_out[7] = mc->mc_out[7]; 862199442Smarius tf->tf_fprs = mc->mc_fprs; 863199442Smarius tf->tf_fsr = mc->mc_fsr; 864199442Smarius tf->tf_gsr = mc->mc_gsr; 865199442Smarius tf->tf_tnpc = mc->mc_tnpc; 866199442Smarius tf->tf_tpc = mc->mc_tpc; 867199442Smarius tf->tf_tstate = mc->mc_tstate; 868199442Smarius tf->tf_y = mc->mc_y; 869112924Sjake if ((mc->mc_fprs & FPRS_FEF) != 0) { 870112924Sjake tf->tf_fprs = 0; 871113018Sjake bcopy(mc->mc_fp, pcb->pcb_ufp, sizeof(pcb->pcb_ufp)); 872112924Sjake pcb->pcb_flags |= PCB_FEF; 873112924Sjake } 874112924Sjake return (0); 875106977Sdeischen} 876106977Sdeischen 87786147Stmm/* 87892205Sjake * Exit the kernel and execute a firmware call that will not return, as 87992205Sjake * specified by the arguments. 88092205Sjake */ 88192205Sjakevoid 88292205Sjakecpu_shutdown(void *args) 88392205Sjake{ 88492205Sjake 88592205Sjake#ifdef SMP 88692205Sjake cpu_mp_shutdown(); 88792205Sjake#endif 888186347Snwhitehorn ofw_exit(args); 88992205Sjake} 89092205Sjake 891192323Smarcel/* 892192323Smarcel * Flush the D-cache for non-DMA I/O so that the I-cache can 893192323Smarcel * be made coherent later. 894192323Smarcel */ 895192323Smarcelvoid 896192323Smarcelcpu_flush_dcache(void *ptr, size_t len) 897192323Smarcel{ 898195149Smarius 899192323Smarcel /* TBD */ 900192323Smarcel} 901192323Smarcel 902181701Smarius/* Get current clock frequency for the given CPU ID. */ 903141237Snjlint 904141237Snjlcpu_est_clockrate(int cpu_id, uint64_t *rate) 905141237Snjl{ 906182730Smarius struct pcpu *pc; 907141237Snjl 908182730Smarius pc = pcpu_find(cpu_id); 909182730Smarius if (pc == NULL || rate == NULL) 910182730Smarius return (EINVAL); 911182730Smarius *rate = pc->pc_clock; 912182730Smarius return (0); 913141237Snjl} 914141237Snjl 91592205Sjake/* 91686147Stmm * Duplicate OF_exit() with a different firmware call function that restores 91786147Stmm * the trap table, otherwise a RED state exception is triggered in at least 91886147Stmm * some firmware versions. 91986147Stmm */ 92080708Sjakevoid 92180708Sjakecpu_halt(void) 92280708Sjake{ 92386147Stmm static struct { 92486147Stmm cell_t name; 92586147Stmm cell_t nargs; 92686147Stmm cell_t nreturns; 92786147Stmm } args = { 92886147Stmm (cell_t)"exit", 92986147Stmm 0, 93086147Stmm 0 93186147Stmm }; 93284178Sjake 93392205Sjake cpu_shutdown(&args); 93480708Sjake} 93580708Sjake 936203838Smariusstatic void 93786147Stmmsparc64_shutdown_final(void *dummy, int howto) 93886147Stmm{ 93986147Stmm static struct { 94086147Stmm cell_t name; 94186147Stmm cell_t nargs; 94286147Stmm cell_t nreturns; 94386147Stmm } args = { 94486147Stmm (cell_t)"SUNW,power-off", 94586147Stmm 0, 94686147Stmm 0 94786147Stmm }; 94886147Stmm 94986147Stmm /* Turn the power off? */ 95086147Stmm if ((howto & RB_POWEROFF) != 0) 95192205Sjake cpu_shutdown(&args); 952185007Smarius /* In case of halt, return to the firmware. */ 95386147Stmm if ((howto & RB_HALT) != 0) 95486147Stmm cpu_halt(); 95586147Stmm} 95686147Stmm 957121237Spetervoid 958178471Sjeffcpu_idle(int busy) 959121237Speter{ 960181701Smarius 961181701Smarius /* Insert code to halt (until next interrupt) for the idle loop. */ 962121237Speter} 963121237Speter 96480708Sjakeint 965178471Sjeffcpu_idle_wakeup(int cpu) 966178471Sjeff{ 967178471Sjeff 968212456Smav return (1); 969178471Sjeff} 970178471Sjeff 971178471Sjeffint 97283366Sjulianptrace_set_pc(struct thread *td, u_long addr) 97380708Sjake{ 97482016Sjake 97583366Sjulian td->td_frame->tf_tpc = addr; 97683366Sjulian td->td_frame->tf_tnpc = addr + 4; 97780708Sjake return (0); 97880708Sjake} 97980708Sjake 98080708Sjakeint 98183366Sjulianptrace_single_step(struct thread *td) 98280708Sjake{ 983181701Smarius 984104271Sjake /* TODO; */ 98580708Sjake return (0); 98680708Sjake} 98780708Sjake 988132088Sdavidxuint 989132088Sdavidxuptrace_clear_single_step(struct thread *td) 990132088Sdavidxu{ 991181701Smarius 992132088Sdavidxu /* TODO; */ 993132088Sdavidxu return (0); 994132088Sdavidxu} 995132088Sdavidxu 99680708Sjakevoid 997205642Snwhitehornexec_setregs(struct thread *td, struct image_params *imgp, u_long stack) 99880708Sjake{ 99988639Sjake struct trapframe *tf; 100081135Stmm struct pcb *pcb; 1001102557Sjake struct proc *p; 100284178Sjake u_long sp; 100381135Stmm 100488782Sjake /* XXX no cpu_exec */ 1005102557Sjake p = td->td_proc; 1006102557Sjake p->p_md.md_sigtramp = NULL; 1007140485Sjhb if (p->p_md.md_utrap != NULL) { 1008140485Sjhb utrap_free(p->p_md.md_utrap); 1009102557Sjake p->p_md.md_utrap = NULL; 101088782Sjake } 101188782Sjake 101283366Sjulian pcb = td->td_pcb; 1013105908Sjake tf = td->td_frame; 101488639Sjake sp = rounddown(stack, 16); 101598032Sjake bzero(pcb, sizeof(*pcb)); 101698032Sjake bzero(tf, sizeof(*tf)); 101788639Sjake tf->tf_out[0] = stack; 1018105908Sjake tf->tf_out[3] = p->p_sysent->sv_psstrings; 101988639Sjake tf->tf_out[6] = sp - SPOFF - sizeof(struct frame); 1020205642Snwhitehorn tf->tf_tnpc = imgp->entry_addr + 4; 1021205642Snwhitehorn tf->tf_tpc = imgp->entry_addr; 102288639Sjake tf->tf_tstate = TSTATE_IE | TSTATE_PEF | TSTATE_MM_TSO; 102388639Sjake 102488639Sjake td->td_retval[0] = tf->tf_out[0]; 102588639Sjake td->td_retval[1] = tf->tf_out[1]; 102680708Sjake} 102780708Sjake 102880708Sjakeint 102984178Sjakefill_regs(struct thread *td, struct reg *regs) 103080708Sjake{ 103180708Sjake 1032105733Sjake bcopy(td->td_frame, regs, sizeof(*regs)); 103380708Sjake return (0); 103480708Sjake} 103580708Sjake 103680708Sjakeint 103784178Sjakeset_regs(struct thread *td, struct reg *regs) 103880708Sjake{ 1039112922Sjake struct trapframe *tf; 104080708Sjake 104184178Sjake if (!TSTATE_SECURE(regs->r_tstate)) 104284178Sjake return (EINVAL); 1043112922Sjake tf = td->td_frame; 1044112922Sjake regs->r_wstate = tf->tf_wstate; 1045112922Sjake bcopy(regs, tf, sizeof(*regs)); 104680708Sjake return (0); 104780708Sjake} 104880708Sjake 104980708Sjakeint 105085294Sdesfill_dbregs(struct thread *td, struct dbreg *dbregs) 105185294Sdes{ 105285294Sdes 105385294Sdes return (ENOSYS); 105485294Sdes} 105585294Sdes 105685294Sdesint 105785294Sdesset_dbregs(struct thread *td, struct dbreg *dbregs) 105885294Sdes{ 105985294Sdes 106085294Sdes return (ENOSYS); 106185294Sdes} 106285294Sdes 106385294Sdesint 106483366Sjulianfill_fpregs(struct thread *td, struct fpreg *fpregs) 106580708Sjake{ 106688639Sjake struct trapframe *tf; 106784178Sjake struct pcb *pcb; 106884178Sjake 106984178Sjake pcb = td->td_pcb; 107088639Sjake tf = td->td_frame; 1071112920Sjake bcopy(pcb->pcb_ufp, fpregs->fr_regs, sizeof(fpregs->fr_regs)); 107288639Sjake fpregs->fr_fsr = tf->tf_fsr; 1073105733Sjake fpregs->fr_gsr = tf->tf_gsr; 107480708Sjake return (0); 107580708Sjake} 107680708Sjake 107780708Sjakeint 107883366Sjulianset_fpregs(struct thread *td, struct fpreg *fpregs) 107980708Sjake{ 108088639Sjake struct trapframe *tf; 108184178Sjake struct pcb *pcb; 108284178Sjake 108384178Sjake pcb = td->td_pcb; 108488639Sjake tf = td->td_frame; 1085112922Sjake tf->tf_fprs &= ~FPRS_FEF; 1086112920Sjake bcopy(fpregs->fr_regs, pcb->pcb_ufp, sizeof(pcb->pcb_ufp)); 108788639Sjake tf->tf_fsr = fpregs->fr_fsr; 1088105733Sjake tf->tf_gsr = fpregs->fr_gsr; 108980708Sjake return (0); 109080708Sjake} 1091140485Sjhb 1092140485Sjhbstruct md_utrap * 1093140485Sjhbutrap_alloc(void) 1094140485Sjhb{ 1095140485Sjhb struct md_utrap *ut; 1096140485Sjhb 1097140485Sjhb ut = malloc(sizeof(struct md_utrap), M_SUBPROC, M_WAITOK | M_ZERO); 1098140485Sjhb ut->ut_refcnt = 1; 1099140485Sjhb return (ut); 1100140485Sjhb} 1101140485Sjhb 1102140485Sjhbvoid 1103140485Sjhbutrap_free(struct md_utrap *ut) 1104140485Sjhb{ 1105140485Sjhb int refcnt; 1106140485Sjhb 1107140485Sjhb if (ut == NULL) 1108140485Sjhb return; 1109140485Sjhb mtx_pool_lock(mtxpool_sleep, ut); 1110140485Sjhb ut->ut_refcnt--; 1111140485Sjhb refcnt = ut->ut_refcnt; 1112140485Sjhb mtx_pool_unlock(mtxpool_sleep, ut); 1113140485Sjhb if (refcnt == 0) 1114140485Sjhb free(ut, M_SUBPROC); 1115140485Sjhb} 1116140485Sjhb 1117140485Sjhbstruct md_utrap * 1118140485Sjhbutrap_hold(struct md_utrap *ut) 1119140485Sjhb{ 1120140485Sjhb 1121140485Sjhb if (ut == NULL) 1122140485Sjhb return (NULL); 1123140485Sjhb mtx_pool_lock(mtxpool_sleep, ut); 1124140485Sjhb ut->ut_refcnt++; 1125140485Sjhb mtx_pool_unlock(mtxpool_sleep, ut); 1126140485Sjhb return (ut); 1127140485Sjhb} 1128