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 static int read_hw_reg_to_cache(struct target
*t
, int num
)
1266 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1268 if (check_not_halted(t
))
1269 return ERROR_TARGET_NOT_HALTED
;
1270 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1271 return ERROR_COMMAND_SYNTAX_ERROR
;
1272 if (x86_32
->read_hw_reg(t
, num
, ®_value
, 1) != ERROR_OK
) {
1273 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1276 LOG_DEBUG("reg %s value 0x%08" PRIx32
,
1277 x86_32
->cache
->reg_list
[num
].name
, reg_value
);
1281 static int write_hw_reg_from_cache(struct target
*t
, int num
)
1283 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1284 if (check_not_halted(t
))
1285 return ERROR_TARGET_NOT_HALTED
;
1286 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1287 return ERROR_COMMAND_SYNTAX_ERROR
;
1288 if (x86_32
->write_hw_reg(t
, num
, 0, 1) != ERROR_OK
) {
1289 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1292 LOG_DEBUG("reg %s value 0x%08" PRIx32
, x86_32
->cache
->reg_list
[num
].name
,
1293 buf_get_u32(x86_32
->cache
->reg_list
[num
].value
, 0, 32));
1297 /* x86 32 commands */
1298 static void handle_iod_output(struct command_context
*cmd_ctx
,
1299 struct target
*target
, uint32_t address
, unsigned size
,
1300 unsigned count
, const uint8_t *buffer
)
1302 const unsigned line_bytecnt
= 32;
1303 unsigned line_modulo
= line_bytecnt
/ size
;
1305 char output
[line_bytecnt
* 4 + 1];
1306 unsigned output_len
= 0;
1308 const char *value_fmt
;
1311 value_fmt
= "%8.8x ";
1314 value_fmt
= "%4.4x ";
1317 value_fmt
= "%2.2x ";
1320 /* "can't happen", caller checked */
1321 LOG_ERROR("%s invalid memory read size: %u", __func__
, size
);
1325 for (unsigned i
= 0; i
< count
; i
++) {
1326 if (i
% line_modulo
== 0) {
1327 output_len
+= snprintf(output
+ output_len
,
1328 sizeof(output
) - output_len
,
1330 (unsigned)(address
+ (i
*size
)));
1334 const uint8_t *value_ptr
= buffer
+ i
* size
;
1337 value
= target_buffer_get_u32(target
, value_ptr
);
1340 value
= target_buffer_get_u16(target
, value_ptr
);
1345 output_len
+= snprintf(output
+ output_len
,
1346 sizeof(output
) - output_len
,
1349 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1350 command_print(cmd_ctx
, "%s", output
);
1356 COMMAND_HANDLER(handle_iod_command
)
1359 return ERROR_COMMAND_SYNTAX_ERROR
;
1362 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1363 if (address
> 0xffff) {
1364 LOG_ERROR("%s IA-32 I/O space is 2^16, 0x%08" PRIx32
" exceeds max", __func__
, address
);
1365 return ERROR_COMMAND_SYNTAX_ERROR
;
1369 switch (CMD_NAME
[2]) {
1380 return ERROR_COMMAND_SYNTAX_ERROR
;
1383 uint8_t *buffer
= calloc(count
, size
);
1384 struct target
*target
= get_current_target(CMD_CTX
);
1385 int retval
= x86_32_common_read_io(target
, address
, size
, buffer
);
1386 if (ERROR_OK
== retval
)
1387 handle_iod_output(CMD_CTX
, target
, address
, size
, count
, buffer
);
1392 static int target_fill_io(struct target
*target
,
1398 LOG_DEBUG("address=0x%08" PRIx32
", data_size=%u, b=0x%08" PRIx32
,
1399 address
, data_size
, b
);
1400 uint8_t target_buf
[data_size
];
1401 switch (data_size
) {
1403 target_buffer_set_u32(target
, target_buf
, b
);
1406 target_buffer_set_u16(target
, target_buf
, b
);
1409 target_buf
[0] = (b
& 0x0ff);
1414 return x86_32_common_write_io(target
, address
, data_size
, target_buf
);
1417 COMMAND_HANDLER(handle_iow_command
)
1420 return ERROR_COMMAND_SYNTAX_ERROR
;
1422 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1424 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
1425 struct target
*target
= get_current_target(CMD_CTX
);
1428 switch (CMD_NAME
[2]) {
1439 return ERROR_COMMAND_SYNTAX_ERROR
;
1441 return target_fill_io(target
, address
, wordsize
, value
);
1444 static const struct command_registration x86_32_exec_command_handlers
[] = {
1447 .mode
= COMMAND_EXEC
,
1448 .handler
= handle_iow_command
,
1449 .help
= "write I/O port word",
1450 .usage
= "port data[word]",
1454 .mode
= COMMAND_EXEC
,
1455 .handler
= handle_iow_command
,
1456 .help
= "write I/O port halfword",
1457 .usage
= "port data[halfword]",
1461 .mode
= COMMAND_EXEC
,
1462 .handler
= handle_iow_command
,
1463 .help
= "write I/O port byte",
1464 .usage
= "port data[byte]",
1468 .mode
= COMMAND_EXEC
,
1469 .handler
= handle_iod_command
,
1470 .help
= "display I/O port word",
1475 .mode
= COMMAND_EXEC
,
1476 .handler
= handle_iod_command
,
1477 .help
= "display I/O port halfword",
1482 .mode
= COMMAND_EXEC
,
1483 .handler
= handle_iod_command
,
1484 .help
= "display I/O port byte",
1488 COMMAND_REGISTRATION_DONE
1491 const struct command_registration x86_32_command_handlers
[] = {
1494 .mode
= COMMAND_ANY
,
1495 .help
= "x86_32 target commands",
1497 .chain
= x86_32_exec_command_handlers
,
1499 COMMAND_REGISTRATION_DONE