Path: blob/main/sys/cddl/dev/dtrace/arm/dtrace_isa.c
48375 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License, Version 1.0 only5* (the "License"). You may not use this file except in compliance6* with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or http://www.opensolaris.org/os/licensing.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright 2005 Sun Microsystems, Inc. All rights reserved.23* Use is subject to license terms.24*/25#include <sys/cdefs.h>2627#include <sys/param.h>28#include <sys/systm.h>29#include <sys/dtrace_impl.h>30#include <sys/kernel.h>31#include <sys/stack.h>32#include <sys/pcpu.h>3334#include <machine/frame.h>35#include <machine/md_var.h>3637#include <vm/vm.h>38#include <vm/vm_param.h>39#include <vm/pmap.h>4041#include <machine/atomic.h>42#include <machine/db_machdep.h>43#include <machine/md_var.h>44#include <machine/stack.h>45#include <ddb/db_sym.h>46#include <ddb/ddb.h>47#include <sys/kdb.h>4849#include "regset.h"5051uint8_t dtrace_fuword8_nocheck(void *);52uint16_t dtrace_fuword16_nocheck(void *);53uint32_t dtrace_fuword32_nocheck(void *);54uint64_t dtrace_fuword64_nocheck(void *);5556void57dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,58uint32_t *intrpc)59{60struct unwind_state state;61register_t sp;62int scp_offset;63int depth = 0;6465if (intrpc != 0)66pcstack[depth++] = (pc_t) intrpc;6768aframes++;6970__asm __volatile("mov %0, sp" : "=&r" (sp));7172state.registers[FP] = (uint32_t)__builtin_frame_address(0);73state.registers[SP] = sp;74state.registers[LR] = (uint32_t)__builtin_return_address(0);75state.registers[PC] = (uint32_t)dtrace_getpcstack;7677while (depth < pcstack_limit) {78int done;7980done = unwind_stack_one(&state, 1);8182/*83* NB: Unlike some other architectures, we don't need to84* explicitly insert cpu_dtrace_caller as it appears in the85* normal kernel stack trace rather than a special trap frame.86*/87if (aframes > 0) {88aframes--;89} else {90pcstack[depth++] = state.registers[PC];91}9293if (done)94break;95}9697for (; depth < pcstack_limit; depth++) {98pcstack[depth] = 0;99}100}101102void103dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)104{105printf("IMPLEMENT ME: %s\n", __func__);106}107108int109dtrace_getustackdepth(void)110{111printf("IMPLEMENT ME: %s\n", __func__);112return (0);113}114115void116dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)117{118printf("IMPLEMENT ME: %s\n", __func__);119}120121/*ARGSUSED*/122uint64_t123dtrace_getarg(int arg, int aframes)124{125/* struct arm_frame *fp = (struct arm_frame *)dtrace_getfp();*/126127return (0);128}129130int131dtrace_getstackdepth(int aframes)132{133struct unwind_state state;134register_t sp;135int scp_offset;136int done = 0;137int depth = 1;138139__asm __volatile("mov %0, sp" : "=&r" (sp));140141state.registers[FP] = (uint32_t)__builtin_frame_address(0);142state.registers[SP] = sp;143state.registers[LR] = (uint32_t)__builtin_return_address(0);144state.registers[PC] = (uint32_t)dtrace_getstackdepth;145146do {147done = unwind_stack_one(&state, 1);148depth++;149} while (!done);150151if (depth < aframes)152return 0;153else154return depth - aframes;155}156157ulong_t158dtrace_getreg(struct trapframe *frame, uint_t reg)159{160printf("IMPLEMENT ME: %s\n", __func__);161162return (0);163}164165static int166dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)167{168169if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) {170DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);171cpu_core[curcpu].cpuc_dtrace_illval = uaddr;172return (0);173}174175return (1);176}177178void179dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,180volatile uint16_t *flags)181{182if (dtrace_copycheck(uaddr, kaddr, size))183dtrace_copy(uaddr, kaddr, size);184}185186void187dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,188volatile uint16_t *flags)189{190if (dtrace_copycheck(uaddr, kaddr, size))191dtrace_copy(kaddr, uaddr, size);192}193194void195dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,196volatile uint16_t *flags)197{198if (dtrace_copycheck(uaddr, kaddr, size))199dtrace_copystr(uaddr, kaddr, size, flags);200}201202void203dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,204volatile uint16_t *flags)205{206if (dtrace_copycheck(uaddr, kaddr, size))207dtrace_copystr(kaddr, uaddr, size, flags);208}209210uint8_t211dtrace_fuword8(void *uaddr)212{213if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {214DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);215cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;216return (0);217}218return (dtrace_fuword8_nocheck(uaddr));219}220221uint16_t222dtrace_fuword16(void *uaddr)223{224if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {225DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);226cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;227return (0);228}229return (dtrace_fuword16_nocheck(uaddr));230}231232uint32_t233dtrace_fuword32(void *uaddr)234{235if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {236DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);237cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;238return (0);239}240return (dtrace_fuword32_nocheck(uaddr));241}242243uint64_t244dtrace_fuword64(void *uaddr)245{246if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {247DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);248cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;249return (0);250}251return (dtrace_fuword64_nocheck(uaddr));252}253254255