16f52b16cSGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2af170c50SDavid Howells #ifndef _UAPI_ASM_X86_DEBUGREG_H 3af170c50SDavid Howells #define _UAPI_ASM_X86_DEBUGREG_H 4af170c50SDavid Howells 5af170c50SDavid Howells 6af170c50SDavid Howells /* Indicate the register numbers for a number of the specific 7af170c50SDavid Howells debug registers. Registers 0-3 contain the addresses we wish to trap on */ 8af170c50SDavid Howells #define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */ 9af170c50SDavid Howells #define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */ 10af170c50SDavid Howells 11af170c50SDavid Howells #define DR_STATUS 6 /* u_debugreg[DR_STATUS] */ 12af170c50SDavid Howells #define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */ 13af170c50SDavid Howells 14af170c50SDavid Howells /* Define a few things for the status register. We can use this to determine 15af170c50SDavid Howells which debugging register was responsible for the trap. The other bits 16af170c50SDavid Howells are either reserved or not of interest to us. */ 17af170c50SDavid Howells 18af170c50SDavid Howells /* Define reserved bits in DR6 which are always set to 1 */ 19af170c50SDavid Howells #define DR6_RESERVED (0xFFFF0FF0) 20af170c50SDavid Howells 21af170c50SDavid Howells #define DR_TRAP0 (0x1) /* db0 */ 22af170c50SDavid Howells #define DR_TRAP1 (0x2) /* db1 */ 23af170c50SDavid Howells #define DR_TRAP2 (0x4) /* db2 */ 24af170c50SDavid Howells #define DR_TRAP3 (0x8) /* db3 */ 25af170c50SDavid Howells #define DR_TRAP_BITS (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3) 26af170c50SDavid Howells 27*ebb1064eSFenghua Yu #define DR_BUS_LOCK (0x800) /* bus_lock */ 28af170c50SDavid Howells #define DR_STEP (0x4000) /* single-step */ 29af170c50SDavid Howells #define DR_SWITCH (0x8000) /* task switch */ 30af170c50SDavid Howells 31af170c50SDavid Howells /* Now define a bunch of things for manipulating the control register. 32af170c50SDavid Howells The top two bytes of the control register consist of 4 fields of 4 33af170c50SDavid Howells bits - each field corresponds to one of the four debug registers, 34af170c50SDavid Howells and indicates what types of access we trap on, and how large the data 35af170c50SDavid Howells field is that we are looking at */ 36af170c50SDavid Howells 37af170c50SDavid Howells #define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */ 38af170c50SDavid Howells #define DR_CONTROL_SIZE 4 /* 4 control bits per register */ 39af170c50SDavid Howells 40af170c50SDavid Howells #define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */ 41af170c50SDavid Howells #define DR_RW_WRITE (0x1) 42af170c50SDavid Howells #define DR_RW_READ (0x3) 43af170c50SDavid Howells 44af170c50SDavid Howells #define DR_LEN_1 (0x0) /* Settings for data length to trap on */ 45af170c50SDavid Howells #define DR_LEN_2 (0x4) 46af170c50SDavid Howells #define DR_LEN_4 (0xC) 47af170c50SDavid Howells #define DR_LEN_8 (0x8) 48af170c50SDavid Howells 49af170c50SDavid Howells /* The low byte to the control register determine which registers are 50af170c50SDavid Howells enabled. There are 4 fields of two bits. One bit is "local", meaning 51af170c50SDavid Howells that the processor will reset the bit after a task switch and the other 52af170c50SDavid Howells is global meaning that we have to explicitly reset the bit. With linux, 53af170c50SDavid Howells you can use either one, since we explicitly zero the register when we enter 54af170c50SDavid Howells kernel mode. */ 55af170c50SDavid Howells 56af170c50SDavid Howells #define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */ 57af170c50SDavid Howells #define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */ 58af170c50SDavid Howells #define DR_LOCAL_ENABLE (0x1) /* Local enable for reg 0 */ 59af170c50SDavid Howells #define DR_GLOBAL_ENABLE (0x2) /* Global enable for reg 0 */ 60af170c50SDavid Howells #define DR_ENABLE_SIZE 2 /* 2 enable bits per register */ 61af170c50SDavid Howells 62af170c50SDavid Howells #define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */ 63af170c50SDavid Howells #define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */ 64af170c50SDavid Howells 65af170c50SDavid Howells /* The second byte to the control register has a few special things. 66af170c50SDavid Howells We can slow the instruction pipeline for instructions coming via the 67af170c50SDavid Howells gdt or the ldt if we want to. I am not sure why this is an advantage */ 68af170c50SDavid Howells 69af170c50SDavid Howells #ifdef __i386__ 70af170c50SDavid Howells #define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */ 71af170c50SDavid Howells #else 72af170c50SDavid Howells #define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */ 73af170c50SDavid Howells #endif 74af170c50SDavid Howells 75af170c50SDavid Howells #define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */ 76af170c50SDavid Howells #define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */ 77af170c50SDavid Howells 78af170c50SDavid Howells /* 79af170c50SDavid Howells * HW breakpoint additions 80af170c50SDavid Howells */ 81af170c50SDavid Howells 82af170c50SDavid Howells #endif /* _UAPI_ASM_X86_DEBUGREG_H */ 83