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