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