18c2ecf20Sopenharmony_ci====== 28c2ecf20Sopenharmony_ciPtrace 38c2ecf20Sopenharmony_ci====== 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciGDB intends to support the following hardware debug features of BookE 68c2ecf20Sopenharmony_ciprocessors: 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci4 hardware breakpoints (IAC) 98c2ecf20Sopenharmony_ci2 hardware watchpoints (read, write and read-write) (DAC) 108c2ecf20Sopenharmony_ci2 value conditions for the hardware watchpoints (DVC) 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ciFor that, we need to extend ptrace so that GDB can query and set these 138c2ecf20Sopenharmony_ciresources. Since we're extending, we're trying to create an interface 148c2ecf20Sopenharmony_cithat's extendable and that covers both BookE and server processors, so 158c2ecf20Sopenharmony_cithat GDB doesn't need to special-case each of them. We added the 168c2ecf20Sopenharmony_cifollowing 3 new ptrace requests. 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci1. PTRACE_PPC_GETHWDEBUGINFO 198c2ecf20Sopenharmony_ci============================ 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ciQuery for GDB to discover the hardware debug features. The main info to 228c2ecf20Sopenharmony_cibe returned here is the minimum alignment for the hardware watchpoints. 238c2ecf20Sopenharmony_ciBookE processors don't have restrictions here, but server processors have 248c2ecf20Sopenharmony_cian 8-byte alignment restriction for hardware watchpoints. We'd like to avoid 258c2ecf20Sopenharmony_ciadding special cases to GDB based on what it sees in AUXV. 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciSince we're at it, we added other useful info that the kernel can return to 288c2ecf20Sopenharmony_ciGDB: this query will return the number of hardware breakpoints, hardware 298c2ecf20Sopenharmony_ciwatchpoints and whether it supports a range of addresses and a condition. 308c2ecf20Sopenharmony_ciThe query will fill the following structure provided by the requesting process:: 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci struct ppc_debug_info { 338c2ecf20Sopenharmony_ci unit32_t version; 348c2ecf20Sopenharmony_ci unit32_t num_instruction_bps; 358c2ecf20Sopenharmony_ci unit32_t num_data_bps; 368c2ecf20Sopenharmony_ci unit32_t num_condition_regs; 378c2ecf20Sopenharmony_ci unit32_t data_bp_alignment; 388c2ecf20Sopenharmony_ci unit32_t sizeof_condition; /* size of the DVC register */ 398c2ecf20Sopenharmony_ci uint64_t features; /* bitmask of the individual flags */ 408c2ecf20Sopenharmony_ci }; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cifeatures will have bits indicating whether there is support for:: 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci #define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1 458c2ecf20Sopenharmony_ci #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2 468c2ecf20Sopenharmony_ci #define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4 478c2ecf20Sopenharmony_ci #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8 488c2ecf20Sopenharmony_ci #define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10 498c2ecf20Sopenharmony_ci #define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 0x20 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci2. PTRACE_SETHWDEBUG 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ciSets a hardware breakpoint or watchpoint, according to the provided structure:: 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci struct ppc_hw_breakpoint { 568c2ecf20Sopenharmony_ci uint32_t version; 578c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1 588c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_TRIGGER_READ 0x2 598c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_TRIGGER_WRITE 0x4 608c2ecf20Sopenharmony_ci uint32_t trigger_type; /* only some combinations allowed */ 618c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_MODE_EXACT 0x0 628c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1 638c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2 648c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_MODE_MASK 0x3 658c2ecf20Sopenharmony_ci uint32_t addr_mode; /* address match mode */ 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_MODE 0x3 688c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_NONE 0x0 698c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_AND 0x1 708c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_EXACT 0x1 /* different name for the same thing as above */ 718c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_OR 0x2 728c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_AND_OR 0x3 738c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000 /* byte enable bits */ 748c2ecf20Sopenharmony_ci #define PPC_BREAKPOINT_CONDITION_BE(n) (1<<((n)+16)) 758c2ecf20Sopenharmony_ci uint32_t condition_mode; /* break/watchpoint condition flags */ 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci uint64_t addr; 788c2ecf20Sopenharmony_ci uint64_t addr2; 798c2ecf20Sopenharmony_ci uint64_t condition_value; 808c2ecf20Sopenharmony_ci }; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ciA request specifies one event, not necessarily just one register to be set. 838c2ecf20Sopenharmony_ciFor instance, if the request is for a watchpoint with a condition, both the 848c2ecf20Sopenharmony_ciDAC and DVC registers will be set in the same request. 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciWith this GDB can ask for all kinds of hardware breakpoints and watchpoints 878c2ecf20Sopenharmony_cithat the BookE supports. COMEFROM breakpoints available in server processors 888c2ecf20Sopenharmony_ciare not contemplated, but that is out of the scope of this work. 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ciptrace will return an integer (handle) uniquely identifying the breakpoint or 918c2ecf20Sopenharmony_ciwatchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG 928c2ecf20Sopenharmony_cirequest to ask for its removal. Return -ENOSPC if the requested breakpoint 938c2ecf20Sopenharmony_cican't be allocated on the registers. 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ciSome examples of using the structure to: 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci- set a breakpoint in the first breakpoint register:: 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci p.version = PPC_DEBUG_CURRENT_VERSION; 1008c2ecf20Sopenharmony_ci p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE; 1018c2ecf20Sopenharmony_ci p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; 1028c2ecf20Sopenharmony_ci p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; 1038c2ecf20Sopenharmony_ci p.addr = (uint64_t) address; 1048c2ecf20Sopenharmony_ci p.addr2 = 0; 1058c2ecf20Sopenharmony_ci p.condition_value = 0; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci- set a watchpoint which triggers on reads in the second watchpoint register:: 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci p.version = PPC_DEBUG_CURRENT_VERSION; 1108c2ecf20Sopenharmony_ci p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ; 1118c2ecf20Sopenharmony_ci p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; 1128c2ecf20Sopenharmony_ci p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; 1138c2ecf20Sopenharmony_ci p.addr = (uint64_t) address; 1148c2ecf20Sopenharmony_ci p.addr2 = 0; 1158c2ecf20Sopenharmony_ci p.condition_value = 0; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci- set a watchpoint which triggers only with a specific value:: 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci p.version = PPC_DEBUG_CURRENT_VERSION; 1208c2ecf20Sopenharmony_ci p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ; 1218c2ecf20Sopenharmony_ci p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; 1228c2ecf20Sopenharmony_ci p.condition_mode = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL; 1238c2ecf20Sopenharmony_ci p.addr = (uint64_t) address; 1248c2ecf20Sopenharmony_ci p.addr2 = 0; 1258c2ecf20Sopenharmony_ci p.condition_value = (uint64_t) condition; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci- set a ranged hardware breakpoint:: 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci p.version = PPC_DEBUG_CURRENT_VERSION; 1308c2ecf20Sopenharmony_ci p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE; 1318c2ecf20Sopenharmony_ci p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; 1328c2ecf20Sopenharmony_ci p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; 1338c2ecf20Sopenharmony_ci p.addr = (uint64_t) begin_range; 1348c2ecf20Sopenharmony_ci p.addr2 = (uint64_t) end_range; 1358c2ecf20Sopenharmony_ci p.condition_value = 0; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci- set a watchpoint in server processors (BookS):: 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci p.version = 1; 1408c2ecf20Sopenharmony_ci p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW; 1418c2ecf20Sopenharmony_ci p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; 1428c2ecf20Sopenharmony_ci or 1438c2ecf20Sopenharmony_ci p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; 1468c2ecf20Sopenharmony_ci p.addr = (uint64_t) begin_range; 1478c2ecf20Sopenharmony_ci /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where 1488c2ecf20Sopenharmony_ci * addr2 - addr <= 8 Bytes. 1498c2ecf20Sopenharmony_ci */ 1508c2ecf20Sopenharmony_ci p.addr2 = (uint64_t) end_range; 1518c2ecf20Sopenharmony_ci p.condition_value = 0; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci3. PTRACE_DELHWDEBUG 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ciTakes an integer which identifies an existing breakpoint or watchpoint 1568c2ecf20Sopenharmony_ci(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the 1578c2ecf20Sopenharmony_cicorresponding breakpoint or watchpoint.. 158