1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 * See "LICENSE_GPLv2.txt" for details. 9 * 10 * @TAG(DATA61_GPL) 11 */ 12 13#ifndef __ARCH_MODE_MACHINE_DEBUG_H_ 14#define __ARCH_MODE_MACHINE_DEBUG_H_ 15 16#include <config.h> 17 18#define DBGDSCR_int "p14,0,%0,c0,c1,0" 19/* Not guaranteed in v7, only v7.1+ */ 20#define DBGDSCR_ext "p14, 0, %0, c0, c2, 2" 21#define DBGSDER "p15, 0, %0, c1, c1, 1" 22 23#define DBGWFAR "p14,0,%0,c0,c6,0" 24#define DFAR "p15,0,%0,c6,c0,0" 25 26#define DBGDSCR_SECURE_MODE_DISABLED (BIT(18)) 27 28#define DBGSDER_ENABLE_SECURE_USER_NON_INVASIVE_DEBUG (BIT(1)) 29 30#if defined(CONFIG_DEBUG_BUILD) || defined (CONFIG_HARDWARE_DEBUG_API) 31 32#ifndef __ASSEMBLER__ 33#include <stdint.h> 34#include <arch/machine/registerset.h> 35 36void debug_init(void) VISIBLE; 37 38typedef void (*break_handler_t)(user_context_t *context); 39 40void software_breakpoint(uint32_t va, user_context_t *context) VISIBLE; 41void breakpoint_multiplexer(uint32_t va, user_context_t *context) VISIBLE; 42 43int set_breakpoint(uint32_t va, break_handler_t handler) VISIBLE; 44void clear_breakpoint(uint32_t va) VISIBLE; 45 46enum vector_ids { 47 VECTOR_RESET = 0, 48 VECTOR_UNDEFINED = 1, 49 VECTOR_SWI = 2, 50 VECTOR_PREFETCH_ABORT = 3, 51 VECTOR_DATA_ABORT = 4, 52 VECTOR_IRQ = 6, 53 VECTOR_FIQ = 7 54}; 55typedef uint32_t vector_t; 56 57typedef void (*catch_handler_t)(user_context_t *context, vector_t vector); 58 59void set_catch_handler(catch_handler_t handler) VISIBLE; 60void catch_vector(vector_t vector) VISIBLE; 61void uncatch_vector(vector_t vector) VISIBLE; 62#endif /* !__ASSEMBLER__ */ 63 64/*********************************/ 65/*** cp14 register definitions ***/ 66/*********************************/ 67 68/* Debug ID Register */ 69#define DIDR_BRP_OFFSET 24 70#define DIDR_BRP_SIZE 4 71#define DIDR_VERSION_OFFSET 16 72#define DIDR_VERSION_SIZE 4 73#define DIDR_VARIANT_OFFSET 4 74#define DIDR_VARIANT_SIZE 4 75#define DIDR_REVISION_OFFSET 0 76#define DIDR_REVISION_SIZE 4 77 78#ifndef __ASSEMBLER__ 79static inline uint32_t 80getDIDR(void) 81{ 82 uint32_t x; 83 84 asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r"(x)); 85 86 return x; 87} 88 89#ifdef CONFIG_HARDWARE_DEBUG_API 90 91#define DEBUG_REPLY_N_REQUIRED_REGISTERS (1) 92 93/* Get Watchpoint Fault Address register value (for async watchpoints). */ 94static inline word_t 95getWFAR(void) 96{ 97 word_t ret; 98 99 MRC(DBGWFAR, ret); 100 return ret; 101} 102#endif 103#endif /* !__ASSEMBLER__ */ 104 105/* Debug Status and Control Register */ 106#define DSCR_MONITOR_MODE_ENABLE 15 107#define DSCR_MODE_SELECT 14 108#define DSCR_ENTRY_OFFSET 2 109#define DSCR_ENTRY_SIZE 4 110 111#define DEBUG_ENTRY_DBGTAP_HALT 0 112#define DEBUG_ENTRY_BREAKPOINT 1 113#define DEBUG_ENTRY_ASYNC_WATCHPOINT 2 114#define DEBUG_ENTRY_EXPLICIT_BKPT 3 115#define DEBUG_ENTRY_EDBGRQ 4 116#define DEBUG_ENTRY_VECTOR_CATCH 5 117#define DEBUG_ENTRY_DATA_ABORT 6 118#define DEBUG_ENTRY_INSTRUCTION_ABORT 7 119#define DEBUG_ENTRY_SYNC_WATCHPOINT (0xA) 120 121/* Vector Catch Register */ 122#define VCR_FIQ 7 123#define VCR_IRQ 6 124#define VCR_DATA 4 125#define VCR_PREFETCH 3 126#define VCR_SWI 2 127#define VCR_UNDEF 1 128#define VCR_RESET 0 129 130#ifndef __ASSEMBLER__ 131static inline uint32_t 132getVCR(void) 133{ 134 uint32_t x; 135 136 asm volatile("mrc p14, 0, %0, c0, c7, 0" : "=r"(x)); 137 138 return x; 139} 140 141static inline void 142setVCR(uint32_t x) 143{ 144 asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r"(x)); 145} 146 147#endif /* !__ASSEMBLER__ */ 148 149/* Breakpoint Control Registers */ 150#define BCR_MEANING 21 151#define BCR_ENABLE_LINKING 20 152#define BCR_LINKED_BRP 16 153#define BCR_BYTE_SELECT 5 154#define BCR_SUPERVISOR 1 155#define BCR_ENABLE 0 156 157#define FSR_SHORTDESC_STATUS_DEBUG_EVENT (0x2) 158#define FSR_LONGDESC_STATUS_DEBUG_EVENT (0x22) 159#define FSR_LPAE_SHIFT (9) 160#define FSR_STATUS_BIT4_SHIFT (10) 161 162#ifndef __ASSEMBLER__ 163 164#ifdef CONFIG_HARDWARE_DEBUG_API 165/** Determines whether or not a Prefetch Abort or Data Abort was really a debug 166 * exception. 167 * 168 * Examines the FSR bits, looking for the "Debug event" value, and also examines 169 * DBGDSCR looking for the "Async watchpoint abort" value, since async 170 * watchpoints behave differently. 171 */ 172bool_t isDebugFault(word_t hsr_or_fsr); 173 174/** Determines and carries out what needs to be done for a debug exception. 175 * 176 * This could be handling a single-stepping exception, or a breakpoint or 177 * watchpoint. 178 */ 179seL4_Fault_t handleUserLevelDebugException(word_t fault_vaddr); 180 181/** These next two functions are part of some state flags. 182 * 183 * A bitfield of all currently enabled breakpoints for a thread is kept in that 184 * thread's TCB. These two functions here set and unset the bits in that 185 * bitfield. 186 */ 187static inline void 188setBreakpointUsedFlag(tcb_t *t, uint16_t bp_num) 189{ 190 if (t != NULL) { 191 t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf |= BIT(bp_num); 192 } 193} 194 195static inline void 196unsetBreakpointUsedFlag(tcb_t *t, uint16_t bp_num) 197{ 198 if (t != NULL) { 199 t->tcbArch.tcbContext.breakpointState.used_breakpoints_bf &= ~BIT(bp_num); 200 } 201} 202 203#endif /* CONFIG_HARDWARE_DEBUG_API */ 204 205#endif /* !__ASSEMBLER__ */ 206 207#endif /* defined(CONFIG_DEBUG_BUILD) || defined (CONFIG_HARDWARE_DEBUG_API) */ 208#endif /* __ARCH_MODE_MACHINE_DEBUG_H_ */ 209