10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1991Sheppo * Common Development and Distribution License (the "License"). 6*1991Sheppo * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*1991Sheppo * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <sys/types.h> 290Sstevel@tonic-gate #include <sys/systm.h> 300Sstevel@tonic-gate #include <sys/archsystm.h> 310Sstevel@tonic-gate #include <sys/machparam.h> 320Sstevel@tonic-gate #include <sys/machsystm.h> 330Sstevel@tonic-gate #include <sys/cpu.h> 340Sstevel@tonic-gate #include <sys/elf_SPARC.h> 350Sstevel@tonic-gate #include <vm/hat_sfmmu.h> 360Sstevel@tonic-gate #include <vm/page.h> 370Sstevel@tonic-gate #include <sys/cpuvar.h> 380Sstevel@tonic-gate #include <sys/async.h> 390Sstevel@tonic-gate #include <sys/cmn_err.h> 400Sstevel@tonic-gate #include <sys/debug.h> 410Sstevel@tonic-gate #include <sys/dditypes.h> 420Sstevel@tonic-gate #include <sys/sunddi.h> 430Sstevel@tonic-gate #include <sys/cpu_module.h> 440Sstevel@tonic-gate #include <sys/prom_debug.h> 450Sstevel@tonic-gate #include <sys/vmsystm.h> 460Sstevel@tonic-gate #include <sys/prom_plat.h> 470Sstevel@tonic-gate #include <sys/sysmacros.h> 480Sstevel@tonic-gate #include <sys/intreg.h> 490Sstevel@tonic-gate #include <sys/machtrap.h> 500Sstevel@tonic-gate #include <sys/ontrap.h> 510Sstevel@tonic-gate #include <sys/ivintr.h> 520Sstevel@tonic-gate #include <sys/atomic.h> 530Sstevel@tonic-gate #include <sys/panic.h> 540Sstevel@tonic-gate #include <sys/dtrace.h> 550Sstevel@tonic-gate #include <vm/seg_spt.h> 56*1991Sheppo #include <sys/simulate.h> 57*1991Sheppo #include <sys/fault.h> 580Sstevel@tonic-gate 590Sstevel@tonic-gate 600Sstevel@tonic-gate uint_t root_phys_addr_lo_mask = 0xffffffffU; 610Sstevel@tonic-gate 620Sstevel@tonic-gate void 630Sstevel@tonic-gate cpu_setup(void) 640Sstevel@tonic-gate { 650Sstevel@tonic-gate extern int mmu_exported_pagesize_mask; 66*1991Sheppo char *generic_isa_set[] = { 67*1991Sheppo "sparcv9+vis", 68*1991Sheppo "sparcv8plus+vis", 69*1991Sheppo NULL 70*1991Sheppo }; 71*1991Sheppo 72*1991Sheppo /* 73*1991Sheppo * The setup common to all CPU modules is done in cpu_setup_common 74*1991Sheppo * routine. 75*1991Sheppo */ 76*1991Sheppo cpu_setup_common(generic_isa_set); 770Sstevel@tonic-gate 780Sstevel@tonic-gate cache |= (CACHE_PTAG | CACHE_IOCOHERENT); 790Sstevel@tonic-gate 80*1991Sheppo if (broken_md_flag) { 81*1991Sheppo /* 82*1991Sheppo * Turn on the missing bits supported by sun4v architecture in 83*1991Sheppo * MMU pagesize mask returned by MD. 84*1991Sheppo */ 85*1991Sheppo mmu_exported_pagesize_mask |= DEFAULT_SUN4V_MMU_PAGESIZE_MASK; 86*1991Sheppo } else { 87*1991Sheppo /* 88*1991Sheppo * According to sun4v architecture each processor must 89*1991Sheppo * support 8K, 64K and 4M page sizes. If any of the page 90*1991Sheppo * size is missing from page size mask, then panic. 91*1991Sheppo */ 92*1991Sheppo if ((mmu_exported_pagesize_mask & 93*1991Sheppo DEFAULT_SUN4V_MMU_PAGESIZE_MASK) != 94*1991Sheppo DEFAULT_SUN4V_MMU_PAGESIZE_MASK) 95*1991Sheppo cmn_err(CE_PANIC, "machine description" 96*1991Sheppo " does not have required sun4v page sizes" 97*1991Sheppo " 8K, 64K and 4M: MD mask is 0x%x", 98*1991Sheppo mmu_exported_pagesize_mask); 990Sstevel@tonic-gate } 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate /* 102*1991Sheppo * If processor supports the subset of full 64-bit virtual 103*1991Sheppo * address space, then set VA hole accordingly. 1040Sstevel@tonic-gate */ 105*1991Sheppo if (va_bits < VA_ADDRESS_SPACE_BITS) { 106*1991Sheppo hole_start = (caddr_t)(1ull << (va_bits - 1)); 107*1991Sheppo hole_end = (caddr_t)(0ull - (1ull << (va_bits - 1))); 108*1991Sheppo } else { 109*1991Sheppo hole_start = hole_end = 0; 110*1991Sheppo } 1110Sstevel@tonic-gate } 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate void 1140Sstevel@tonic-gate cpu_fiximp(struct cpu_node *cpunode) 1150Sstevel@tonic-gate { 1160Sstevel@tonic-gate /* 117*1991Sheppo * The Cache node is optional in MD. Therefore in case "Cache" 118*1991Sheppo * does not exists in MD, set the default L2 cache associativity, 119*1991Sheppo * size, linesize for generic CPU module. 1200Sstevel@tonic-gate */ 121*1991Sheppo if (cpunode->ecache_size == 0) 122*1991Sheppo cpunode->ecache_size = 0x100000; 123*1991Sheppo if (cpunode->ecache_linesize == 0) 124*1991Sheppo cpunode->ecache_linesize = 64; 125*1991Sheppo if (cpunode->ecache_associativity == 0) 126*1991Sheppo cpunode->ecache_associativity = 1; 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate void 1300Sstevel@tonic-gate dtrace_flush_sec(uintptr_t addr) 1310Sstevel@tonic-gate { 1320Sstevel@tonic-gate pfn_t pfn; 1330Sstevel@tonic-gate proc_t *procp = ttoproc(curthread); 1340Sstevel@tonic-gate page_t *pp; 1350Sstevel@tonic-gate caddr_t va; 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate pfn = hat_getpfnum(procp->p_as->a_hat, (void *)addr); 1380Sstevel@tonic-gate if (pfn != -1) { 1390Sstevel@tonic-gate ASSERT(pf_is_memory(pfn)); 1400Sstevel@tonic-gate pp = page_numtopp_noreclaim(pfn, SE_SHARED); 1410Sstevel@tonic-gate if (pp != NULL) { 1420Sstevel@tonic-gate va = ppmapin(pp, PROT_READ | PROT_WRITE, (void *)addr); 1430Sstevel@tonic-gate /* sparc needs 8-byte align */ 1440Sstevel@tonic-gate doflush((caddr_t)((uintptr_t)va & -8l)); 1450Sstevel@tonic-gate ppmapout(va); 1460Sstevel@tonic-gate page_unlock(pp); 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate } 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate void 1520Sstevel@tonic-gate cpu_init_private(struct cpu *cp) 1530Sstevel@tonic-gate { 154220Sesaxe /* 155220Sesaxe * The cpu_ipipe field is initialized based on the execution 156220Sesaxe * unit sharing information from the Machine Description table. 157220Sesaxe * It defaults to the CPU id in the absence of such information. 158220Sesaxe */ 159*1991Sheppo cp->cpu_m.cpu_ipipe = cpunodes[cp->cpu_id].exec_unit_mapping; 160*1991Sheppo if (cp->cpu_m.cpu_ipipe == NO_EU_MAPPING_FOUND) 161*1991Sheppo cp->cpu_m.cpu_ipipe = (id_t)(cp->cpu_id); 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate void 1650Sstevel@tonic-gate cpu_uninit_private(struct cpu *cp) 1660Sstevel@tonic-gate { 1670Sstevel@tonic-gate } 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate /* 1700Sstevel@tonic-gate * Invalidate a TSB. Since this needs to work on all sun4v 1710Sstevel@tonic-gate * architecture compliant processors, we use the old method of 1720Sstevel@tonic-gate * walking the TSB, setting each tag to TSBTAG_INVALID. 1730Sstevel@tonic-gate */ 1740Sstevel@tonic-gate void 1750Sstevel@tonic-gate cpu_inv_tsb(caddr_t tsb_base, uint_t tsb_bytes) 1760Sstevel@tonic-gate { 1770Sstevel@tonic-gate struct tsbe *tsbaddr; 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate for (tsbaddr = (struct tsbe *)tsb_base; 1800Sstevel@tonic-gate (uintptr_t)tsbaddr < (uintptr_t)(tsb_base + tsb_bytes); 1810Sstevel@tonic-gate tsbaddr++) { 1820Sstevel@tonic-gate tsbaddr->tte_tag.tag_inthi = TSBTAG_INVALID; 1830Sstevel@tonic-gate } 1840Sstevel@tonic-gate } 1851050Sgirish 1861050Sgirish /* 187*1991Sheppo * Sun4v kernel must emulate code a generic sun4v processor may not support 188*1991Sheppo * i.e. VIS1 and VIS2. 189*1991Sheppo */ 190*1991Sheppo #define IS_FLOAT(i) (((i) & 0x1000000) != 0) 191*1991Sheppo #define IS_IBIT_SET(x) (x & 0x2000) 192*1991Sheppo #define IS_VIS1(op, op3)(op == 2 && op3 == 0x36) 193*1991Sheppo #define IS_PARTIAL_OR_SHORT_FLOAT_LD_ST(op, op3, asi) \ 194*1991Sheppo (op == 3 && (op3 == IOP_V8_LDDFA || \ 195*1991Sheppo op3 == IOP_V8_STDFA) && asi > ASI_SNFL) 196*1991Sheppo int 197*1991Sheppo vis1_partial_support(struct regs *rp, k_siginfo_t *siginfo, uint_t *fault) 198*1991Sheppo { 199*1991Sheppo char *badaddr; 200*1991Sheppo int instr; 201*1991Sheppo uint_t optype, op3, asi; 202*1991Sheppo uint_t rd, ignor; 203*1991Sheppo 204*1991Sheppo if (!USERMODE(rp->r_tstate)) 205*1991Sheppo return (-1); 206*1991Sheppo 207*1991Sheppo instr = fetch_user_instr((caddr_t)rp->r_pc); 208*1991Sheppo 209*1991Sheppo rd = (instr >> 25) & 0x1f; 210*1991Sheppo optype = (instr >> 30) & 0x3; 211*1991Sheppo op3 = (instr >> 19) & 0x3f; 212*1991Sheppo ignor = (instr >> 5) & 0xff; 213*1991Sheppo if (IS_IBIT_SET(instr)) { 214*1991Sheppo asi = (uint32_t)((rp->r_tstate >> TSTATE_ASI_SHIFT) & 215*1991Sheppo TSTATE_ASI_MASK); 216*1991Sheppo } else { 217*1991Sheppo asi = ignor; 218*1991Sheppo } 219*1991Sheppo 220*1991Sheppo if (!IS_VIS1(optype, op3) && 221*1991Sheppo !IS_PARTIAL_OR_SHORT_FLOAT_LD_ST(optype, op3, asi)) { 222*1991Sheppo return (-1); 223*1991Sheppo } 224*1991Sheppo switch (simulate_unimp(rp, &badaddr)) { 225*1991Sheppo case SIMU_RETRY: 226*1991Sheppo break; /* regs are already set up */ 227*1991Sheppo /*NOTREACHED*/ 228*1991Sheppo 229*1991Sheppo case SIMU_SUCCESS: 230*1991Sheppo /* 231*1991Sheppo * skip the successfully 232*1991Sheppo * simulated instruction 233*1991Sheppo */ 234*1991Sheppo rp->r_pc = rp->r_npc; 235*1991Sheppo rp->r_npc += 4; 236*1991Sheppo break; 237*1991Sheppo /*NOTREACHED*/ 238*1991Sheppo 239*1991Sheppo case SIMU_FAULT: 240*1991Sheppo siginfo->si_signo = SIGSEGV; 241*1991Sheppo siginfo->si_code = SEGV_MAPERR; 242*1991Sheppo siginfo->si_addr = badaddr; 243*1991Sheppo *fault = FLTBOUNDS; 244*1991Sheppo break; 245*1991Sheppo 246*1991Sheppo case SIMU_DZERO: 247*1991Sheppo siginfo->si_signo = SIGFPE; 248*1991Sheppo siginfo->si_code = FPE_INTDIV; 249*1991Sheppo siginfo->si_addr = (caddr_t)rp->r_pc; 250*1991Sheppo *fault = FLTIZDIV; 251*1991Sheppo break; 252*1991Sheppo 253*1991Sheppo case SIMU_UNALIGN: 254*1991Sheppo siginfo->si_signo = SIGBUS; 255*1991Sheppo siginfo->si_code = BUS_ADRALN; 256*1991Sheppo siginfo->si_addr = badaddr; 257*1991Sheppo *fault = FLTACCESS; 258*1991Sheppo break; 259*1991Sheppo 260*1991Sheppo case SIMU_ILLEGAL: 261*1991Sheppo default: 262*1991Sheppo siginfo->si_signo = SIGILL; 263*1991Sheppo op3 = (instr >> 19) & 0x3F; 264*1991Sheppo if ((IS_FLOAT(instr) && (op3 == IOP_V8_STQFA) || 265*1991Sheppo (op3 == IOP_V8_STDFA))) 266*1991Sheppo siginfo->si_code = ILL_ILLADR; 267*1991Sheppo else 268*1991Sheppo siginfo->si_code = ILL_ILLOPC; 269*1991Sheppo siginfo->si_addr = (caddr_t)rp->r_pc; 270*1991Sheppo *fault = FLTILL; 271*1991Sheppo break; 272*1991Sheppo } 273*1991Sheppo return (0); 274*1991Sheppo } 275*1991Sheppo 276*1991Sheppo /* 2771050Sgirish * Trapstat support for generic sun4v processor 2781050Sgirish */ 2791050Sgirish int 2801050Sgirish cpu_trapstat_conf(int cmd) 2811050Sgirish { 2821050Sgirish int status; 2831050Sgirish 2841050Sgirish switch (cmd) { 2851050Sgirish case CPU_TSTATCONF_INIT: 2861050Sgirish case CPU_TSTATCONF_FINI: 2871050Sgirish case CPU_TSTATCONF_ENABLE: 2881050Sgirish case CPU_TSTATCONF_DISABLE: 2891050Sgirish status = ENOTSUP; 2901050Sgirish break; 2911050Sgirish 2921050Sgirish default: 2931050Sgirish status = EINVAL; 2941050Sgirish break; 2951050Sgirish } 2961050Sgirish return (status); 2971050Sgirish } 2981050Sgirish 2991050Sgirish /*ARGSUSED*/ 3001050Sgirish void 3011050Sgirish cpu_trapstat_data(void *buf, uint_t tstat_pgszs) 3021050Sgirish { 3031050Sgirish } 304