| Dave Kleikamp | 3162d92 | 2010-02-08 11:51:05 +0000 | [diff] [blame] | 1 | GDB intends to support the following hardware debug features of BookE | 
 | 2 | processors: | 
 | 3 |  | 
 | 4 | 4 hardware breakpoints (IAC) | 
 | 5 | 2 hardware watchpoints (read, write and read-write) (DAC) | 
 | 6 | 2 value conditions for the hardware watchpoints (DVC) | 
 | 7 |  | 
 | 8 | For that, we need to extend ptrace so that GDB can query and set these | 
 | 9 | resources. Since we're extending, we're trying to create an interface | 
 | 10 | that's extendable and that covers both BookE and server processors, so | 
 | 11 | that GDB doesn't need to special-case each of them. We added the | 
 | 12 | following 3 new ptrace requests. | 
 | 13 |  | 
 | 14 | 1. PTRACE_PPC_GETHWDEBUGINFO | 
 | 15 |  | 
 | 16 | Query for GDB to discover the hardware debug features. The main info to | 
 | 17 | be returned here is the minimum alignment for the hardware watchpoints. | 
 | 18 | BookE processors don't have restrictions here, but server processors have | 
 | 19 | an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid | 
 | 20 | adding special cases to GDB based on what it sees in AUXV. | 
 | 21 |  | 
 | 22 | Since we're at it, we added other useful info that the kernel can return to | 
 | 23 | GDB: this query will return the number of hardware breakpoints, hardware | 
 | 24 | watchpoints and whether it supports a range of addresses and a condition. | 
 | 25 | The query will fill the following structure provided by the requesting process: | 
 | 26 |  | 
 | 27 | struct ppc_debug_info { | 
 | 28 |        unit32_t version; | 
 | 29 |        unit32_t num_instruction_bps; | 
 | 30 |        unit32_t num_data_bps; | 
 | 31 |        unit32_t num_condition_regs; | 
 | 32 |        unit32_t data_bp_alignment; | 
 | 33 |        unit32_t sizeof_condition; /* size of the DVC register */ | 
 | 34 |        uint64_t features; /* bitmask of the individual flags */ | 
 | 35 | }; | 
 | 36 |  | 
 | 37 | features will have bits indicating whether there is support for: | 
 | 38 |  | 
 | 39 | #define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x1 | 
 | 40 | #define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x2 | 
 | 41 | #define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x4 | 
 | 42 | #define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x8 | 
 | 43 |  | 
 | 44 | 2. PTRACE_SETHWDEBUG | 
 | 45 |  | 
 | 46 | Sets a hardware breakpoint or watchpoint, according to the provided structure: | 
 | 47 |  | 
 | 48 | struct ppc_hw_breakpoint { | 
 | 49 |         uint32_t version; | 
 | 50 | #define PPC_BREAKPOINT_TRIGGER_EXECUTE  0x1 | 
 | 51 | #define PPC_BREAKPOINT_TRIGGER_READ     0x2 | 
 | 52 | #define PPC_BREAKPOINT_TRIGGER_WRITE    0x4 | 
 | 53 |         uint32_t trigger_type;       /* only some combinations allowed */ | 
 | 54 | #define PPC_BREAKPOINT_MODE_EXACT               0x0 | 
 | 55 | #define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE     0x1 | 
 | 56 | #define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE     0x2 | 
 | 57 | #define PPC_BREAKPOINT_MODE_MASK                0x3 | 
 | 58 |         uint32_t addr_mode;          /* address match mode */ | 
 | 59 |  | 
 | 60 | #define PPC_BREAKPOINT_CONDITION_MODE   0x3 | 
 | 61 | #define PPC_BREAKPOINT_CONDITION_NONE   0x0 | 
 | 62 | #define PPC_BREAKPOINT_CONDITION_AND    0x1 | 
 | 63 | #define PPC_BREAKPOINT_CONDITION_EXACT  0x1	/* different name for the same thing as above */ | 
 | 64 | #define PPC_BREAKPOINT_CONDITION_OR     0x2 | 
 | 65 | #define PPC_BREAKPOINT_CONDITION_AND_OR 0x3 | 
 | 66 | #define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000	/* byte enable bits */ | 
 | 67 | #define PPC_BREAKPOINT_CONDITION_BE(n)  (1<<((n)+16)) | 
 | 68 |         uint32_t condition_mode;     /* break/watchpoint condition flags */ | 
 | 69 |  | 
 | 70 |         uint64_t addr; | 
 | 71 |         uint64_t addr2; | 
 | 72 |         uint64_t condition_value; | 
 | 73 | }; | 
 | 74 |  | 
 | 75 | A request specifies one event, not necessarily just one register to be set. | 
 | 76 | For instance, if the request is for a watchpoint with a condition, both the | 
 | 77 | DAC and DVC registers will be set in the same request. | 
 | 78 |  | 
 | 79 | With this GDB can ask for all kinds of hardware breakpoints and watchpoints | 
 | 80 | that the BookE supports. COMEFROM breakpoints available in server processors | 
 | 81 | are not contemplated, but that is out of the scope of this work. | 
 | 82 |  | 
 | 83 | ptrace will return an integer (handle) uniquely identifying the breakpoint or | 
 | 84 | watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG | 
 | 85 | request to ask for its removal. Return -ENOSPC if the requested breakpoint | 
 | 86 | can't be allocated on the registers. | 
 | 87 |  | 
 | 88 | Some examples of using the structure to: | 
 | 89 |  | 
 | 90 | - set a breakpoint in the first breakpoint register | 
 | 91 |  | 
 | 92 |   p.version         = PPC_DEBUG_CURRENT_VERSION; | 
 | 93 |   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE; | 
 | 94 |   p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT; | 
 | 95 |   p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE; | 
 | 96 |   p.addr            = (uint64_t) address; | 
 | 97 |   p.addr2           = 0; | 
 | 98 |   p.condition_value = 0; | 
 | 99 |  | 
 | 100 | - set a watchpoint which triggers on reads in the second watchpoint register | 
 | 101 |  | 
 | 102 |   p.version         = PPC_DEBUG_CURRENT_VERSION; | 
 | 103 |   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ; | 
 | 104 |   p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT; | 
 | 105 |   p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE; | 
 | 106 |   p.addr            = (uint64_t) address; | 
 | 107 |   p.addr2           = 0; | 
 | 108 |   p.condition_value = 0; | 
 | 109 |  | 
 | 110 | - set a watchpoint which triggers only with a specific value | 
 | 111 |  | 
 | 112 |   p.version         = PPC_DEBUG_CURRENT_VERSION; | 
 | 113 |   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ; | 
 | 114 |   p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT; | 
 | 115 |   p.condition_mode  = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL; | 
 | 116 |   p.addr            = (uint64_t) address; | 
 | 117 |   p.addr2           = 0; | 
 | 118 |   p.condition_value = (uint64_t) condition; | 
 | 119 |  | 
 | 120 | - set a ranged hardware breakpoint | 
 | 121 |  | 
 | 122 |   p.version         = PPC_DEBUG_CURRENT_VERSION; | 
 | 123 |   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE; | 
 | 124 |   p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; | 
 | 125 |   p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE; | 
 | 126 |   p.addr            = (uint64_t) begin_range; | 
 | 127 |   p.addr2           = (uint64_t) end_range; | 
 | 128 |   p.condition_value = 0; | 
 | 129 |  | 
 | 130 | 3. PTRACE_DELHWDEBUG | 
 | 131 |  | 
 | 132 | Takes an integer which identifies an existing breakpoint or watchpoint | 
 | 133 | (i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the | 
 | 134 | corresponding breakpoint or watchpoint.. |