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 version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
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_pyhsfromlin(struct target
*t
, uint32_t addr
,
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
, uint32_t address
, uint32_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_pyhsfromlin(t
, address
, physical
) != ERROR_OK
) {
138 LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32
,
146 int x86_32_common_read_phys_mem(struct target
*t
, uint32_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
, uint32_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=0x%08" PRIx32
,
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_pyhsfromlin(struct target
*t
, uint32_t addr
, uint32_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
, uint32_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=0x%08" PRIx32
", 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=0x%08" PRIx32
,
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 uint32_t physaddr
= 0;
595 if (calcaddr_pyhsfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
596 LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32
, __func__
, addr
);
599 /* TODO: !!! Watch out for page boundaries
600 * for every 4kB, the physical address has to be re-calculated
601 * This should be fixed together with bulk memory reads
604 if (retval
== ERROR_OK
605 && x86_32_common_read_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
606 LOG_ERROR("%s failed to read memory from physical address 0x%08" PRIx32
, __func__
, physaddr
);
609 /* restore PG bit if it was cleared prior (regardless of retval) */
610 retval
= x86_32
->enable_paging(t
);
611 if (retval
!= ERROR_OK
) {
612 LOG_ERROR("%s could not enable paging", __func__
);
616 /* paging is off - linear address is physical address */
617 if (x86_32_common_read_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
618 LOG_ERROR("%s failed to read memory from address 0%08" PRIx32
, __func__
, addr
);
626 int x86_32_common_write_memory(struct target
*t
, uint32_t addr
,
627 uint32_t size
, uint32_t count
, const uint8_t *buf
)
629 int retval
= ERROR_OK
;
630 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
631 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
632 addr
, size
, count
, buf
);
634 if (!count
|| !buf
|| !addr
) {
635 LOG_ERROR("%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32
,
636 __func__
, count
, buf
, addr
);
637 return ERROR_COMMAND_ARGUMENT_INVALID
;
639 if (x86_32
->is_paging_enabled(t
)) {
640 /* all memory accesses from debugger must be physical (CR0.PG == 0)
641 * conversion to physical address space needed
643 retval
= x86_32
->disable_paging(t
);
644 if (retval
!= ERROR_OK
) {
645 LOG_ERROR("%s could not disable paging", __func__
);
648 uint32_t physaddr
= 0;
649 if (calcaddr_pyhsfromlin(t
, addr
, &physaddr
) != ERROR_OK
) {
650 LOG_ERROR("%s failed to calculate physical address from 0x%08" PRIx32
,
654 /* TODO: !!! Watch out for page boundaries
655 * for every 4kB, the physical address has to be re-calculated
656 * This should be fixed together with bulk memory reads
658 if (retval
== ERROR_OK
659 && x86_32_common_write_phys_mem(t
, physaddr
, size
, count
, buf
) != ERROR_OK
) {
660 LOG_ERROR("%s failed to write memory to physical address 0x%08" PRIx32
,
664 /* restore PG bit if it was cleared prior (regardless of retval) */
665 retval
= x86_32
->enable_paging(t
);
666 if (retval
!= ERROR_OK
) {
667 LOG_ERROR("%s could not enable paging", __func__
);
672 /* paging is off - linear address is physical address */
673 if (x86_32_common_write_phys_mem(t
, addr
, size
, count
, buf
) != ERROR_OK
) {
674 LOG_ERROR("%s failed to write memory to address 0x%08" PRIx32
,
682 int x86_32_common_read_io(struct target
*t
, uint32_t addr
,
683 uint32_t size
, uint8_t *buf
)
685 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
686 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
687 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
688 int retval
= ERROR_FAIL
;
689 bool pg_disabled
= false;
690 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
693 LOG_ERROR("%s invalid params buf=%p, addr=%08" PRIx32
, __func__
, buf
, addr
);
696 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
697 if (retval
!= ERROR_OK
) {
698 LOG_ERROR("%s error EDX write", __func__
);
701 /* to access physical memory, switch off the CR0.PG bit */
702 if (x86_32
->is_paging_enabled(t
)) {
703 retval
= x86_32
->disable_paging(t
);
704 if (retval
!= ERROR_OK
) {
705 LOG_ERROR("%s could not disable paging", __func__
);
713 retval
= x86_32
->submit_instruction(t
, IORDB32
);
715 retval
= x86_32
->submit_instruction(t
, IORDB16
);
719 retval
= x86_32
->submit_instruction(t
, IORDH32
);
721 retval
= x86_32
->submit_instruction(t
, IORDH16
);
725 retval
= x86_32
->submit_instruction(t
, IORDW32
);
727 retval
= x86_32
->submit_instruction(t
, IORDW16
);
730 LOG_ERROR("%s invalid read io size", __func__
);
733 /* restore CR0.PG bit if needed */
735 retval
= x86_32
->enable_paging(t
);
736 if (retval
!= ERROR_OK
) {
737 LOG_ERROR("%s could not enable paging", __func__
);
743 retval
= x86_32
->read_hw_reg(t
, EAX
, ®val
, 0);
744 if (retval
!= ERROR_OK
) {
745 LOG_ERROR("%s error on read EAX", __func__
);
748 for (uint8_t i
= 0; i
< size
; i
++)
749 buf
[i
] = (regval
>> (i
*8)) & 0x000000FF;
750 retval
= x86_32
->transaction_status(t
);
751 if (retval
!= ERROR_OK
) {
752 LOG_ERROR("%s error on io read", __func__
);
758 int x86_32_common_write_io(struct target
*t
, uint32_t addr
,
759 uint32_t size
, const uint8_t *buf
)
761 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
762 /* if CS.D bit=1 then its a 32 bit code segment, else 16 */
763 bool use32
= (buf_get_u32(x86_32
->cache
->reg_list
[CSAR
].value
, 0, 32)) & CSAR_D
;
764 LOG_DEBUG("addr=0x%08" PRIx32
", size=%" PRIu32
", buf=%p", addr
, size
, buf
);
766 int retval
= ERROR_FAIL
;
767 bool pg_disabled
= false;
769 LOG_ERROR("%s invalid params buf=%p, addr=0x%08" PRIx32
, __func__
, buf
, addr
);
772 /* no do the write */
773 retval
= x86_32
->write_hw_reg(t
, EDX
, addr
, 0);
774 if (retval
!= ERROR_OK
) {
775 LOG_ERROR("%s error on EDX write", __func__
);
779 for (uint8_t i
= 0; i
< size
; i
++)
780 regval
+= (buf
[i
] << (i
*8));
781 retval
= x86_32
->write_hw_reg(t
, EAX
, regval
, 0);
782 if (retval
!= ERROR_OK
) {
783 LOG_ERROR("%s error on EAX write", __func__
);
786 /* to access physical memory, switch off the CR0.PG bit */
787 if (x86_32
->is_paging_enabled(t
)) {
788 retval
= x86_32
->disable_paging(t
);
789 if (retval
!= ERROR_OK
) {
790 LOG_ERROR("%s could not disable paging", __func__
);
798 retval
= x86_32
->submit_instruction(t
, IOWRB32
);
800 retval
= x86_32
->submit_instruction(t
, IOWRB16
);
804 retval
= x86_32
->submit_instruction(t
, IOWRH32
);
806 retval
= x86_32
->submit_instruction(t
, IOWRH16
);
810 retval
= x86_32
->submit_instruction(t
, IOWRW32
);
812 retval
= x86_32
->submit_instruction(t
, IOWRW16
);
815 LOG_ERROR("%s invalid write io size", __func__
);
818 /* restore CR0.PG bit if needed */
820 retval
= x86_32
->enable_paging(t
);
821 if (retval
!= ERROR_OK
) {
822 LOG_ERROR("%s could not enable paging", __func__
);
827 retval
= x86_32
->transaction_status(t
);
828 if (retval
!= ERROR_OK
) {
829 LOG_ERROR("%s error on io write", __func__
);
835 int x86_32_common_add_watchpoint(struct target
*t
, struct watchpoint
*wp
)
838 /* set_watchpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
839 * hardware registers are gone
841 return set_watchpoint(t
, wp
);
844 int x86_32_common_remove_watchpoint(struct target
*t
, struct watchpoint
*wp
)
846 if (check_not_halted(t
))
847 return ERROR_TARGET_NOT_HALTED
;
849 unset_watchpoint(t
, wp
);
853 int x86_32_common_add_breakpoint(struct target
*t
, struct breakpoint
*bp
)
855 LOG_DEBUG("type=%d, addr=0x%08" PRIx32
, bp
->type
, bp
->address
);
856 if (check_not_halted(t
))
857 return ERROR_TARGET_NOT_HALTED
;
858 /* set_breakpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all
859 * hardware registers are gone (for hardware breakpoints)
861 return set_breakpoint(t
, bp
);
864 int x86_32_common_remove_breakpoint(struct target
*t
, struct breakpoint
*bp
)
866 LOG_DEBUG("type=%d, addr=0x%08" PRIx32
, bp
->type
, bp
->address
);
867 if (check_not_halted(t
))
868 return ERROR_TARGET_NOT_HALTED
;
870 unset_breakpoint(t
, bp
);
875 static int set_debug_regs(struct target
*t
, uint32_t address
,
876 uint8_t bp_num
, uint8_t bp_type
, uint8_t bp_length
)
878 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
879 LOG_DEBUG("addr=0x%08" PRIx32
", bp_num=%" PRIu8
", bp_type=%" PRIu8
", pb_length=%" PRIu8
,
880 address
, bp_num
, bp_type
, bp_length
);
882 /* DR7 - set global enable */
883 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
885 if (bp_length
!= 1 && bp_length
!= 2 && bp_length
!= 4)
888 if (DR7_BP_FREE(dr7
, bp_num
))
889 DR7_GLOBAL_ENABLE(dr7
, bp_num
);
891 LOG_ERROR("%s dr7 error, already enabled, val=%08" PRIx32
, __func__
, dr7
);
892 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
897 /* 00 - only on instruction execution */
898 DR7_SET_EXE(dr7
, bp_num
);
899 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
902 /* 01 - only on data writes */
903 DR7_SET_WRITE(dr7
, bp_num
);
904 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
907 /* 10 UNSUPPORTED - an I/O read and I/O write */
908 LOG_ERROR("%s unsupported feature bp_type=%d", __func__
, bp_type
);
912 /* on data read or data write */
913 DR7_SET_ACCESS(dr7
, bp_num
);
914 DR7_SET_LENGTH(dr7
, bp_num
, bp_length
);
917 LOG_ERROR("%s invalid request [only 0-3] bp_type=%d", __func__
, bp_type
);
921 /* update regs in the reg cache ready to be written to hardware
924 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, address
);
925 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= 1;
926 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= 1;
927 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
928 x86_32
->cache
->reg_list
[DR6
].dirty
= 1;
929 x86_32
->cache
->reg_list
[DR6
].valid
= 1;
930 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
931 x86_32
->cache
->reg_list
[DR7
].dirty
= 1;
932 x86_32
->cache
->reg_list
[DR7
].valid
= 1;
936 static int unset_debug_regs(struct target
*t
, uint8_t bp_num
)
938 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
939 LOG_DEBUG("bp_num=%" PRIu8
, bp_num
);
941 uint32_t dr7
= buf_get_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32);
943 if (!(DR7_BP_FREE(dr7
, bp_num
))) {
944 DR7_GLOBAL_DISABLE(dr7
, bp_num
);
946 LOG_ERROR("%s dr7 error, not enabled, val=0x%08" PRIx32
, __func__
, dr7
);
947 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
949 /* this will clear rw and len bits */
950 DR7_RESET_RWLEN_BITS(dr7
, bp_num
);
952 /* update regs in the reg cache ready to be written to hardware
955 buf_set_u32(x86_32
->cache
->reg_list
[bp_num
+DR0
].value
, 0, 32, 0);
956 x86_32
->cache
->reg_list
[bp_num
+DR0
].dirty
= 1;
957 x86_32
->cache
->reg_list
[bp_num
+DR0
].valid
= 1;
958 buf_set_u32(x86_32
->cache
->reg_list
[DR6
].value
, 0, 32, PM_DR6
);
959 x86_32
->cache
->reg_list
[DR6
].dirty
= 1;
960 x86_32
->cache
->reg_list
[DR6
].valid
= 1;
961 buf_set_u32(x86_32
->cache
->reg_list
[DR7
].value
, 0, 32, dr7
);
962 x86_32
->cache
->reg_list
[DR7
].dirty
= 1;
963 x86_32
->cache
->reg_list
[DR7
].valid
= 1;
967 static int set_hwbp(struct target
*t
, struct breakpoint
*bp
)
969 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
970 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
971 uint8_t hwbp_num
= 0;
973 while (debug_reg_list
[hwbp_num
].used
&& (hwbp_num
< x86_32
->num_hw_bpoints
))
975 if (hwbp_num
>= x86_32
->num_hw_bpoints
) {
976 LOG_ERROR("%s no free hw breakpoint bpid=0x%" PRIx32
, __func__
, bp
->unique_id
);
977 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
979 if (set_debug_regs(t
, bp
->address
, hwbp_num
, DR7_BP_EXECUTE
, 1) != ERROR_OK
)
981 bp
->set
= hwbp_num
+ 1;
982 debug_reg_list
[hwbp_num
].used
= 1;
983 debug_reg_list
[hwbp_num
].bp_value
= bp
->address
;
984 LOG_USER("%s hardware breakpoint %" PRIu32
" set at 0x%08" PRIx32
" (hwreg=%" PRIu8
")", __func__
,
985 bp
->unique_id
, debug_reg_list
[hwbp_num
].bp_value
, hwbp_num
);
989 static int unset_hwbp(struct target
*t
, struct breakpoint
*bp
)
991 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
992 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
993 int hwbp_num
= bp
->set
- 1;
995 if ((hwbp_num
< 0) || (hwbp_num
>= x86_32
->num_hw_bpoints
)) {
996 LOG_ERROR("%s invalid breakpoint number=%d, bpid=%" PRIu32
,
997 __func__
, hwbp_num
, bp
->unique_id
);
1001 if (unset_debug_regs(t
, hwbp_num
) != ERROR_OK
)
1003 debug_reg_list
[hwbp_num
].used
= 0;
1004 debug_reg_list
[hwbp_num
].bp_value
= 0;
1006 LOG_USER("%s hardware breakpoint %" PRIu32
" removed from 0x%08" PRIx32
" (hwreg=%d)",
1007 __func__
, bp
->unique_id
, bp
->address
, hwbp_num
);
1011 static int set_swbp(struct target
*t
, struct breakpoint
*bp
)
1013 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1014 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1016 uint8_t opcode
= SW_BP_OPCODE
;
1019 if (calcaddr_pyhsfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1021 if (read_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1024 LOG_DEBUG("set software breakpoint - orig byte=0x%02" PRIx8
"", *bp
->orig_instr
);
1026 /* just write the instruction trap byte */
1027 if (write_phys_mem(t
, physaddr
, 1, 1, &opcode
))
1030 /* verify that this is not invalid/read-only memory */
1031 if (read_phys_mem(t
, physaddr
, 1, 1, &readback
))
1034 if (readback
!= SW_BP_OPCODE
) {
1035 LOG_ERROR("%s software breakpoint error at 0x%08" PRIx32
", check memory",
1036 __func__
, bp
->address
);
1037 LOG_ERROR("%s readback=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1038 __func__
, readback
, *bp
->orig_instr
);
1041 bp
->set
= SW_BP_OPCODE
; /* just non 0 */
1043 /* add the memory patch */
1044 struct swbp_mem_patch
*new_patch
= malloc(sizeof(struct swbp_mem_patch
));
1045 if (new_patch
== NULL
) {
1046 LOG_ERROR("%s out of memory", __func__
);
1049 new_patch
->next
= NULL
;
1050 new_patch
->orig_byte
= *bp
->orig_instr
;
1051 new_patch
->physaddr
= physaddr
;
1052 new_patch
->swbp_unique_id
= bp
->unique_id
;
1054 struct swbp_mem_patch
*addto
= x86_32
->swbbp_mem_patch_list
;
1056 x86_32
->swbbp_mem_patch_list
= new_patch
;
1058 while (addto
->next
!= NULL
)
1059 addto
= addto
->next
;
1060 addto
->next
= new_patch
;
1062 LOG_USER("%s software breakpoint %" PRIu32
" set at 0x%08" PRIx32
,
1063 __func__
, bp
->unique_id
, bp
->address
);
1067 static int unset_swbp(struct target
*t
, struct breakpoint
*bp
)
1069 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1070 LOG_DEBUG("id %" PRIx32
, bp
->unique_id
);
1072 uint8_t current_instr
;
1074 /* check that user program has not modified breakpoint instruction */
1075 if (calcaddr_pyhsfromlin(t
, bp
->address
, &physaddr
) != ERROR_OK
)
1077 if (read_phys_mem(t
, physaddr
, 1, 1, ¤t_instr
))
1080 if (current_instr
== SW_BP_OPCODE
) {
1081 if (write_phys_mem(t
, physaddr
, 1, 1, bp
->orig_instr
))
1084 LOG_ERROR("%s software breakpoint remove error at 0x%08" PRIx32
", check memory",
1085 __func__
, bp
->address
);
1086 LOG_ERROR("%s current=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1087 __func__
, current_instr
, *bp
->orig_instr
);
1091 /* remove from patch */
1092 struct swbp_mem_patch
*iter
= x86_32
->swbbp_mem_patch_list
;
1094 if (iter
->swbp_unique_id
== bp
->unique_id
) {
1095 /* it's the first item */
1096 x86_32
->swbbp_mem_patch_list
= iter
->next
;
1099 while (iter
->next
!= NULL
&& iter
->next
->swbp_unique_id
!= bp
->unique_id
)
1101 if (iter
->next
!= NULL
) {
1102 /* it's the next one */
1103 struct swbp_mem_patch
*freeme
= iter
->next
;
1104 iter
->next
= iter
->next
->next
;
1110 LOG_USER("%s software breakpoint %" PRIu32
" removed from 0x%08" PRIx32
,
1111 __func__
, bp
->unique_id
, bp
->address
);
1115 static int set_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1117 int error
= ERROR_OK
;
1118 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1119 LOG_DEBUG("type=%d, addr=0x%08" PRIx32
, bp
->type
, bp
->address
);
1121 LOG_ERROR("breakpoint already set");
1124 if (bp
->type
== BKPT_HARD
) {
1125 error
= set_hwbp(t
, bp
);
1126 if (error
!= ERROR_OK
) {
1127 LOG_ERROR("%s error setting hardware breakpoint at 0x%08" PRIx32
,
1128 __func__
, bp
->address
);
1132 if (x86_32
->sw_bpts_supported(t
)) {
1133 error
= set_swbp(t
, bp
);
1134 if (error
!= ERROR_OK
) {
1135 LOG_ERROR("%s error setting software breakpoint at 0x%08" PRIx32
,
1136 __func__
, bp
->address
);
1140 LOG_ERROR("%s core doesn't support SW breakpoints", __func__
);
1148 static int unset_breakpoint(struct target
*t
, struct breakpoint
*bp
)
1150 LOG_DEBUG("type=%d, addr=0x%08" PRIx32
, bp
->type
, bp
->address
);
1152 LOG_WARNING("breakpoint not set");
1156 if (bp
->type
== BKPT_HARD
) {
1157 if (unset_hwbp(t
, bp
) != ERROR_OK
) {
1158 LOG_ERROR("%s error removing hardware breakpoint at 0x%08" PRIx32
,
1159 __func__
, bp
->address
);
1163 if (unset_swbp(t
, bp
) != ERROR_OK
) {
1164 LOG_ERROR("%s error removing software breakpoint at 0x%08" PRIx32
,
1165 __func__
, bp
->address
);
1173 static int set_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1175 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1176 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1178 LOG_DEBUG("type=%d, addr=0x%08" PRIx32
, wp
->rw
, wp
->address
);
1181 LOG_ERROR("%s watchpoint already set", __func__
);
1185 if (wp
->rw
== WPT_READ
) {
1186 LOG_ERROR("%s no support for 'read' watchpoints, use 'access' or 'write'"
1188 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1191 while (debug_reg_list
[wp_num
].used
&& (wp_num
< x86_32
->num_hw_bpoints
))
1193 if (wp_num
>= x86_32
->num_hw_bpoints
) {
1194 LOG_ERROR("%s no debug registers left", __func__
);
1195 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1198 if (wp
->length
!= 4 && wp
->length
!= 2 && wp
->length
!= 1) {
1199 LOG_ERROR("%s only watchpoints of length 1, 2 or 4 are supported", __func__
);
1200 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1205 if (set_debug_regs(t
, wp
->address
, wp_num
,
1206 DR7_BP_WRITE
, wp
->length
) != ERROR_OK
) {
1211 if (set_debug_regs(t
, wp
->address
, wp_num
, DR7_BP_READWRITE
,
1212 wp
->length
) != ERROR_OK
) {
1217 LOG_ERROR("%s only 'access' or 'write' watchpoints are supported", __func__
);
1220 wp
->set
= wp_num
+ 1;
1221 debug_reg_list
[wp_num
].used
= 1;
1222 debug_reg_list
[wp_num
].bp_value
= wp
->address
;
1223 LOG_USER("'%s' watchpoint %d set at 0x%08" PRIx32
" with length %" PRIu32
" (hwreg=%d)",
1224 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1225 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1226 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1230 static int unset_watchpoint(struct target
*t
, struct watchpoint
*wp
)
1232 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1233 struct x86_32_dbg_reg
*debug_reg_list
= x86_32
->hw_break_list
;
1234 LOG_DEBUG("type=%d, addr=0x%08" PRIx32
, wp
->rw
, wp
->address
);
1236 LOG_WARNING("watchpoint not set");
1240 int wp_num
= wp
->set
- 1;
1241 if ((wp_num
< 0) || (wp_num
>= x86_32
->num_hw_bpoints
)) {
1242 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
1245 if (unset_debug_regs(t
, wp_num
) != ERROR_OK
)
1248 debug_reg_list
[wp_num
].used
= 0;
1249 debug_reg_list
[wp_num
].bp_value
= 0;
1252 LOG_USER("'%s' watchpoint %d removed from 0x%08" PRIx32
" with length %" PRIu32
" (hwreg=%d)",
1253 wp
->rw
== WPT_READ
? "read" : wp
->rw
== WPT_WRITE
?
1254 "write" : wp
->rw
== WPT_ACCESS
? "access" : "?",
1255 wp
->unique_id
, wp
->address
, wp
->length
, wp_num
);
1260 static int read_hw_reg_to_cache(struct target
*t
, int num
)
1263 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1265 if (check_not_halted(t
))
1266 return ERROR_TARGET_NOT_HALTED
;
1267 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1268 return ERROR_COMMAND_SYNTAX_ERROR
;
1269 if (x86_32
->read_hw_reg(t
, num
, ®_value
, 1) != ERROR_OK
) {
1270 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1273 LOG_DEBUG("reg %s value 0x%08" PRIx32
,
1274 x86_32
->cache
->reg_list
[num
].name
, reg_value
);
1278 static int write_hw_reg_from_cache(struct target
*t
, int num
)
1280 struct x86_32_common
*x86_32
= target_to_x86_32(t
);
1281 if (check_not_halted(t
))
1282 return ERROR_TARGET_NOT_HALTED
;
1283 if ((num
< 0) || (num
>= x86_32
->get_num_user_regs(t
)))
1284 return ERROR_COMMAND_SYNTAX_ERROR
;
1285 if (x86_32
->write_hw_reg(t
, num
, 0, 1) != ERROR_OK
) {
1286 LOG_ERROR("%s fail for %s", x86_32
->cache
->reg_list
[num
].name
, __func__
);
1289 LOG_DEBUG("reg %s value 0x%08" PRIx32
, x86_32
->cache
->reg_list
[num
].name
,
1290 buf_get_u32(x86_32
->cache
->reg_list
[num
].value
, 0, 32));
1294 /* x86 32 commands */
1295 static void handle_iod_output(struct command_context
*cmd_ctx
,
1296 struct target
*target
, uint32_t address
, unsigned size
,
1297 unsigned count
, const uint8_t *buffer
)
1299 const unsigned line_bytecnt
= 32;
1300 unsigned line_modulo
= line_bytecnt
/ size
;
1302 char output
[line_bytecnt
* 4 + 1];
1303 unsigned output_len
= 0;
1305 const char *value_fmt
;
1308 value_fmt
= "%8.8x ";
1311 value_fmt
= "%4.4x ";
1314 value_fmt
= "%2.2x ";
1317 /* "can't happen", caller checked */
1318 LOG_ERROR("%s invalid memory read size: %u", __func__
, size
);
1322 for (unsigned i
= 0; i
< count
; i
++) {
1323 if (i
% line_modulo
== 0) {
1324 output_len
+= snprintf(output
+ output_len
,
1325 sizeof(output
) - output_len
,
1327 (unsigned)(address
+ (i
*size
)));
1331 const uint8_t *value_ptr
= buffer
+ i
* size
;
1334 value
= target_buffer_get_u32(target
, value_ptr
);
1337 value
= target_buffer_get_u16(target
, value_ptr
);
1342 output_len
+= snprintf(output
+ output_len
,
1343 sizeof(output
) - output_len
,
1346 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1347 command_print(cmd_ctx
, "%s", output
);
1353 COMMAND_HANDLER(handle_iod_command
)
1356 return ERROR_COMMAND_SYNTAX_ERROR
;
1359 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1360 if (address
> 0xffff) {
1361 LOG_ERROR("%s IA-32 I/O space is 2^16, 0x%08" PRIx32
" exceeds max", __func__
, address
);
1362 return ERROR_COMMAND_SYNTAX_ERROR
;
1366 switch (CMD_NAME
[2]) {
1377 return ERROR_COMMAND_SYNTAX_ERROR
;
1380 uint8_t *buffer
= calloc(count
, size
);
1381 struct target
*target
= get_current_target(CMD_CTX
);
1382 int retval
= x86_32_common_read_io(target
, address
, size
, buffer
);
1383 if (ERROR_OK
== retval
)
1384 handle_iod_output(CMD_CTX
, target
, address
, size
, count
, buffer
);
1389 static int target_fill_io(struct target
*target
,
1395 LOG_DEBUG("address=0x%08" PRIx32
", data_size=%u, b=0x%08" PRIx32
,
1396 address
, data_size
, b
);
1397 uint8_t target_buf
[data_size
];
1398 switch (data_size
) {
1400 target_buffer_set_u32(target
, target_buf
, b
);
1403 target_buffer_set_u16(target
, target_buf
, b
);
1406 target_buf
[0] = (b
& 0x0ff);
1411 return x86_32_common_write_io(target
, address
, data_size
, target_buf
);
1414 COMMAND_HANDLER(handle_iow_command
)
1417 return ERROR_COMMAND_SYNTAX_ERROR
;
1419 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1421 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], value
);
1422 struct target
*target
= get_current_target(CMD_CTX
);
1425 switch (CMD_NAME
[2]) {
1436 return ERROR_COMMAND_SYNTAX_ERROR
;
1438 return target_fill_io(target
, address
, wordsize
, value
);
1441 static const struct command_registration x86_32_exec_command_handlers
[] = {
1444 .mode
= COMMAND_EXEC
,
1445 .handler
= handle_iow_command
,
1446 .help
= "write I/O port word",
1447 .usage
= "port data[word]",
1451 .mode
= COMMAND_EXEC
,
1452 .handler
= handle_iow_command
,
1453 .help
= "write I/O port halfword",
1454 .usage
= "port data[halfword]",
1458 .mode
= COMMAND_EXEC
,
1459 .handler
= handle_iow_command
,
1460 .help
= "write I/O port byte",
1461 .usage
= "port data[byte]",
1465 .mode
= COMMAND_EXEC
,
1466 .handler
= handle_iod_command
,
1467 .help
= "display I/O port word",
1472 .mode
= COMMAND_EXEC
,
1473 .handler
= handle_iod_command
,
1474 .help
= "display I/O port halfword",
1479 .mode
= COMMAND_EXEC
,
1480 .handler
= handle_iod_command
,
1481 .help
= "display I/O port byte",
1485 COMMAND_REGISTRATION_DONE
1488 const struct command_registration x86_32_command_handlers
[] = {
1491 .mode
= COMMAND_ANY
,
1492 .help
= "x86_32 target commands",
1494 .chain
= x86_32_exec_command_handlers
,
1496 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)