2 * Copyright(c) 2013 Intel Corporation.
4 * Adrian Burns (adrian.burns@intel.com)
5 * Thomas Faust (thomas.faust@intel.com)
6 * Ivan De Cesaris (ivan.de.cesaris@intel.com)
7 * Julien Carreno (julien.carreno@intel.com)
8 * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * Contact Information:
29 * This implements generic x86 32 bit memory and breakpoint operations.
36 #include <helper/log.h>
39 #include "target_type.h"
41 #include "breakpoints.h"
42 #include "x86_32_common.h"
44 static int set_debug_regs(struct target
*t
, uint32_t address
,
45 uint8_t bp_num
, uint8_t bp_type
, uint8_t bp_length
);
46 static int unset_debug_regs(struct target
*t
, uint8_t bp_num
);
47 static int read_mem(struct target
*t
, uint32_t size
,
48 uint32_t addr
, uint8_t *buf
);
49 static int write_mem(struct target
*t
, uint32_t size
,
50 uint32_t addr
, const uint8_t *buf
);
51 static int calcaddr_physfromlin(struct target
*t
, target_addr_t addr
,
52 target_addr_t
*physaddr
);
53 static int read_phys_mem(struct target
*t
, uint32_t phys_address
,
54 uint32_t size
, uint32_t count
, uint8_t *buffer
);
55 static int write_phys_mem(struct target
*t
, uint32_t phys_address
,
56 uint32_t size
, uint32_t count
, const uint8_t *buffer
);
57 static int set_breakpoint(struct target
*target
,
58 struct breakpoint
*breakpoint
);
59 static int unset_breakpoint(struct target
*target
,
60 struct breakpoint
*breakpoint
);
61 static int set_watchpoint(struct target
*target
,
62 struct watchpoint
*watchpoint
);
63 static int unset_watchpoint(struct target
*target
,
64 struct watchpoint
*watchpoint
);
65 static int read_hw_reg_to_cache(struct target
*t
, int num
);
66 static int write_hw_reg_from_cache(struct target
*t
, int num
);
68 int x86_32_get_gdb_reg_list(struct target
*t
,
69 struct reg
**reg_list
[], int *reg_list_size
,
70 enum target_register_class reg_class
)
73 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
75 *reg_list_size
= x86_32
->cache
->num_regs
;
76 LOG_DEBUG("num_regs=%d, reg_class=%d", (*reg_list_size
), reg_class
);
77 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
78 if (*reg_list
== NULL
) {
79 LOG_ERROR("%s out of memory", __func__
);
82 /* this will copy the values from our reg list to gdbs */
83 for (i
= 0; i
< (*reg_list_size
); i
++) {
84 (*reg_list
)[i
] = &x86_32
->cache
->reg_list
[i
];
85 LOG_DEBUG("value %s = %08" PRIx32
, x86_32
->cache
->reg_list
[i
].name
,
86 buf_get_u32(x86_32
->cache
->reg_list
[i
].value
, 0, 32));
91 int x86_32_common_init_arch_info(struct target
*t
, struct x86_32_common
*x86_32
)
93 t
->arch_info
= x86_32
;
94 x86_32
->common_magic
= X86_32_COMMON_MAGIC
;
95 x86_32
->num_hw_bpoints
= MAX_DEBUG_REGS
;
96 x86_32
->hw_break_list
= calloc(x86_32
->num_hw_bpoints
,
97 sizeof(struct x86_32_dbg_reg
));
98 if (x86_32
->hw_break_list
== NULL
) {
99 LOG_ERROR("%s out of memory", __func__
);
102 x86_32
->curr_tap
= t
->tap
;
103 x86_32
->fast_data_area
= NULL
;
105 x86_32
->read_hw_reg_to_cache
= read_hw_reg_to_cache
;
106 x86_32
->write_hw_reg_from_cache
= write_hw_reg_from_cache
;
110 int x86_32_common_mmu(struct target
*t
, int *enabled
)
116 int x86_32_common_virt2phys(struct target
*t
, target_addr_t address
, target_addr_t
*physical
)
118 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
121 * We need to ignore 'segmentation' for now, as OpenOCD can't handle
122 * segmented addresses.
123 * In protected mode that is almost OK, as (almost) any known OS is using
124 * flat segmentation. In real mode we use use the base of the DS segment,
125 * as we don't know better ...
128 uint32_t cr0
= buf_get_u32(x86_32
->cache
->reg_list
[CR0
].value
, 0, 32);
129 if (!(cr0
& CR0_PG
)) {
130 /* target halted in real mode */
131 /* TODO: needs validation !!! */
132 uint32_t dsb
= buf_get_u32(x86_32
->cache
->reg_list
[DSB
].value
, 0, 32);
133 *physical
= dsb
+ address
;
136 /* target halted in protected mode */
137 if (calcaddr_physfromlin(t
, address
, physical
) != ERROR_OK
) {
138 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
146 int x86_32_common_read_phys_mem(struct target
*t
, target_addr_t phys_address
,
147 uint32_t size
, uint32_t count
, uint8_t *buffer
)
149 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
152 error
= read_phys_mem(t
, phys_address
, size
, count
, buffer
);
153 if (error
!= ERROR_OK
)
156 /* After reading memory from target, we must replace software breakpoints
157 * with the original instructions again.
159 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
160 while (iter
!= NULL
) {
161 if (iter
->physaddr
>= phys_address
&& iter
->physaddr
< phys_address
+(size
*count
)) {
162 uint32_t offset
= iter
->physaddr
- phys_address
;
163 buffer
[offset
] = iter
->orig_byte
;
170 static int read_phys_mem(struct target
*t
, uint32_t phys_address
,
171 uint32_t size
, uint32_t count
, uint8_t *buffer
)
173 int retval
= ERROR_OK
;
174 bool pg_disabled
= false;
175 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
176 phys_address
, size
, count
, buffer
);
177 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
179 if (check_not_halted(t
))
180 return ERROR_TARGET_NOT_HALTED
;
181 if (!count
|| !buffer
|| !phys_address
) {
182 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32
,
183 __func__
, count
, buffer
, phys_address
);
184 return ERROR_COMMAND_ARGUMENT_INVALID
;
187 /* to access physical memory, switch off the CR0.PG bit */
188 if (x86_32
->is_paging_enabled(t
)) {
189 retval
= x86_32
->disable_paging(t
);
190 if (retval
!= ERROR_OK
) {
191 LOG_ERROR("%s could not disable paging", __func__
);
197 for (uint32_t i
= 0; i
< count
; i
++) {
200 retval
= read_mem(t
, size
, phys_address
+ i
, buffer
+ i
);
203 retval
= read_mem(t
, size
, phys_address
+ i
* 2, buffer
+ i
* 2);
206 retval
= read_mem(t
, size
, phys_address
+ i
* 4, buffer
+ i
* 4);
209 LOG_ERROR("%s invalid read size", __func__
);
212 if (retval
!= ERROR_OK
)
215 /* restore CR0.PG bit if needed (regardless of retval) */
217 int retval2
= x86_32
->enable_paging(t
);
218 if (retval2
!= ERROR_OK
) {
219 LOG_ERROR("%s could not enable paging", __func__
);
223 /* TODO: After reading memory from target, we must replace
224 * software breakpoints with the original instructions again.
225 * Solve this with the breakpoint fix
230 int x86_32_common_write_phys_mem(struct target
*t
, target_addr_t phys_address
,
231 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
233 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
234 int error
= ERROR_OK
;
235 uint8_t *newbuffer
= NULL
;
238 if (!count
|| !buffer
|| !phys_address
) {
239 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
240 __func__
, count
, buffer
, phys_address
);
241 return ERROR_COMMAND_ARGUMENT_INVALID
;
243 /* Before writing memory to target, we must update software breakpoints
244 * with the new instructions and patch the memory buffer with the
245 * breakpoint instruction.
247 newbuffer
= malloc(size
*count
);
248 if (newbuffer
== NULL
) {
249 LOG_ERROR("%s out of memory", __func__
);
252 memcpy(newbuffer
, buffer
, size
*count
);
253 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
254 while (iter
!= NULL
) {
255 if (iter
->physaddr
>= phys_address
&& iter
->physaddr
< phys_address
+(size
*count
)) {
256 uint32_t offset
= iter
->physaddr
- phys_address
;
257 newbuffer
[offset
] = SW_BP_OPCODE
;
259 /* update the breakpoint */
260 struct breakpoint
*pbiter
= t
->breakpoints
;
261 while (pbiter
!= NULL
&& pbiter
->unique_id
!= iter
->swbp_unique_id
)
262 pbiter
= pbiter
->next
;
264 pbiter
->orig_instr
[0] = buffer
[offset
];
269 error
= write_phys_mem(t
, phys_address
, size
, count
, newbuffer
);
274 static int write_phys_mem(struct target
*t
, uint32_t phys_address
,
275 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
277 int retval
= ERROR_OK
;
278 bool pg_disabled
= false;
279 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
280 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
281 phys_address
, size
, count
, buffer
);
284 if (!count
|| !buffer
|| !phys_address
) {
285 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32
,
286 __func__
, count
, buffer
, phys_address
);
287 return ERROR_COMMAND_ARGUMENT_INVALID
;
289 /* TODO: Before writing memory to target, we must update
290 * software breakpoints with the new instructions and
291 * patch the memory buffer with the breakpoint instruction.
292 * Solve this with the breakpoint fix
295 /* to access physical memory, switch off the CR0.PG bit */
296 if (x86_32
->is_paging_enabled(t
)) {
297 retval
= x86_32
->disable_paging(t
);
298 if (retval
!= ERROR_OK
) {
299 LOG_ERROR("%s could not disable paging", __func__
);
304 for (uint32_t i
= 0; i
< count
; i
++) {
307 retval
= write_mem(t
, size
, phys_address
+ i
, buffer
+ i
);
310 retval
= write_mem(t
, size
, phys_address
+ i
* 2, buffer
+ i
* 2);
313 retval
= write_mem(t
, size
, phys_address
+ i
* 4, buffer
+ i
* 4);
316 LOG_DEBUG("invalid read size");
320 /* restore CR0.PG bit if needed (regardless of retval) */
322 retval
= x86_32
->enable_paging(t
);
323 if (retval
!= ERROR_OK
) {
324 LOG_ERROR("%s could not enable paging", __func__
);
331 static int read_mem(struct target
*t
, uint32_t size
,
332 uint32_t addr
, uint8_t *buf
)
334 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
336 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
337 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
338 int retval
= x86_32
->write_hw_reg(t
, EAX
, addr
, 0);
339 if (retval
!= ERROR_OK
) {
340 LOG_ERROR("%s error write EAX", __func__
);
347 retval
= x86_32
->submit_instruction(t
, MEMRDB32
);
349 retval
= x86_32
->submit_instruction(t
, MEMRDB16
);
353 retval
= x86_32
->submit_instruction(t
, MEMRDH32
);
355 retval
= x86_32
->submit_instruction(t
, MEMRDH16
);
359 retval
= x86_32
->submit_instruction(t
, MEMRDW32
);
361 retval
= x86_32
->submit_instruction(t
, MEMRDW16
);
364 LOG_ERROR("%s invalid read mem size", __func__
);
368 if (retval
!= ERROR_OK
)
371 /* read_hw_reg() will write to 4 bytes (uint32_t)
372 * Watch out, the buffer passed into read_mem() might be 1 or 2 bytes.
375 retval
= x86_32
->read_hw_reg(t
, EDX
, ®val
, 0);
377 if (retval
!= ERROR_OK
) {
378 LOG_ERROR("%s error read EDX", __func__
);
381 for (uint8_t i
= 0; i
< size
; i
++)
382 buf
[i
] = (regval
>> (i
*8)) & 0x000000FF;
384 retval
= x86_32
->transaction_status(t
);
385 if (retval
!= ERROR_OK
) {
386 LOG_ERROR("%s error on mem read", __func__
);
392 static int write_mem(struct target
*t
, uint32_t size
,
393 uint32_t addr
, const uint8_t *buf
)
396 uint32_t buf4bytes
= 0;
397 int retval
= ERROR_OK
;
398 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
400 for (i
= 0; i
< size
; ++i
) {
401 buf4bytes
= buf4bytes
<< 8; /* first time we only shift 0s */
402 buf4bytes
+= buf
[(size
-1)-i
]; /* it was hard to write, should be hard to read! */
404 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
405 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
406 retval
= x86_32
->write_hw_reg(t
, EAX
, addr
, 0);
407 if (retval
!= ERROR_OK
) {
408 LOG_ERROR("%s error write EAX", __func__
);
412 /* write_hw_reg() will write to 4 bytes (uint32_t)
413 * Watch out, the buffer passed into write_mem() might be 1 or 2 bytes.
415 retval
= x86_32
->write_hw_reg(t
, EDX
, buf4bytes
, 0);
416 if (retval
!= ERROR_OK
) {
417 LOG_ERROR("%s error write EDX", __func__
);
423 retval
= x86_32
->submit_instruction(t
, MEMWRB32
);
425 retval
= x86_32
->submit_instruction(t
, MEMWRB16
);
429 retval
= x86_32
->submit_instruction(t
, MEMWRH32
);
431 retval
= x86_32
->submit_instruction(t
, MEMWRH16
);
435 retval
= x86_32
->submit_instruction(t
, MEMWRW32
);
437 retval
= x86_32
->submit_instruction(t
, MEMWRW16
);
440 LOG_ERROR("%s invalid write mem size", __func__
);
444 if (retval
!= ERROR_OK
)
447 retval
= x86_32
->transaction_status(t
);
448 if (retval
!= ERROR_OK
) {
449 LOG_ERROR("%s error on mem write", __func__
);
455 int calcaddr_physfromlin(struct target
*t
, target_addr_t addr
, target_addr_t
*physaddr
)
457 uint8_t entry_buffer
[8];
459 if (physaddr
== NULL
|| t
== NULL
)
462 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
464 /* The 'user-visible' CR0.PG should be set - otherwise the function shouldn't be called
465 * (Don't check the CR0.PG on the target, this might be temporally disabled at this point)
467 uint32_t cr0
= buf_get_u32(x86_32
->cache
->reg_list
[CR0
].value
, 0, 32);
468 if (!(cr0
& CR0_PG
)) {
469 /* you are wrong in this function, never mind */
474 uint32_t cr4
= buf_get_u32(x86_32
->cache
->reg_list
[CR4
].value
, 0, 32);
475 bool isPAE
= cr4
& 0x00000020; /* PAE - Physical Address Extension */
477 uint32_t cr3
= buf_get_u32(x86_32
->cache
->reg_list
[CR3
].value
, 0, 32);
479 uint32_t pdpt_base
= cr3
& 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */
480 uint32_t pdpt_index
= (addr
& 0xC0000000) >> 30; /* A[31:30] index to PDPT */
481 uint32_t pdpt_addr
= pdpt_base
+ (8 * pdpt_index
);
482 if (x86_32_common_read_phys_mem(t
, pdpt_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
483 LOG_ERROR("%s couldn't read page directory pointer table entry at 0x%08" PRIx32
,
484 __func__
, pdpt_addr
);
487 uint64_t pdpt_entry
= target_buffer_get_u64(t
, entry_buffer
);
488 if (!(pdpt_entry
& 0x0000000000000001)) {
489 LOG_ERROR("%s page directory pointer table entry at 0x%08" PRIx32
" is not present",
490 __func__
, pdpt_addr
);
494 uint32_t pd_base
= pdpt_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
495 uint32_t pd_index
= (addr
& 0x3FE00000) >> 21; /* A[29:21] index to PD entry with PAE */
496 uint32_t pd_addr
= pd_base
+ (8 * pd_index
);
497 if (x86_32_common_read_phys_mem(t
, pd_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
498 LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32
,
502 uint64_t pd_entry
= target_buffer_get_u64(t
, entry_buffer
);
503 if (!(pd_entry
& 0x0000000000000001)) {
504 LOG_ERROR("%s page directory entry at 0x%08" PRIx32
" is not present",
509 /* PS bit in PD entry is indicating 4KB or 2MB page size */
510 if (pd_entry
& 0x0000000000000080) {
512 uint32_t page_base
= (uint32_t)(pd_entry
& 0x00000000FFE00000); /* [31:21] */
513 uint32_t offset
= addr
& 0x001FFFFF; /* [20:0] */
514 *physaddr
= page_base
+ offset
;
519 uint32_t pt_base
= (uint32_t)(pd_entry
& 0x00000000FFFFF000); /*[31:12]*/
520 uint32_t pt_index
= (addr
& 0x001FF000) >> 12; /*[20:12]*/
521 uint32_t pt_addr
= pt_base
+ (8 * pt_index
);
522 if (x86_32_common_read_phys_mem(t
, pt_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
523 LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32
, __func__
, pt_addr
);
526 uint64_t pt_entry
= target_buffer_get_u64(t
, entry_buffer
);
527 if (!(pt_entry
& 0x0000000000000001)) {
528 LOG_ERROR("%s page table entry at 0x%08" PRIx32
" is not present", __func__
, pt_addr
);
532 uint32_t page_base
= (uint32_t)(pt_entry
& 0x00000000FFFFF000); /*[31:12]*/
533 uint32_t offset
= addr
& 0x00000FFF; /*[11:0]*/
534 *physaddr
= page_base
+ offset
;
538 uint32_t pd_base
= cr3
& 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */
539 uint32_t pd_index
= (addr
& 0xFFC00000) >> 22; /* A[31:22] index to PD entry */
540 uint32_t pd_addr
= pd_base
+ (4 * pd_index
);
541 if (x86_32_common_read_phys_mem(t
, pd_addr
, 4, 1, entry_buffer
) != ERROR_OK
) {
542 LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32
, __func__
, pd_addr
);
545 uint32_t pd_entry
= target_buffer_get_u32(t
, entry_buffer
);
546 if (!(pd_entry
& 0x00000001)) {
547 LOG_ERROR("%s page directory entry at 0x%08" PRIx32
" is not present", __func__
, pd_addr
);
551 /* Bit 7 in page directory entry is page size.
553 if (pd_entry
& 0x00000080) {
555 uint32_t page_base
= pd_entry
& 0xFFC00000;
556 *physaddr
= page_base
+ (addr
& 0x003FFFFF);
560 uint32_t pt_base
= pd_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
561 uint32_t pt_index
= (addr
& 0x003FF000) >> 12; /* A[21:12] index to page table entry */
562 uint32_t pt_addr
= pt_base
+ (4 * pt_index
);
563 if (x86_32_common_read_phys_mem(t
, pt_addr
, 4, 1, entry_buffer
) != ERROR_OK
) {
564 LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32
, __func__
, pt_addr
);
567 uint32_t pt_entry
= target_buffer_get_u32(t
, entry_buffer
);
568 if (!(pt_entry
& 0x00000001)) {
569 LOG_ERROR("%s page table entry at 0x%08" PRIx32
" is not present", __func__
, pt_addr
);
572 uint32_t page_base
= pt_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
573 *physaddr
= page_base
+ (addr
& 0x00000FFF); /* A[11:0] offset to 4KB page in linear address */
579 int x86_32_common_read_memory(struct target
*t
, target_addr_t addr
,
580 uint32_t size
, uint32_t count
, uint8_t *buf
)
582 int retval
= ERROR_OK
;
583 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
584 LOG_DEBUG("addr=" TARGET_ADDR_FMT
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
585 addr
, size
, count
, buf
);
587 if (!count
|| !buf
|| !addr
) {
588 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
589 __func__
, count
, buf
, addr
);
590 return ERROR_COMMAND_ARGUMENT_INVALID
;
593 if (x86_32
->is_paging_enabled(t
)) {
594 /* all memory accesses from debugger must be physical (CR0.PG == 0)
595 * conversion to physical address space needed
597 retval
= x86_32
->disable_paging(t
);
598 if (retval
!= ERROR_OK
) {
599 LOG_ERROR("%s could not disable paging", __func__
);
602 target_addr_t physaddr
= 0;
603 if (calcaddr_physfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
604 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
608 /* TODO: !!! Watch out for page boundaries
609 * for every 4kB, the physical address has to be re-calculated
610 * This should be fixed together with bulk memory reads
613 if (retval
== ERROR_OK
614 && x86_32_common_read_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
615 LOG_ERROR("%s failed to read memory from physical address " TARGET_ADDR_FMT
,
618 /* restore PG bit if it was cleared prior (regardless of retval) */
619 retval
= x86_32
->enable_paging(t
);
620 if (retval
!= ERROR_OK
) {
621 LOG_ERROR("%s could not enable paging", __func__
);
625 /* paging is off - linear address is physical address */
626 if (x86_32_common_read_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
627 LOG_ERROR("%s failed to read memory from address " TARGET_ADDR_FMT
,
636 int x86_32_common_write_memory(struct target
*t
, target_addr_t addr
,
637 uint32_t size
, uint32_t count
, const uint8_t *buf
)
639 int retval
= ERROR_OK
;
640 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
641 LOG_DEBUG("addr=" TARGET_ADDR_FMT
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
642 addr
, size
, count
, buf
);
644 if (!count
|| !buf
|| !addr
) {
645 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
646 __func__
, count
, buf
, addr
);
647 return ERROR_COMMAND_ARGUMENT_INVALID
;
649 if (x86_32
->is_paging_enabled(t
)) {
650 /* all memory accesses from debugger must be physical (CR0.PG == 0)
651 * conversion to physical address space needed
653 retval
= x86_32
->disable_paging(t
);
654 if (retval
!= ERROR_OK
) {
655 LOG_ERROR("%s could not disable paging", __func__
);
658 target_addr_t physaddr
= 0;
659 if (calcaddr_physfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
660 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
664 /* TODO: !!! Watch out for page boundaries
665 * for every 4kB, the physical address has to be re-calculated
666 * This should be fixed together with bulk memory reads
668 if (retval
== ERROR_OK
669 && x86_32_common_write_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
670 LOG_ERROR("%s failed to write memory to physical address " TARGET_ADDR_FMT
,
673 /* restore PG bit if it was cleared prior (regardless of retval) */
674 retval
= x86_32
->enable_paging(t
);
675 if (retval
!= ERROR_OK
) {
676 LOG_ERROR("%s could not enable paging", __func__
);
681 /* paging is off - linear address is physical address */
682 if (x86_32_common_write_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
683 LOG_ERROR("%s failed to write memory to address " TARGET_ADDR_FMT
,
691 int x86_32_common_read_io(struct target
*t
, uint32_t addr
,
692 uint32_t size
, uint8_t *buf
)
694 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
695 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
696 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
697 int retval
= ERROR_FAIL
;
698 bool pg_disabled
= false;
699 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
702 LOG_ERROR("%s invalid params buf=%p, addr=%08" PRIx32
, __func__
, buf
, addr
);
705 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
706 if (retval
!= ERROR_OK
) {
707 LOG_ERROR("%s error EDX write", __func__
);
710 /* to access physical memory, switch off the CR0.PG bit */
711 if (x86_32
->is_paging_enabled(t
)) {
712 retval
= x86_32
->disable_paging(t
);
713 if (retval
!= ERROR_OK
) {
714 LOG_ERROR("%s could not disable paging", __func__
);
722 retval
= x86_32
->submit_instruction(t
, IORDB32
);
724 retval
= x86_32
->submit_instruction(t
, IORDB16
);
728 retval
= x86_32
->submit_instruction(t
, IORDH32
);
730 retval
= x86_32
->submit_instruction(t
, IORDH16
);
734 retval
= x86_32
->submit_instruction(t
, IORDW32
);
736 retval
= x86_32
->submit_instruction(t
, IORDW16
);
739 LOG_ERROR("%s invalid read io size", __func__
);
743 /* restore CR0.PG bit if needed */
745 int retval2
= x86_32
->enable_paging(t
);
746 if (retval2
!= ERROR_OK
) {
747 LOG_ERROR("%s could not enable paging", __func__
);
752 if (retval
!= ERROR_OK
)
756 retval
= x86_32
->read_hw_reg(t
, EAX
, ®val
, 0);
757 if (retval
!= ERROR_OK
) {
758 LOG_ERROR("%s error on read EAX", __func__
);
761 for (uint8_t i
= 0; i
< size
; i
++)
762 buf
[i
] = (regval
>> (i
*8)) & 0x000000FF;
763 retval
= x86_32
->transaction_status(t
);
764 if (retval
!= ERROR_OK
) {
765 LOG_ERROR("%s error on io read", __func__
);
771 int x86_32_common_write_io(struct target
*t
, uint32_t addr
,
772 uint32_t size
, const uint8_t *buf
)
774 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
775 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
776 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
777 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
779 int retval
= ERROR_FAIL
;
780 bool pg_disabled
= false;
782 LOG_ERROR("%s invalid params buf=%p, addr=0x%08" PRIx32
, __func__
, buf
, addr
);
785 /* no do the write */
786 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
787 if (retval
!= ERROR_OK
) {
788 LOG_ERROR("%s error on EDX write", __func__
);
792 for (uint8_t i
= 0; i
< size
; i
++)
793 regval
+= (buf
[i
] << (i
*8));
794 retval
= x86_32
->write_hw_reg(t
, EAX
, regval
, 0);
795 if (retval
!= ERROR_OK
) {
796 LOG_ERROR("%s error on EAX write", __func__
);
799 /* to access physical memory, switch off the CR0.PG bit */
800 if (x86_32
->is_paging_enabled(t
)) {
801 retval
= x86_32
->disable_paging(t
);
802 if (retval
!= ERROR_OK
) {
803 LOG_ERROR("%s could not disable paging", __func__
);
811 retval
= x86_32
->submit_instruction(t
, IOWRB32
);
813 retval
= x86_32
->submit_instruction(t
, IOWRB16
);
817 retval
= x86_32
->submit_instruction(t
, IOWRH32
);
819 retval
= x86_32
->submit_instruction(t
, IOWRH16
);
823 retval
= x86_32
->submit_instruction(t
, IOWRW32
);
825 retval
= x86_32
->submit_instruction(t
, IOWRW16
);
828 LOG_ERROR("%s invalid write io size", __func__
);
832 /* restore CR0.PG bit if needed */
834 int retval2
= x86_32
->enable_paging(t
);
835 if (retval2
!= ERROR_OK
) {
836 LOG_ERROR("%s could not enable paging", __func__
);
841 if (retval
!= ERROR_OK
)
844 retval
= x86_32
->transaction_status(t
);
845 if (retval
!= ERROR_OK
) {
846 LOG_ERROR("%s error on io write", __func__
);
852 int x86_32_common_add_watchpoint(struct target
*t
, struct watchpoint
*wp
)
855 /* set_watchpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
856 * hardware registers are gone
858 return set_watchpoint(t
, wp
);
861 int x86_32_common_remove_watchpoint(struct target
*t
, struct watchpoint
*wp
)
863 if (check_not_halted(t
))
864 return ERROR_TARGET_NOT_HALTED
;
866 unset_watchpoint(t
, wp
);
870 int x86_32_common_add_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
;
875 /* set_breakpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
876 * hardware registers are gone (for hardware breakpoints)
878 return set_breakpoint(t
, bp
);
881 int x86_32_common_remove_breakpoint(struct target
*t
, struct breakpoint
*bp
)
883 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
884 if (check_not_halted(t
))
885 return ERROR_TARGET_NOT_HALTED
;
887 unset_breakpoint(t
, bp
);
892 static int set_debug_regs(struct target
*t
, uint32_t address
,
893 uint8_t bp_num
, uint8_t bp_type
, uint8_t bp_length
)
895 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
896 LOG_DEBUG("addr=0x%08" PRIx32
", bp_num=%" PRIu8
", bp_type=%" PRIu8
", pb_length=%" PRIu8
,
897 address
, bp_num
, bp_type
, bp_length
);
899 /* DR7 - set global enable */
900 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
902 if (bp_length
!= 1 && bp_length
!= 2 && bp_length
!= 4)
905 if (DR7_BP_FREE(dr7
, bp_num
))
906 DR7_GLOBAL_ENABLE(dr7
, bp_num
);
908 LOG_ERROR("%s dr7 error, already enabled, val=%08" PRIx32
, __func__
, dr7
);
909 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
914 /* 00 - only on instruction execution */
915 DR7_SET_EXE(dr7
, bp_num
);
916 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
919 /* 01 - only on data writes */
920 DR7_SET_WRITE(dr7
, bp_num
);
921 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
924 /* 10 UNSUPPORTED - an I/O read and I/O write */
925 LOG_ERROR("%s unsupported feature bp_type=%d", __func__
, bp_type
);
929 /* on data read or data write */
930 DR7_SET_ACCESS(dr7
, bp_num
);
931 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
934 LOG_ERROR("%s invalid request [only 0-3] bp_type=%d", __func__
, bp_type
);
938 /* update regs in the reg cache ready to be written to hardware
941 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, address
);
942 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= 1;
943 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= 1;
944 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
945 x86_32
->cache
->reg_list
[DR6
].dirty
= 1;
946 x86_32
->cache
->reg_list
[DR6
].valid
= 1;
947 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
948 x86_32
->cache
->reg_list
[DR7
].dirty
= 1;
949 x86_32
->cache
->reg_list
[DR7
].valid
= 1;
953 static int unset_debug_regs(struct target
*t
, uint8_t bp_num
)
955 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
956 LOG_DEBUG("bp_num=%" PRIu8
, bp_num
);
958 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
960 if (!(DR7_BP_FREE(dr7
, bp_num
))) {
961 DR7_GLOBAL_DISABLE(dr7
, bp_num
);
963 LOG_ERROR("%s dr7 error, not enabled, val=0x%08" PRIx32
, __func__
, dr7
);
964 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
966 /* this will clear rw and len bits */
967 DR7_RESET_RWLEN_BITS(dr7
, bp_num
);
969 /* update regs in the reg cache ready to be written to hardware
972 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, 0);
973 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= 1;
974 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= 1;
975 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
976 x86_32
->cache
->reg_list
[DR6
].dirty
= 1;
977 x86_32
->cache
->reg_list
[DR6
].valid
= 1;
978 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
979 x86_32
->cache
->reg_list
[DR7
].dirty
= 1;
980 x86_32
->cache
->reg_list
[DR7
].valid
= 1;
984 static int set_hwbp(struct target
*t
, struct breakpoint
*bp
)
986 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
987 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
988 uint8_t hwbp_num
= 0;
990 while (debug_reg_list
[hwbp_num
].used
&& (hwbp_num
< x86_32
->num_hw_bpoints
))
992 if (hwbp_num
>= x86_32
->num_hw_bpoints
) {
993 LOG_ERROR("%s no free hw breakpoint bpid=0x%" PRIx32
, __func__
, bp
->unique_id
);
994 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
996 if (set_debug_regs(t
, bp
->address
, hwbp_num
, DR7_BP_EXECUTE
, 1) != ERROR_OK
)
998 bp
->set
= hwbp_num
+ 1;
999 debug_reg_list
[hwbp_num
].used
= 1;
1000 debug_reg_list
[hwbp_num
].bp_value
= bp
->address
;
1001 LOG_USER("%s hardware breakpoint %" PRIu32
" set at 0x%08" PRIx32
" (hwreg=%" PRIu8
")", __func__
,
1002 bp
->unique_id
, debug_reg_list
[hwbp_num
].bp_value
, hwbp_num
);
1006 static int unset_hwbp(struct target
*t
, struct breakpoint
*bp
)
1008 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1009 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1010 int hwbp_num
= bp
->set
- 1;
1012 if ((hwbp_num
< 0) || (hwbp_num
>= x86_32
->num_hw_bpoints
)) {
1013 LOG_ERROR("%s invalid breakpoint number=%d, bpid=%" PRIu32
,
1014 __func__
, hwbp_num
, bp
->unique_id
);
1018 if (unset_debug_regs(t
, hwbp_num
) != ERROR_OK
)
1020 debug_reg_list
[hwbp_num
].used
= 0;
1021 debug_reg_list
[hwbp_num
].bp_value
= 0;
1023 LOG_USER("%s hardware breakpoint %" PRIu32
" removed from " TARGET_ADDR_FMT
" (hwreg=%d)",
1024 __func__
, bp
->unique_id
, bp
->address
, hwbp_num
);
1028 static int set_swbp(struct target
*t
, struct breakpoint
*bp
)
1030 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1031 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1032 target_addr_t physaddr
;
1033 uint8_t opcode
= SW_BP_OPCODE
;
1036 if (calcaddr_physfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1038 if (read_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1041 LOG_DEBUG("set software breakpoint - orig byte=0x%02" PRIx8
"", *bp
->orig_instr
);
1043 /* just write the instruction trap byte */
1044 if (write_phys_mem(t
, physaddr
, 1, 1, &opcode
))
1047 /* verify that this is not invalid/read-only memory */
1048 if (read_phys_mem(t
, physaddr
, 1, 1, &readback
))
1051 if (readback
!= SW_BP_OPCODE
) {
1052 LOG_ERROR("%s software breakpoint error at " TARGET_ADDR_FMT
", check memory",
1053 __func__
, bp
->address
);
1054 LOG_ERROR("%s readback=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1055 __func__
, readback
, *bp
->orig_instr
);
1058 bp
->set
= SW_BP_OPCODE
; /* just non 0 */
1060 /* add the memory patch */
1061 struct swbp_mem_patch
*new_patch
= malloc(sizeof(struct swbp_mem_patch
));
1062 if (new_patch
== NULL
) {
1063 LOG_ERROR("%s out of memory", __func__
);
1066 new_patch
->next
= NULL
;
1067 new_patch
->orig_byte
= *bp
->orig_instr
;
1068 new_patch
->physaddr
= physaddr
;
1069 new_patch
->swbp_unique_id
= bp
->unique_id
;
1071 struct swbp_mem_patch
*addto
= x86_32
->swbbp_mem_patch_list
;
1073 x86_32
->swbbp_mem_patch_list
= new_patch
;
1075 while (addto
->next
!= NULL
)
1076 addto
= addto
->next
;
1077 addto
->next
= new_patch
;
1079 LOG_USER("%s software breakpoint %" PRIu32
" set at " TARGET_ADDR_FMT
,
1080 __func__
, bp
->unique_id
, bp
->address
);
1084 static int unset_swbp(struct target
*t
, struct breakpoint
*bp
)
1086 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1087 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1088 target_addr_t physaddr
;
1089 uint8_t current_instr
;
1091 /* check that user program has not modified breakpoint instruction */
1092 if (calcaddr_physfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1094 if (read_phys_mem(t
, physaddr
, 1, 1, ¤t_instr
))
1097 if (current_instr
== SW_BP_OPCODE
) {
1098 if (write_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1101 LOG_ERROR("%s software breakpoint remove error at " TARGET_ADDR_FMT
", check memory",
1102 __func__
, bp
->address
);
1103 LOG_ERROR("%s current=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1104 __func__
, current_instr
, *bp
->orig_instr
);
1108 /* remove from patch */
1109 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
1111 if (iter
->swbp_unique_id
== bp
->unique_id
) {
1112 /* it's the first item */
1113 x86_32
->swbbp_mem_patch_list
= iter
->next
;
1116 while (iter
->next
!= NULL
&& iter
->next
->swbp_unique_id
!= bp
->unique_id
)
1118 if (iter
->next
!= NULL
) {
1119 /* it's the next one */
1120 struct swbp_mem_patch
*freeme
= iter
->next
;
1121 iter
->next
= iter
->next
->next
;
1127 LOG_USER("%s software breakpoint %" PRIu32
" removed from " TARGET_ADDR_FMT
,
1128 __func__
, bp
->unique_id
, bp
->address
);
1132 static int set_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1134 int error
= ERROR_OK
;
1135 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1136 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
1138 LOG_ERROR("breakpoint already set");
1141 if (bp
->type
== BKPT_HARD
) {
1142 error
= set_hwbp(t
, bp
);
1143 if (error
!= ERROR_OK
) {
1144 LOG_ERROR("%s error setting hardware breakpoint at " TARGET_ADDR_FMT
,
1145 __func__
, bp
->address
);
1149 if (x86_32
->sw_bpts_supported(t
)) {
1150 error
= set_swbp(t
, bp
);
1151 if (error
!= ERROR_OK
) {
1152 LOG_ERROR("%s error setting software breakpoint at " TARGET_ADDR_FMT
,
1153 __func__
, bp
->address
);
1157 LOG_ERROR("%s core doesn't support SW breakpoints", __func__
);
1164 static int unset_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1166 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
1168 LOG_WARNING("breakpoint not set");
1172 if (bp
->type
== BKPT_HARD
) {
1173 if (unset_hwbp(t
, bp
) != ERROR_OK
) {
1174 LOG_ERROR("%s error removing hardware breakpoint at " TARGET_ADDR_FMT
,
1175 __func__
, bp
->address
);
1179 if (unset_swbp(t
, bp
) != ERROR_OK
) {
1180 LOG_ERROR("%s error removing software breakpoint at " TARGET_ADDR_FMT
,
1181 __func__
, bp
->address
);
1189 static int set_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1191 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1192 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1194 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, wp
->rw
, wp
->address
);
1197 LOG_ERROR("%s watchpoint already set", __func__
);
1201 if (wp
->rw
== WPT_READ
) {
1202 LOG_ERROR("%s no support for 'read' watchpoints, use 'access' or 'write'"
1204 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1207 while (debug_reg_list
[wp_num
].used
&& (wp_num
< x86_32
->num_hw_bpoints
))
1209 if (wp_num
>= x86_32
->num_hw_bpoints
) {
1210 LOG_ERROR("%s no debug registers left", __func__
);
1211 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1214 if (wp
->length
!= 4 && wp
->length
!= 2 && wp
->length
!= 1) {
1215 LOG_ERROR("%s only watchpoints of length 1, 2 or 4 are supported", __func__
);
1216 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1221 if (set_debug_regs(t
, wp
->address
, wp_num
,
1222 DR7_BP_WRITE
, wp
->length
) != ERROR_OK
) {
1227 if (set_debug_regs(t
, wp
->address
, wp_num
, DR7_BP_READWRITE
,
1228 wp
->length
) != ERROR_OK
) {
1233 LOG_ERROR("%s only 'access' or 'write' watchpoints are supported", __func__
);
1236 wp
->set
= wp_num
+ 1;
1237 debug_reg_list
[wp_num
].used
= 1;
1238 debug_reg_list
[wp_num
].bp_value
= wp
->address
;
1239 LOG_USER("'%s' watchpoint %d set at " TARGET_ADDR_FMT
" with length %" PRIu32
" (hwreg=%d)",
1240 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1241 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1242 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1246 static int unset_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1248 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1249 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1250 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, wp
->rw
, wp
->address
);
1252 LOG_WARNING("watchpoint not set");
1256 int wp_num
= wp
->set
- 1;
1257 if ((wp_num
< 0) || (wp_num
>= x86_32
->num_hw_bpoints
)) {
1258 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
1261 if (unset_debug_regs(t
, wp_num
) != ERROR_OK
)
1264 debug_reg_list
[wp_num
].used
= 0;
1265 debug_reg_list
[wp_num
].bp_value
= 0;
1268 LOG_USER("'%s' watchpoint %d removed from " TARGET_ADDR_FMT
" with length %" PRIu32
" (hwreg=%d)",
1269 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1270 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1271 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1276 /* after reset breakpoints and watchpoints in memory are not valid anymore and
1277 * debug registers are cleared.
1278 * we can't afford to remove sw breakpoints using the default methods as the
1279 * memory doesn't have the same layout yet and an access might crash the target,
1280 * so we just clear the openocd breakpoints structures.
1282 void x86_32_common_reset_breakpoints_watchpoints(struct target
*t
)
1284 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1285 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1286 struct breakpoint
*next_b
;
1287 struct watchpoint
*next_w
;
1289 while (t
->breakpoints
) {
1290 next_b
= t
->breakpoints
->next
;
1291 free(t
->breakpoints
->orig_instr
);
1292 free(t
->breakpoints
);
1293 t
->breakpoints
= next_b
;
1296 while (t
->watchpoints
) {
1297 next_w
= t
->watchpoints
->next
;
1298 free(t
->watchpoints
);
1299 t
->watchpoints
= next_w
;
1302 for (int i
= 0; i
< x86_32
->num_hw_bpoints
; i
++) {
1303 debug_reg_list
[i
].used
= 0;
1304 debug_reg_list
[i
].bp_value
= 0;
1308 static int read_hw_reg_to_cache(struct target
*t
, int num
)
1311 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1313 if (check_not_halted(t
))
1314 return ERROR_TARGET_NOT_HALTED
;
1315 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1316 return ERROR_COMMAND_SYNTAX_ERROR
;
1317 if (x86_32
->read_hw_reg(t
, num
, ®_value
, 1) != ERROR_OK
) {
1318 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1321 LOG_DEBUG("reg %s value 0x%08" PRIx32
,
1322 x86_32
->cache
->reg_list
[num
].name
, reg_value
);
1326 static int write_hw_reg_from_cache(struct target
*t
, int num
)
1328 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1329 if (check_not_halted(t
))
1330 return ERROR_TARGET_NOT_HALTED
;
1331 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1332 return ERROR_COMMAND_SYNTAX_ERROR
;
1333 if (x86_32
->write_hw_reg(t
, num
, 0, 1) != ERROR_OK
) {
1334 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1337 LOG_DEBUG("reg %s value 0x%08" PRIx32
, x86_32
->cache
->reg_list
[num
].name
,
1338 buf_get_u32(x86_32
->cache
->reg_list
[num
].value
, 0, 32));
1342 /* x86 32 commands */
1343 static void handle_iod_output(struct command_context
*cmd_ctx
,
1344 struct target
*target
, uint32_t address
, unsigned size
,
1345 unsigned count
, const uint8_t *buffer
)
1347 const unsigned line_bytecnt
= 32;
1348 unsigned line_modulo
= line_bytecnt
/ size
;
1350 char output
[line_bytecnt
* 4 + 1];
1351 unsigned output_len
= 0;
1353 const char *value_fmt
;
1356 value_fmt
= "%8.8x ";
1359 value_fmt
= "%4.4x ";
1362 value_fmt
= "%2.2x ";
1365 /* "can't happen", caller checked */
1366 LOG_ERROR("%s invalid memory read size: %u", __func__
, size
);
1370 for (unsigned i
= 0; i
< count
; i
++) {
1371 if (i
% line_modulo
== 0) {
1372 output_len
+= snprintf(output
+ output_len
,
1373 sizeof(output
) - output_len
,
1375 (unsigned)(address
+ (i
*size
)));
1379 const uint8_t *value_ptr
= buffer
+ i
* size
;
1382 value
= target_buffer_get_u32(target
, value_ptr
);
1385 value
= target_buffer_get_u16(target
, value_ptr
);
1390 output_len
+= snprintf(output
+ output_len
,
1391 sizeof(output
) - output_len
,
1394 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1395 command_print(cmd_ctx
, "%s", output
);
1401 COMMAND_HANDLER(handle_iod_command
)
1404 return ERROR_COMMAND_SYNTAX_ERROR
;
1407 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1408 if (address
> 0xffff) {
1409 LOG_ERROR("%s IA-32 I/O space is 2^16, 0x%08" PRIx32
" exceeds max", __func__
, address
);
1410 return ERROR_COMMAND_SYNTAX_ERROR
;
1414 switch (CMD_NAME
[2]) {
1425 return ERROR_COMMAND_SYNTAX_ERROR
;
1428 uint8_t *buffer
= calloc(count
, size
);
1429 struct target
*target
= get_current_target(CMD_CTX
);
1430 int retval
= x86_32_common_read_io(target
, address
, size
, buffer
);
1431 if (ERROR_OK
== retval
)
1432 handle_iod_output(CMD_CTX
, target
, address
, size
, count
, buffer
);
1437 static int target_fill_io(struct target
*target
,
1443 LOG_DEBUG("address=0x%08" PRIx32
", data_size=%u, b=0x%08" PRIx32
,
1444 address
, data_size
, b
);
1445 uint8_t target_buf
[data_size
];
1446 switch (data_size
) {
1448 target_buffer_set_u32(target
, target_buf
, b
);
1451 target_buffer_set_u16(target
, target_buf
, b
);
1454 target_buf
[0] = (b
& 0x0ff);
1459 return x86_32_common_write_io(target
, address
, data_size
, target_buf
);
1462 COMMAND_HANDLER(handle_iow_command
)
1465 return ERROR_COMMAND_SYNTAX_ERROR
;
1467 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1469 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
1470 struct target
*target
= get_current_target(CMD_CTX
);
1473 switch (CMD_NAME
[2]) {
1484 return ERROR_COMMAND_SYNTAX_ERROR
;
1486 return target_fill_io(target
, address
, wordsize
, value
);
1489 static const struct command_registration x86_32_exec_command_handlers
[] = {
1492 .mode
= COMMAND_EXEC
,
1493 .handler
= handle_iow_command
,
1494 .help
= "write I/O port word",
1495 .usage
= "port data[word]",
1499 .mode
= COMMAND_EXEC
,
1500 .handler
= handle_iow_command
,
1501 .help
= "write I/O port halfword",
1502 .usage
= "port data[halfword]",
1506 .mode
= COMMAND_EXEC
,
1507 .handler
= handle_iow_command
,
1508 .help
= "write I/O port byte",
1509 .usage
= "port data[byte]",
1513 .mode
= COMMAND_EXEC
,
1514 .handler
= handle_iod_command
,
1515 .help
= "display I/O port word",
1520 .mode
= COMMAND_EXEC
,
1521 .handler
= handle_iod_command
,
1522 .help
= "display I/O port halfword",
1527 .mode
= COMMAND_EXEC
,
1528 .handler
= handle_iod_command
,
1529 .help
= "display I/O port byte",
1533 COMMAND_REGISTRATION_DONE
1536 const struct command_registration x86_32_command_handlers
[] = {
1539 .mode
= COMMAND_ANY
,
1540 .help
= "x86_32 target commands",
1542 .chain
= x86_32_exec_command_handlers
,
1544 COMMAND_REGISTRATION_DONE