123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- GDB intends to support the following hardware debug features of BookE
- processors:
- 4 hardware breakpoints (IAC)
- 2 hardware watchpoints (read, write and read-write) (DAC)
- 2 value conditions for the hardware watchpoints (DVC)
- For that, we need to extend ptrace so that GDB can query and set these
- resources. Since we're extending, we're trying to create an interface
- that's extendable and that covers both BookE and server processors, so
- that GDB doesn't need to special-case each of them. We added the
- following 3 new ptrace requests.
- 1. PTRACE_PPC_GETHWDEBUGINFO
- Query for GDB to discover the hardware debug features. The main info to
- be returned here is the minimum alignment for the hardware watchpoints.
- BookE processors don't have restrictions here, but server processors have
- an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid
- adding special cases to GDB based on what it sees in AUXV.
- Since we're at it, we added other useful info that the kernel can return to
- GDB: this query will return the number of hardware breakpoints, hardware
- watchpoints and whether it supports a range of addresses and a condition.
- The query will fill the following structure provided by the requesting process:
- struct ppc_debug_info {
- unit32_t version;
- unit32_t num_instruction_bps;
- unit32_t num_data_bps;
- unit32_t num_condition_regs;
- unit32_t data_bp_alignment;
- unit32_t sizeof_condition; /* size of the DVC register */
- uint64_t features; /* bitmask of the individual flags */
- };
- features will have bits indicating whether there is support for:
- #define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1
- #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2
- #define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4
- #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8
- #define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10
- 2. PTRACE_SETHWDEBUG
- Sets a hardware breakpoint or watchpoint, according to the provided structure:
- struct ppc_hw_breakpoint {
- uint32_t version;
- #define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1
- #define PPC_BREAKPOINT_TRIGGER_READ 0x2
- #define PPC_BREAKPOINT_TRIGGER_WRITE 0x4
- uint32_t trigger_type; /* only some combinations allowed */
- #define PPC_BREAKPOINT_MODE_EXACT 0x0
- #define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1
- #define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2
- #define PPC_BREAKPOINT_MODE_MASK 0x3
- uint32_t addr_mode; /* address match mode */
- #define PPC_BREAKPOINT_CONDITION_MODE 0x3
- #define PPC_BREAKPOINT_CONDITION_NONE 0x0
- #define PPC_BREAKPOINT_CONDITION_AND 0x1
- #define PPC_BREAKPOINT_CONDITION_EXACT 0x1 /* different name for the same thing as above */
- #define PPC_BREAKPOINT_CONDITION_OR 0x2
- #define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
- #define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000 /* byte enable bits */
- #define PPC_BREAKPOINT_CONDITION_BE(n) (1<<((n)+16))
- uint32_t condition_mode; /* break/watchpoint condition flags */
- uint64_t addr;
- uint64_t addr2;
- uint64_t condition_value;
- };
- A request specifies one event, not necessarily just one register to be set.
- For instance, if the request is for a watchpoint with a condition, both the
- DAC and DVC registers will be set in the same request.
- With this GDB can ask for all kinds of hardware breakpoints and watchpoints
- that the BookE supports. COMEFROM breakpoints available in server processors
- are not contemplated, but that is out of the scope of this work.
- ptrace will return an integer (handle) uniquely identifying the breakpoint or
- watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG
- request to ask for its removal. Return -ENOSPC if the requested breakpoint
- can't be allocated on the registers.
- Some examples of using the structure to:
- - set a breakpoint in the first breakpoint register
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) address;
- p.addr2 = 0;
- p.condition_value = 0;
- - set a watchpoint which triggers on reads in the second watchpoint register
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) address;
- p.addr2 = 0;
- p.condition_value = 0;
- - set a watchpoint which triggers only with a specific value
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
- p.addr = (uint64_t) address;
- p.addr2 = 0;
- p.condition_value = (uint64_t) condition;
- - set a ranged hardware breakpoint
- p.version = PPC_DEBUG_CURRENT_VERSION;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
- p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) begin_range;
- p.addr2 = (uint64_t) end_range;
- p.condition_value = 0;
- - set a watchpoint in server processors (BookS)
- p.version = 1;
- p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW;
- p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
- or
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- p.addr = (uint64_t) begin_range;
- /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
- * addr2 - addr <= 8 Bytes.
- */
- p.addr2 = (uint64_t) end_range;
- p.condition_value = 0;
- 3. PTRACE_DELHWDEBUG
- Takes an integer which identifies an existing breakpoint or watchpoint
- (i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
- corresponding breakpoint or watchpoint..
|