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