dbregs.h revision 1.3
1/* $NetBSD: dbregs.h,v 1.3 2017/01/18 05:12:00 kamil Exp $ */ 2 3/*- 4 * Copyright (c) 2016 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 30#ifndef _X86_DBREGS_H_ 31#define _X86_DBREGS_H_ 32 33#if defined(_KERNEL) 34 35#include <sys/param.h> 36#include <sys/types.h> 37 38/* 39 * CPU Debug Status Register (DR6) 40 * 41 * Reserved bits: 4-12 and on x86_64 32-64 42 */ 43#define X86_HW_WATCHPOINT_DR6_DR0_BREAKPOINT_CONDITION_DETECTED __BIT(0) 44#define X86_HW_WATCHPOINT_DR6_DR1_BREAKPOINT_CONDITION_DETECTED __BIT(1) 45#define X86_HW_WATCHPOINT_DR6_DR2_BREAKPOINT_CONDITION_DETECTED __BIT(2) 46#define X86_HW_WATCHPOINT_DR6_DR3_BREAKPOINT_CONDITION_DETECTED __BIT(3) 47#define X86_HW_WATCHPOINT_DR6_DEBUG_REGISTER_ACCESS_DETECTED __BIT(13) 48#define X86_HW_WATCHPOINT_DR6_SINGLE_STEP __BIT(14) 49#define X86_HW_WATCHPOINT_DR6_TASK_SWITCH __BIT(15) 50 51/* 52 * CPU Debug Control Register (DR7) 53 * 54 * LOCAL_EXACT_BREAKPOINT and GLOBAL_EXACT_BREAKPOINT are no longer used since 55 * the P6 processor family - portable code should set these bits 56 * unconditionally in oder to get exact breakpoints 57 * 58 * Reserved bits: 10, 12, 14-15 and on x86_64 32-64 59 */ 60#define X86_HW_WATCHPOINT_DR7_LOCAL_DR0_BREAKPOINT __BIT(0) 61#define X86_HW_WATCHPOINT_DR7_GLOBAL_DR0_BREAKPOINT __BIT(1) 62#define X86_HW_WATCHPOINT_DR7_LOCAL_DR1_BREAKPOINT __BIT(2) 63#define X86_HW_WATCHPOINT_DR7_GLOBAL_DR1_BREAKPOINT __BIT(3) 64#define X86_HW_WATCHPOINT_DR7_LOCAL_DR2_BREAKPOINT __BIT(4) 65#define X86_HW_WATCHPOINT_DR7_GLOBAL_DR2_BREAKPOINT __BIT(5) 66#define X86_HW_WATCHPOINT_DR7_LOCAL_DR3_BREAKPOINT __BIT(6) 67#define X86_HW_WATCHPOINT_DR7_GLOBAL_DR3_BREAKPOINT __BIT(7) 68#define X86_HW_WATCHPOINT_DR7_LOCAL_EXACT_BREAKPOINT __BIT(8) 69#define X86_HW_WATCHPOINT_DR7_GLOBAL_EXACT_BREAKPOINT __BIT(9) 70#define X86_HW_WATCHPOINT_DR7_RESTRICTED_TRANSACTIONAL_MEMORY __BIT(11) 71#define X86_HW_WATCHPOINT_DR7_GENERAL_DETECT_ENABLE __BIT(13) 72 73#define X86_HW_WATCHPOINT_DR7_DR0_CONDITION_MASK __BITS(16, 17) 74#define X86_HW_WATCHPOINT_DR7_DR0_LENGTH_MASK __BITS(18, 19) 75#define X86_HW_WATCHPOINT_DR7_DR1_CONDITION_MASK __BITS(20, 21) 76#define X86_HW_WATCHPOINT_DR7_DR1_LENGTH_MASK __BITS(22, 23) 77#define X86_HW_WATCHPOINT_DR7_DR2_CONDITION_MASK __BITS(24, 25) 78#define X86_HW_WATCHPOINT_DR7_DR2_LENGTH_MASK __BITS(26, 27) 79#define X86_HW_WATCHPOINT_DR7_DR3_CONDITION_MASK __BITS(28, 29) 80#define X86_HW_WATCHPOINT_DR7_DR3_LENGTH_MASK __BITS(30, 31) 81 82#endif /* !defined(_KERNEL) */ 83 84/* 85 * X86_HW_WATCHPOINT_DR7_CONDITION_IO_READWRITE is currently unused 86 * it requires DE (debug extension) flag in control register CR4 set 87 * not all CPUs support it 88 */ 89enum x86_hw_watchpoint_condition { 90 X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION = 0x0, 91 X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE = 0x1, 92 X86_HW_WATCHPOINT_DR7_CONDITION_IO_READWRITE = 0x2, 93 X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE = 0x3 94}; 95 96/* 97 * 0x2 is currently unimplemented - it reflects 8 bytes on modern CPUs 98 */ 99enum x86_hw_watchpoint_length { 100 X86_HW_WATCHPOINT_DR7_LENGTH_BYTE = 0x0, 101 X86_HW_WATCHPOINT_DR7_LENGTH_TWOBYTES = 0x1, 102 /* 0x2 undefined */ 103 X86_HW_WATCHPOINT_DR7_LENGTH_FOURBYTES = 0x3 104}; 105 106/* 107 * 0x2 is currently unimplemented - it reflects 8 bytes on modern CPUs 108 */ 109enum x86_hw_watchpoint_event { 110 X86_HW_WATCHPOINT_EVENT_NONE = 0x0, 111 X86_HW_WATCHPOINT_EVENT_FIRED = 0x1, 112 X86_HW_WATCHPOINT_EVENT_FIRED_AND_SSTEP = 0x2, 113}; 114 115#if defined(_KMEMUSER) || defined(_KERNEL) 116 117/* 118 * The number of available watchpoint registers available since Intel 80386 119 * New CPUs ship with up to 16 Debug Registers but they still offer four 120 * watchpoints, while there other registers are reserved 121 */ 122#define X86_HW_WATCHPOINTS 4 123 124/* 125 * lwpid - 0 means all LWPs in the process 126 * address - 0 means that watchpoint is disabled 127 */ 128struct x86_hw_watchpoint { 129 vaddr_t address; 130 enum x86_hw_watchpoint_condition condition; 131 enum x86_hw_watchpoint_length length; 132}; 133 134#endif /* !defined(_KMEMUSER) && !defined(_KERNEL) */ 135 136#if defined(_KERNEL) 137/* 138 * Set CPU Debug Registers - to be used before entering user-land context 139 */ 140void set_x86_hw_watchpoints(struct lwp *l); 141 142/* 143 * Reset CPU Debug Registers - to be used after entering kernel context 144 */ 145void clear_x86_hw_watchpoints(void); 146 147/* 148 * Check if trap is triggered from user-land if so return nonzero value 149 */ 150int user_trap_x86_hw_watchpoint(void); 151 152/* 153 * Check if trap is triggered from user-land if so return nonzero value 154 */ 155int x86_hw_watchpoint_type(int); 156 157/* 158 * Return register that fired 159 */ 160int x86_hw_watchpoint_reg(int); 161 162#endif /* !defined(_KERNEL) */ 163 164#endif /* !_X86_DBREGS_H_ */ 165