xref: /linux/arch/x86/include/uapi/asm/debugreg.h (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
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