1160332Scognet/*- 2160332Scognet * Copyright (c) 2006 Olivier Houchard 3160332Scognet * All rights reserved. 4160332Scognet * 5160332Scognet * Redistribution and use in source and binary forms, with or without 6160332Scognet * modification, are permitted provided that the following conditions 7160332Scognet * are met: 8160332Scognet * 9160332Scognet * 1. Redistributions of source code must retain the above copyright 10160332Scognet * notice, this list of conditions and the following disclaimer. 11160332Scognet * 2. Redistributions in binary form must reproduce the above copyright 12160332Scognet * notice, this list of conditions and the following disclaimer in the 13160332Scognet * documentation and/or other materials provided with the distribution. 14160332Scognet * 15160332Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16160332Scognet * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17160332Scognet * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18160332Scognet * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19160332Scognet * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20160332Scognet * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21160332Scognet * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22160332Scognet * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23160332Scognet * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24160332Scognet * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25160332Scognet */ 26160332Scognet 27160332Scognet#include <sys/cdefs.h> 28160332Scognet__FBSDID("$FreeBSD: releng/10.3/sys/arm/arm/gdb_machdep.c 278614 2015-02-12 04:15:55Z ian $"); 29160332Scognet 30160332Scognet 31160332Scognet#include <sys/param.h> 32160332Scognet#include <sys/systm.h> 33160332Scognet#include <sys/kdb.h> 34160332Scognet#include <sys/kernel.h> 35160332Scognet#include <sys/proc.h> 36160332Scognet#include <sys/signal.h> 37160332Scognet 38160332Scognet#include <machine/gdb_machdep.h> 39160332Scognet#include <machine/db_machdep.h> 40160332Scognet#include <machine/vmparam.h> 41160332Scognet#include <machine/pcb.h> 42160332Scognet#include <machine/trap.h> 43160332Scognet#include <machine/frame.h> 44160332Scognet#include <machine/endian.h> 45160332Scognet 46160332Scognet#include <gdb/gdb.h> 47160332Scognet 48160332Scognetstatic register_t stacktest; 49160332Scognet 50160332Scognetvoid * 51160332Scognetgdb_cpu_getreg(int regnum, size_t *regsz) 52160332Scognet{ 53160332Scognet 54160332Scognet *regsz = gdb_cpu_regsz(regnum); 55160332Scognet 56198944Smarcel if (kdb_thread == curthread) { 57235908Sgber if (regnum < 13) 58198944Smarcel return (&kdb_frame->tf_r0 + regnum); 59235908Sgber if (regnum == 13) 60235908Sgber return (&kdb_frame->tf_svc_sp); 61235908Sgber if (regnum == 14) 62235908Sgber return (&kdb_frame->tf_svc_lr); 63198944Smarcel if (regnum == 15) 64198944Smarcel return (&kdb_frame->tf_pc); 65160332Scognet if (regnum == 25) 66160332Scognet return (&kdb_frame->tf_spsr); 67160332Scognet } 68198944Smarcel 69160332Scognet switch (regnum) { 70278614Sian case 4: return (&kdb_thrctx->pcb_regs.sf_r4); 71278614Sian case 5: return (&kdb_thrctx->pcb_regs.sf_r5); 72278614Sian case 6: return (&kdb_thrctx->pcb_regs.sf_r6); 73278614Sian case 7: return (&kdb_thrctx->pcb_regs.sf_r7); 74278614Sian case 8: return (&kdb_thrctx->pcb_regs.sf_r8); 75278614Sian case 9: return (&kdb_thrctx->pcb_regs.sf_r9); 76278614Sian case 10: return (&kdb_thrctx->pcb_regs.sf_r10); 77278614Sian case 11: return (&kdb_thrctx->pcb_regs.sf_r11); 78278614Sian case 12: return (&kdb_thrctx->pcb_regs.sf_r12); 79278614Sian case 13: stacktest = kdb_thrctx->pcb_regs.sf_sp + 5 * 4; 80160332Scognet return (&stacktest); 81236991Simp case 15: 82236991Simp /* 83160332Scognet * On context switch, the PC is not put in the PCB, but 84160332Scognet * we can retrieve it from the stack. 85160332Scognet */ 86278614Sian if (kdb_thrctx->pcb_regs.sf_sp > KERNBASE) { 87278614Sian kdb_thrctx->pcb_regs.sf_pc = *(register_t *) 88278614Sian (kdb_thrctx->pcb_regs.sf_sp + 4 * 4); 89278614Sian return (&kdb_thrctx->pcb_regs.sf_pc); 90160332Scognet } 91160332Scognet } 92198944Smarcel 93160332Scognet return (NULL); 94160332Scognet} 95160332Scognet 96160332Scognetvoid 97160332Scognetgdb_cpu_setreg(int regnum, void *val) 98160332Scognet{ 99160332Scognet 100160332Scognet switch (regnum) { 101160332Scognet case GDB_REG_PC: 102160332Scognet if (kdb_thread == curthread) 103160332Scognet kdb_frame->tf_pc = *(register_t *)val; 104160332Scognet } 105160332Scognet} 106160332Scognet 107160332Scognetint 108160332Scognetgdb_cpu_signal(int type, int code) 109160332Scognet{ 110160332Scognet 111160332Scognet switch (type) { 112160332Scognet case T_BREAKPOINT: return (SIGTRAP); 113160332Scognet } 114160332Scognet return (SIGEMT); 115160332Scognet} 116