1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright(c) 2013 Intel Corporation.
6 * Adrian Burns (adrian.burns@intel.com)
7 * Thomas Faust (thomas.faust@intel.com)
8 * Ivan De Cesaris (ivan.de.cesaris@intel.com)
9 * Julien Carreno (julien.carreno@intel.com)
10 * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)
12 * Contact Information:
18 * This implements generic x86 32 bit memory and breakpoint operations.
25 #include <helper/log.h>
28 #include "target_type.h"
30 #include "breakpoints.h"
31 #include "x86_32_common.h"
33 static int set_debug_regs(struct target
*t
, uint32_t address
,
34 uint8_t bp_num
, uint8_t bp_type
, uint8_t bp_length
);
35 static int unset_debug_regs(struct target
*t
, uint8_t bp_num
);
36 static int read_mem(struct target
*t
, uint32_t size
,
37 uint32_t addr
, uint8_t *buf
);
38 static int write_mem(struct target
*t
, uint32_t size
,
39 uint32_t addr
, const uint8_t *buf
);
40 static int calcaddr_physfromlin(struct target
*t
, target_addr_t addr
,
41 target_addr_t
*physaddr
);
42 static int read_phys_mem(struct target
*t
, uint32_t phys_address
,
43 uint32_t size
, uint32_t count
, uint8_t *buffer
);
44 static int write_phys_mem(struct target
*t
, uint32_t phys_address
,
45 uint32_t size
, uint32_t count
, const uint8_t *buffer
);
46 static int set_breakpoint(struct target
*target
,
47 struct breakpoint
*breakpoint
);
48 static int unset_breakpoint(struct target
*target
,
49 struct breakpoint
*breakpoint
);
50 static int set_watchpoint(struct target
*target
,
51 struct watchpoint
*watchpoint
);
52 static int unset_watchpoint(struct target
*target
,
53 struct watchpoint
*watchpoint
);
54 static int read_hw_reg_to_cache(struct target
*t
, int num
);
55 static int write_hw_reg_from_cache(struct target
*t
, int num
);
57 int x86_32_get_gdb_reg_list(struct target
*t
,
58 struct reg
**reg_list
[], int *reg_list_size
,
59 enum target_register_class reg_class
)
62 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
64 *reg_list_size
= x86_32
->cache
->num_regs
;
65 LOG_DEBUG("num_regs=%d, reg_class=%d", (*reg_list_size
), reg_class
);
66 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
68 LOG_ERROR("%s out of memory", __func__
);
71 /* this will copy the values from our reg list to gdbs */
72 for (i
= 0; i
< (*reg_list_size
); i
++) {
73 (*reg_list
)[i
] = &x86_32
->cache
->reg_list
[i
];
74 LOG_DEBUG("value %s = %08" PRIx32
, x86_32
->cache
->reg_list
[i
].name
,
75 buf_get_u32(x86_32
->cache
->reg_list
[i
].value
, 0, 32));
80 int x86_32_common_init_arch_info(struct target
*t
, struct x86_32_common
*x86_32
)
82 t
->arch_info
= x86_32
;
83 x86_32
->common_magic
= X86_32_COMMON_MAGIC
;
84 x86_32
->num_hw_bpoints
= MAX_DEBUG_REGS
;
85 x86_32
->hw_break_list
= calloc(x86_32
->num_hw_bpoints
,
86 sizeof(struct x86_32_dbg_reg
));
87 if (!x86_32
->hw_break_list
) {
88 LOG_ERROR("%s out of memory", __func__
);
91 x86_32
->curr_tap
= t
->tap
;
92 x86_32
->fast_data_area
= NULL
;
94 x86_32
->read_hw_reg_to_cache
= read_hw_reg_to_cache
;
95 x86_32
->write_hw_reg_from_cache
= write_hw_reg_from_cache
;
99 int x86_32_common_mmu(struct target
*t
, int *enabled
)
105 int x86_32_common_virt2phys(struct target
*t
, target_addr_t address
, target_addr_t
*physical
)
107 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
110 * We need to ignore 'segmentation' for now, as OpenOCD can't handle
111 * segmented addresses.
112 * In protected mode that is almost OK, as (almost) any known OS is using
113 * flat segmentation. In real mode we use use the base of the DS segment,
114 * as we don't know better ...
117 uint32_t cr0
= buf_get_u32(x86_32
->cache
->reg_list
[CR0
].value
, 0, 32);
118 if (!(cr0
& CR0_PG
)) {
119 /* target halted in real mode */
120 /* TODO: needs validation !!! */
121 uint32_t dsb
= buf_get_u32(x86_32
->cache
->reg_list
[DSB
].value
, 0, 32);
122 *physical
= dsb
+ address
;
125 /* target halted in protected mode */
126 if (calcaddr_physfromlin(t
, address
, physical
) != ERROR_OK
) {
127 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
135 int x86_32_common_read_phys_mem(struct target
*t
, target_addr_t phys_address
,
136 uint32_t size
, uint32_t count
, uint8_t *buffer
)
138 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
141 error
= read_phys_mem(t
, phys_address
, size
, count
, buffer
);
142 if (error
!= ERROR_OK
)
145 /* After reading memory from target, we must replace software breakpoints
146 * with the original instructions again.
148 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
150 if (iter
->physaddr
>= phys_address
&& iter
->physaddr
< phys_address
+(size
*count
)) {
151 uint32_t offset
= iter
->physaddr
- phys_address
;
152 buffer
[offset
] = iter
->orig_byte
;
159 static int read_phys_mem(struct target
*t
, uint32_t phys_address
,
160 uint32_t size
, uint32_t count
, uint8_t *buffer
)
162 int retval
= ERROR_OK
;
163 bool pg_disabled
= false;
164 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
165 phys_address
, size
, count
, buffer
);
166 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
168 if (check_not_halted(t
))
169 return ERROR_TARGET_NOT_HALTED
;
170 if (!count
|| !buffer
|| !phys_address
) {
171 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32
,
172 __func__
, count
, buffer
, phys_address
);
173 return ERROR_COMMAND_ARGUMENT_INVALID
;
176 /* to access physical memory, switch off the CR0.PG bit */
177 if (x86_32
->is_paging_enabled(t
)) {
178 retval
= x86_32
->disable_paging(t
);
179 if (retval
!= ERROR_OK
) {
180 LOG_ERROR("%s could not disable paging", __func__
);
186 for (uint32_t i
= 0; i
< count
; i
++) {
189 retval
= read_mem(t
, size
, phys_address
+ i
, buffer
+ i
);
192 retval
= read_mem(t
, size
, phys_address
+ i
* 2, buffer
+ i
* 2);
195 retval
= read_mem(t
, size
, phys_address
+ i
* 4, buffer
+ i
* 4);
198 LOG_ERROR("%s invalid read size", __func__
);
201 if (retval
!= ERROR_OK
)
204 /* restore CR0.PG bit if needed (regardless of retval) */
206 int retval2
= x86_32
->enable_paging(t
);
207 if (retval2
!= ERROR_OK
) {
208 LOG_ERROR("%s could not enable paging", __func__
);
212 /* TODO: After reading memory from target, we must replace
213 * software breakpoints with the original instructions again.
214 * Solve this with the breakpoint fix
219 int x86_32_common_write_phys_mem(struct target
*t
, target_addr_t phys_address
,
220 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
222 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
223 int error
= ERROR_OK
;
224 uint8_t *newbuffer
= NULL
;
227 if (!count
|| !buffer
|| !phys_address
) {
228 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
229 __func__
, count
, buffer
, phys_address
);
230 return ERROR_COMMAND_ARGUMENT_INVALID
;
232 /* Before writing memory to target, we must update software breakpoints
233 * with the new instructions and patch the memory buffer with the
234 * breakpoint instruction.
236 newbuffer
= malloc(size
*count
);
238 LOG_ERROR("%s out of memory", __func__
);
241 memcpy(newbuffer
, buffer
, size
*count
);
242 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
244 if (iter
->physaddr
>= phys_address
&& iter
->physaddr
< phys_address
+(size
*count
)) {
245 uint32_t offset
= iter
->physaddr
- phys_address
;
246 newbuffer
[offset
] = SW_BP_OPCODE
;
248 /* update the breakpoint */
249 struct breakpoint
*pbiter
= t
->breakpoints
;
250 while (pbiter
&& pbiter
->unique_id
!= iter
->swbp_unique_id
)
251 pbiter
= pbiter
->next
;
253 pbiter
->orig_instr
[0] = buffer
[offset
];
258 error
= write_phys_mem(t
, phys_address
, size
, count
, newbuffer
);
263 static int write_phys_mem(struct target
*t
, uint32_t phys_address
,
264 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
266 int retval
= ERROR_OK
;
267 bool pg_disabled
= false;
268 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
269 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
270 phys_address
, size
, count
, buffer
);
273 if (!count
|| !buffer
|| !phys_address
) {
274 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32
,
275 __func__
, count
, buffer
, phys_address
);
276 return ERROR_COMMAND_ARGUMENT_INVALID
;
278 /* TODO: Before writing memory to target, we must update
279 * software breakpoints with the new instructions and
280 * patch the memory buffer with the breakpoint instruction.
281 * Solve this with the breakpoint fix
284 /* to access physical memory, switch off the CR0.PG bit */
285 if (x86_32
->is_paging_enabled(t
)) {
286 retval
= x86_32
->disable_paging(t
);
287 if (retval
!= ERROR_OK
) {
288 LOG_ERROR("%s could not disable paging", __func__
);
293 for (uint32_t i
= 0; i
< count
; i
++) {
296 retval
= write_mem(t
, size
, phys_address
+ i
, buffer
+ i
);
299 retval
= write_mem(t
, size
, phys_address
+ i
* 2, buffer
+ i
* 2);
302 retval
= write_mem(t
, size
, phys_address
+ i
* 4, buffer
+ i
* 4);
305 LOG_DEBUG("invalid read size");
309 /* restore CR0.PG bit if needed (regardless of retval) */
311 retval
= x86_32
->enable_paging(t
);
312 if (retval
!= ERROR_OK
) {
313 LOG_ERROR("%s could not enable paging", __func__
);
320 static int read_mem(struct target
*t
, uint32_t size
,
321 uint32_t addr
, uint8_t *buf
)
323 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
325 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
326 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
327 int retval
= x86_32
->write_hw_reg(t
, EAX
, addr
, 0);
328 if (retval
!= ERROR_OK
) {
329 LOG_ERROR("%s error write EAX", __func__
);
336 retval
= x86_32
->submit_instruction(t
, MEMRDB32
);
338 retval
= x86_32
->submit_instruction(t
, MEMRDB16
);
342 retval
= x86_32
->submit_instruction(t
, MEMRDH32
);
344 retval
= x86_32
->submit_instruction(t
, MEMRDH16
);
348 retval
= x86_32
->submit_instruction(t
, MEMRDW32
);
350 retval
= x86_32
->submit_instruction(t
, MEMRDW16
);
353 LOG_ERROR("%s invalid read mem size", __func__
);
357 if (retval
!= ERROR_OK
)
360 /* read_hw_reg() will write to 4 bytes (uint32_t)
361 * Watch out, the buffer passed into read_mem() might be 1 or 2 bytes.
364 retval
= x86_32
->read_hw_reg(t
, EDX
, ®val
, 0);
366 if (retval
!= ERROR_OK
) {
367 LOG_ERROR("%s error read EDX", __func__
);
370 for (uint8_t i
= 0; i
< size
; i
++)
371 buf
[i
] = (regval
>> (i
*8)) & 0x000000FF;
373 retval
= x86_32
->transaction_status(t
);
374 if (retval
!= ERROR_OK
) {
375 LOG_ERROR("%s error on mem read", __func__
);
381 static int write_mem(struct target
*t
, uint32_t size
,
382 uint32_t addr
, const uint8_t *buf
)
385 uint32_t buf4bytes
= 0;
386 int retval
= ERROR_OK
;
387 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
389 for (i
= 0; i
< size
; ++i
) {
390 buf4bytes
= buf4bytes
<< 8; /* first time we only shift 0s */
391 buf4bytes
+= buf
[(size
-1)-i
]; /* it was hard to write, should be hard to read! */
393 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
394 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
395 retval
= x86_32
->write_hw_reg(t
, EAX
, addr
, 0);
396 if (retval
!= ERROR_OK
) {
397 LOG_ERROR("%s error write EAX", __func__
);
401 /* write_hw_reg() will write to 4 bytes (uint32_t)
402 * Watch out, the buffer passed into write_mem() might be 1 or 2 bytes.
404 retval
= x86_32
->write_hw_reg(t
, EDX
, buf4bytes
, 0);
405 if (retval
!= ERROR_OK
) {
406 LOG_ERROR("%s error write EDX", __func__
);
412 retval
= x86_32
->submit_instruction(t
, MEMWRB32
);
414 retval
= x86_32
->submit_instruction(t
, MEMWRB16
);
418 retval
= x86_32
->submit_instruction(t
, MEMWRH32
);
420 retval
= x86_32
->submit_instruction(t
, MEMWRH16
);
424 retval
= x86_32
->submit_instruction(t
, MEMWRW32
);
426 retval
= x86_32
->submit_instruction(t
, MEMWRW16
);
429 LOG_ERROR("%s invalid write mem size", __func__
);
433 if (retval
!= ERROR_OK
)
436 retval
= x86_32
->transaction_status(t
);
437 if (retval
!= ERROR_OK
) {
438 LOG_ERROR("%s error on mem write", __func__
);
444 int calcaddr_physfromlin(struct target
*t
, target_addr_t addr
, target_addr_t
*physaddr
)
446 uint8_t entry_buffer
[8];
451 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
453 /* The 'user-visible' CR0.PG should be set - otherwise the function shouldn't be called
454 * (Don't check the CR0.PG on the target, this might be temporally disabled at this point)
456 uint32_t cr0
= buf_get_u32(x86_32
->cache
->reg_list
[CR0
].value
, 0, 32);
457 if (!(cr0
& CR0_PG
)) {
458 /* you are wrong in this function, never mind */
463 uint32_t cr4
= buf_get_u32(x86_32
->cache
->reg_list
[CR4
].value
, 0, 32);
464 bool is_pae
= cr4
& 0x00000020; /* PAE - Physical Address Extension */
466 uint32_t cr3
= buf_get_u32(x86_32
->cache
->reg_list
[CR3
].value
, 0, 32);
468 uint32_t pdpt_base
= cr3
& 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */
469 uint32_t pdpt_index
= (addr
& 0xC0000000) >> 30; /* A[31:30] index to PDPT */
470 uint32_t pdpt_addr
= pdpt_base
+ (8 * pdpt_index
);
471 if (x86_32_common_read_phys_mem(t
, pdpt_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
472 LOG_ERROR("%s couldn't read page directory pointer table entry at 0x%08" PRIx32
,
473 __func__
, pdpt_addr
);
476 uint64_t pdpt_entry
= target_buffer_get_u64(t
, entry_buffer
);
477 if (!(pdpt_entry
& 0x0000000000000001)) {
478 LOG_ERROR("%s page directory pointer table entry at 0x%08" PRIx32
" is not present",
479 __func__
, pdpt_addr
);
483 uint32_t pd_base
= pdpt_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
484 uint32_t pd_index
= (addr
& 0x3FE00000) >> 21; /* A[29:21] index to PD entry with PAE */
485 uint32_t pd_addr
= pd_base
+ (8 * pd_index
);
486 if (x86_32_common_read_phys_mem(t
, pd_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
487 LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32
,
491 uint64_t pd_entry
= target_buffer_get_u64(t
, entry_buffer
);
492 if (!(pd_entry
& 0x0000000000000001)) {
493 LOG_ERROR("%s page directory entry at 0x%08" PRIx32
" is not present",
498 /* PS bit in PD entry is indicating 4KB or 2MB page size */
499 if (pd_entry
& 0x0000000000000080) {
501 uint32_t page_base
= (uint32_t)(pd_entry
& 0x00000000FFE00000); /* [31:21] */
502 uint32_t offset
= addr
& 0x001FFFFF; /* [20:0] */
503 *physaddr
= page_base
+ offset
;
508 uint32_t pt_base
= (uint32_t)(pd_entry
& 0x00000000FFFFF000); /*[31:12]*/
509 uint32_t pt_index
= (addr
& 0x001FF000) >> 12; /*[20:12]*/
510 uint32_t pt_addr
= pt_base
+ (8 * pt_index
);
511 if (x86_32_common_read_phys_mem(t
, pt_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
512 LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32
, __func__
, pt_addr
);
515 uint64_t pt_entry
= target_buffer_get_u64(t
, entry_buffer
);
516 if (!(pt_entry
& 0x0000000000000001)) {
517 LOG_ERROR("%s page table entry at 0x%08" PRIx32
" is not present", __func__
, pt_addr
);
521 uint32_t page_base
= (uint32_t)(pt_entry
& 0x00000000FFFFF000); /*[31:12]*/
522 uint32_t offset
= addr
& 0x00000FFF; /*[11:0]*/
523 *physaddr
= page_base
+ offset
;
527 uint32_t pd_base
= cr3
& 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */
528 uint32_t pd_index
= (addr
& 0xFFC00000) >> 22; /* A[31:22] index to PD entry */
529 uint32_t pd_addr
= pd_base
+ (4 * pd_index
);
530 if (x86_32_common_read_phys_mem(t
, pd_addr
, 4, 1, entry_buffer
) != ERROR_OK
) {
531 LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32
, __func__
, pd_addr
);
534 uint32_t pd_entry
= target_buffer_get_u32(t
, entry_buffer
);
535 if (!(pd_entry
& 0x00000001)) {
536 LOG_ERROR("%s page directory entry at 0x%08" PRIx32
" is not present", __func__
, pd_addr
);
540 /* Bit 7 in page directory entry is page size.
542 if (pd_entry
& 0x00000080) {
544 uint32_t page_base
= pd_entry
& 0xFFC00000;
545 *physaddr
= page_base
+ (addr
& 0x003FFFFF);
549 uint32_t pt_base
= pd_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
550 uint32_t pt_index
= (addr
& 0x003FF000) >> 12; /* A[21:12] index to page table entry */
551 uint32_t pt_addr
= pt_base
+ (4 * pt_index
);
552 if (x86_32_common_read_phys_mem(t
, pt_addr
, 4, 1, entry_buffer
) != ERROR_OK
) {
553 LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32
, __func__
, pt_addr
);
556 uint32_t pt_entry
= target_buffer_get_u32(t
, entry_buffer
);
557 if (!(pt_entry
& 0x00000001)) {
558 LOG_ERROR("%s page table entry at 0x%08" PRIx32
" is not present", __func__
, pt_addr
);
561 uint32_t page_base
= pt_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
562 *physaddr
= page_base
+ (addr
& 0x00000FFF); /* A[11:0] offset to 4KB page in linear address */
568 int x86_32_common_read_memory(struct target
*t
, target_addr_t addr
,
569 uint32_t size
, uint32_t count
, uint8_t *buf
)
571 int retval
= ERROR_OK
;
572 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
573 LOG_DEBUG("addr=" TARGET_ADDR_FMT
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
574 addr
, size
, count
, buf
);
576 if (!count
|| !buf
|| !addr
) {
577 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
578 __func__
, count
, buf
, addr
);
579 return ERROR_COMMAND_ARGUMENT_INVALID
;
582 if (x86_32
->is_paging_enabled(t
)) {
583 /* all memory accesses from debugger must be physical (CR0.PG == 0)
584 * conversion to physical address space needed
586 retval
= x86_32
->disable_paging(t
);
587 if (retval
!= ERROR_OK
) {
588 LOG_ERROR("%s could not disable paging", __func__
);
591 target_addr_t physaddr
= 0;
592 if (calcaddr_physfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
593 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
597 /* TODO: !!! Watch out for page boundaries
598 * for every 4kB, the physical address has to be re-calculated
599 * This should be fixed together with bulk memory reads
602 if (retval
== ERROR_OK
603 && x86_32_common_read_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
604 LOG_ERROR("%s failed to read memory from physical address " TARGET_ADDR_FMT
,
607 /* restore PG bit if it was cleared prior (regardless of retval) */
608 retval
= x86_32
->enable_paging(t
);
609 if (retval
!= ERROR_OK
) {
610 LOG_ERROR("%s could not enable paging", __func__
);
614 /* paging is off - linear address is physical address */
615 if (x86_32_common_read_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
616 LOG_ERROR("%s failed to read memory from address " TARGET_ADDR_FMT
,
625 int x86_32_common_write_memory(struct target
*t
, target_addr_t addr
,
626 uint32_t size
, uint32_t count
, const uint8_t *buf
)
628 int retval
= ERROR_OK
;
629 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
630 LOG_DEBUG("addr=" TARGET_ADDR_FMT
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
631 addr
, size
, count
, buf
);
633 if (!count
|| !buf
|| !addr
) {
634 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
635 __func__
, count
, buf
, addr
);
636 return ERROR_COMMAND_ARGUMENT_INVALID
;
638 if (x86_32
->is_paging_enabled(t
)) {
639 /* all memory accesses from debugger must be physical (CR0.PG == 0)
640 * conversion to physical address space needed
642 retval
= x86_32
->disable_paging(t
);
643 if (retval
!= ERROR_OK
) {
644 LOG_ERROR("%s could not disable paging", __func__
);
647 target_addr_t physaddr
= 0;
648 if (calcaddr_physfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
649 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
653 /* TODO: !!! Watch out for page boundaries
654 * for every 4kB, the physical address has to be re-calculated
655 * This should be fixed together with bulk memory reads
657 if (retval
== ERROR_OK
658 && x86_32_common_write_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
659 LOG_ERROR("%s failed to write memory to physical address " TARGET_ADDR_FMT
,
662 /* restore PG bit if it was cleared prior (regardless of retval) */
663 retval
= x86_32
->enable_paging(t
);
664 if (retval
!= ERROR_OK
) {
665 LOG_ERROR("%s could not enable paging", __func__
);
670 /* paging is off - linear address is physical address */
671 if (x86_32_common_write_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
672 LOG_ERROR("%s failed to write memory to address " TARGET_ADDR_FMT
,
680 int x86_32_common_read_io(struct target
*t
, uint32_t addr
,
681 uint32_t size
, uint8_t *buf
)
683 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
684 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
685 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
686 int retval
= ERROR_FAIL
;
687 bool pg_disabled
= false;
688 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
691 LOG_ERROR("%s invalid params buf=%p, addr=%08" PRIx32
, __func__
, buf
, addr
);
694 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
695 if (retval
!= ERROR_OK
) {
696 LOG_ERROR("%s error EDX write", __func__
);
699 /* to access physical memory, switch off the CR0.PG bit */
700 if (x86_32
->is_paging_enabled(t
)) {
701 retval
= x86_32
->disable_paging(t
);
702 if (retval
!= ERROR_OK
) {
703 LOG_ERROR("%s could not disable paging", __func__
);
711 retval
= x86_32
->submit_instruction(t
, IORDB32
);
713 retval
= x86_32
->submit_instruction(t
, IORDB16
);
717 retval
= x86_32
->submit_instruction(t
, IORDH32
);
719 retval
= x86_32
->submit_instruction(t
, IORDH16
);
723 retval
= x86_32
->submit_instruction(t
, IORDW32
);
725 retval
= x86_32
->submit_instruction(t
, IORDW16
);
728 LOG_ERROR("%s invalid read io size", __func__
);
732 /* restore CR0.PG bit if needed */
734 int retval2
= x86_32
->enable_paging(t
);
735 if (retval2
!= ERROR_OK
) {
736 LOG_ERROR("%s could not enable paging", __func__
);
741 if (retval
!= ERROR_OK
)
745 retval
= x86_32
->read_hw_reg(t
, EAX
, ®val
, 0);
746 if (retval
!= ERROR_OK
) {
747 LOG_ERROR("%s error on read EAX", __func__
);
750 for (uint8_t i
= 0; i
< size
; i
++)
751 buf
[i
] = (regval
>> (i
*8)) & 0x000000FF;
752 retval
= x86_32
->transaction_status(t
);
753 if (retval
!= ERROR_OK
) {
754 LOG_ERROR("%s error on io read", __func__
);
760 int x86_32_common_write_io(struct target
*t
, uint32_t addr
,
761 uint32_t size
, const uint8_t *buf
)
763 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
764 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
765 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
766 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
768 int retval
= ERROR_FAIL
;
769 bool pg_disabled
= false;
771 LOG_ERROR("%s invalid params buf=%p, addr=0x%08" PRIx32
, __func__
, buf
, addr
);
774 /* no do the write */
775 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
776 if (retval
!= ERROR_OK
) {
777 LOG_ERROR("%s error on EDX write", __func__
);
781 for (uint8_t i
= 0; i
< size
; i
++)
782 regval
+= (buf
[i
] << (i
*8));
783 retval
= x86_32
->write_hw_reg(t
, EAX
, regval
, 0);
784 if (retval
!= ERROR_OK
) {
785 LOG_ERROR("%s error on EAX write", __func__
);
788 /* to access physical memory, switch off the CR0.PG bit */
789 if (x86_32
->is_paging_enabled(t
)) {
790 retval
= x86_32
->disable_paging(t
);
791 if (retval
!= ERROR_OK
) {
792 LOG_ERROR("%s could not disable paging", __func__
);
800 retval
= x86_32
->submit_instruction(t
, IOWRB32
);
802 retval
= x86_32
->submit_instruction(t
, IOWRB16
);
806 retval
= x86_32
->submit_instruction(t
, IOWRH32
);
808 retval
= x86_32
->submit_instruction(t
, IOWRH16
);
812 retval
= x86_32
->submit_instruction(t
, IOWRW32
);
814 retval
= x86_32
->submit_instruction(t
, IOWRW16
);
817 LOG_ERROR("%s invalid write io size", __func__
);
821 /* restore CR0.PG bit if needed */
823 int retval2
= x86_32
->enable_paging(t
);
824 if (retval2
!= ERROR_OK
) {
825 LOG_ERROR("%s could not enable paging", __func__
);
830 if (retval
!= ERROR_OK
)
833 retval
= x86_32
->transaction_status(t
);
834 if (retval
!= ERROR_OK
) {
835 LOG_ERROR("%s error on io write", __func__
);
841 int x86_32_common_add_watchpoint(struct target
*t
, struct watchpoint
*wp
)
844 /* set_watchpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
845 * hardware registers are gone
847 return set_watchpoint(t
, wp
);
850 int x86_32_common_remove_watchpoint(struct target
*t
, struct watchpoint
*wp
)
852 if (check_not_halted(t
))
853 return ERROR_TARGET_NOT_HALTED
;
855 unset_watchpoint(t
, wp
);
859 int x86_32_common_add_breakpoint(struct target
*t
, struct breakpoint
*bp
)
861 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
862 if (check_not_halted(t
))
863 return ERROR_TARGET_NOT_HALTED
;
864 /* set_breakpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
865 * hardware registers are gone (for hardware breakpoints)
867 return set_breakpoint(t
, bp
);
870 int x86_32_common_remove_breakpoint(struct target
*t
, struct breakpoint
*bp
)
872 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
873 if (check_not_halted(t
))
874 return ERROR_TARGET_NOT_HALTED
;
876 unset_breakpoint(t
, bp
);
881 static int set_debug_regs(struct target
*t
, uint32_t address
,
882 uint8_t bp_num
, uint8_t bp_type
, uint8_t bp_length
)
884 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
885 LOG_DEBUG("addr=0x%08" PRIx32
", bp_num=%" PRIu8
", bp_type=%" PRIu8
", pb_length=%" PRIu8
,
886 address
, bp_num
, bp_type
, bp_length
);
888 /* DR7 - set global enable */
889 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
891 if (bp_length
!= 1 && bp_length
!= 2 && bp_length
!= 4)
894 if (DR7_BP_FREE(dr7
, bp_num
))
895 DR7_GLOBAL_ENABLE(dr7
, bp_num
);
897 LOG_ERROR("%s dr7 error, already enabled, val=%08" PRIx32
, __func__
, dr7
);
898 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
903 /* 00 - only on instruction execution */
904 DR7_SET_EXE(dr7
, bp_num
);
905 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
908 /* 01 - only on data writes */
909 DR7_SET_WRITE(dr7
, bp_num
);
910 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
913 /* 10 UNSUPPORTED - an I/O read and I/O write */
914 LOG_ERROR("%s unsupported feature bp_type=%d", __func__
, bp_type
);
918 /* on data read or data write */
919 DR7_SET_ACCESS(dr7
, bp_num
);
920 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
923 LOG_ERROR("%s invalid request [only 0-3] bp_type=%d", __func__
, bp_type
);
927 /* update regs in the reg cache ready to be written to hardware
930 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, address
);
931 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= true;
932 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= true;
933 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
934 x86_32
->cache
->reg_list
[DR6
].dirty
= true;
935 x86_32
->cache
->reg_list
[DR6
].valid
= true;
936 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
937 x86_32
->cache
->reg_list
[DR7
].dirty
= true;
938 x86_32
->cache
->reg_list
[DR7
].valid
= true;
942 static int unset_debug_regs(struct target
*t
, uint8_t bp_num
)
944 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
945 LOG_DEBUG("bp_num=%" PRIu8
, bp_num
);
947 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
949 if (!(DR7_BP_FREE(dr7
, bp_num
))) {
950 DR7_GLOBAL_DISABLE(dr7
, bp_num
);
952 LOG_ERROR("%s dr7 error, not enabled, val=0x%08" PRIx32
, __func__
, dr7
);
953 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
955 /* this will clear rw and len bits */
956 DR7_RESET_RWLEN_BITS(dr7
, bp_num
);
958 /* update regs in the reg cache ready to be written to hardware
961 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, 0);
962 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= true;
963 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= true;
964 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
965 x86_32
->cache
->reg_list
[DR6
].dirty
= true;
966 x86_32
->cache
->reg_list
[DR6
].valid
= true;
967 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
968 x86_32
->cache
->reg_list
[DR7
].dirty
= true;
969 x86_32
->cache
->reg_list
[DR7
].valid
= true;
973 static int set_hwbp(struct target
*t
, struct breakpoint
*bp
)
975 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
976 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
977 uint8_t hwbp_num
= 0;
979 while (debug_reg_list
[hwbp_num
].used
&& (hwbp_num
< x86_32
->num_hw_bpoints
))
981 if (hwbp_num
>= x86_32
->num_hw_bpoints
) {
982 LOG_ERROR("%s no free hw breakpoint bpid=0x%" PRIx32
, __func__
, bp
->unique_id
);
983 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
985 if (set_debug_regs(t
, bp
->address
, hwbp_num
, DR7_BP_EXECUTE
, 1) != ERROR_OK
)
987 breakpoint_hw_set(bp
, hwbp_num
);
988 debug_reg_list
[hwbp_num
].used
= 1;
989 debug_reg_list
[hwbp_num
].bp_value
= bp
->address
;
990 LOG_USER("%s hardware breakpoint %" PRIu32
" set at 0x%08" PRIx32
" (hwreg=%" PRIu8
")", __func__
,
991 bp
->unique_id
, debug_reg_list
[hwbp_num
].bp_value
, hwbp_num
);
995 static int unset_hwbp(struct target
*t
, struct breakpoint
*bp
)
997 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
998 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
999 int hwbp_num
= bp
->number
;
1001 if (hwbp_num
>= x86_32
->num_hw_bpoints
) {
1002 LOG_ERROR("%s invalid breakpoint number=%d, bpid=%" PRIu32
,
1003 __func__
, hwbp_num
, bp
->unique_id
);
1007 if (unset_debug_regs(t
, hwbp_num
) != ERROR_OK
)
1009 debug_reg_list
[hwbp_num
].used
= 0;
1010 debug_reg_list
[hwbp_num
].bp_value
= 0;
1012 LOG_USER("%s hardware breakpoint %" PRIu32
" removed from " TARGET_ADDR_FMT
" (hwreg=%d)",
1013 __func__
, bp
->unique_id
, bp
->address
, hwbp_num
);
1017 static int set_swbp(struct target
*t
, struct breakpoint
*bp
)
1019 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1020 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1021 target_addr_t physaddr
;
1022 uint8_t opcode
= SW_BP_OPCODE
;
1025 if (calcaddr_physfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1027 if (read_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1030 LOG_DEBUG("set software breakpoint - orig byte=0x%02" PRIx8
"", *bp
->orig_instr
);
1032 /* just write the instruction trap byte */
1033 if (write_phys_mem(t
, physaddr
, 1, 1, &opcode
))
1036 /* verify that this is not invalid/read-only memory */
1037 if (read_phys_mem(t
, physaddr
, 1, 1, &readback
))
1040 if (readback
!= SW_BP_OPCODE
) {
1041 LOG_ERROR("%s software breakpoint error at " TARGET_ADDR_FMT
", check memory",
1042 __func__
, bp
->address
);
1043 LOG_ERROR("%s readback=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1044 __func__
, readback
, *bp
->orig_instr
);
1049 /* add the memory patch */
1050 struct swbp_mem_patch
*new_patch
= malloc(sizeof(struct swbp_mem_patch
));
1052 LOG_ERROR("%s out of memory", __func__
);
1055 new_patch
->next
= NULL
;
1056 new_patch
->orig_byte
= *bp
->orig_instr
;
1057 new_patch
->physaddr
= physaddr
;
1058 new_patch
->swbp_unique_id
= bp
->unique_id
;
1060 struct swbp_mem_patch
*addto
= x86_32
->swbbp_mem_patch_list
;
1062 x86_32
->swbbp_mem_patch_list
= new_patch
;
1065 addto
= addto
->next
;
1066 addto
->next
= new_patch
;
1068 LOG_USER("%s software breakpoint %" PRIu32
" set at " TARGET_ADDR_FMT
,
1069 __func__
, bp
->unique_id
, bp
->address
);
1073 static int unset_swbp(struct target
*t
, struct breakpoint
*bp
)
1075 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1076 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1077 target_addr_t physaddr
;
1078 uint8_t current_instr
;
1080 /* check that user program has not modified breakpoint instruction */
1081 if (calcaddr_physfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1083 if (read_phys_mem(t
, physaddr
, 1, 1, ¤t_instr
))
1086 if (current_instr
== SW_BP_OPCODE
) {
1087 if (write_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1090 LOG_ERROR("%s software breakpoint remove error at " TARGET_ADDR_FMT
", check memory",
1091 __func__
, bp
->address
);
1092 LOG_ERROR("%s current=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1093 __func__
, current_instr
, *bp
->orig_instr
);
1097 /* remove from patch */
1098 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
1100 if (iter
->swbp_unique_id
== bp
->unique_id
) {
1101 /* it's the first item */
1102 x86_32
->swbbp_mem_patch_list
= iter
->next
;
1105 while (iter
->next
&& iter
->next
->swbp_unique_id
!= bp
->unique_id
)
1108 /* it's the next one */
1109 struct swbp_mem_patch
*freeme
= iter
->next
;
1110 iter
->next
= iter
->next
->next
;
1116 LOG_USER("%s software breakpoint %" PRIu32
" removed from " TARGET_ADDR_FMT
,
1117 __func__
, bp
->unique_id
, bp
->address
);
1121 static int set_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1123 int error
= ERROR_OK
;
1124 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1125 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
1127 LOG_ERROR("breakpoint already set");
1130 if (bp
->type
== BKPT_HARD
) {
1131 error
= set_hwbp(t
, bp
);
1132 if (error
!= ERROR_OK
) {
1133 LOG_ERROR("%s error setting hardware breakpoint at " TARGET_ADDR_FMT
,
1134 __func__
, bp
->address
);
1138 if (x86_32
->sw_bpts_supported(t
)) {
1139 error
= set_swbp(t
, bp
);
1140 if (error
!= ERROR_OK
) {
1141 LOG_ERROR("%s error setting software breakpoint at " TARGET_ADDR_FMT
,
1142 __func__
, bp
->address
);
1146 LOG_ERROR("%s core doesn't support SW breakpoints", __func__
);
1153 static int unset_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1155 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
1157 LOG_WARNING("breakpoint not set");
1161 if (bp
->type
== BKPT_HARD
) {
1162 if (unset_hwbp(t
, bp
) != ERROR_OK
) {
1163 LOG_ERROR("%s error removing hardware breakpoint at " TARGET_ADDR_FMT
,
1164 __func__
, bp
->address
);
1168 if (unset_swbp(t
, bp
) != ERROR_OK
) {
1169 LOG_ERROR("%s error removing software breakpoint at " TARGET_ADDR_FMT
,
1170 __func__
, bp
->address
);
1178 static int set_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1180 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1181 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1183 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, wp
->rw
, wp
->address
);
1186 LOG_ERROR("%s watchpoint already set", __func__
);
1190 if (wp
->rw
== WPT_READ
) {
1191 LOG_ERROR("%s no support for 'read' watchpoints, use 'access' or 'write'"
1193 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1196 while (debug_reg_list
[wp_num
].used
&& (wp_num
< x86_32
->num_hw_bpoints
))
1198 if (wp_num
>= x86_32
->num_hw_bpoints
) {
1199 LOG_ERROR("%s no debug registers left", __func__
);
1200 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1203 if (wp
->length
!= 4 && wp
->length
!= 2 && wp
->length
!= 1) {
1204 LOG_ERROR("%s only watchpoints of length 1, 2 or 4 are supported", __func__
);
1205 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1210 if (set_debug_regs(t
, wp
->address
, wp_num
,
1211 DR7_BP_WRITE
, wp
->length
) != ERROR_OK
) {
1216 if (set_debug_regs(t
, wp
->address
, wp_num
, DR7_BP_READWRITE
,
1217 wp
->length
) != ERROR_OK
) {
1222 LOG_ERROR("%s only 'access' or 'write' watchpoints are supported", __func__
);
1225 watchpoint_set(wp
, wp_num
);
1226 debug_reg_list
[wp_num
].used
= 1;
1227 debug_reg_list
[wp_num
].bp_value
= wp
->address
;
1228 LOG_USER("'%s' watchpoint %d set at " TARGET_ADDR_FMT
" with length %" PRIu32
" (hwreg=%d)",
1229 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1230 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1231 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1235 static int unset_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1237 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1238 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1239 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, wp
->rw
, wp
->address
);
1241 LOG_WARNING("watchpoint not set");
1245 int wp_num
= wp
->number
;
1246 if (wp_num
>= x86_32
->num_hw_bpoints
) {
1247 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
1250 if (unset_debug_regs(t
, wp_num
) != ERROR_OK
)
1253 debug_reg_list
[wp_num
].used
= 0;
1254 debug_reg_list
[wp_num
].bp_value
= 0;
1257 LOG_USER("'%s' watchpoint %d removed from " TARGET_ADDR_FMT
" with length %" PRIu32
" (hwreg=%d)",
1258 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1259 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1260 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1265 /* after reset breakpoints and watchpoints in memory are not valid anymore and
1266 * debug registers are cleared.
1267 * we can't afford to remove sw breakpoints using the default methods as the
1268 * memory doesn't have the same layout yet and an access might crash the target,
1269 * so we just clear the openocd breakpoints structures.
1271 void x86_32_common_reset_breakpoints_watchpoints(struct target
*t
)
1273 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1274 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1275 struct breakpoint
*next_b
;
1276 struct watchpoint
*next_w
;
1278 while (t
->breakpoints
) {
1279 next_b
= t
->breakpoints
->next
;
1280 free(t
->breakpoints
->orig_instr
);
1281 free(t
->breakpoints
);
1282 t
->breakpoints
= next_b
;
1285 while (t
->watchpoints
) {
1286 next_w
= t
->watchpoints
->next
;
1287 free(t
->watchpoints
);
1288 t
->watchpoints
= next_w
;
1291 for (int i
= 0; i
< x86_32
->num_hw_bpoints
; i
++) {
1292 debug_reg_list
[i
].used
= 0;
1293 debug_reg_list
[i
].bp_value
= 0;
1297 static int read_hw_reg_to_cache(struct target
*t
, int num
)
1300 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1302 if (check_not_halted(t
))
1303 return ERROR_TARGET_NOT_HALTED
;
1304 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1305 return ERROR_COMMAND_SYNTAX_ERROR
;
1306 if (x86_32
->read_hw_reg(t
, num
, ®_value
, 1) != ERROR_OK
) {
1307 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1310 LOG_DEBUG("reg %s value 0x%08" PRIx32
,
1311 x86_32
->cache
->reg_list
[num
].name
, reg_value
);
1315 static int write_hw_reg_from_cache(struct target
*t
, int num
)
1317 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1318 if (check_not_halted(t
))
1319 return ERROR_TARGET_NOT_HALTED
;
1320 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1321 return ERROR_COMMAND_SYNTAX_ERROR
;
1322 if (x86_32
->write_hw_reg(t
, num
, 0, 1) != ERROR_OK
) {
1323 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1326 LOG_DEBUG("reg %s value 0x%08" PRIx32
, x86_32
->cache
->reg_list
[num
].name
,
1327 buf_get_u32(x86_32
->cache
->reg_list
[num
].value
, 0, 32));
1331 /* x86 32 commands */
1332 static void handle_iod_output(struct command_invocation
*cmd
,
1333 struct target
*target
, uint32_t address
, unsigned size
,
1334 unsigned count
, const uint8_t *buffer
)
1336 const unsigned line_bytecnt
= 32;
1337 unsigned line_modulo
= line_bytecnt
/ size
;
1339 char output
[line_bytecnt
* 4 + 1];
1340 unsigned output_len
= 0;
1342 const char *value_fmt
;
1345 value_fmt
= "%8.8x ";
1348 value_fmt
= "%4.4x ";
1351 value_fmt
= "%2.2x ";
1354 /* "can't happen", caller checked */
1355 LOG_ERROR("%s invalid memory read size: %u", __func__
, size
);
1359 for (unsigned i
= 0; i
< count
; i
++) {
1360 if (i
% line_modulo
== 0) {
1361 output_len
+= snprintf(output
+ output_len
,
1362 sizeof(output
) - output_len
,
1364 (unsigned)(address
+ (i
*size
)));
1368 const uint8_t *value_ptr
= buffer
+ i
* size
;
1371 value
= target_buffer_get_u32(target
, value_ptr
);
1374 value
= target_buffer_get_u16(target
, value_ptr
);
1379 output_len
+= snprintf(output
+ output_len
,
1380 sizeof(output
) - output_len
,
1383 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1384 command_print(cmd
, "%s", output
);
1390 COMMAND_HANDLER(handle_iod_command
)
1393 return ERROR_COMMAND_SYNTAX_ERROR
;
1396 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1397 if (address
> 0xffff) {
1398 LOG_ERROR("%s IA-32 I/O space is 2^16, 0x%08" PRIx32
" exceeds max", __func__
, address
);
1399 return ERROR_COMMAND_SYNTAX_ERROR
;
1403 switch (CMD_NAME
[2]) {
1414 return ERROR_COMMAND_SYNTAX_ERROR
;
1417 uint8_t *buffer
= calloc(count
, size
);
1418 struct target
*target
= get_current_target(CMD_CTX
);
1419 int retval
= x86_32_common_read_io(target
, address
, size
, buffer
);
1420 if (retval
== ERROR_OK
)
1421 handle_iod_output(CMD
, target
, address
, size
, count
, buffer
);
1426 static int target_fill_io(struct target
*target
,
1432 LOG_DEBUG("address=0x%08" PRIx32
", data_size=%u, b=0x%08" PRIx32
,
1433 address
, data_size
, b
);
1434 uint8_t target_buf
[data_size
];
1435 switch (data_size
) {
1437 target_buffer_set_u32(target
, target_buf
, b
);
1440 target_buffer_set_u16(target
, target_buf
, b
);
1443 target_buf
[0] = (b
& 0x0ff);
1448 return x86_32_common_write_io(target
, address
, data_size
, target_buf
);
1451 COMMAND_HANDLER(handle_iow_command
)
1454 return ERROR_COMMAND_SYNTAX_ERROR
;
1456 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1458 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
1459 struct target
*target
= get_current_target(CMD_CTX
);
1462 switch (CMD_NAME
[2]) {
1473 return ERROR_COMMAND_SYNTAX_ERROR
;
1475 return target_fill_io(target
, address
, wordsize
, value
);
1478 static const struct command_registration x86_32_exec_command_handlers
[] = {
1481 .mode
= COMMAND_EXEC
,
1482 .handler
= handle_iow_command
,
1483 .help
= "write I/O port word",
1484 .usage
= "port data[word]",
1488 .mode
= COMMAND_EXEC
,
1489 .handler
= handle_iow_command
,
1490 .help
= "write I/O port halfword",
1491 .usage
= "port data[halfword]",
1495 .mode
= COMMAND_EXEC
,
1496 .handler
= handle_iow_command
,
1497 .help
= "write I/O port byte",
1498 .usage
= "port data[byte]",
1502 .mode
= COMMAND_EXEC
,
1503 .handler
= handle_iod_command
,
1504 .help
= "display I/O port word",
1509 .mode
= COMMAND_EXEC
,
1510 .handler
= handle_iod_command
,
1511 .help
= "display I/O port halfword",
1516 .mode
= COMMAND_EXEC
,
1517 .handler
= handle_iod_command
,
1518 .help
= "display I/O port byte",
1522 COMMAND_REGISTRATION_DONE
1525 const struct command_registration x86_32_command_handlers
[] = {
1528 .mode
= COMMAND_ANY
,
1529 .help
= "x86_32 target commands",
1531 .chain
= x86_32_exec_command_handlers
,
1533 COMMAND_REGISTRATION_DONE
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)