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 * $FreeBSD$ 23fcb56067SGeorge V. Neville-Neil */ 24fcb56067SGeorge V. Neville-Neil /* 25fcb56067SGeorge V. Neville-Neil * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 26fcb56067SGeorge V. Neville-Neil * Use is subject to license terms. 27fcb56067SGeorge V. Neville-Neil */ 28fcb56067SGeorge V. Neville-Neil #include <sys/cdefs.h> 29fcb56067SGeorge V. Neville-Neil 30fcb56067SGeorge V. Neville-Neil #include <sys/param.h> 31fcb56067SGeorge V. Neville-Neil #include <sys/systm.h> 32fcb56067SGeorge V. Neville-Neil #include <sys/kernel.h> 33fcb56067SGeorge V. Neville-Neil #include <sys/stack.h> 34fcb56067SGeorge V. Neville-Neil #include <sys/pcpu.h> 35fcb56067SGeorge V. Neville-Neil 36fcb56067SGeorge V. Neville-Neil #include <machine/frame.h> 37fcb56067SGeorge V. Neville-Neil #include <machine/md_var.h> 38fcb56067SGeorge V. Neville-Neil 39fcb56067SGeorge V. Neville-Neil #include <vm/vm.h> 40fcb56067SGeorge V. Neville-Neil #include <vm/vm_param.h> 41fcb56067SGeorge V. Neville-Neil #include <vm/pmap.h> 42fcb56067SGeorge V. Neville-Neil 43fcb56067SGeorge V. Neville-Neil #include <machine/atomic.h> 44fcb56067SGeorge V. Neville-Neil #include <machine/db_machdep.h> 45fcb56067SGeorge V. Neville-Neil #include <machine/md_var.h> 46fcb56067SGeorge V. Neville-Neil #include <machine/stack.h> 47fcb56067SGeorge V. Neville-Neil #include <ddb/db_sym.h> 48fcb56067SGeorge V. Neville-Neil #include <ddb/ddb.h> 49fcb56067SGeorge V. Neville-Neil #include <sys/kdb.h> 50fcb56067SGeorge V. Neville-Neil 51fcb56067SGeorge V. Neville-Neil #include "regset.h" 52fcb56067SGeorge V. Neville-Neil 53fcb56067SGeorge V. Neville-Neil uint8_t dtrace_fuword8_nocheck(void *); 54fcb56067SGeorge V. Neville-Neil uint16_t dtrace_fuword16_nocheck(void *); 55fcb56067SGeorge V. Neville-Neil uint32_t dtrace_fuword32_nocheck(void *); 56fcb56067SGeorge V. Neville-Neil uint64_t dtrace_fuword64_nocheck(void *); 57fcb56067SGeorge V. Neville-Neil 58fcb56067SGeorge V. Neville-Neil void 59fcb56067SGeorge V. Neville-Neil dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, 60fcb56067SGeorge V. Neville-Neil uint32_t *intrpc) 61fcb56067SGeorge V. Neville-Neil { 62aeca5b8bSAndrew Turner struct unwind_state state; 63aeca5b8bSAndrew Turner register_t sp; 64fcb56067SGeorge V. Neville-Neil int scp_offset; 65fcb56067SGeorge V. Neville-Neil int depth = 0; 66fcb56067SGeorge V. Neville-Neil 67fcb56067SGeorge V. Neville-Neil if (intrpc != 0) 68fcb56067SGeorge V. Neville-Neil pcstack[depth++] = (pc_t) intrpc; 69fcb56067SGeorge V. Neville-Neil 70fcb56067SGeorge V. Neville-Neil aframes++; 71fcb56067SGeorge V. Neville-Neil 72aeca5b8bSAndrew Turner __asm __volatile("mov %0, sp" : "=&r" (sp)); 73fcb56067SGeorge V. Neville-Neil 74aeca5b8bSAndrew Turner state.registers[FP] = (uint32_t)__builtin_frame_address(0); 75aeca5b8bSAndrew Turner state.registers[SP] = sp; 76aeca5b8bSAndrew Turner state.registers[LR] = (uint32_t)__builtin_return_address(0); 77aeca5b8bSAndrew Turner state.registers[PC] = (uint32_t)dtrace_getpcstack; 78fcb56067SGeorge V. Neville-Neil 79aeca5b8bSAndrew Turner while (depth < pcstack_limit) { 80aeca5b8bSAndrew Turner int done; 81aeca5b8bSAndrew Turner 82aeca5b8bSAndrew Turner done = unwind_stack_one(&state, 1); 83fcb56067SGeorge V. Neville-Neil 842a1d3deeSRobert Watson /* 852a1d3deeSRobert Watson * NB: Unlike some other architectures, we don't need to 862a1d3deeSRobert Watson * explicitly insert cpu_dtrace_caller as it appears in the 872a1d3deeSRobert Watson * normal kernel stack trace rather than a special trap frame. 882a1d3deeSRobert Watson */ 89fcb56067SGeorge V. Neville-Neil if (aframes > 0) { 90fcb56067SGeorge V. Neville-Neil aframes--; 912a1d3deeSRobert Watson } else { 92aeca5b8bSAndrew Turner pcstack[depth++] = state.registers[PC]; 93fcb56067SGeorge V. Neville-Neil } 94fcb56067SGeorge V. Neville-Neil 95aeca5b8bSAndrew Turner if (done) 96fcb56067SGeorge V. Neville-Neil break; 97fcb56067SGeorge V. Neville-Neil } 98fcb56067SGeorge V. Neville-Neil 99fcb56067SGeorge V. Neville-Neil for (; depth < pcstack_limit; depth++) { 100fcb56067SGeorge V. Neville-Neil pcstack[depth] = 0; 101fcb56067SGeorge V. Neville-Neil } 102fcb56067SGeorge V. Neville-Neil } 103fcb56067SGeorge V. Neville-Neil 104fcb56067SGeorge V. Neville-Neil void 105fcb56067SGeorge V. Neville-Neil dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) 106fcb56067SGeorge V. Neville-Neil { 107fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 108fcb56067SGeorge V. Neville-Neil } 109fcb56067SGeorge V. Neville-Neil 110fcb56067SGeorge V. Neville-Neil int 111fcb56067SGeorge V. Neville-Neil dtrace_getustackdepth(void) 112fcb56067SGeorge V. Neville-Neil { 113fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 114fcb56067SGeorge V. Neville-Neil return (0); 115fcb56067SGeorge V. Neville-Neil } 116fcb56067SGeorge V. Neville-Neil 117fcb56067SGeorge V. Neville-Neil void 118fcb56067SGeorge V. Neville-Neil dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) 119fcb56067SGeorge V. Neville-Neil { 120fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 121fcb56067SGeorge V. Neville-Neil } 122fcb56067SGeorge V. Neville-Neil 123fcb56067SGeorge V. Neville-Neil /*ARGSUSED*/ 124fcb56067SGeorge V. Neville-Neil uint64_t 125fcb56067SGeorge V. Neville-Neil dtrace_getarg(int arg, int aframes) 126fcb56067SGeorge V. Neville-Neil { 127fcb56067SGeorge V. Neville-Neil /* struct arm_frame *fp = (struct arm_frame *)dtrace_getfp();*/ 128fcb56067SGeorge V. Neville-Neil 129fcb56067SGeorge V. Neville-Neil return (0); 130fcb56067SGeorge V. Neville-Neil } 131fcb56067SGeorge V. Neville-Neil 132fcb56067SGeorge V. Neville-Neil int 133fcb56067SGeorge V. Neville-Neil dtrace_getstackdepth(int aframes) 134fcb56067SGeorge V. Neville-Neil { 135aeca5b8bSAndrew Turner struct unwind_state state; 136aeca5b8bSAndrew Turner register_t sp; 137fcb56067SGeorge V. Neville-Neil int scp_offset; 138aeca5b8bSAndrew Turner int done = 0; 139fcb56067SGeorge V. Neville-Neil int depth = 1; 140fcb56067SGeorge V. Neville-Neil 141aeca5b8bSAndrew Turner __asm __volatile("mov %0, sp" : "=&r" (sp)); 142fcb56067SGeorge V. Neville-Neil 143aeca5b8bSAndrew Turner state.registers[FP] = (uint32_t)__builtin_frame_address(0); 144aeca5b8bSAndrew Turner state.registers[SP] = sp; 145aeca5b8bSAndrew Turner state.registers[LR] = (uint32_t)__builtin_return_address(0); 146aeca5b8bSAndrew Turner state.registers[PC] = (uint32_t)dtrace_getstackdepth; 147fcb56067SGeorge V. Neville-Neil 148aeca5b8bSAndrew Turner do { 149aeca5b8bSAndrew Turner done = unwind_stack_one(&state, 1); 150fcb56067SGeorge V. Neville-Neil depth++; 151aeca5b8bSAndrew Turner } while (!done); 152fcb56067SGeorge V. Neville-Neil 153fcb56067SGeorge V. Neville-Neil if (depth < aframes) 154fcb56067SGeorge V. Neville-Neil return 0; 155fcb56067SGeorge V. Neville-Neil else 156fcb56067SGeorge V. Neville-Neil return depth - aframes; 157fcb56067SGeorge V. Neville-Neil } 158fcb56067SGeorge V. Neville-Neil 159fcb56067SGeorge V. Neville-Neil ulong_t 16098ab9802SChristos Margiolis dtrace_getreg(struct trapframe *frame, uint_t reg) 161fcb56067SGeorge V. Neville-Neil { 162fcb56067SGeorge V. Neville-Neil printf("IMPLEMENT ME: %s\n", __func__); 163fcb56067SGeorge V. Neville-Neil 164fcb56067SGeorge V. Neville-Neil return (0); 165fcb56067SGeorge V. Neville-Neil } 166fcb56067SGeorge V. Neville-Neil 167fcb56067SGeorge V. Neville-Neil static int 168fcb56067SGeorge V. Neville-Neil dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) 169fcb56067SGeorge V. Neville-Neil { 170fcb56067SGeorge V. Neville-Neil 171fcb56067SGeorge V. Neville-Neil if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) { 172fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 173fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = uaddr; 174fcb56067SGeorge V. Neville-Neil return (0); 175fcb56067SGeorge V. Neville-Neil } 176fcb56067SGeorge V. Neville-Neil 177fcb56067SGeorge V. Neville-Neil return (1); 178fcb56067SGeorge V. Neville-Neil } 179fcb56067SGeorge V. Neville-Neil 180fcb56067SGeorge V. Neville-Neil void 181fcb56067SGeorge V. Neville-Neil dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 182fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 183fcb56067SGeorge V. Neville-Neil { 184fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 185fcb56067SGeorge V. Neville-Neil dtrace_copy(uaddr, kaddr, size); 186fcb56067SGeorge V. Neville-Neil } 187fcb56067SGeorge V. Neville-Neil 188fcb56067SGeorge V. Neville-Neil void 189fcb56067SGeorge V. Neville-Neil dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 190fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 191fcb56067SGeorge V. Neville-Neil { 192fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 193fcb56067SGeorge V. Neville-Neil dtrace_copy(kaddr, uaddr, size); 194fcb56067SGeorge V. Neville-Neil } 195fcb56067SGeorge V. Neville-Neil 196fcb56067SGeorge V. Neville-Neil void 197fcb56067SGeorge V. Neville-Neil dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 198fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 199fcb56067SGeorge V. Neville-Neil { 200fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 201fcb56067SGeorge V. Neville-Neil dtrace_copystr(uaddr, kaddr, size, flags); 202fcb56067SGeorge V. Neville-Neil } 203fcb56067SGeorge V. Neville-Neil 204fcb56067SGeorge V. Neville-Neil void 205fcb56067SGeorge V. Neville-Neil dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 206fcb56067SGeorge V. Neville-Neil volatile uint16_t *flags) 207fcb56067SGeorge V. Neville-Neil { 208fcb56067SGeorge V. Neville-Neil if (dtrace_copycheck(uaddr, kaddr, size)) 209fcb56067SGeorge V. Neville-Neil dtrace_copystr(kaddr, uaddr, size, flags); 210fcb56067SGeorge V. Neville-Neil } 211fcb56067SGeorge V. Neville-Neil 212fcb56067SGeorge V. Neville-Neil uint8_t 213fcb56067SGeorge V. Neville-Neil dtrace_fuword8(void *uaddr) 214fcb56067SGeorge V. Neville-Neil { 215fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 216fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 217fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 218fcb56067SGeorge V. Neville-Neil return (0); 219fcb56067SGeorge V. Neville-Neil } 220fcb56067SGeorge V. Neville-Neil return (dtrace_fuword8_nocheck(uaddr)); 221fcb56067SGeorge V. Neville-Neil } 222fcb56067SGeorge V. Neville-Neil 223fcb56067SGeorge V. Neville-Neil uint16_t 224fcb56067SGeorge V. Neville-Neil dtrace_fuword16(void *uaddr) 225fcb56067SGeorge V. Neville-Neil { 226fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 227fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 228fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 229fcb56067SGeorge V. Neville-Neil return (0); 230fcb56067SGeorge V. Neville-Neil } 231fcb56067SGeorge V. Neville-Neil return (dtrace_fuword16_nocheck(uaddr)); 232fcb56067SGeorge V. Neville-Neil } 233fcb56067SGeorge V. Neville-Neil 234fcb56067SGeorge V. Neville-Neil uint32_t 235fcb56067SGeorge V. Neville-Neil dtrace_fuword32(void *uaddr) 236fcb56067SGeorge V. Neville-Neil { 237fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 238fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 239fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 240fcb56067SGeorge V. Neville-Neil return (0); 241fcb56067SGeorge V. Neville-Neil } 242fcb56067SGeorge V. Neville-Neil return (dtrace_fuword32_nocheck(uaddr)); 243fcb56067SGeorge V. Neville-Neil } 244fcb56067SGeorge V. Neville-Neil 245fcb56067SGeorge V. Neville-Neil uint64_t 246fcb56067SGeorge V. Neville-Neil dtrace_fuword64(void *uaddr) 247fcb56067SGeorge V. Neville-Neil { 248fcb56067SGeorge V. Neville-Neil if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 249fcb56067SGeorge V. Neville-Neil DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 250fcb56067SGeorge V. Neville-Neil cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 251fcb56067SGeorge V. Neville-Neil return (0); 252fcb56067SGeorge V. Neville-Neil } 253fcb56067SGeorge V. Neville-Neil return (dtrace_fuword64_nocheck(uaddr)); 254fcb56067SGeorge V. Neville-Neil } 255