2 * OpenOCD STM8 target driver
3 * Copyright (C) 2017 Ake Rehnman
4 * ake.rehnman(at)gmail.com
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <helper/log.h>
26 #include "target_type.h"
28 #include "jtag/interface.h"
29 #include "jtag/jtag.h"
30 #include "jtag/swim.h"
32 #include "breakpoints.h"
33 #include "algorithm.h"
36 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
);
37 static int stm8_read_core_reg(struct target
*target
, unsigned int num
);
38 static int stm8_write_core_reg(struct target
*target
, unsigned int num
);
39 static int stm8_save_context(struct target
*target
);
40 static void stm8_enable_breakpoints(struct target
*target
);
41 static int stm8_unset_breakpoint(struct target
*target
,
42 struct breakpoint
*breakpoint
);
43 static int stm8_set_breakpoint(struct target
*target
,
44 struct breakpoint
*breakpoint
);
45 static void stm8_enable_watchpoints(struct target
*target
);
46 static int stm8_unset_watchpoint(struct target
*target
,
47 struct watchpoint
*watchpoint
);
48 static int (*adapter_speed
)(int speed
);
49 extern struct adapter_driver
*adapter_driver
;
60 { 0, "pc", 32, REG_TYPE_UINT32
, "general", "org.gnu.gdb.stm8.core", 0 },
61 { 1, "a", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
62 { 2, "x", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
63 { 3, "y", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
64 { 4, "sp", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
65 { 5, "cc", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
68 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
79 #define DM_REGS 0x7f00
80 #define DM_REG_A 0x7f00
81 #define DM_REG_PC 0x7f01
82 #define DM_REG_X 0x7f04
83 #define DM_REG_Y 0x7f06
84 #define DM_REG_SP 0x7f08
85 #define DM_REG_CC 0x7f0a
87 #define DM_BKR1E 0x7f90
88 #define DM_BKR2E 0x7f93
91 #define DM_CSR1 0x7f98
92 #define DM_CSR2 0x7f99
106 #define FLASH_CR1_STM8S 0x505A
107 #define FLASH_CR2_STM8S 0x505B
108 #define FLASH_NCR2_STM8S 0x505C
109 #define FLASH_IAPSR_STM8S 0x505F
110 #define FLASH_PUKR_STM8S 0x5062
111 #define FLASH_DUKR_STM8S 0x5064
113 #define FLASH_CR1_STM8L 0x5050
114 #define FLASH_CR2_STM8L 0x5051
115 #define FLASH_NCR2_STM8L 0
116 #define FLASH_PUKR_STM8L 0x5052
117 #define FLASH_DUKR_STM8L 0x5053
118 #define FLASH_IAPSR_STM8L 0x5054
125 #define WR_PG_DIS 0x01
135 #define SAFE_MASK 0x80
136 #define NO_ACCESS 0x40
140 #define SWIM_RST 0x04
144 #define SWIM_CSR 0x7f80
146 #define STM8_BREAK 0x8B
155 struct stm8_algorithm
{
159 struct stm8_core_reg
{
161 struct target
*target
;
162 struct stm8_common
*stm8_common
;
166 /* break on execute */
172 /* break on read, write and execute */
176 struct stm8_comparator
{
179 uint32_t reg_address
;
180 enum hw_break_type type
;
183 static int stm8_adapter_read_memory(struct target
*target
,
184 uint32_t addr
, int size
, int count
, void *buf
)
186 return swim_read_mem(addr
, size
, count
, buf
);
189 static int stm8_adapter_write_memory(struct target
*target
,
190 uint32_t addr
, int size
, int count
, const void *buf
)
192 return swim_write_mem(addr
, size
, count
, buf
);
195 static int stm8_write_u8(struct target
*target
,
196 uint32_t addr
, uint8_t val
)
201 return swim_write_mem(addr
, 1, 1, buf
);
204 static int stm8_read_u8(struct target
*target
,
205 uint32_t addr
, uint8_t *val
)
207 return swim_read_mem(addr
, 1, 1, val
);
211 <enable == 0> Disables interrupts.
212 If interrupts are enabled they are masked and the cc register
215 <enable == 1> Enables interrupts.
216 Enable interrupts is actually restoring I1 I0 state from previous
217 call with enable == 0. Note that if stepping and breaking on a sim
218 instruction will NOT work since the interrupt flags are restored on
219 debug_entry. We don't have any way for the debugger to exclusively
220 disable the interrupts
222 static int stm8_enable_interrupts(struct target
*target
, int enable
)
224 struct stm8_common
*stm8
= target_to_stm8(target
);
229 return ERROR_OK
; /* cc was not stashed */
230 /* fetch current cc */
231 stm8_read_u8(target
, DM_REG_CC
, &cc
);
233 cc
&= ~(CC_I0
+ CC_I1
);
234 /* restore I1 & I0 from stash*/
235 cc
|= (stm8
->cc
& (CC_I0
+CC_I1
));
236 /* update current cc */
237 stm8_write_u8(target
, DM_REG_CC
, cc
);
238 stm8
->cc_valid
= false;
240 stm8_read_u8(target
, DM_REG_CC
, &cc
);
241 if ((cc
& CC_I0
) && (cc
& CC_I1
))
242 return ERROR_OK
; /* interrupts already masked */
245 stm8
->cc_valid
= true;
246 /* mask interrupts (disable) */
247 cc
|= (CC_I0
+ CC_I1
);
248 stm8_write_u8(target
, DM_REG_CC
, cc
);
254 static int stm8_set_hwbreak(struct target
*target
,
255 struct stm8_comparator comparator_list
[])
260 /* Refer to Table 4 in UM0470 */
268 if (!comparator_list
[0].used
) {
269 comparator_list
[0].type
= HWBRK_EXEC
;
270 comparator_list
[0].bp_value
= -1;
273 if (!comparator_list
[1].used
) {
274 comparator_list
[1].type
= HWBRK_EXEC
;
275 comparator_list
[1].bp_value
= -1;
278 if ((comparator_list
[0].type
== HWBRK_EXEC
)
279 && (comparator_list
[1].type
== HWBRK_EXEC
)) {
280 comparator_list
[0].reg_address
= 0;
281 comparator_list
[1].reg_address
= 1;
284 if ((comparator_list
[0].type
== HWBRK_EXEC
)
285 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
286 comparator_list
[0].reg_address
= 0;
287 comparator_list
[1].reg_address
= 1;
288 switch (comparator_list
[1].type
) {
302 if ((comparator_list
[1].type
== HWBRK_EXEC
)
303 && (comparator_list
[0].type
!= HWBRK_EXEC
)) {
304 comparator_list
[0].reg_address
= 1;
305 comparator_list
[1].reg_address
= 0;
306 switch (comparator_list
[0].type
) {
320 if ((comparator_list
[0].type
!= HWBRK_EXEC
)
321 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
322 if (comparator_list
[0].type
!= comparator_list
[1].type
) {
323 LOG_ERROR("data hw breakpoints must be of same type");
324 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
328 for (i
= 0; i
< 2; i
++) {
329 data
= comparator_list
[i
].bp_value
;
330 addr
= comparator_list
[i
].reg_address
;
337 ret
= stm8_adapter_write_memory(target
, DM_BKR1E
, 1, 3, buf
);
338 LOG_DEBUG("DM_BKR1E=%" PRIx32
, data
);
339 } else if (addr
== 1) {
340 ret
= stm8_adapter_write_memory(target
, DM_BKR2E
, 1, 3, buf
);
341 LOG_DEBUG("DM_BKR2E=%" PRIx32
, data
);
343 LOG_DEBUG("addr=%" PRIu32
, addr
);
350 ret
= stm8_write_u8(target
, DM_CR1
,
351 (bc
<< 3) + (bir
<< 2) + (biw
<< 1));
352 LOG_DEBUG("DM_CR1=%" PRIx8
, buf
[0]);
360 /* read DM control and status regs */
361 static int stm8_read_dm_csrx(struct target
*target
, uint8_t *csr1
,
367 ret
= stm8_adapter_read_memory(target
, DM_CSR1
, 1, sizeof(buf
), buf
);
377 /* set or clear the single step flag in DM */
378 static int stm8_config_step(struct target
*target
, int enable
)
383 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
391 ret
= stm8_write_u8(target
, DM_CSR1
, csr1
);
397 /* set the stall flag in DM */
398 static int stm8_debug_stall(struct target
*target
)
403 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
407 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
413 static int stm8_configure_break_unit(struct target
*target
)
415 /* get pointers to arch-specific information */
416 struct stm8_common
*stm8
= target_to_stm8(target
);
418 if (stm8
->bp_scanned
)
421 stm8
->num_hw_bpoints
= 2;
422 stm8
->num_hw_bpoints_avail
= stm8
->num_hw_bpoints
;
424 stm8
->hw_break_list
= calloc(stm8
->num_hw_bpoints
,
425 sizeof(struct stm8_comparator
));
427 stm8
->hw_break_list
[0].reg_address
= 0;
428 stm8
->hw_break_list
[1].reg_address
= 1;
430 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8
->num_hw_bpoints
,
431 stm8
->num_hw_bpoints
);
433 stm8
->bp_scanned
= true;
438 static int stm8_examine_debug_reason(struct target
*target
)
443 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
444 if (retval
== ERROR_OK
)
445 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
447 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
448 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
450 if (retval
!= ERROR_OK
)
454 /* halted on reset */
455 target
->debug_reason
= DBG_REASON_UNDEFINED
;
457 if (csr1
& (BK1F
+BK2F
))
458 /* we have halted on a breakpoint (or wp)*/
459 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
462 /* we have halted on a breakpoint */
463 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
470 static int stm8_debug_entry(struct target
*target
)
472 struct stm8_common
*stm8
= target_to_stm8(target
);
474 /* restore interrupts */
475 stm8_enable_interrupts(target
, 1);
477 stm8_save_context(target
);
479 /* make sure stepping disabled STE bit in CSR1 cleared */
480 stm8_config_step(target
, 0);
482 /* attempt to find halt reason */
483 stm8_examine_debug_reason(target
);
485 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
486 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32),
487 target_state_name(target
));
492 /* clear stall flag in DM and flush instruction pipe */
493 static int stm8_exit_debug(struct target
*target
)
498 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
502 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
508 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
514 static int stm8_read_regs(struct target
*target
, uint32_t regs
[])
519 ret
= stm8_adapter_read_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
523 regs
[0] = be_to_h_u24(buf
+DM_REG_PC
-DM_REGS
);
524 regs
[1] = buf
[DM_REG_A
-DM_REGS
];
525 regs
[2] = be_to_h_u16(buf
+DM_REG_X
-DM_REGS
);
526 regs
[3] = be_to_h_u16(buf
+DM_REG_Y
-DM_REGS
);
527 regs
[4] = be_to_h_u16(buf
+DM_REG_SP
-DM_REGS
);
528 regs
[5] = buf
[DM_REG_CC
-DM_REGS
];
533 static int stm8_write_regs(struct target
*target
, uint32_t regs
[])
538 h_u24_to_be(buf
+DM_REG_PC
-DM_REGS
, regs
[0]);
539 buf
[DM_REG_A
-DM_REGS
] = regs
[1];
540 h_u16_to_be(buf
+DM_REG_X
-DM_REGS
, regs
[2]);
541 h_u16_to_be(buf
+DM_REG_Y
-DM_REGS
, regs
[3]);
542 h_u16_to_be(buf
+DM_REG_SP
-DM_REGS
, regs
[4]);
543 buf
[DM_REG_CC
-DM_REGS
] = regs
[5];
545 ret
= stm8_adapter_write_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
552 static int stm8_get_core_reg(struct reg
*reg
)
555 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
556 struct target
*target
= stm8_reg
->target
;
557 struct stm8_common
*stm8_target
= target_to_stm8(target
);
559 if (target
->state
!= TARGET_HALTED
)
560 return ERROR_TARGET_NOT_HALTED
;
562 retval
= stm8_target
->read_core_reg(target
, stm8_reg
->num
);
567 static int stm8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
569 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
570 struct target
*target
= stm8_reg
->target
;
571 uint32_t value
= buf_get_u32(buf
, 0, reg
->size
);
573 if (target
->state
!= TARGET_HALTED
)
574 return ERROR_TARGET_NOT_HALTED
;
576 buf_set_u32(reg
->value
, 0, 32, value
);
583 static int stm8_save_context(struct target
*target
)
587 /* get pointers to arch-specific information */
588 struct stm8_common
*stm8
= target_to_stm8(target
);
590 /* read core registers */
591 stm8_read_regs(target
, stm8
->core_regs
);
593 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
594 if (!stm8
->core_cache
->reg_list
[i
].valid
)
595 stm8
->read_core_reg(target
, i
);
601 static int stm8_restore_context(struct target
*target
)
605 /* get pointers to arch-specific information */
606 struct stm8_common
*stm8
= target_to_stm8(target
);
608 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
609 if (stm8
->core_cache
->reg_list
[i
].dirty
)
610 stm8
->write_core_reg(target
, i
);
613 /* write core regs */
614 stm8_write_regs(target
, stm8
->core_regs
);
619 static int stm8_unlock_flash(struct target
*target
)
623 struct stm8_common
*stm8
= target_to_stm8(target
);
625 /* check if flash is unlocked */
626 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
627 if (~data
[0] & PUL
) {
629 stm8_write_u8(target
, stm8
->flash_pukr
, 0x56);
630 stm8_write_u8(target
, stm8
->flash_pukr
, 0xae);
633 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
639 static int stm8_unlock_eeprom(struct target
*target
)
643 struct stm8_common
*stm8
= target_to_stm8(target
);
645 /* check if eeprom is unlocked */
646 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
647 if (~data
[0] & DUL
) {
649 stm8_write_u8(target
, stm8
->flash_dukr
, 0xae);
650 stm8_write_u8(target
, stm8
->flash_dukr
, 0x56);
653 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
659 static int stm8_write_flash(struct target
*target
, enum mem_type type
,
661 uint32_t size
, uint32_t count
, uint32_t blocksize_param
,
662 const uint8_t *buffer
)
664 struct stm8_common
*stm8
= target_to_stm8(target
);
669 uint32_t blocksize
= 0;
675 stm8_unlock_flash(target
);
678 stm8_unlock_eeprom(target
);
681 stm8_unlock_eeprom(target
);
685 LOG_ERROR("BUG: wrong mem_type %d", type
);
690 /* we don't support short writes */
695 bytecnt
= count
* size
;
698 if ((bytecnt
>= blocksize_param
) && ((address
& (blocksize_param
-1)) == 0)) {
700 stm8_write_u8(target
, stm8
->flash_cr2
, PRG
+ opt
);
701 if (stm8
->flash_ncr2
)
702 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(PRG
+ opt
));
703 blocksize
= blocksize_param
;
705 if ((bytecnt
>= 4) && ((address
& 0x3) == 0)) {
707 stm8_write_u8(target
, stm8
->flash_cr2
, WPRG
+ opt
);
708 if (stm8
->flash_ncr2
)
709 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(WPRG
+ opt
));
712 if (blocksize
!= 1) {
714 stm8_write_u8(target
, stm8
->flash_cr2
, opt
);
715 if (stm8
->flash_ncr2
)
716 stm8_write_u8(target
, stm8
->flash_ncr2
, ~opt
);
720 res
= stm8_adapter_write_memory(target
, address
, 1, blocksize
, buffer
);
723 address
+= blocksize
;
725 bytecnt
-= blocksize
;
727 /* lets hang here until end of program (EOP) */
728 for (i
= 0; i
< 16; i
++) {
729 stm8_read_u8(target
, stm8
->flash_iapsr
, &iapsr
);
739 /* disable write access */
740 res
= stm8_write_u8(target
, stm8
->flash_iapsr
, 0x0);
748 static int stm8_write_memory(struct target
*target
, target_addr_t address
,
749 uint32_t size
, uint32_t count
,
750 const uint8_t *buffer
)
752 struct stm8_common
*stm8
= target_to_stm8(target
);
754 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
755 ", size: 0x%8.8" PRIx32
756 ", count: 0x%8.8" PRIx32
,
757 address
, size
, count
);
759 if (target
->state
!= TARGET_HALTED
)
760 LOG_WARNING("target not halted");
764 if ((address
>= stm8
->flashstart
) && (address
<= stm8
->flashend
))
765 retval
= stm8_write_flash(target
, FLASH
, address
, size
, count
,
766 stm8
->blocksize
, buffer
);
767 else if ((address
>= stm8
->eepromstart
) && (address
<= stm8
->eepromend
))
768 retval
= stm8_write_flash(target
, EEPROM
, address
, size
, count
,
769 stm8
->blocksize
, buffer
);
770 else if ((address
>= stm8
->optionstart
) && (address
<= stm8
->optionend
))
771 retval
= stm8_write_flash(target
, OPTION
, address
, size
, count
, 0, buffer
);
773 retval
= stm8_adapter_write_memory(target
, address
, size
, count
,
776 if (retval
!= ERROR_OK
)
777 return ERROR_TARGET_FAILURE
;
782 static int stm8_read_memory(struct target
*target
, target_addr_t address
,
783 uint32_t size
, uint32_t count
, uint8_t *buffer
)
785 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
786 ", size: 0x%8.8" PRIx32
787 ", count: 0x%8.8" PRIx32
,
788 address
, size
, count
);
790 if (target
->state
!= TARGET_HALTED
)
791 LOG_WARNING("target not halted");
794 retval
= stm8_adapter_read_memory(target
, address
, size
, count
, buffer
);
796 if (retval
!= ERROR_OK
)
797 return ERROR_TARGET_FAILURE
;
802 static int stm8_speed(int speed
)
807 LOG_DEBUG("stm8_speed: %d", speed
);
809 csr
= SAFE_MASK
| SWIM_DM
;
810 if (speed
>= SWIM_FREQ_HIGH
)
813 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)", csr
& HS
? 1 : 0);
814 retval
= stm8_write_u8(NULL
, SWIM_CSR
, csr
);
815 if (retval
!= ERROR_OK
)
817 return adapter_speed(speed
);
820 static int stm8_init(struct command_context
*cmd_ctx
, struct target
*target
)
823 * FIXME: this is a temporarily hack that needs better implementation.
824 * Being the only overwrite of adapter_driver, it prevents declaring const
825 * the struct adapter_driver.
826 * intercept adapter_driver->speed() calls
828 adapter_speed
= adapter_driver
->speed
;
829 adapter_driver
->speed
= stm8_speed
;
831 stm8_build_reg_cache(target
);
836 static int stm8_poll(struct target
*target
)
838 int retval
= ERROR_OK
;
842 LOG_DEBUG("target->state=%d", target
->state
);
845 /* read dm_csrx control regs */
846 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
847 if (retval
!= ERROR_OK
) {
848 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval
);
850 We return ERROR_OK here even if we didn't get an answer.
851 openocd will call target_wait_state until we get target state TARGET_HALTED
856 /* check for processor halted */
858 if (target
->state
!= TARGET_HALTED
) {
859 if (target
->state
== TARGET_UNKNOWN
)
860 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
862 retval
= stm8_debug_entry(target
);
863 if (retval
!= ERROR_OK
) {
864 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval
);
865 return ERROR_TARGET_FAILURE
;
868 if (target
->state
== TARGET_DEBUG_RUNNING
) {
869 target
->state
= TARGET_HALTED
;
870 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
872 target
->state
= TARGET_HALTED
;
873 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
877 target
->state
= TARGET_RUNNING
;
879 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
884 static int stm8_halt(struct target
*target
)
886 LOG_DEBUG("target->state: %s", target_state_name(target
));
888 if (target
->state
== TARGET_HALTED
) {
889 LOG_DEBUG("target was already halted");
893 if (target
->state
== TARGET_UNKNOWN
)
894 LOG_WARNING("target was in unknown state when halt was requested");
896 if (target
->state
== TARGET_RESET
) {
897 /* we came here in a reset_halt or reset_init sequence
898 * debug entry was already prepared in stm8_assert_reset()
900 target
->debug_reason
= DBG_REASON_DBGRQ
;
906 /* break processor */
907 stm8_debug_stall(target
);
909 target
->debug_reason
= DBG_REASON_DBGRQ
;
914 static int stm8_reset_assert(struct target
*target
)
917 struct stm8_common
*stm8
= target_to_stm8(target
);
918 bool use_srst_fallback
= true;
920 enum reset_types jtag_reset_config
= jtag_get_reset_config();
922 if (jtag_reset_config
& RESET_HAS_SRST
) {
923 res
= adapter_assert_reset();
925 /* hardware srst supported */
926 use_srst_fallback
= false;
927 else if (res
!= ERROR_COMMAND_NOTFOUND
)
928 /* some other failure */
932 if (use_srst_fallback
) {
933 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
934 res
= swim_system_reset();
939 /* registers are now invalid */
940 register_cache_invalidate(stm8
->core_cache
);
942 target
->state
= TARGET_RESET
;
943 target
->debug_reason
= DBG_REASON_NOTHALTED
;
945 if (target
->reset_halt
) {
946 res
= target_halt(target
);
954 static int stm8_reset_deassert(struct target
*target
)
957 enum reset_types jtag_reset_config
= jtag_get_reset_config();
959 if (jtag_reset_config
& RESET_HAS_SRST
) {
960 res
= adapter_deassert_reset();
961 if ((res
!= ERROR_OK
) && (res
!= ERROR_COMMAND_NOTFOUND
))
965 /* The cpu should now be stalled. If halt was requested
966 let poll detect the stall */
967 if (target
->reset_halt
)
970 /* Instead of going through saving context, polling and
971 then resuming target again just clear stall and proceed. */
972 target
->state
= TARGET_RUNNING
;
973 return stm8_exit_debug(target
);
976 /* stm8_single_step_core() is only used for stepping over breakpoints
977 from stm8_resume() */
978 static int stm8_single_step_core(struct target
*target
)
980 struct stm8_common
*stm8
= target_to_stm8(target
);
982 /* configure single step mode */
983 stm8_config_step(target
, 1);
985 /* disable interrupts while stepping */
986 if (!stm8
->enable_step_irq
)
987 stm8_enable_interrupts(target
, 0);
989 /* exit debug mode */
990 stm8_exit_debug(target
);
992 stm8_debug_entry(target
);
997 static int stm8_resume(struct target
*target
, int current
,
998 target_addr_t address
, int handle_breakpoints
,
1001 struct stm8_common
*stm8
= target_to_stm8(target
);
1002 struct breakpoint
*breakpoint
= NULL
;
1005 LOG_DEBUG("%d " TARGET_ADDR_FMT
" %d %d", current
, address
,
1006 handle_breakpoints
, debug_execution
);
1008 if (target
->state
!= TARGET_HALTED
) {
1009 LOG_WARNING("target not halted");
1010 return ERROR_TARGET_NOT_HALTED
;
1013 if (!debug_execution
) {
1014 target_free_all_working_areas(target
);
1015 stm8_enable_breakpoints(target
);
1016 stm8_enable_watchpoints(target
);
1017 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1018 stm8_set_hwbreak(target
, comparator_list
);
1021 /* current = 1: continue on current pc,
1022 otherwise continue at <address> */
1024 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1026 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1027 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1031 resume_pc
= address
;
1033 resume_pc
= buf_get_u32(
1034 stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1037 stm8_restore_context(target
);
1039 /* the front-end may request us not to handle breakpoints */
1040 if (handle_breakpoints
) {
1041 /* Single step past breakpoint at current address */
1042 breakpoint
= breakpoint_find(target
, resume_pc
);
1044 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
,
1045 breakpoint
->address
);
1046 stm8_unset_breakpoint(target
, breakpoint
);
1047 stm8_single_step_core(target
);
1048 stm8_set_breakpoint(target
, breakpoint
);
1052 /* disable interrupts if we are debugging */
1053 if (debug_execution
)
1054 stm8_enable_interrupts(target
, 0);
1056 /* exit debug mode */
1057 stm8_exit_debug(target
);
1058 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1060 /* registers are now invalid */
1061 register_cache_invalidate(stm8
->core_cache
);
1063 if (!debug_execution
) {
1064 target
->state
= TARGET_RUNNING
;
1065 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1066 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
1068 target
->state
= TARGET_DEBUG_RUNNING
;
1069 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1070 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
1076 static int stm8_init_flash_regs(bool enable_stm8l
, struct stm8_common
*stm8
)
1078 stm8
->enable_stm8l
= enable_stm8l
;
1080 if (stm8
->enable_stm8l
) {
1081 stm8
->flash_cr2
= FLASH_CR2_STM8L
;
1082 stm8
->flash_ncr2
= FLASH_NCR2_STM8L
;
1083 stm8
->flash_iapsr
= FLASH_IAPSR_STM8L
;
1084 stm8
->flash_dukr
= FLASH_DUKR_STM8L
;
1085 stm8
->flash_pukr
= FLASH_PUKR_STM8L
;
1087 stm8
->flash_cr2
= FLASH_CR2_STM8S
;
1088 stm8
->flash_ncr2
= FLASH_NCR2_STM8S
;
1089 stm8
->flash_iapsr
= FLASH_IAPSR_STM8S
;
1090 stm8
->flash_dukr
= FLASH_DUKR_STM8S
;
1091 stm8
->flash_pukr
= FLASH_PUKR_STM8S
;
1096 static int stm8_init_arch_info(struct target
*target
,
1097 struct stm8_common
*stm8
, struct jtag_tap
*tap
)
1099 target
->endianness
= TARGET_BIG_ENDIAN
;
1100 target
->arch_info
= stm8
;
1101 stm8
->common_magic
= STM8_COMMON_MAGIC
;
1102 stm8
->fast_data_area
= NULL
;
1103 stm8
->blocksize
= 0x80;
1104 stm8
->flashstart
= 0x8000;
1105 stm8
->flashend
= 0xffff;
1106 stm8
->eepromstart
= 0x4000;
1107 stm8
->eepromend
= 0x43ff;
1108 stm8
->optionstart
= 0x4800;
1109 stm8
->optionend
= 0x487F;
1111 /* has breakpoint/watchpoint unit been scanned */
1112 stm8
->bp_scanned
= false;
1113 stm8
->hw_break_list
= NULL
;
1115 stm8
->read_core_reg
= stm8_read_core_reg
;
1116 stm8
->write_core_reg
= stm8_write_core_reg
;
1118 stm8_init_flash_regs(0, stm8
);
1123 static int stm8_target_create(struct target
*target
,
1127 struct stm8_common
*stm8
= calloc(1, sizeof(struct stm8_common
));
1129 stm8_init_arch_info(target
, stm8
, target
->tap
);
1130 stm8_configure_break_unit(target
);
1135 static int stm8_read_core_reg(struct target
*target
, unsigned int num
)
1139 /* get pointers to arch-specific information */
1140 struct stm8_common
*stm8
= target_to_stm8(target
);
1142 if (num
>= STM8_NUM_REGS
)
1143 return ERROR_COMMAND_SYNTAX_ERROR
;
1145 reg_value
= stm8
->core_regs
[num
];
1146 LOG_DEBUG("read core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1147 buf_set_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
1148 stm8
->core_cache
->reg_list
[num
].valid
= true;
1149 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1154 static int stm8_write_core_reg(struct target
*target
, unsigned int num
)
1158 /* get pointers to arch-specific information */
1159 struct stm8_common
*stm8
= target_to_stm8(target
);
1161 if (num
>= STM8_NUM_REGS
)
1162 return ERROR_COMMAND_SYNTAX_ERROR
;
1164 reg_value
= buf_get_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32);
1165 stm8
->core_regs
[num
] = reg_value
;
1166 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1167 stm8
->core_cache
->reg_list
[num
].valid
= true;
1168 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1173 static const char *stm8_get_gdb_arch(struct target
*target
)
1178 static int stm8_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1179 int *reg_list_size
, enum target_register_class reg_class
)
1181 /* get pointers to arch-specific information */
1182 struct stm8_common
*stm8
= target_to_stm8(target
);
1185 *reg_list_size
= STM8_NUM_REGS
;
1186 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1188 for (i
= 0; i
< STM8_NUM_REGS
; i
++)
1189 (*reg_list
)[i
] = &stm8
->core_cache
->reg_list
[i
];
1194 static const struct reg_arch_type stm8_reg_type
= {
1195 .get
= stm8_get_core_reg
,
1196 .set
= stm8_set_core_reg
,
1199 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
)
1201 /* get pointers to arch-specific information */
1202 struct stm8_common
*stm8
= target_to_stm8(target
);
1204 int num_regs
= STM8_NUM_REGS
;
1205 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1206 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1207 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1208 struct stm8_core_reg
*arch_info
= malloc(
1209 sizeof(struct stm8_core_reg
) * num_regs
);
1210 struct reg_feature
*feature
;
1213 /* Build the process context cache */
1214 cache
->name
= "stm8 registers";
1216 cache
->reg_list
= reg_list
;
1217 cache
->num_regs
= num_regs
;
1219 stm8
->core_cache
= cache
;
1221 for (i
= 0; i
< num_regs
; i
++) {
1222 arch_info
[i
].num
= stm8_regs
[i
].id
;
1223 arch_info
[i
].target
= target
;
1224 arch_info
[i
].stm8_common
= stm8
;
1226 reg_list
[i
].name
= stm8_regs
[i
].name
;
1227 reg_list
[i
].size
= stm8_regs
[i
].bits
;
1229 reg_list
[i
].value
= calloc(1, 4);
1230 reg_list
[i
].valid
= false;
1231 reg_list
[i
].type
= &stm8_reg_type
;
1232 reg_list
[i
].arch_info
= &arch_info
[i
];
1234 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1235 if (reg_list
[i
].reg_data_type
)
1236 reg_list
[i
].reg_data_type
->type
= stm8_regs
[i
].type
;
1238 LOG_ERROR("unable to allocate reg type list");
1242 reg_list
[i
].dirty
= false;
1243 reg_list
[i
].group
= stm8_regs
[i
].group
;
1244 reg_list
[i
].number
= stm8_regs
[i
].id
;
1245 reg_list
[i
].exist
= true;
1246 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1248 feature
= calloc(1, sizeof(struct reg_feature
));
1250 feature
->name
= stm8_regs
[i
].feature
;
1251 reg_list
[i
].feature
= feature
;
1253 LOG_ERROR("unable to allocate feature list");
1259 static void stm8_free_reg_cache(struct target
*target
)
1261 struct stm8_common
*stm8
= target_to_stm8(target
);
1262 struct reg_cache
*cache
;
1266 cache
= stm8
->core_cache
;
1271 for (i
= 0; i
< cache
->num_regs
; i
++) {
1272 reg
= &cache
->reg_list
[i
];
1275 free(reg
->reg_data_type
);
1279 free(cache
->reg_list
[0].arch_info
);
1280 free(cache
->reg_list
);
1283 stm8
->core_cache
= NULL
;
1286 static void stm8_deinit(struct target
*target
)
1288 struct stm8_common
*stm8
= target_to_stm8(target
);
1290 free(stm8
->hw_break_list
);
1292 stm8_free_reg_cache(target
);
1297 static int stm8_arch_state(struct target
*target
)
1299 struct stm8_common
*stm8
= target_to_stm8(target
);
1301 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
1302 debug_reason_name(target
),
1303 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1308 static int stm8_step(struct target
*target
, int current
,
1309 target_addr_t address
, int handle_breakpoints
)
1311 LOG_DEBUG("%x " TARGET_ADDR_FMT
" %x",
1312 current
, address
, handle_breakpoints
);
1314 /* get pointers to arch-specific information */
1315 struct stm8_common
*stm8
= target_to_stm8(target
);
1316 struct breakpoint
*breakpoint
= NULL
;
1318 if (target
->state
!= TARGET_HALTED
) {
1319 LOG_WARNING("target not halted");
1320 return ERROR_TARGET_NOT_HALTED
;
1323 /* current = 1: continue on current pc, otherwise continue at <address> */
1325 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32, address
);
1326 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1327 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1330 /* the front-end may request us not to handle breakpoints */
1331 if (handle_breakpoints
) {
1332 breakpoint
= breakpoint_find(target
,
1333 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1335 stm8_unset_breakpoint(target
, breakpoint
);
1338 /* restore context */
1339 stm8_restore_context(target
);
1341 /* configure single step mode */
1342 stm8_config_step(target
, 1);
1344 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1346 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1348 /* disable interrupts while stepping */
1349 if (!stm8
->enable_step_irq
)
1350 stm8_enable_interrupts(target
, 0);
1352 /* exit debug mode */
1353 stm8_exit_debug(target
);
1355 /* registers are now invalid */
1356 register_cache_invalidate(stm8
->core_cache
);
1358 LOG_DEBUG("target stepped ");
1359 stm8_debug_entry(target
);
1362 stm8_set_breakpoint(target
, breakpoint
);
1364 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1369 static void stm8_enable_breakpoints(struct target
*target
)
1371 struct breakpoint
*breakpoint
= target
->breakpoints
;
1373 /* set any pending breakpoints */
1374 while (breakpoint
) {
1375 if (breakpoint
->set
== 0)
1376 stm8_set_breakpoint(target
, breakpoint
);
1377 breakpoint
= breakpoint
->next
;
1381 static int stm8_set_breakpoint(struct target
*target
,
1382 struct breakpoint
*breakpoint
)
1384 struct stm8_common
*stm8
= target_to_stm8(target
);
1385 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1388 if (breakpoint
->set
) {
1389 LOG_WARNING("breakpoint already set");
1393 if (breakpoint
->type
== BKPT_HARD
) {
1396 while (comparator_list
[bp_num
].used
&& (bp_num
< stm8
->num_hw_bpoints
))
1398 if (bp_num
>= stm8
->num_hw_bpoints
) {
1399 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32
")",
1400 breakpoint
->unique_id
);
1401 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1403 breakpoint
->set
= bp_num
+ 1;
1404 comparator_list
[bp_num
].used
= true;
1405 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
1406 comparator_list
[bp_num
].type
= HWBRK_EXEC
;
1408 retval
= stm8_set_hwbreak(target
, comparator_list
);
1409 if (retval
!= ERROR_OK
)
1412 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1413 breakpoint
->unique_id
,
1414 bp_num
, comparator_list
[bp_num
].bp_value
);
1415 } else if (breakpoint
->type
== BKPT_SOFT
) {
1416 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1417 if (breakpoint
->length
== 1) {
1418 uint8_t verify
= 0x55;
1420 retval
= target_read_u8(target
, breakpoint
->address
,
1421 breakpoint
->orig_instr
);
1422 if (retval
!= ERROR_OK
)
1424 retval
= target_write_u8(target
, breakpoint
->address
, STM8_BREAK
);
1425 if (retval
!= ERROR_OK
)
1428 retval
= target_read_u8(target
, breakpoint
->address
, &verify
);
1429 if (retval
!= ERROR_OK
)
1431 if (verify
!= STM8_BREAK
) {
1432 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1433 " - check that memory is read/writable",
1434 breakpoint
->address
);
1435 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1438 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1440 breakpoint
->set
= 1; /* Any nice value but 0 */
1446 static int stm8_add_breakpoint(struct target
*target
,
1447 struct breakpoint
*breakpoint
)
1449 struct stm8_common
*stm8
= target_to_stm8(target
);
1452 if (breakpoint
->type
== BKPT_HARD
) {
1453 if (stm8
->num_hw_bpoints_avail
< 1) {
1454 LOG_INFO("no hardware breakpoint available");
1455 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1458 ret
= stm8_set_breakpoint(target
, breakpoint
);
1459 if (ret
!= ERROR_OK
)
1462 stm8
->num_hw_bpoints_avail
--;
1466 ret
= stm8_set_breakpoint(target
, breakpoint
);
1467 if (ret
!= ERROR_OK
)
1473 static int stm8_unset_breakpoint(struct target
*target
,
1474 struct breakpoint
*breakpoint
)
1476 /* get pointers to arch-specific information */
1477 struct stm8_common
*stm8
= target_to_stm8(target
);
1478 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1481 if (!breakpoint
->set
) {
1482 LOG_WARNING("breakpoint not set");
1486 if (breakpoint
->type
== BKPT_HARD
) {
1487 int bp_num
= breakpoint
->set
- 1;
1488 if ((bp_num
< 0) || (bp_num
>= stm8
->num_hw_bpoints
)) {
1489 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1490 breakpoint
->unique_id
);
1493 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d",
1494 breakpoint
->unique_id
,
1496 comparator_list
[bp_num
].used
= false;
1497 retval
= stm8_set_hwbreak(target
, comparator_list
);
1498 if (retval
!= ERROR_OK
)
1501 /* restore original instruction (kept in target endianness) */
1502 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1503 if (breakpoint
->length
== 1) {
1504 uint8_t current_instr
;
1506 /* check that user program has not
1507 modified breakpoint instruction */
1508 retval
= target_read_memory(target
, breakpoint
->address
, 1, 1,
1509 (uint8_t *)¤t_instr
);
1510 if (retval
!= ERROR_OK
)
1513 if (current_instr
== STM8_BREAK
) {
1514 retval
= target_write_memory(target
, breakpoint
->address
, 1, 1,
1515 breakpoint
->orig_instr
);
1516 if (retval
!= ERROR_OK
)
1522 breakpoint
->set
= 0;
1527 static int stm8_remove_breakpoint(struct target
*target
,
1528 struct breakpoint
*breakpoint
)
1530 /* get pointers to arch-specific information */
1531 struct stm8_common
*stm8
= target_to_stm8(target
);
1533 if (target
->state
!= TARGET_HALTED
) {
1534 LOG_WARNING("target not halted");
1535 return ERROR_TARGET_NOT_HALTED
;
1538 if (breakpoint
->set
)
1539 stm8_unset_breakpoint(target
, breakpoint
);
1541 if (breakpoint
->type
== BKPT_HARD
)
1542 stm8
->num_hw_bpoints_avail
++;
1547 static int stm8_set_watchpoint(struct target
*target
,
1548 struct watchpoint
*watchpoint
)
1550 struct stm8_common
*stm8
= target_to_stm8(target
);
1551 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1555 if (watchpoint
->set
) {
1556 LOG_WARNING("watchpoint already set");
1560 while (comparator_list
[wp_num
].used
&& (wp_num
< stm8
->num_hw_bpoints
))
1562 if (wp_num
>= stm8
->num_hw_bpoints
) {
1563 LOG_ERROR("Can not find free hw breakpoint");
1564 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1567 if (watchpoint
->length
!= 1) {
1568 LOG_ERROR("Only watchpoints of length 1 are supported");
1569 return ERROR_TARGET_UNALIGNED_ACCESS
;
1572 enum hw_break_type enable
= 0;
1574 switch (watchpoint
->rw
) {
1585 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1588 comparator_list
[wp_num
].used
= true;
1589 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
1590 comparator_list
[wp_num
].type
= enable
;
1592 ret
= stm8_set_hwbreak(target
, comparator_list
);
1593 if (ret
!= ERROR_OK
) {
1594 comparator_list
[wp_num
].used
= false;
1598 watchpoint
->set
= wp_num
+ 1;
1600 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"",
1602 comparator_list
[wp_num
].bp_value
);
1607 static int stm8_add_watchpoint(struct target
*target
,
1608 struct watchpoint
*watchpoint
)
1611 struct stm8_common
*stm8
= target_to_stm8(target
);
1613 if (stm8
->num_hw_bpoints_avail
< 1) {
1614 LOG_INFO("no hardware watchpoints available");
1615 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1618 ret
= stm8_set_watchpoint(target
, watchpoint
);
1619 if (ret
!= ERROR_OK
)
1622 stm8
->num_hw_bpoints_avail
--;
1626 static void stm8_enable_watchpoints(struct target
*target
)
1628 struct watchpoint
*watchpoint
= target
->watchpoints
;
1630 /* set any pending watchpoints */
1631 while (watchpoint
) {
1632 if (watchpoint
->set
== 0)
1633 stm8_set_watchpoint(target
, watchpoint
);
1634 watchpoint
= watchpoint
->next
;
1638 static int stm8_unset_watchpoint(struct target
*target
,
1639 struct watchpoint
*watchpoint
)
1641 /* get pointers to arch-specific information */
1642 struct stm8_common
*stm8
= target_to_stm8(target
);
1643 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1645 if (!watchpoint
->set
) {
1646 LOG_WARNING("watchpoint not set");
1650 int wp_num
= watchpoint
->set
- 1;
1651 if ((wp_num
< 0) || (wp_num
>= stm8
->num_hw_bpoints
)) {
1652 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1655 comparator_list
[wp_num
].used
= false;
1656 watchpoint
->set
= 0;
1658 stm8_set_hwbreak(target
, comparator_list
);
1663 static int stm8_remove_watchpoint(struct target
*target
,
1664 struct watchpoint
*watchpoint
)
1666 /* get pointers to arch-specific information */
1667 struct stm8_common
*stm8
= target_to_stm8(target
);
1669 if (target
->state
!= TARGET_HALTED
) {
1670 LOG_WARNING("target not halted");
1671 return ERROR_TARGET_NOT_HALTED
;
1674 if (watchpoint
->set
)
1675 stm8_unset_watchpoint(target
, watchpoint
);
1677 stm8
->num_hw_bpoints_avail
++;
1682 static int stm8_examine(struct target
*target
)
1686 /* get pointers to arch-specific information */
1687 struct stm8_common
*stm8
= target_to_stm8(target
);
1688 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1690 if (!target_was_examined(target
)) {
1691 if (!stm8
->swim_configured
) {
1692 stm8
->swim_configured
= true;
1694 Now is the time to deassert reset if connect_under_reset.
1695 Releasing reset line will cause the option bytes to load.
1696 The core will still be stalled.
1698 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
1699 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
1700 stm8_reset_deassert(target
);
1702 LOG_WARNING("\'srst_nogate\' reset_config option is required");
1705 LOG_INFO("trying to reconnect");
1707 retval
= swim_reconnect();
1708 if (retval
!= ERROR_OK
) {
1709 LOG_ERROR("reconnect failed");
1713 /* read dm_csrx control regs */
1714 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
1715 if (retval
!= ERROR_OK
) {
1716 LOG_ERROR("state query failed");
1721 target_set_examined(target
);
1729 /** Checks whether a memory region is erased. */
1730 static int stm8_blank_check_memory(struct target
*target
,
1731 struct target_memory_check_block
*blocks
, int num_blocks
, uint8_t erased_value
)
1733 struct working_area
*erase_check_algorithm
;
1734 struct reg_param reg_params
[2];
1735 struct mem_param mem_params
[2];
1736 struct stm8_algorithm stm8_info
;
1738 static const uint8_t stm8_erase_check_code
[] = {
1739 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1742 if (erased_value
!= 0xff) {
1743 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for STM8",
1748 /* make sure we have a working area */
1749 if (target_alloc_working_area(target
, sizeof(stm8_erase_check_code
),
1750 &erase_check_algorithm
) != ERROR_OK
)
1751 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1753 target_write_buffer(target
, erase_check_algorithm
->address
,
1754 sizeof(stm8_erase_check_code
), stm8_erase_check_code
);
1756 stm8_info
.common_magic
= STM8_COMMON_MAGIC
;
1758 init_mem_param(&mem_params
[0], 0x0, 3, PARAM_OUT
);
1759 buf_set_u32(mem_params
[0].value
, 0, 24, blocks
[0].address
);
1761 init_mem_param(&mem_params
[1], 0x3, 3, PARAM_OUT
);
1762 buf_set_u32(mem_params
[1].value
, 0, 24, blocks
[0].size
);
1764 init_reg_param(®_params
[0], "a", 32, PARAM_IN_OUT
);
1765 buf_set_u32(reg_params
[0].value
, 0, 32, erased_value
);
1767 init_reg_param(®_params
[1], "sp", 32, PARAM_OUT
);
1768 buf_set_u32(reg_params
[1].value
, 0, 32, erase_check_algorithm
->address
);
1770 int retval
= target_run_algorithm(target
, 2, mem_params
, 2, reg_params
,
1771 erase_check_algorithm
->address
+ 6,
1772 erase_check_algorithm
->address
+ (sizeof(stm8_erase_check_code
) - 1),
1775 if (retval
== ERROR_OK
)
1776 blocks
[0].result
= (*(reg_params
[0].value
) == 0xff);
1778 destroy_mem_param(&mem_params
[0]);
1779 destroy_mem_param(&mem_params
[1]);
1780 destroy_reg_param(®_params
[0]);
1781 destroy_reg_param(®_params
[1]);
1783 target_free_working_area(target
, erase_check_algorithm
);
1785 if (retval
!= ERROR_OK
)
1788 return 1; /* only one block has been checked */
1791 static int stm8_checksum_memory(struct target
*target
, target_addr_t address
,
1792 uint32_t count
, uint32_t *checksum
)
1794 /* let image_calculate_checksum() take care of business */
1795 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1798 /* run to exit point. return error if exit point was not reached. */
1799 static int stm8_run_and_wait(struct target
*target
, uint32_t entry_point
,
1800 int timeout_ms
, uint32_t exit_point
, struct stm8_common
*stm8
)
1804 /* This code relies on the target specific resume() and
1805 poll()->debug_entry() sequence to write register values to the
1806 processor and the read them back */
1807 retval
= target_resume(target
, 0, entry_point
, 0, 1);
1808 if (retval
!= ERROR_OK
)
1811 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1812 /* If the target fails to halt due to the breakpoint, force a halt */
1813 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
1814 retval
= target_halt(target
);
1815 if (retval
!= ERROR_OK
)
1817 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
1818 if (retval
!= ERROR_OK
)
1820 return ERROR_TARGET_TIMEOUT
;
1823 pc
= buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32);
1824 if (exit_point
&& (pc
!= exit_point
)) {
1825 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
1826 return ERROR_TARGET_TIMEOUT
;
1832 static int stm8_run_algorithm(struct target
*target
, int num_mem_params
,
1833 struct mem_param
*mem_params
, int num_reg_params
,
1834 struct reg_param
*reg_params
, target_addr_t entry_point
,
1835 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
1837 struct stm8_common
*stm8
= target_to_stm8(target
);
1839 uint32_t context
[STM8_NUM_REGS
];
1840 int retval
= ERROR_OK
;
1842 LOG_DEBUG("Running algorithm");
1844 /* NOTE: stm8_run_algorithm requires that each
1845 algorithm uses a software breakpoint
1846 at the exit point */
1848 if (stm8
->common_magic
!= STM8_COMMON_MAGIC
) {
1849 LOG_ERROR("current target isn't a STM8 target");
1850 return ERROR_TARGET_INVALID
;
1853 if (target
->state
!= TARGET_HALTED
) {
1854 LOG_WARNING("target not halted");
1855 return ERROR_TARGET_NOT_HALTED
;
1858 /* refresh core register cache */
1859 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1860 if (!stm8
->core_cache
->reg_list
[i
].valid
)
1861 stm8
->read_core_reg(target
, i
);
1862 context
[i
] = buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1865 for (int i
= 0; i
< num_mem_params
; i
++) {
1866 if (mem_params
[i
].direction
== PARAM_IN
)
1868 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1869 mem_params
[i
].size
, mem_params
[i
].value
);
1870 if (retval
!= ERROR_OK
)
1874 for (int i
= 0; i
< num_reg_params
; i
++) {
1875 if (reg_params
[i
].direction
== PARAM_IN
)
1878 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1879 reg_params
[i
].reg_name
, 0);
1882 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1883 return ERROR_COMMAND_SYNTAX_ERROR
;
1886 if (reg_params
[i
].size
!= 32) {
1887 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1888 reg_params
[i
].reg_name
);
1889 return ERROR_COMMAND_SYNTAX_ERROR
;
1892 stm8_set_core_reg(reg
, reg_params
[i
].value
);
1895 retval
= stm8_run_and_wait(target
, entry_point
,
1896 timeout_ms
, exit_point
, stm8
);
1898 if (retval
!= ERROR_OK
)
1901 for (int i
= 0; i
< num_mem_params
; i
++) {
1902 if (mem_params
[i
].direction
!= PARAM_OUT
) {
1903 retval
= target_read_buffer(target
, mem_params
[i
].address
,
1904 mem_params
[i
].size
, mem_params
[i
].value
);
1905 if (retval
!= ERROR_OK
)
1910 for (int i
= 0; i
< num_reg_params
; i
++) {
1911 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1912 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1913 reg_params
[i
].reg_name
, 0);
1915 LOG_ERROR("BUG: register '%s' not found",
1916 reg_params
[i
].reg_name
);
1917 return ERROR_COMMAND_SYNTAX_ERROR
;
1920 if (reg_params
[i
].size
!= 32) {
1921 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1922 reg_params
[i
].reg_name
);
1923 return ERROR_COMMAND_SYNTAX_ERROR
;
1926 buf_set_u32(reg_params
[i
].value
,
1927 0, 32, buf_get_u32(reg
->value
, 0, 32));
1931 /* restore everything we saved before */
1932 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1934 regvalue
= buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1935 if (regvalue
!= context
[i
]) {
1936 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
1937 stm8
->core_cache
->reg_list
[i
].name
, context
[i
]);
1938 buf_set_u32(stm8
->core_cache
->reg_list
[i
].value
,
1940 stm8
->core_cache
->reg_list
[i
].valid
= true;
1941 stm8
->core_cache
->reg_list
[i
].dirty
= true;
1948 static int stm8_jim_configure(struct target
*target
, Jim_GetOptInfo
*goi
)
1950 struct stm8_common
*stm8
= target_to_stm8(target
);
1955 arg
= Jim_GetString(goi
->argv
[0], NULL
);
1956 if (!strcmp(arg
, "-blocksize")) {
1957 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1961 if (goi
->argc
== 0) {
1962 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1963 "-blocksize ?bytes? ...");
1967 e
= Jim_GetOpt_Wide(goi
, &w
);
1971 stm8
->blocksize
= w
;
1972 LOG_DEBUG("blocksize=%8.8" PRIx32
, stm8
->blocksize
);
1975 if (!strcmp(arg
, "-flashstart")) {
1976 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1980 if (goi
->argc
== 0) {
1981 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1982 "-flashstart ?address? ...");
1986 e
= Jim_GetOpt_Wide(goi
, &w
);
1990 stm8
->flashstart
= w
;
1991 LOG_DEBUG("flashstart=%8.8" PRIx32
, stm8
->flashstart
);
1994 if (!strcmp(arg
, "-flashend")) {
1995 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1999 if (goi
->argc
== 0) {
2000 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2001 "-flashend ?address? ...");
2005 e
= Jim_GetOpt_Wide(goi
, &w
);
2010 LOG_DEBUG("flashend=%8.8" PRIx32
, stm8
->flashend
);
2013 if (!strcmp(arg
, "-eepromstart")) {
2014 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2018 if (goi
->argc
== 0) {
2019 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2020 "-eepromstart ?address? ...");
2024 e
= Jim_GetOpt_Wide(goi
, &w
);
2028 stm8
->eepromstart
= w
;
2029 LOG_DEBUG("eepromstart=%8.8" PRIx32
, stm8
->eepromstart
);
2032 if (!strcmp(arg
, "-eepromend")) {
2033 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2037 if (goi
->argc
== 0) {
2038 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2039 "-eepromend ?address? ...");
2043 e
= Jim_GetOpt_Wide(goi
, &w
);
2047 stm8
->eepromend
= w
;
2048 LOG_DEBUG("eepromend=%8.8" PRIx32
, stm8
->eepromend
);
2051 if (!strcmp(arg
, "-optionstart")) {
2052 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2056 if (goi
->argc
== 0) {
2057 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2058 "-optionstart ?address? ...");
2062 e
= Jim_GetOpt_Wide(goi
, &w
);
2066 stm8
->optionstart
= w
;
2067 LOG_DEBUG("optionstart=%8.8" PRIx32
, stm8
->optionstart
);
2070 if (!strcmp(arg
, "-optionend")) {
2071 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2075 if (goi
->argc
== 0) {
2076 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2077 "-optionend ?address? ...");
2081 e
= Jim_GetOpt_Wide(goi
, &w
);
2085 stm8
->optionend
= w
;
2086 LOG_DEBUG("optionend=%8.8" PRIx32
, stm8
->optionend
);
2089 if (!strcmp(arg
, "-enable_step_irq")) {
2090 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2094 stm8
->enable_step_irq
= true;
2095 LOG_DEBUG("enable_step_irq=%8.8x", stm8
->enable_step_irq
);
2098 if (!strcmp(arg
, "-enable_stm8l")) {
2099 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2103 stm8
->enable_stm8l
= true;
2104 LOG_DEBUG("enable_stm8l=%8.8x", stm8
->enable_stm8l
);
2105 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2108 return JIM_CONTINUE
;
2111 COMMAND_HANDLER(stm8_handle_enable_step_irq_command
)
2114 struct target
*target
= get_current_target(CMD_CTX
);
2115 struct stm8_common
*stm8
= target_to_stm8(target
);
2116 bool enable
= stm8
->enable_step_irq
;
2119 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2120 stm8
->enable_step_irq
= enable
;
2122 msg
= stm8
->enable_step_irq
? "enabled" : "disabled";
2123 command_print(CMD
, "enable_step_irq = %s", msg
);
2127 COMMAND_HANDLER(stm8_handle_enable_stm8l_command
)
2130 struct target
*target
= get_current_target(CMD_CTX
);
2131 struct stm8_common
*stm8
= target_to_stm8(target
);
2132 bool enable
= stm8
->enable_stm8l
;
2135 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2136 stm8
->enable_stm8l
= enable
;
2138 msg
= stm8
->enable_stm8l
? "enabled" : "disabled";
2139 command_print(CMD
, "enable_stm8l = %s", msg
);
2140 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2144 static const struct command_registration stm8_exec_command_handlers
[] = {
2146 .name
= "enable_step_irq",
2147 .handler
= stm8_handle_enable_step_irq_command
,
2148 .mode
= COMMAND_ANY
,
2149 .help
= "Enable/disable irq handling during step",
2153 .name
= "enable_stm8l",
2154 .handler
= stm8_handle_enable_stm8l_command
,
2155 .mode
= COMMAND_ANY
,
2156 .help
= "Enable/disable STM8L flash programming",
2159 COMMAND_REGISTRATION_DONE
2162 const struct command_registration stm8_command_handlers
[] = {
2165 .mode
= COMMAND_ANY
,
2166 .help
= "stm8 command group",
2168 .chain
= stm8_exec_command_handlers
,
2170 COMMAND_REGISTRATION_DONE
2173 struct target_type stm8_target
= {
2177 .arch_state
= stm8_arch_state
,
2180 .resume
= stm8_resume
,
2183 .assert_reset
= stm8_reset_assert
,
2184 .deassert_reset
= stm8_reset_deassert
,
2186 .get_gdb_arch
= stm8_get_gdb_arch
,
2187 .get_gdb_reg_list
= stm8_get_gdb_reg_list
,
2189 .read_memory
= stm8_read_memory
,
2190 .write_memory
= stm8_write_memory
,
2191 .checksum_memory
= stm8_checksum_memory
,
2192 .blank_check_memory
= stm8_blank_check_memory
,
2194 .run_algorithm
= stm8_run_algorithm
,
2196 .add_breakpoint
= stm8_add_breakpoint
,
2197 .remove_breakpoint
= stm8_remove_breakpoint
,
2198 .add_watchpoint
= stm8_add_watchpoint
,
2199 .remove_watchpoint
= stm8_remove_watchpoint
,
2201 .commands
= stm8_command_handlers
,
2202 .target_create
= stm8_target_create
,
2203 .init_target
= stm8_init
,
2204 .examine
= stm8_examine
,
2206 .deinit_target
= stm8_deinit
,
2207 .target_jim_configure
= stm8_jim_configure
,