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__
);
213 /* restore CR0.PG bit if needed (regardless of retval) */
215 retval
= x86_32
->enable_paging(t
);
216 if (retval
!= ERROR_OK
) {
217 LOG_ERROR("%s could not enable paging", __func__
);
222 /* TODO: After reading memory from target, we must replace
223 * software breakpoints with the original instructions again.
224 * Solve this with the breakpoint fix
229 int x86_32_common_write_phys_mem(struct target
*t
, target_addr_t phys_address
,
230 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
232 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
233 int error
= ERROR_OK
;
234 uint8_t *newbuffer
= NULL
;
237 if (!count
|| !buffer
|| !phys_address
) {
238 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
239 __func__
, count
, buffer
, phys_address
);
240 return ERROR_COMMAND_ARGUMENT_INVALID
;
242 /* Before writing memory to target, we must update software breakpoints
243 * with the new instructions and patch the memory buffer with the
244 * breakpoint instruction.
246 newbuffer
= malloc(size
*count
);
247 if (newbuffer
== NULL
) {
248 LOG_ERROR("%s out of memory", __func__
);
251 memcpy(newbuffer
, buffer
, size
*count
);
252 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
253 while (iter
!= NULL
) {
254 if (iter
->physaddr
>= phys_address
&& iter
->physaddr
< phys_address
+(size
*count
)) {
255 uint32_t offset
= iter
->physaddr
- phys_address
;
256 newbuffer
[offset
] = SW_BP_OPCODE
;
258 /* update the breakpoint */
259 struct breakpoint
*pbiter
= t
->breakpoints
;
260 while (pbiter
!= NULL
&& pbiter
->unique_id
!= iter
->swbp_unique_id
)
261 pbiter
= pbiter
->next
;
263 pbiter
->orig_instr
[0] = buffer
[offset
];
268 error
= write_phys_mem(t
, phys_address
, size
, count
, newbuffer
);
273 static int write_phys_mem(struct target
*t
, uint32_t phys_address
,
274 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
276 int retval
= ERROR_OK
;
277 bool pg_disabled
= false;
278 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
279 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
280 phys_address
, size
, count
, buffer
);
283 if (!count
|| !buffer
|| !phys_address
) {
284 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32
,
285 __func__
, count
, buffer
, phys_address
);
286 return ERROR_COMMAND_ARGUMENT_INVALID
;
288 /* TODO: Before writing memory to target, we must update
289 * software breakpoints with the new instructions and
290 * patch the memory buffer with the breakpoint instruction.
291 * Solve this with the breakpoint fix
294 /* to access physical memory, switch off the CR0.PG bit */
295 if (x86_32
->is_paging_enabled(t
)) {
296 retval
= x86_32
->disable_paging(t
);
297 if (retval
!= ERROR_OK
) {
298 LOG_ERROR("%s could not disable paging", __func__
);
303 for (uint32_t i
= 0; i
< count
; i
++) {
306 retval
= write_mem(t
, size
, phys_address
+ i
, buffer
+ i
);
309 retval
= write_mem(t
, size
, phys_address
+ i
* 2, buffer
+ i
* 2);
312 retval
= write_mem(t
, size
, phys_address
+ i
* 4, buffer
+ i
* 4);
315 LOG_DEBUG("invalid read size");
319 /* restore CR0.PG bit if needed (regardless of retval) */
321 retval
= x86_32
->enable_paging(t
);
322 if (retval
!= ERROR_OK
) {
323 LOG_ERROR("%s could not enable paging", __func__
);
330 static int read_mem(struct target
*t
, uint32_t size
,
331 uint32_t addr
, uint8_t *buf
)
333 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
335 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
336 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
337 int retval
= x86_32
->write_hw_reg(t
, EAX
, addr
, 0);
338 if (retval
!= ERROR_OK
) {
339 LOG_ERROR("%s error write EAX", __func__
);
346 retval
= x86_32
->submit_instruction(t
, MEMRDB32
);
348 retval
= x86_32
->submit_instruction(t
, MEMRDB16
);
352 retval
= x86_32
->submit_instruction(t
, MEMRDH32
);
354 retval
= x86_32
->submit_instruction(t
, MEMRDH16
);
358 retval
= x86_32
->submit_instruction(t
, MEMRDW32
);
360 retval
= x86_32
->submit_instruction(t
, MEMRDW16
);
363 LOG_ERROR("%s invalid read mem size", __func__
);
367 /* read_hw_reg() will write to 4 bytes (uint32_t)
368 * Watch out, the buffer passed into read_mem() might be 1 or 2 bytes.
371 retval
= x86_32
->read_hw_reg(t
, EDX
, ®val
, 0);
373 if (retval
!= ERROR_OK
) {
374 LOG_ERROR("%s error read EDX", __func__
);
377 for (uint8_t i
= 0; i
< size
; i
++)
378 buf
[i
] = (regval
>> (i
*8)) & 0x000000FF;
380 retval
= x86_32
->transaction_status(t
);
381 if (retval
!= ERROR_OK
) {
382 LOG_ERROR("%s error on mem read", __func__
);
388 static int write_mem(struct target
*t
, uint32_t size
,
389 uint32_t addr
, const uint8_t *buf
)
392 uint32_t buf4bytes
= 0;
393 int retval
= ERROR_OK
;
394 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
396 for (i
= 0; i
< size
; ++i
) {
397 buf4bytes
= buf4bytes
<< 8; /* first time we only shift 0s */
398 buf4bytes
+= buf
[(size
-1)-i
]; /* it was hard to write, should be hard to read! */
400 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
401 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
402 retval
= x86_32
->write_hw_reg(t
, EAX
, addr
, 0);
403 if (retval
!= ERROR_OK
) {
404 LOG_ERROR("%s error write EAX", __func__
);
408 /* write_hw_reg() will write to 4 bytes (uint32_t)
409 * Watch out, the buffer passed into write_mem() might be 1 or 2 bytes.
411 retval
= x86_32
->write_hw_reg(t
, EDX
, buf4bytes
, 0);
412 if (retval
!= ERROR_OK
) {
413 LOG_ERROR("%s error write EDX", __func__
);
419 retval
= x86_32
->submit_instruction(t
, MEMWRB32
);
421 retval
= x86_32
->submit_instruction(t
, MEMWRB16
);
425 retval
= x86_32
->submit_instruction(t
, MEMWRH32
);
427 retval
= x86_32
->submit_instruction(t
, MEMWRH16
);
431 retval
= x86_32
->submit_instruction(t
, MEMWRW32
);
433 retval
= x86_32
->submit_instruction(t
, MEMWRW16
);
436 LOG_ERROR("%s invalid write mem size", __func__
);
439 retval
= x86_32
->transaction_status(t
);
440 if (retval
!= ERROR_OK
) {
441 LOG_ERROR("%s error on mem write", __func__
);
447 int calcaddr_physfromlin(struct target
*t
, target_addr_t addr
, target_addr_t
*physaddr
)
449 uint8_t entry_buffer
[8];
451 if (physaddr
== NULL
|| t
== NULL
)
454 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
456 /* The 'user-visible' CR0.PG should be set - otherwise the function shouldn't be called
457 * (Don't check the CR0.PG on the target, this might be temporally disabled at this point)
459 uint32_t cr0
= buf_get_u32(x86_32
->cache
->reg_list
[CR0
].value
, 0, 32);
460 if (!(cr0
& CR0_PG
)) {
461 /* you are wrong in this function, never mind */
466 uint32_t cr4
= buf_get_u32(x86_32
->cache
->reg_list
[CR4
].value
, 0, 32);
467 bool isPAE
= cr4
& 0x00000020; /* PAE - Physical Address Extension */
469 uint32_t cr3
= buf_get_u32(x86_32
->cache
->reg_list
[CR3
].value
, 0, 32);
471 uint32_t pdpt_base
= cr3
& 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */
472 uint32_t pdpt_index
= (addr
& 0xC0000000) >> 30; /* A[31:30] index to PDPT */
473 uint32_t pdpt_addr
= pdpt_base
+ (8 * pdpt_index
);
474 if (x86_32_common_read_phys_mem(t
, pdpt_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
475 LOG_ERROR("%s couldn't read page directory pointer table entry at 0x%08" PRIx32
,
476 __func__
, pdpt_addr
);
479 uint64_t pdpt_entry
= target_buffer_get_u64(t
, entry_buffer
);
480 if (!(pdpt_entry
& 0x0000000000000001)) {
481 LOG_ERROR("%s page directory pointer table entry at 0x%08" PRIx32
" is not present",
482 __func__
, pdpt_addr
);
486 uint32_t pd_base
= pdpt_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
487 uint32_t pd_index
= (addr
& 0x3FE00000) >> 21; /* A[29:21] index to PD entry with PAE */
488 uint32_t pd_addr
= pd_base
+ (8 * pd_index
);
489 if (x86_32_common_read_phys_mem(t
, pd_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
490 LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32
,
494 uint64_t pd_entry
= target_buffer_get_u64(t
, entry_buffer
);
495 if (!(pd_entry
& 0x0000000000000001)) {
496 LOG_ERROR("%s page directory entry at 0x%08" PRIx32
" is not present",
501 /* PS bit in PD entry is indicating 4KB or 2MB page size */
502 if (pd_entry
& 0x0000000000000080) {
504 uint32_t page_base
= (uint32_t)(pd_entry
& 0x00000000FFE00000); /* [31:21] */
505 uint32_t offset
= addr
& 0x001FFFFF; /* [20:0] */
506 *physaddr
= page_base
+ offset
;
511 uint32_t pt_base
= (uint32_t)(pd_entry
& 0x00000000FFFFF000); /*[31:12]*/
512 uint32_t pt_index
= (addr
& 0x001FF000) >> 12; /*[20:12]*/
513 uint32_t pt_addr
= pt_base
+ (8 * pt_index
);
514 if (x86_32_common_read_phys_mem(t
, pt_addr
, 4, 2, entry_buffer
) != ERROR_OK
) {
515 LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32
, __func__
, pt_addr
);
518 uint64_t pt_entry
= target_buffer_get_u64(t
, entry_buffer
);
519 if (!(pt_entry
& 0x0000000000000001)) {
520 LOG_ERROR("%s page table entry at 0x%08" PRIx32
" is not present", __func__
, pt_addr
);
524 uint32_t page_base
= (uint32_t)(pt_entry
& 0x00000000FFFFF000); /*[31:12]*/
525 uint32_t offset
= addr
& 0x00000FFF; /*[11:0]*/
526 *physaddr
= page_base
+ offset
;
530 uint32_t pd_base
= cr3
& 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */
531 uint32_t pd_index
= (addr
& 0xFFC00000) >> 22; /* A[31:22] index to PD entry */
532 uint32_t pd_addr
= pd_base
+ (4 * pd_index
);
533 if (x86_32_common_read_phys_mem(t
, pd_addr
, 4, 1, entry_buffer
) != ERROR_OK
) {
534 LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32
, __func__
, pd_addr
);
537 uint32_t pd_entry
= target_buffer_get_u32(t
, entry_buffer
);
538 if (!(pd_entry
& 0x00000001)) {
539 LOG_ERROR("%s page directory entry at 0x%08" PRIx32
" is not present", __func__
, pd_addr
);
543 /* Bit 7 in page directory entry is page size.
545 if (pd_entry
& 0x00000080) {
547 uint32_t page_base
= pd_entry
& 0xFFC00000;
548 *physaddr
= page_base
+ (addr
& 0x003FFFFF);
552 uint32_t pt_base
= pd_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
553 uint32_t pt_index
= (addr
& 0x003FF000) >> 12; /* A[21:12] index to page table entry */
554 uint32_t pt_addr
= pt_base
+ (4 * pt_index
);
555 if (x86_32_common_read_phys_mem(t
, pt_addr
, 4, 1, entry_buffer
) != ERROR_OK
) {
556 LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32
, __func__
, pt_addr
);
559 uint32_t pt_entry
= target_buffer_get_u32(t
, entry_buffer
);
560 if (!(pt_entry
& 0x00000001)) {
561 LOG_ERROR("%s page table entry at 0x%08" PRIx32
" is not present", __func__
, pt_addr
);
564 uint32_t page_base
= pt_entry
& 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */
565 *physaddr
= page_base
+ (addr
& 0x00000FFF); /* A[11:0] offset to 4KB page in linear address */
571 int x86_32_common_read_memory(struct target
*t
, target_addr_t addr
,
572 uint32_t size
, uint32_t count
, uint8_t *buf
)
574 int retval
= ERROR_OK
;
575 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
576 LOG_DEBUG("addr=" TARGET_ADDR_FMT
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
577 addr
, size
, count
, buf
);
579 if (!count
|| !buf
|| !addr
) {
580 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
581 __func__
, count
, buf
, addr
);
582 return ERROR_COMMAND_ARGUMENT_INVALID
;
585 if (x86_32
->is_paging_enabled(t
)) {
586 /* all memory accesses from debugger must be physical (CR0.PG == 0)
587 * conversion to physical address space needed
589 retval
= x86_32
->disable_paging(t
);
590 if (retval
!= ERROR_OK
) {
591 LOG_ERROR("%s could not disable paging", __func__
);
594 target_addr_t physaddr
= 0;
595 if (calcaddr_physfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
596 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
600 /* TODO: !!! Watch out for page boundaries
601 * for every 4kB, the physical address has to be re-calculated
602 * This should be fixed together with bulk memory reads
605 if (retval
== ERROR_OK
606 && x86_32_common_read_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
607 LOG_ERROR("%s failed to read memory from physical address " TARGET_ADDR_FMT
,
611 /* restore PG bit if it was cleared prior (regardless of retval) */
612 retval
= x86_32
->enable_paging(t
);
613 if (retval
!= ERROR_OK
) {
614 LOG_ERROR("%s could not enable paging", __func__
);
618 /* paging is off - linear address is physical address */
619 if (x86_32_common_read_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
620 LOG_ERROR("%s failed to read memory from address " TARGET_ADDR_FMT
,
629 int x86_32_common_write_memory(struct target
*t
, target_addr_t addr
,
630 uint32_t size
, uint32_t count
, const uint8_t *buf
)
632 int retval
= ERROR_OK
;
633 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
634 LOG_DEBUG("addr=" TARGET_ADDR_FMT
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
635 addr
, size
, count
, buf
);
637 if (!count
|| !buf
|| !addr
) {
638 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=" TARGET_ADDR_FMT
,
639 __func__
, count
, buf
, addr
);
640 return ERROR_COMMAND_ARGUMENT_INVALID
;
642 if (x86_32
->is_paging_enabled(t
)) {
643 /* all memory accesses from debugger must be physical (CR0.PG == 0)
644 * conversion to physical address space needed
646 retval
= x86_32
->disable_paging(t
);
647 if (retval
!= ERROR_OK
) {
648 LOG_ERROR("%s could not disable paging", __func__
);
651 target_addr_t physaddr
= 0;
652 if (calcaddr_physfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
653 LOG_ERROR("%s failed to calculate physical address from " TARGET_ADDR_FMT
,
657 /* TODO: !!! Watch out for page boundaries
658 * for every 4kB, the physical address has to be re-calculated
659 * This should be fixed together with bulk memory reads
661 if (retval
== ERROR_OK
662 && x86_32_common_write_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
663 LOG_ERROR("%s failed to write memory to physical address " TARGET_ADDR_FMT
,
667 /* restore PG bit if it was cleared prior (regardless of retval) */
668 retval
= x86_32
->enable_paging(t
);
669 if (retval
!= ERROR_OK
) {
670 LOG_ERROR("%s could not enable paging", __func__
);
675 /* paging is off - linear address is physical address */
676 if (x86_32_common_write_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
677 LOG_ERROR("%s failed to write memory to address " TARGET_ADDR_FMT
,
685 int x86_32_common_read_io(struct target
*t
, uint32_t addr
,
686 uint32_t size
, uint8_t *buf
)
688 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
689 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
690 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
691 int retval
= ERROR_FAIL
;
692 bool pg_disabled
= false;
693 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
696 LOG_ERROR("%s invalid params buf=%p, addr=%08" PRIx32
, __func__
, buf
, addr
);
699 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
700 if (retval
!= ERROR_OK
) {
701 LOG_ERROR("%s error EDX write", __func__
);
704 /* to access physical memory, switch off the CR0.PG bit */
705 if (x86_32
->is_paging_enabled(t
)) {
706 retval
= x86_32
->disable_paging(t
);
707 if (retval
!= ERROR_OK
) {
708 LOG_ERROR("%s could not disable paging", __func__
);
716 retval
= x86_32
->submit_instruction(t
, IORDB32
);
718 retval
= x86_32
->submit_instruction(t
, IORDB16
);
722 retval
= x86_32
->submit_instruction(t
, IORDH32
);
724 retval
= x86_32
->submit_instruction(t
, IORDH16
);
728 retval
= x86_32
->submit_instruction(t
, IORDW32
);
730 retval
= x86_32
->submit_instruction(t
, IORDW16
);
733 LOG_ERROR("%s invalid read io size", __func__
);
736 /* restore CR0.PG bit if needed */
738 retval
= x86_32
->enable_paging(t
);
739 if (retval
!= ERROR_OK
) {
740 LOG_ERROR("%s could not enable paging", __func__
);
746 retval
= x86_32
->read_hw_reg(t
, EAX
, ®val
, 0);
747 if (retval
!= ERROR_OK
) {
748 LOG_ERROR("%s error on read EAX", __func__
);
751 for (uint8_t i
= 0; i
< size
; i
++)
752 buf
[i
] = (regval
>> (i
*8)) & 0x000000FF;
753 retval
= x86_32
->transaction_status(t
);
754 if (retval
!= ERROR_OK
) {
755 LOG_ERROR("%s error on io read", __func__
);
761 int x86_32_common_write_io(struct target
*t
, uint32_t addr
,
762 uint32_t size
, const uint8_t *buf
)
764 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
765 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
766 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
767 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
769 int retval
= ERROR_FAIL
;
770 bool pg_disabled
= false;
772 LOG_ERROR("%s invalid params buf=%p, addr=0x%08" PRIx32
, __func__
, buf
, addr
);
775 /* no do the write */
776 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
777 if (retval
!= ERROR_OK
) {
778 LOG_ERROR("%s error on EDX write", __func__
);
782 for (uint8_t i
= 0; i
< size
; i
++)
783 regval
+= (buf
[i
] << (i
*8));
784 retval
= x86_32
->write_hw_reg(t
, EAX
, regval
, 0);
785 if (retval
!= ERROR_OK
) {
786 LOG_ERROR("%s error on EAX write", __func__
);
789 /* to access physical memory, switch off the CR0.PG bit */
790 if (x86_32
->is_paging_enabled(t
)) {
791 retval
= x86_32
->disable_paging(t
);
792 if (retval
!= ERROR_OK
) {
793 LOG_ERROR("%s could not disable paging", __func__
);
801 retval
= x86_32
->submit_instruction(t
, IOWRB32
);
803 retval
= x86_32
->submit_instruction(t
, IOWRB16
);
807 retval
= x86_32
->submit_instruction(t
, IOWRH32
);
809 retval
= x86_32
->submit_instruction(t
, IOWRH16
);
813 retval
= x86_32
->submit_instruction(t
, IOWRW32
);
815 retval
= x86_32
->submit_instruction(t
, IOWRW16
);
818 LOG_ERROR("%s invalid write io size", __func__
);
821 /* restore CR0.PG bit if needed */
823 retval
= x86_32
->enable_paging(t
);
824 if (retval
!= ERROR_OK
) {
825 LOG_ERROR("%s could not enable paging", __func__
);
830 retval
= x86_32
->transaction_status(t
);
831 if (retval
!= ERROR_OK
) {
832 LOG_ERROR("%s error on io write", __func__
);
838 int x86_32_common_add_watchpoint(struct target
*t
, struct watchpoint
*wp
)
841 /* set_watchpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
842 * hardware registers are gone
844 return set_watchpoint(t
, wp
);
847 int x86_32_common_remove_watchpoint(struct target
*t
, struct watchpoint
*wp
)
849 if (check_not_halted(t
))
850 return ERROR_TARGET_NOT_HALTED
;
852 unset_watchpoint(t
, wp
);
856 int x86_32_common_add_breakpoint(struct target
*t
, struct breakpoint
*bp
)
858 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
859 if (check_not_halted(t
))
860 return ERROR_TARGET_NOT_HALTED
;
861 /* set_breakpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
862 * hardware registers are gone (for hardware breakpoints)
864 return set_breakpoint(t
, bp
);
867 int x86_32_common_remove_breakpoint(struct target
*t
, struct breakpoint
*bp
)
869 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
870 if (check_not_halted(t
))
871 return ERROR_TARGET_NOT_HALTED
;
873 unset_breakpoint(t
, bp
);
878 static int set_debug_regs(struct target
*t
, uint32_t address
,
879 uint8_t bp_num
, uint8_t bp_type
, uint8_t bp_length
)
881 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
882 LOG_DEBUG("addr=0x%08" PRIx32
", bp_num=%" PRIu8
", bp_type=%" PRIu8
", pb_length=%" PRIu8
,
883 address
, bp_num
, bp_type
, bp_length
);
885 /* DR7 - set global enable */
886 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
888 if (bp_length
!= 1 && bp_length
!= 2 && bp_length
!= 4)
891 if (DR7_BP_FREE(dr7
, bp_num
))
892 DR7_GLOBAL_ENABLE(dr7
, bp_num
);
894 LOG_ERROR("%s dr7 error, already enabled, val=%08" PRIx32
, __func__
, dr7
);
895 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
900 /* 00 - only on instruction execution */
901 DR7_SET_EXE(dr7
, bp_num
);
902 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
905 /* 01 - only on data writes */
906 DR7_SET_WRITE(dr7
, bp_num
);
907 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
910 /* 10 UNSUPPORTED - an I/O read and I/O write */
911 LOG_ERROR("%s unsupported feature bp_type=%d", __func__
, bp_type
);
915 /* on data read or data write */
916 DR7_SET_ACCESS(dr7
, bp_num
);
917 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
920 LOG_ERROR("%s invalid request [only 0-3] bp_type=%d", __func__
, bp_type
);
924 /* update regs in the reg cache ready to be written to hardware
927 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, address
);
928 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= 1;
929 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= 1;
930 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
931 x86_32
->cache
->reg_list
[DR6
].dirty
= 1;
932 x86_32
->cache
->reg_list
[DR6
].valid
= 1;
933 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
934 x86_32
->cache
->reg_list
[DR7
].dirty
= 1;
935 x86_32
->cache
->reg_list
[DR7
].valid
= 1;
939 static int unset_debug_regs(struct target
*t
, uint8_t bp_num
)
941 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
942 LOG_DEBUG("bp_num=%" PRIu8
, bp_num
);
944 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
946 if (!(DR7_BP_FREE(dr7
, bp_num
))) {
947 DR7_GLOBAL_DISABLE(dr7
, bp_num
);
949 LOG_ERROR("%s dr7 error, not enabled, val=0x%08" PRIx32
, __func__
, dr7
);
950 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
952 /* this will clear rw and len bits */
953 DR7_RESET_RWLEN_BITS(dr7
, bp_num
);
955 /* update regs in the reg cache ready to be written to hardware
958 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, 0);
959 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= 1;
960 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= 1;
961 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
962 x86_32
->cache
->reg_list
[DR6
].dirty
= 1;
963 x86_32
->cache
->reg_list
[DR6
].valid
= 1;
964 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
965 x86_32
->cache
->reg_list
[DR7
].dirty
= 1;
966 x86_32
->cache
->reg_list
[DR7
].valid
= 1;
970 static int set_hwbp(struct target
*t
, struct breakpoint
*bp
)
972 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
973 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
974 uint8_t hwbp_num
= 0;
976 while (debug_reg_list
[hwbp_num
].used
&& (hwbp_num
< x86_32
->num_hw_bpoints
))
978 if (hwbp_num
>= x86_32
->num_hw_bpoints
) {
979 LOG_ERROR("%s no free hw breakpoint bpid=0x%" PRIx32
, __func__
, bp
->unique_id
);
980 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
982 if (set_debug_regs(t
, bp
->address
, hwbp_num
, DR7_BP_EXECUTE
, 1) != ERROR_OK
)
984 bp
->set
= hwbp_num
+ 1;
985 debug_reg_list
[hwbp_num
].used
= 1;
986 debug_reg_list
[hwbp_num
].bp_value
= bp
->address
;
987 LOG_USER("%s hardware breakpoint %" PRIu32
" set at 0x%08" PRIx32
" (hwreg=%" PRIu8
")", __func__
,
988 bp
->unique_id
, debug_reg_list
[hwbp_num
].bp_value
, hwbp_num
);
992 static int unset_hwbp(struct target
*t
, struct breakpoint
*bp
)
994 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
995 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
996 int hwbp_num
= bp
->set
- 1;
998 if ((hwbp_num
< 0) || (hwbp_num
>= x86_32
->num_hw_bpoints
)) {
999 LOG_ERROR("%s invalid breakpoint number=%d, bpid=%" PRIu32
,
1000 __func__
, hwbp_num
, bp
->unique_id
);
1004 if (unset_debug_regs(t
, hwbp_num
) != ERROR_OK
)
1006 debug_reg_list
[hwbp_num
].used
= 0;
1007 debug_reg_list
[hwbp_num
].bp_value
= 0;
1009 LOG_USER("%s hardware breakpoint %" PRIu32
" removed from " TARGET_ADDR_FMT
" (hwreg=%d)",
1010 __func__
, bp
->unique_id
, bp
->address
, hwbp_num
);
1014 static int set_swbp(struct target
*t
, struct breakpoint
*bp
)
1016 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1017 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1018 target_addr_t physaddr
;
1019 uint8_t opcode
= SW_BP_OPCODE
;
1022 if (calcaddr_physfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1024 if (read_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1027 LOG_DEBUG("set software breakpoint - orig byte=0x%02" PRIx8
"", *bp
->orig_instr
);
1029 /* just write the instruction trap byte */
1030 if (write_phys_mem(t
, physaddr
, 1, 1, &opcode
))
1033 /* verify that this is not invalid/read-only memory */
1034 if (read_phys_mem(t
, physaddr
, 1, 1, &readback
))
1037 if (readback
!= SW_BP_OPCODE
) {
1038 LOG_ERROR("%s software breakpoint error at " TARGET_ADDR_FMT
", check memory",
1039 __func__
, bp
->address
);
1040 LOG_ERROR("%s readback=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1041 __func__
, readback
, *bp
->orig_instr
);
1044 bp
->set
= SW_BP_OPCODE
; /* just non 0 */
1046 /* add the memory patch */
1047 struct swbp_mem_patch
*new_patch
= malloc(sizeof(struct swbp_mem_patch
));
1048 if (new_patch
== NULL
) {
1049 LOG_ERROR("%s out of memory", __func__
);
1052 new_patch
->next
= NULL
;
1053 new_patch
->orig_byte
= *bp
->orig_instr
;
1054 new_patch
->physaddr
= physaddr
;
1055 new_patch
->swbp_unique_id
= bp
->unique_id
;
1057 struct swbp_mem_patch
*addto
= x86_32
->swbbp_mem_patch_list
;
1059 x86_32
->swbbp_mem_patch_list
= new_patch
;
1061 while (addto
->next
!= NULL
)
1062 addto
= addto
->next
;
1063 addto
->next
= new_patch
;
1065 LOG_USER("%s software breakpoint %" PRIu32
" set at " TARGET_ADDR_FMT
,
1066 __func__
, bp
->unique_id
, bp
->address
);
1070 static int unset_swbp(struct target
*t
, struct breakpoint
*bp
)
1072 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1073 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1074 target_addr_t physaddr
;
1075 uint8_t current_instr
;
1077 /* check that user program has not modified breakpoint instruction */
1078 if (calcaddr_physfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1080 if (read_phys_mem(t
, physaddr
, 1, 1, ¤t_instr
))
1083 if (current_instr
== SW_BP_OPCODE
) {
1084 if (write_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1087 LOG_ERROR("%s software breakpoint remove error at " TARGET_ADDR_FMT
", check memory",
1088 __func__
, bp
->address
);
1089 LOG_ERROR("%s current=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1090 __func__
, current_instr
, *bp
->orig_instr
);
1094 /* remove from patch */
1095 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
1097 if (iter
->swbp_unique_id
== bp
->unique_id
) {
1098 /* it's the first item */
1099 x86_32
->swbbp_mem_patch_list
= iter
->next
;
1102 while (iter
->next
!= NULL
&& iter
->next
->swbp_unique_id
!= bp
->unique_id
)
1104 if (iter
->next
!= NULL
) {
1105 /* it's the next one */
1106 struct swbp_mem_patch
*freeme
= iter
->next
;
1107 iter
->next
= iter
->next
->next
;
1113 LOG_USER("%s software breakpoint %" PRIu32
" removed from " TARGET_ADDR_FMT
,
1114 __func__
, bp
->unique_id
, bp
->address
);
1118 static int set_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1120 int error
= ERROR_OK
;
1121 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1122 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
1124 LOG_ERROR("breakpoint already set");
1127 if (bp
->type
== BKPT_HARD
) {
1128 error
= set_hwbp(t
, bp
);
1129 if (error
!= ERROR_OK
) {
1130 LOG_ERROR("%s error setting hardware breakpoint at " TARGET_ADDR_FMT
,
1131 __func__
, bp
->address
);
1135 if (x86_32
->sw_bpts_supported(t
)) {
1136 error
= set_swbp(t
, bp
);
1137 if (error
!= ERROR_OK
) {
1138 LOG_ERROR("%s error setting software breakpoint at " TARGET_ADDR_FMT
,
1139 __func__
, bp
->address
);
1143 LOG_ERROR("%s core doesn't support SW breakpoints", __func__
);
1151 static int unset_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1153 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, bp
->type
, bp
->address
);
1155 LOG_WARNING("breakpoint not set");
1159 if (bp
->type
== BKPT_HARD
) {
1160 if (unset_hwbp(t
, bp
) != ERROR_OK
) {
1161 LOG_ERROR("%s error removing hardware breakpoint at " TARGET_ADDR_FMT
,
1162 __func__
, bp
->address
);
1166 if (unset_swbp(t
, bp
) != ERROR_OK
) {
1167 LOG_ERROR("%s error removing software breakpoint at " TARGET_ADDR_FMT
,
1168 __func__
, bp
->address
);
1176 static int set_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1178 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1179 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1181 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, wp
->rw
, wp
->address
);
1184 LOG_ERROR("%s watchpoint already set", __func__
);
1188 if (wp
->rw
== WPT_READ
) {
1189 LOG_ERROR("%s no support for 'read' watchpoints, use 'access' or 'write'"
1191 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1194 while (debug_reg_list
[wp_num
].used
&& (wp_num
< x86_32
->num_hw_bpoints
))
1196 if (wp_num
>= x86_32
->num_hw_bpoints
) {
1197 LOG_ERROR("%s no debug registers left", __func__
);
1198 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1201 if (wp
->length
!= 4 && wp
->length
!= 2 && wp
->length
!= 1) {
1202 LOG_ERROR("%s only watchpoints of length 1, 2 or 4 are supported", __func__
);
1203 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1208 if (set_debug_regs(t
, wp
->address
, wp_num
,
1209 DR7_BP_WRITE
, wp
->length
) != ERROR_OK
) {
1214 if (set_debug_regs(t
, wp
->address
, wp_num
, DR7_BP_READWRITE
,
1215 wp
->length
) != ERROR_OK
) {
1220 LOG_ERROR("%s only 'access' or 'write' watchpoints are supported", __func__
);
1223 wp
->set
= wp_num
+ 1;
1224 debug_reg_list
[wp_num
].used
= 1;
1225 debug_reg_list
[wp_num
].bp_value
= wp
->address
;
1226 LOG_USER("'%s' watchpoint %d set at " TARGET_ADDR_FMT
" with length %" PRIu32
" (hwreg=%d)",
1227 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1228 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1229 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1233 static int unset_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1235 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1236 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1237 LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT
, wp
->rw
, wp
->address
);
1239 LOG_WARNING("watchpoint not set");
1243 int wp_num
= wp
->set
- 1;
1244 if ((wp_num
< 0) || (wp_num
>= x86_32
->num_hw_bpoints
)) {
1245 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
1248 if (unset_debug_regs(t
, wp_num
) != ERROR_OK
)
1251 debug_reg_list
[wp_num
].used
= 0;
1252 debug_reg_list
[wp_num
].bp_value
= 0;
1255 LOG_USER("'%s' watchpoint %d removed from " TARGET_ADDR_FMT
" with length %" PRIu32
" (hwreg=%d)",
1256 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1257 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1258 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1263 /* after reset breakpoints and watchpoints in memory are not valid anymore and
1264 * debug registers are cleared.
1265 * we can't afford to remove sw breakpoints using the default methods as the
1266 * memory doesn't have the same layout yet and an access might crash the target,
1267 * so we just clear the openocd breakpoints structures.
1269 void x86_32_common_reset_breakpoints_watchpoints(struct target
*t
)
1271 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1272 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1273 struct breakpoint
*next_b
;
1274 struct watchpoint
*next_w
;
1276 while (t
->breakpoints
) {
1277 next_b
= t
->breakpoints
->next
;
1278 free(t
->breakpoints
->orig_instr
);
1279 free(t
->breakpoints
);
1280 t
->breakpoints
= next_b
;
1283 while (t
->watchpoints
) {
1284 next_w
= t
->watchpoints
->next
;
1285 free(t
->watchpoints
);
1286 t
->watchpoints
= next_w
;
1289 for (int i
= 0; i
< x86_32
->num_hw_bpoints
; i
++) {
1290 debug_reg_list
[i
].used
= 0;
1291 debug_reg_list
[i
].bp_value
= 0;
1295 static int read_hw_reg_to_cache(struct target
*t
, int num
)
1298 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1300 if (check_not_halted(t
))
1301 return ERROR_TARGET_NOT_HALTED
;
1302 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1303 return ERROR_COMMAND_SYNTAX_ERROR
;
1304 if (x86_32
->read_hw_reg(t
, num
, ®_value
, 1) != ERROR_OK
) {
1305 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1308 LOG_DEBUG("reg %s value 0x%08" PRIx32
,
1309 x86_32
->cache
->reg_list
[num
].name
, reg_value
);
1313 static int write_hw_reg_from_cache(struct target
*t
, int num
)
1315 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1316 if (check_not_halted(t
))
1317 return ERROR_TARGET_NOT_HALTED
;
1318 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1319 return ERROR_COMMAND_SYNTAX_ERROR
;
1320 if (x86_32
->write_hw_reg(t
, num
, 0, 1) != ERROR_OK
) {
1321 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1324 LOG_DEBUG("reg %s value 0x%08" PRIx32
, x86_32
->cache
->reg_list
[num
].name
,
1325 buf_get_u32(x86_32
->cache
->reg_list
[num
].value
, 0, 32));
1329 /* x86 32 commands */
1330 static void handle_iod_output(struct command_context
*cmd_ctx
,
1331 struct target
*target
, uint32_t address
, unsigned size
,
1332 unsigned count
, const uint8_t *buffer
)
1334 const unsigned line_bytecnt
= 32;
1335 unsigned line_modulo
= line_bytecnt
/ size
;
1337 char output
[line_bytecnt
* 4 + 1];
1338 unsigned output_len
= 0;
1340 const char *value_fmt
;
1343 value_fmt
= "%8.8x ";
1346 value_fmt
= "%4.4x ";
1349 value_fmt
= "%2.2x ";
1352 /* "can't happen", caller checked */
1353 LOG_ERROR("%s invalid memory read size: %u", __func__
, size
);
1357 for (unsigned i
= 0; i
< count
; i
++) {
1358 if (i
% line_modulo
== 0) {
1359 output_len
+= snprintf(output
+ output_len
,
1360 sizeof(output
) - output_len
,
1362 (unsigned)(address
+ (i
*size
)));
1366 const uint8_t *value_ptr
= buffer
+ i
* size
;
1369 value
= target_buffer_get_u32(target
, value_ptr
);
1372 value
= target_buffer_get_u16(target
, value_ptr
);
1377 output_len
+= snprintf(output
+ output_len
,
1378 sizeof(output
) - output_len
,
1381 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1382 command_print(cmd_ctx
, "%s", output
);
1388 COMMAND_HANDLER(handle_iod_command
)
1391 return ERROR_COMMAND_SYNTAX_ERROR
;
1394 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1395 if (address
> 0xffff) {
1396 LOG_ERROR("%s IA-32 I/O space is 2^16, 0x%08" PRIx32
" exceeds max", __func__
, address
);
1397 return ERROR_COMMAND_SYNTAX_ERROR
;
1401 switch (CMD_NAME
[2]) {
1412 return ERROR_COMMAND_SYNTAX_ERROR
;
1415 uint8_t *buffer
= calloc(count
, size
);
1416 struct target
*target
= get_current_target(CMD_CTX
);
1417 int retval
= x86_32_common_read_io(target
, address
, size
, buffer
);
1418 if (ERROR_OK
== retval
)
1419 handle_iod_output(CMD_CTX
, target
, address
, size
, count
, buffer
);
1424 static int target_fill_io(struct target
*target
,
1430 LOG_DEBUG("address=0x%08" PRIx32
", data_size=%u, b=0x%08" PRIx32
,
1431 address
, data_size
, b
);
1432 uint8_t target_buf
[data_size
];
1433 switch (data_size
) {
1435 target_buffer_set_u32(target
, target_buf
, b
);
1438 target_buffer_set_u16(target
, target_buf
, b
);
1441 target_buf
[0] = (b
& 0x0ff);
1446 return x86_32_common_write_io(target
, address
, data_size
, target_buf
);
1449 COMMAND_HANDLER(handle_iow_command
)
1452 return ERROR_COMMAND_SYNTAX_ERROR
;
1454 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1456 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
1457 struct target
*target
= get_current_target(CMD_CTX
);
1460 switch (CMD_NAME
[2]) {
1471 return ERROR_COMMAND_SYNTAX_ERROR
;
1473 return target_fill_io(target
, address
, wordsize
, value
);
1476 static const struct command_registration x86_32_exec_command_handlers
[] = {
1479 .mode
= COMMAND_EXEC
,
1480 .handler
= handle_iow_command
,
1481 .help
= "write I/O port word",
1482 .usage
= "port data[word]",
1486 .mode
= COMMAND_EXEC
,
1487 .handler
= handle_iow_command
,
1488 .help
= "write I/O port halfword",
1489 .usage
= "port data[halfword]",
1493 .mode
= COMMAND_EXEC
,
1494 .handler
= handle_iow_command
,
1495 .help
= "write I/O port byte",
1496 .usage
= "port data[byte]",
1500 .mode
= COMMAND_EXEC
,
1501 .handler
= handle_iod_command
,
1502 .help
= "display I/O port word",
1507 .mode
= COMMAND_EXEC
,
1508 .handler
= handle_iod_command
,
1509 .help
= "display I/O port halfword",
1514 .mode
= COMMAND_EXEC
,
1515 .handler
= handle_iod_command
,
1516 .help
= "display I/O port byte",
1520 COMMAND_REGISTRATION_DONE
1523 const struct command_registration x86_32_command_handlers
[] = {
1526 .mode
= COMMAND_ANY
,
1527 .help
= "x86_32 target commands",
1529 .chain
= x86_32_exec_command_handlers
,
1531 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)