1fcb56067SGeorge V. Neville-Neil /* 2fcb56067SGeorge V. Neville-Neil * CDDL HEADER START 3fcb56067SGeorge V. Neville-Neil * 4fcb56067SGeorge V. Neville-Neil * The contents of this file are subject to the terms of the 5fcb56067SGeorge V. Neville-Neil * Common Development and Distribution License, Version 1.0 only 6fcb56067SGeorge V. Neville-Neil * (the "License"). You may not use this file except in compliance 7fcb56067SGeorge V. Neville-Neil * with the License. 8fcb56067SGeorge V. Neville-Neil * 9fcb56067SGeorge V. Neville-Neil * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10fcb56067SGeorge V. Neville-Neil * or http://www.opensolaris.org/os/licensing. 11fcb56067SGeorge V. Neville-Neil * See the License for the specific language governing permissions 12fcb56067SGeorge V. Neville-Neil * and limitations under the License. 13fcb56067SGeorge V. Neville-Neil * 14fcb56067SGeorge V. Neville-Neil * When distributing Covered Code, include this CDDL HEADER in each 15fcb56067SGeorge V. Neville-Neil * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16fcb56067SGeorge V. Neville-Neil * If applicable, add the following below this CDDL HEADER, with the 17fcb56067SGeorge V. Neville-Neil * fields enclosed by brackets "[]" replaced with your own identifying 18fcb56067SGeorge V. Neville-Neil * information: Portions Copyright [yyyy] [name of copyright owner] 19fcb56067SGeorge V. Neville-Neil * 20fcb56067SGeorge V. Neville-Neil * CDDL HEADER END 21fcb56067SGeorge V. Neville-Neil */ 22fcb56067SGeorge V. Neville-Neil /* 23fcb56067SGeorge V. Neville-Neil * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24fcb56067SGeorge V. Neville-Neil * Use is subject to license terms. 25fcb56067SGeorge V. Neville-Neil */ 26fcb56067SGeorge V. Neville-Neil #include <sys/cdefs.h> 27fcb56067SGeorge V. Neville-Neil 28fcb56067SGeorge V. Neville-Neil #include <sys/param.h> 29fcb56067SGeorge V. Neville-Neil #include <sys/systm.h> 30*82283cadSMark Johnston #include <sys/dtrace_impl.h> 31fcb56067SGeorge V. Neville-Neil #include <sys/kernel.h> 32fcb56067SGeorge V. Neville-Neil #include <sys/stack.h> 33fcb56067SGeorge V. Neville-Neil #include <sys/pcpu.h> 34fcb56067SGeorge V. Neville-Neil 35fcb56067SGeorge V. Neville-Neil #include <machine/frame.h> 36fcb56067SGeorge V. Neville-Neil #include <machine/md_var.h> 37fcb56067SGeorge V. Neville-Neil 38fcb56067SGeorge V. Neville-Neil #include <vm/vm.h> 39fcb56067SGeorge V. Neville-Neil #include <vm/vm_param.h> 40fcb56067SGeorge V. Neville-Neil #include <vm/pmap.h> 41fcb56067SGeorge V. Neville-Neil 42fcb56067SGeorge V. Neville-Neil #include <machine/atomic.h> 43fcb56067SGeorge V. Neville-Neil #include <machine/db_machdep.h> 44fcb56067SGeorge V. Neville-Neil #include <machine/md_var.h> 45fcb56067SGeorge V. Neville-Neil #include <machine/stack.h> 46fcb56067SGeorge V. Neville-Neil #include <ddb/db_sym.h> 47fcb56067SGeorge V. Neville-Neil #include <ddb/ddb.h> 48fcb56067SGeorge V. Neville-Neil #include <sys/kdb.h> 49fcb56067SGeorge V. Neville-Neil 50fcb56067SGeorge V. Neville-Neil #include "regset.h" 51fcb56067SGeorge V. Neville-Neil 52fcb56067SGeorge V. Neville-Neil uint8_t dtrace_fuword8_nocheck(void *); 53fcb56067SGeorge V. Neville-Neil uint16_t dtrace_fuword16_nocheck(void *); 54fcb56067SGeorge V. Neville-Neil uint32_t dtrace_fuword32_nocheck(void *); 55fcb56067SGeorge V. Neville-Neil uint64_t dtrace_fuword64_nocheck(void *); 56fcb56067SGeorge V. Neville-Neil 57fcb56067SGeorge V. Neville-Neil void 58fcb56067SGeorge V. Neville-Neil dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, 59fcb56067SGeorge V. Neville-Neil uint32_t *intrpc) 60fcb56067SGeorge V. Neville-Neil { 61aeca5b8bSAndrew Turner struct unwind_state state; 62aeca5b8bSAndrew Turner register_t sp; 63fcb56067SGeorge V. Neville-Neil int scp_offset; 64fcb56067SGeorge V. Neville-Neil int depth = 0; 65fcb56067SGeorge V. Neville-Neil 66fcb56067SGeorge V. Neville-Neil if (intrpc != 0) 67fcb56067SGeorge V. Neville-Neil pcstack[depth++] = (pc_t) intrpc; 68fcb56067SGeorge V. Neville-Neil 69fcb56067SGeorge V. Neville-Neil aframes++; 70fcb56067SGeorge V. Neville-Neil 71aeca5b8bSAndrew Turner __asm __volatile("mov %0, sp" : "=&r" (sp)); 72fcb56067SGeorge V. Neville-Neil 73aeca5b8bSAndrew Turner state.registers[FP] = (uint32_t)__builtin_frame_address(0); 74aeca5b8bSAndrew Turner state.registers[SP] = sp; 75aeca5b8bSAndrew Turner state.registers[LR] = (uint32_t)__builtin_return_address(0); 76aeca5b8bSAndrew Turner state.registers[PC] = (uint32_t)dtrace_getpcstack; 77fcb56067SGeorge V. Neville-Neil 78aeca5b8bSAndrew Turner while (depth < pcstack_limit) { 79aeca5b8bSAndrew Turner int done; 80aeca5b8bSAndrew Turner 81aeca5b8bSAndrew Turner done = unwind_stack_one(&state, 1); 82fcb56067SGeorge V. Neville-Neil 832a1d3deeSRobert Watson /* 842a1d3deeSRobert Watson * NB: Unlike some other architectures, we don't need to 852a1d3deeSRobert Watson * explicitly insert cpu_dtrace_caller as it appears in the 862a1d3deeSRobert Watson * normal kernel stack trace rather than a special trap frame. 872a1d3deeSRobert Watson */ 88fcb56067SGeorge V. Neville-Neil if (aframes > 0) { 89fcb56067SGeorge V. Neville-Neil aframes--; 902a1d3deeSRobert Watson } else { 91aeca5b8bSAndrew Turner pcstack[depth++] = state.registers[PC]; 92fcb56067SGeorge V. Neville-Neil } 93fcb56067SGeorge V. Neville-Neil 94aeca5b8bSAndrew Turner if (done) 95fcb56067SGeorge V. Neville-Neil break; 96fcb56067SGeorge V. Neville-Neil } 97fcb56067SGeorge V. Neville-Neil 98fcb56067SGeorge V. Neville-Neil for (; depth < pcstack_limit; depth++) { 99fcb56067SGeorge V. Neville-Neil pcstack[depth] = 0; 100fcb56067SGeorge V. Neville-Neil } 101fcb56067SGeorge V. Neville-Neil } 102fcb56067SGeorge V. Neville-Neil 103fcb56067SGeorge V. Neville-Neil void 104fcb56067SGeorge V. Neville-Neil dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) 105fcb56067SGeorge V. Neville-Neil { 106fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 107fcb56067SGeorge V. Neville-Neil } 108fcb56067SGeorge V. Neville-Neil 109fcb56067SGeorge V. Neville-Neil int 110fcb56067SGeorge V. Neville-Neil dtrace_getustackdepth(void) 111fcb56067SGeorge V. Neville-Neil { 112fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 113fcb56067SGeorge V. Neville-Neil return (0); 114fcb56067SGeorge V. Neville-Neil } 115fcb56067SGeorge V. Neville-Neil 116fcb56067SGeorge V. Neville-Neil void 117fcb56067SGeorge V. Neville-Neil dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) 118fcb56067SGeorge V. Neville-Neil { 119fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 120fcb56067SGeorge V. Neville-Neil } 121fcb56067SGeorge V. Neville-Neil 122fcb56067SGeorge V. Neville-Neil /*ARGSUSED*/ 123fcb56067SGeorge V. Neville-Neil uint64_t 124fcb56067SGeorge V. Neville-Neil dtrace_getarg(int arg, int aframes) 125fcb56067SGeorge V. Neville-Neil { 126fcb56067SGeorge V. Neville-Neil /* struct arm_frame *fp = (struct arm_frame *)dtrace_getfp();*/ 127fcb56067SGeorge V. Neville-Neil 128fcb56067SGeorge V. Neville-Neil return (0); 129fcb56067SGeorge V. Neville-Neil } 130fcb56067SGeorge V. Neville-Neil 131fcb56067SGeorge V. Neville-Neil int 132fcb56067SGeorge V. Neville-Neil dtrace_getstackdepth(int aframes) 133fcb56067SGeorge V. Neville-Neil { 134aeca5b8bSAndrew Turner struct unwind_state state; 135aeca5b8bSAndrew Turner register_t sp; 136fcb56067SGeorge V. Neville-Neil int scp_offset; 137aeca5b8bSAndrew Turner int done = 0; 138fcb56067SGeorge V. Neville-Neil int depth = 1; 139fcb56067SGeorge V. Neville-Neil 140aeca5b8bSAndrew Turner __asm __volatile("mov %0, sp" : "=&r" (sp)); 141fcb56067SGeorge V. Neville-Neil 142aeca5b8bSAndrew Turner state.registers[FP] = (uint32_t)__builtin_frame_address(0); 143aeca5b8bSAndrew Turner state.registers[SP] = sp; 144aeca5b8bSAndrew Turner state.registers[LR] = (uint32_t)__builtin_return_address(0); 145aeca5b8bSAndrew Turner state.registers[PC] = (uint32_t)dtrace_getstackdepth; 146fcb56067SGeorge V. Neville-Neil 147aeca5b8bSAndrew Turner do { 148aeca5b8bSAndrew Turner done = unwind_stack_one(&state, 1); 149fcb56067SGeorge V. Neville-Neil depth++; 150aeca5b8bSAndrew Turner } while (!done); 151fcb56067SGeorge V. Neville-Neil 152fcb56067SGeorge V. Neville-Neil if (depth < aframes) 153fcb56067SGeorge V. Neville-Neil return 0; 154fcb56067SGeorge V. Neville-Neil else 155fcb56067SGeorge V. Neville-Neil return depth - aframes; 156fcb56067SGeorge V. Neville-Neil } 157fcb56067SGeorge V. Neville-Neil 158fcb56067SGeorge V. Neville-Neil ulong_t 15998ab9802SChristos Margiolis dtrace_getreg(struct trapframe *frame, uint_t reg) 160fcb56067SGeorge V. Neville-Neil { 161fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 162fcb56067SGeorge V. Neville-Neil 163fcb56067SGeorge V. Neville-Neil return (0); 164fcb56067SGeorge V. Neville-Neil } 165fcb56067SGeorge V. Neville-Neil 166fcb56067SGeorge V. Neville-Neil static int 167fcb56067SGeorge V. Neville-Neil dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) 168fcb56067SGeorge V. Neville-Neil { 169fcb56067SGeorge V. Neville-Neil 170fcb56067SGeorge V. Neville-Neil if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) { 171fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 172fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = uaddr; 173fcb56067SGeorge V. Neville-Neil return (0); 174fcb56067SGeorge V. Neville-Neil } 175fcb56067SGeorge V. Neville-Neil 176fcb56067SGeorge V. Neville-Neil return (1); 177fcb56067SGeorge V. Neville-Neil } 178fcb56067SGeorge V. Neville-Neil 179fcb56067SGeorge V. Neville-Neil void 180fcb56067SGeorge V. Neville-Neil dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 181fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 182fcb56067SGeorge V. Neville-Neil { 183fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 184fcb56067SGeorge V. Neville-Neil dtrace_copy(uaddr, kaddr, size); 185fcb56067SGeorge V. Neville-Neil } 186fcb56067SGeorge V. Neville-Neil 187fcb56067SGeorge V. Neville-Neil void 188fcb56067SGeorge V. Neville-Neil dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 189fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 190fcb56067SGeorge V. Neville-Neil { 191fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 192fcb56067SGeorge V. Neville-Neil dtrace_copy(kaddr, uaddr, size); 193fcb56067SGeorge V. Neville-Neil } 194fcb56067SGeorge V. Neville-Neil 195fcb56067SGeorge V. Neville-Neil void 196fcb56067SGeorge V. Neville-Neil dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 197fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 198fcb56067SGeorge V. Neville-Neil { 199fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 200fcb56067SGeorge V. Neville-Neil dtrace_copystr(uaddr, kaddr, size, flags); 201fcb56067SGeorge V. Neville-Neil } 202fcb56067SGeorge V. Neville-Neil 203fcb56067SGeorge V. Neville-Neil void 204fcb56067SGeorge V. Neville-Neil dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 205fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 206fcb56067SGeorge V. Neville-Neil { 207fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 208fcb56067SGeorge V. Neville-Neil dtrace_copystr(kaddr, uaddr, size, flags); 209fcb56067SGeorge V. Neville-Neil } 210fcb56067SGeorge V. Neville-Neil 211fcb56067SGeorge V. Neville-Neil uint8_t 212fcb56067SGeorge V. Neville-Neil dtrace_fuword8(void *uaddr) 213fcb56067SGeorge V. Neville-Neil { 214fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 215fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 216fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 217fcb56067SGeorge V. Neville-Neil return (0); 218fcb56067SGeorge V. Neville-Neil } 219fcb56067SGeorge V. Neville-Neil return (dtrace_fuword8_nocheck(uaddr)); 220fcb56067SGeorge V. Neville-Neil } 221fcb56067SGeorge V. Neville-Neil 222fcb56067SGeorge V. Neville-Neil uint16_t 223fcb56067SGeorge V. Neville-Neil dtrace_fuword16(void *uaddr) 224fcb56067SGeorge V. Neville-Neil { 225fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 226fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 227fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 228fcb56067SGeorge V. Neville-Neil return (0); 229fcb56067SGeorge V. Neville-Neil } 230fcb56067SGeorge V. Neville-Neil return (dtrace_fuword16_nocheck(uaddr)); 231fcb56067SGeorge V. Neville-Neil } 232fcb56067SGeorge V. Neville-Neil 233fcb56067SGeorge V. Neville-Neil uint32_t 234fcb56067SGeorge V. Neville-Neil dtrace_fuword32(void *uaddr) 235fcb56067SGeorge V. Neville-Neil { 236fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 237fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 238fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 239fcb56067SGeorge V. Neville-Neil return (0); 240fcb56067SGeorge V. Neville-Neil } 241fcb56067SGeorge V. Neville-Neil return (dtrace_fuword32_nocheck(uaddr)); 242fcb56067SGeorge V. Neville-Neil } 243fcb56067SGeorge V. Neville-Neil 244fcb56067SGeorge V. Neville-Neil uint64_t 245fcb56067SGeorge V. Neville-Neil dtrace_fuword64(void *uaddr) 246fcb56067SGeorge V. Neville-Neil { 247fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 248fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 249fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 250fcb56067SGeorge V. Neville-Neil return (0); 251fcb56067SGeorge V. Neville-Neil } 252fcb56067SGeorge V. Neville-Neil return (dtrace_fuword64_nocheck(uaddr)); 253fcb56067SGeorge V. Neville-Neil } 254