1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * OpenOCD STM8 target driver
5 * Copyright (C) 2017 Ake Rehnman
6 * ake.rehnman(at)gmail.com
13 #include <helper/log.h>
15 #include "target_type.h"
17 #include "jtag/interface.h"
18 #include "jtag/jtag.h"
19 #include "jtag/swim.h"
21 #include "breakpoints.h"
22 #include "algorithm.h"
25 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
);
26 static int stm8_read_core_reg(struct target
*target
, unsigned int num
);
27 static int stm8_write_core_reg(struct target
*target
, unsigned int num
);
28 static int stm8_save_context(struct target
*target
);
29 static void stm8_enable_breakpoints(struct target
*target
);
30 static int stm8_unset_breakpoint(struct target
*target
,
31 struct breakpoint
*breakpoint
);
32 static int stm8_set_breakpoint(struct target
*target
,
33 struct breakpoint
*breakpoint
);
34 static void stm8_enable_watchpoints(struct target
*target
);
35 static int stm8_unset_watchpoint(struct target
*target
,
36 struct watchpoint
*watchpoint
);
37 static int (*adapter_speed
)(int speed
);
38 extern struct adapter_driver
*adapter_driver
;
49 { 0, "pc", 32, REG_TYPE_UINT32
, "general", "org.gnu.gdb.stm8.core", 0 },
50 { 1, "a", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
51 { 2, "x", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
52 { 3, "y", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
53 { 4, "sp", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
54 { 5, "cc", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
57 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
68 #define DM_REGS 0x7f00
69 #define DM_REG_A 0x7f00
70 #define DM_REG_PC 0x7f01
71 #define DM_REG_X 0x7f04
72 #define DM_REG_Y 0x7f06
73 #define DM_REG_SP 0x7f08
74 #define DM_REG_CC 0x7f0a
76 #define DM_BKR1E 0x7f90
77 #define DM_BKR2E 0x7f93
80 #define DM_CSR1 0x7f98
81 #define DM_CSR2 0x7f99
95 #define FLASH_CR1_STM8S 0x505A
96 #define FLASH_CR2_STM8S 0x505B
97 #define FLASH_NCR2_STM8S 0x505C
98 #define FLASH_IAPSR_STM8S 0x505F
99 #define FLASH_PUKR_STM8S 0x5062
100 #define FLASH_DUKR_STM8S 0x5064
102 #define FLASH_CR1_STM8L 0x5050
103 #define FLASH_CR2_STM8L 0x5051
104 #define FLASH_NCR2_STM8L 0
105 #define FLASH_PUKR_STM8L 0x5052
106 #define FLASH_DUKR_STM8L 0x5053
107 #define FLASH_IAPSR_STM8L 0x5054
114 #define WR_PG_DIS 0x01
124 #define SAFE_MASK 0x80
125 #define NO_ACCESS 0x40
129 #define SWIM_RST 0x04
133 #define SWIM_CSR 0x7f80
135 #define STM8_BREAK 0x8B
144 struct stm8_algorithm
{
148 struct stm8_core_reg
{
150 struct target
*target
;
154 /* break on execute */
160 /* break on read, write and execute */
164 struct stm8_comparator
{
167 uint32_t reg_address
;
168 enum hw_break_type type
;
171 static int stm8_adapter_read_memory(struct target
*target
,
172 uint32_t addr
, int size
, int count
, void *buf
)
174 return swim_read_mem(addr
, size
, count
, buf
);
177 static int stm8_adapter_write_memory(struct target
*target
,
178 uint32_t addr
, int size
, int count
, const void *buf
)
180 return swim_write_mem(addr
, size
, count
, buf
);
183 static int stm8_write_u8(struct target
*target
,
184 uint32_t addr
, uint8_t val
)
189 return swim_write_mem(addr
, 1, 1, buf
);
192 static int stm8_read_u8(struct target
*target
,
193 uint32_t addr
, uint8_t *val
)
195 return swim_read_mem(addr
, 1, 1, val
);
199 <enable == 0> Disables interrupts.
200 If interrupts are enabled they are masked and the cc register
203 <enable == 1> Enables interrupts.
204 Enable interrupts is actually restoring I1 I0 state from previous
205 call with enable == 0. Note that if stepping and breaking on a sim
206 instruction will NOT work since the interrupt flags are restored on
207 debug_entry. We don't have any way for the debugger to exclusively
208 disable the interrupts
210 static int stm8_enable_interrupts(struct target
*target
, int enable
)
212 struct stm8_common
*stm8
= target_to_stm8(target
);
217 return ERROR_OK
; /* cc was not stashed */
218 /* fetch current cc */
219 stm8_read_u8(target
, DM_REG_CC
, &cc
);
221 cc
&= ~(CC_I0
+ CC_I1
);
222 /* restore I1 & I0 from stash*/
223 cc
|= (stm8
->cc
& (CC_I0
+CC_I1
));
224 /* update current cc */
225 stm8_write_u8(target
, DM_REG_CC
, cc
);
226 stm8
->cc_valid
= false;
228 stm8_read_u8(target
, DM_REG_CC
, &cc
);
229 if ((cc
& CC_I0
) && (cc
& CC_I1
))
230 return ERROR_OK
; /* interrupts already masked */
233 stm8
->cc_valid
= true;
234 /* mask interrupts (disable) */
235 cc
|= (CC_I0
+ CC_I1
);
236 stm8_write_u8(target
, DM_REG_CC
, cc
);
242 static int stm8_set_hwbreak(struct target
*target
,
243 struct stm8_comparator comparator_list
[])
248 /* Refer to Table 4 in UM0470 */
256 if (!comparator_list
[0].used
) {
257 comparator_list
[0].type
= HWBRK_EXEC
;
258 comparator_list
[0].bp_value
= -1;
261 if (!comparator_list
[1].used
) {
262 comparator_list
[1].type
= HWBRK_EXEC
;
263 comparator_list
[1].bp_value
= -1;
266 if ((comparator_list
[0].type
== HWBRK_EXEC
)
267 && (comparator_list
[1].type
== HWBRK_EXEC
)) {
268 comparator_list
[0].reg_address
= 0;
269 comparator_list
[1].reg_address
= 1;
272 if ((comparator_list
[0].type
== HWBRK_EXEC
)
273 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
274 comparator_list
[0].reg_address
= 0;
275 comparator_list
[1].reg_address
= 1;
276 switch (comparator_list
[1].type
) {
290 if ((comparator_list
[1].type
== HWBRK_EXEC
)
291 && (comparator_list
[0].type
!= HWBRK_EXEC
)) {
292 comparator_list
[0].reg_address
= 1;
293 comparator_list
[1].reg_address
= 0;
294 switch (comparator_list
[0].type
) {
308 if ((comparator_list
[0].type
!= HWBRK_EXEC
)
309 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
310 if (comparator_list
[0].type
!= comparator_list
[1].type
) {
311 LOG_ERROR("data hw breakpoints must be of same type");
312 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
316 for (i
= 0; i
< 2; i
++) {
317 data
= comparator_list
[i
].bp_value
;
318 addr
= comparator_list
[i
].reg_address
;
325 ret
= stm8_adapter_write_memory(target
, DM_BKR1E
, 1, 3, buf
);
326 LOG_DEBUG("DM_BKR1E=%" PRIx32
, data
);
327 } else if (addr
== 1) {
328 ret
= stm8_adapter_write_memory(target
, DM_BKR2E
, 1, 3, buf
);
329 LOG_DEBUG("DM_BKR2E=%" PRIx32
, data
);
331 LOG_DEBUG("addr=%" PRIu32
, addr
);
338 ret
= stm8_write_u8(target
, DM_CR1
,
339 (bc
<< 3) + (bir
<< 2) + (biw
<< 1));
340 LOG_DEBUG("DM_CR1=%" PRIx8
, buf
[0]);
348 /* read DM control and status regs */
349 static int stm8_read_dm_csrx(struct target
*target
, uint8_t *csr1
,
355 ret
= stm8_adapter_read_memory(target
, DM_CSR1
, 1, sizeof(buf
), buf
);
365 /* set or clear the single step flag in DM */
366 static int stm8_config_step(struct target
*target
, int enable
)
371 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
379 ret
= stm8_write_u8(target
, DM_CSR1
, csr1
);
385 /* set the stall flag in DM */
386 static int stm8_debug_stall(struct target
*target
)
391 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
395 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
401 static int stm8_configure_break_unit(struct target
*target
)
403 /* get pointers to arch-specific information */
404 struct stm8_common
*stm8
= target_to_stm8(target
);
406 if (stm8
->bp_scanned
)
409 stm8
->num_hw_bpoints
= 2;
410 stm8
->num_hw_bpoints_avail
= stm8
->num_hw_bpoints
;
412 stm8
->hw_break_list
= calloc(stm8
->num_hw_bpoints
,
413 sizeof(struct stm8_comparator
));
415 stm8
->hw_break_list
[0].reg_address
= 0;
416 stm8
->hw_break_list
[1].reg_address
= 1;
418 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8
->num_hw_bpoints
,
419 stm8
->num_hw_bpoints
);
421 stm8
->bp_scanned
= true;
426 static int stm8_examine_debug_reason(struct target
*target
)
431 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
432 if (retval
== ERROR_OK
)
433 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
435 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
436 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
438 if (retval
!= ERROR_OK
)
442 /* halted on reset */
443 target
->debug_reason
= DBG_REASON_UNDEFINED
;
445 if (csr1
& (BK1F
+BK2F
))
446 /* we have halted on a breakpoint (or wp)*/
447 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
450 /* we have halted on a breakpoint */
451 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
458 static int stm8_debug_entry(struct target
*target
)
460 struct stm8_common
*stm8
= target_to_stm8(target
);
462 /* restore interrupts */
463 stm8_enable_interrupts(target
, 1);
465 stm8_save_context(target
);
467 /* make sure stepping disabled STE bit in CSR1 cleared */
468 stm8_config_step(target
, 0);
470 /* attempt to find halt reason */
471 stm8_examine_debug_reason(target
);
473 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
474 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32),
475 target_state_name(target
));
480 /* clear stall flag in DM and flush instruction pipe */
481 static int stm8_exit_debug(struct target
*target
)
486 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
490 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
496 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
502 static int stm8_read_regs(struct target
*target
, uint32_t regs
[])
507 ret
= stm8_adapter_read_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
511 regs
[0] = be_to_h_u24(buf
+DM_REG_PC
-DM_REGS
);
512 regs
[1] = buf
[DM_REG_A
-DM_REGS
];
513 regs
[2] = be_to_h_u16(buf
+DM_REG_X
-DM_REGS
);
514 regs
[3] = be_to_h_u16(buf
+DM_REG_Y
-DM_REGS
);
515 regs
[4] = be_to_h_u16(buf
+DM_REG_SP
-DM_REGS
);
516 regs
[5] = buf
[DM_REG_CC
-DM_REGS
];
521 static int stm8_write_regs(struct target
*target
, uint32_t regs
[])
526 h_u24_to_be(buf
+DM_REG_PC
-DM_REGS
, regs
[0]);
527 buf
[DM_REG_A
-DM_REGS
] = regs
[1];
528 h_u16_to_be(buf
+DM_REG_X
-DM_REGS
, regs
[2]);
529 h_u16_to_be(buf
+DM_REG_Y
-DM_REGS
, regs
[3]);
530 h_u16_to_be(buf
+DM_REG_SP
-DM_REGS
, regs
[4]);
531 buf
[DM_REG_CC
-DM_REGS
] = regs
[5];
533 ret
= stm8_adapter_write_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
540 static int stm8_get_core_reg(struct reg
*reg
)
543 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
544 struct target
*target
= stm8_reg
->target
;
545 struct stm8_common
*stm8_target
= target_to_stm8(target
);
547 if (target
->state
!= TARGET_HALTED
)
548 return ERROR_TARGET_NOT_HALTED
;
550 retval
= stm8_target
->read_core_reg(target
, stm8_reg
->num
);
555 static int stm8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
557 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
558 struct target
*target
= stm8_reg
->target
;
559 uint32_t value
= buf_get_u32(buf
, 0, reg
->size
);
561 if (target
->state
!= TARGET_HALTED
)
562 return ERROR_TARGET_NOT_HALTED
;
564 buf_set_u32(reg
->value
, 0, 32, value
);
571 static int stm8_save_context(struct target
*target
)
575 /* get pointers to arch-specific information */
576 struct stm8_common
*stm8
= target_to_stm8(target
);
578 /* read core registers */
579 stm8_read_regs(target
, stm8
->core_regs
);
581 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
582 if (!stm8
->core_cache
->reg_list
[i
].valid
)
583 stm8
->read_core_reg(target
, i
);
589 static int stm8_restore_context(struct target
*target
)
593 /* get pointers to arch-specific information */
594 struct stm8_common
*stm8
= target_to_stm8(target
);
596 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
597 if (stm8
->core_cache
->reg_list
[i
].dirty
)
598 stm8
->write_core_reg(target
, i
);
601 /* write core regs */
602 stm8_write_regs(target
, stm8
->core_regs
);
607 static int stm8_unlock_flash(struct target
*target
)
611 struct stm8_common
*stm8
= target_to_stm8(target
);
613 /* check if flash is unlocked */
614 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
615 if (~data
[0] & PUL
) {
617 stm8_write_u8(target
, stm8
->flash_pukr
, 0x56);
618 stm8_write_u8(target
, stm8
->flash_pukr
, 0xae);
621 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
627 static int stm8_unlock_eeprom(struct target
*target
)
631 struct stm8_common
*stm8
= target_to_stm8(target
);
633 /* check if eeprom is unlocked */
634 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
635 if (~data
[0] & DUL
) {
637 stm8_write_u8(target
, stm8
->flash_dukr
, 0xae);
638 stm8_write_u8(target
, stm8
->flash_dukr
, 0x56);
641 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
647 static int stm8_write_flash(struct target
*target
, enum mem_type type
,
649 uint32_t size
, uint32_t count
, uint32_t blocksize_param
,
650 const uint8_t *buffer
)
652 struct stm8_common
*stm8
= target_to_stm8(target
);
657 uint32_t blocksize
= 0;
663 stm8_unlock_flash(target
);
666 stm8_unlock_eeprom(target
);
669 stm8_unlock_eeprom(target
);
673 LOG_ERROR("BUG: wrong mem_type %d", type
);
678 /* we don't support short writes */
683 bytecnt
= count
* size
;
686 if ((bytecnt
>= blocksize_param
) && ((address
& (blocksize_param
-1)) == 0)) {
688 stm8_write_u8(target
, stm8
->flash_cr2
, PRG
+ opt
);
689 if (stm8
->flash_ncr2
)
690 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(PRG
+ opt
));
691 blocksize
= blocksize_param
;
693 if ((bytecnt
>= 4) && ((address
& 0x3) == 0)) {
695 stm8_write_u8(target
, stm8
->flash_cr2
, WPRG
+ opt
);
696 if (stm8
->flash_ncr2
)
697 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(WPRG
+ opt
));
700 if (blocksize
!= 1) {
702 stm8_write_u8(target
, stm8
->flash_cr2
, opt
);
703 if (stm8
->flash_ncr2
)
704 stm8_write_u8(target
, stm8
->flash_ncr2
, ~opt
);
708 res
= stm8_adapter_write_memory(target
, address
, 1, blocksize
, buffer
);
711 address
+= blocksize
;
713 bytecnt
-= blocksize
;
715 /* lets hang here until end of program (EOP) */
716 for (i
= 0; i
< 16; i
++) {
717 stm8_read_u8(target
, stm8
->flash_iapsr
, &iapsr
);
727 /* disable write access */
728 res
= stm8_write_u8(target
, stm8
->flash_iapsr
, 0x0);
736 static int stm8_write_memory(struct target
*target
, target_addr_t address
,
737 uint32_t size
, uint32_t count
,
738 const uint8_t *buffer
)
740 struct stm8_common
*stm8
= target_to_stm8(target
);
742 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
743 ", size: 0x%8.8" PRIx32
744 ", count: 0x%8.8" PRIx32
,
745 address
, size
, count
);
747 if (target
->state
!= TARGET_HALTED
)
748 LOG_WARNING("target not halted");
752 if ((address
>= stm8
->flashstart
) && (address
<= stm8
->flashend
))
753 retval
= stm8_write_flash(target
, FLASH
, address
, size
, count
,
754 stm8
->blocksize
, buffer
);
755 else if ((address
>= stm8
->eepromstart
) && (address
<= stm8
->eepromend
))
756 retval
= stm8_write_flash(target
, EEPROM
, address
, size
, count
,
757 stm8
->blocksize
, buffer
);
758 else if ((address
>= stm8
->optionstart
) && (address
<= stm8
->optionend
))
759 retval
= stm8_write_flash(target
, OPTION
, address
, size
, count
, 0, buffer
);
761 retval
= stm8_adapter_write_memory(target
, address
, size
, count
,
764 if (retval
!= ERROR_OK
)
765 return ERROR_TARGET_FAILURE
;
770 static int stm8_read_memory(struct target
*target
, target_addr_t address
,
771 uint32_t size
, uint32_t count
, uint8_t *buffer
)
773 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
774 ", size: 0x%8.8" PRIx32
775 ", count: 0x%8.8" PRIx32
,
776 address
, size
, count
);
778 if (target
->state
!= TARGET_HALTED
)
779 LOG_WARNING("target not halted");
782 retval
= stm8_adapter_read_memory(target
, address
, size
, count
, buffer
);
784 if (retval
!= ERROR_OK
)
785 return ERROR_TARGET_FAILURE
;
790 static int stm8_speed(int speed
)
795 LOG_DEBUG("stm8_speed: %d", speed
);
797 csr
= SAFE_MASK
| SWIM_DM
;
798 if (speed
>= SWIM_FREQ_HIGH
)
801 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)", csr
& HS
? 1 : 0);
802 retval
= stm8_write_u8(NULL
, SWIM_CSR
, csr
);
803 if (retval
!= ERROR_OK
)
805 return adapter_speed(speed
);
808 static int stm8_init(struct command_context
*cmd_ctx
, struct target
*target
)
811 * FIXME: this is a temporarily hack that needs better implementation.
812 * Being the only overwrite of adapter_driver, it prevents declaring const
813 * the struct adapter_driver.
814 * intercept adapter_driver->speed() calls
816 adapter_speed
= adapter_driver
->speed
;
817 adapter_driver
->speed
= stm8_speed
;
819 stm8_build_reg_cache(target
);
824 static int stm8_poll(struct target
*target
)
826 int retval
= ERROR_OK
;
830 LOG_DEBUG("target->state=%d", target
->state
);
833 /* read dm_csrx control regs */
834 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
835 if (retval
!= ERROR_OK
) {
836 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval
);
838 We return ERROR_OK here even if we didn't get an answer.
839 openocd will call target_wait_state until we get target state TARGET_HALTED
844 /* check for processor halted */
846 if (target
->state
!= TARGET_HALTED
) {
847 if (target
->state
== TARGET_UNKNOWN
)
848 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
850 retval
= stm8_debug_entry(target
);
851 if (retval
!= ERROR_OK
) {
852 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval
);
853 return ERROR_TARGET_FAILURE
;
856 if (target
->state
== TARGET_DEBUG_RUNNING
) {
857 target
->state
= TARGET_HALTED
;
858 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
860 target
->state
= TARGET_HALTED
;
861 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
865 target
->state
= TARGET_RUNNING
;
867 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
872 static int stm8_halt(struct target
*target
)
874 LOG_DEBUG("target->state: %s", target_state_name(target
));
876 if (target
->state
== TARGET_HALTED
) {
877 LOG_DEBUG("target was already halted");
881 if (target
->state
== TARGET_UNKNOWN
)
882 LOG_WARNING("target was in unknown state when halt was requested");
884 if (target
->state
== TARGET_RESET
) {
885 /* we came here in a reset_halt or reset_init sequence
886 * debug entry was already prepared in stm8_assert_reset()
888 target
->debug_reason
= DBG_REASON_DBGRQ
;
894 /* break processor */
895 stm8_debug_stall(target
);
897 target
->debug_reason
= DBG_REASON_DBGRQ
;
902 static int stm8_reset_assert(struct target
*target
)
905 struct stm8_common
*stm8
= target_to_stm8(target
);
906 bool use_srst_fallback
= true;
908 enum reset_types jtag_reset_config
= jtag_get_reset_config();
910 if (jtag_reset_config
& RESET_HAS_SRST
) {
911 res
= adapter_assert_reset();
913 /* hardware srst supported */
914 use_srst_fallback
= false;
915 else if (res
!= ERROR_COMMAND_NOTFOUND
)
916 /* some other failure */
920 if (use_srst_fallback
) {
921 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
922 res
= swim_system_reset();
927 /* registers are now invalid */
928 register_cache_invalidate(stm8
->core_cache
);
930 target
->state
= TARGET_RESET
;
931 target
->debug_reason
= DBG_REASON_NOTHALTED
;
933 if (target
->reset_halt
) {
934 res
= target_halt(target
);
942 static int stm8_reset_deassert(struct target
*target
)
945 enum reset_types jtag_reset_config
= jtag_get_reset_config();
947 if (jtag_reset_config
& RESET_HAS_SRST
) {
948 res
= adapter_deassert_reset();
949 if ((res
!= ERROR_OK
) && (res
!= ERROR_COMMAND_NOTFOUND
))
953 /* The cpu should now be stalled. If halt was requested
954 let poll detect the stall */
955 if (target
->reset_halt
)
958 /* Instead of going through saving context, polling and
959 then resuming target again just clear stall and proceed. */
960 target
->state
= TARGET_RUNNING
;
961 return stm8_exit_debug(target
);
964 /* stm8_single_step_core() is only used for stepping over breakpoints
965 from stm8_resume() */
966 static int stm8_single_step_core(struct target
*target
)
968 struct stm8_common
*stm8
= target_to_stm8(target
);
970 /* configure single step mode */
971 stm8_config_step(target
, 1);
973 /* disable interrupts while stepping */
974 if (!stm8
->enable_step_irq
)
975 stm8_enable_interrupts(target
, 0);
977 /* exit debug mode */
978 stm8_exit_debug(target
);
980 stm8_debug_entry(target
);
985 static int stm8_resume(struct target
*target
, int current
,
986 target_addr_t address
, int handle_breakpoints
,
989 struct stm8_common
*stm8
= target_to_stm8(target
);
990 struct breakpoint
*breakpoint
= NULL
;
993 LOG_DEBUG("%d " TARGET_ADDR_FMT
" %d %d", current
, address
,
994 handle_breakpoints
, debug_execution
);
996 if (target
->state
!= TARGET_HALTED
) {
997 LOG_WARNING("target not halted");
998 return ERROR_TARGET_NOT_HALTED
;
1001 if (!debug_execution
) {
1002 target_free_all_working_areas(target
);
1003 stm8_enable_breakpoints(target
);
1004 stm8_enable_watchpoints(target
);
1005 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1006 stm8_set_hwbreak(target
, comparator_list
);
1009 /* current = 1: continue on current pc,
1010 otherwise continue at <address> */
1012 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1014 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1015 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1019 resume_pc
= address
;
1021 resume_pc
= buf_get_u32(
1022 stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1025 stm8_restore_context(target
);
1027 /* the front-end may request us not to handle breakpoints */
1028 if (handle_breakpoints
) {
1029 /* Single step past breakpoint at current address */
1030 breakpoint
= breakpoint_find(target
, resume_pc
);
1032 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
,
1033 breakpoint
->address
);
1034 stm8_unset_breakpoint(target
, breakpoint
);
1035 stm8_single_step_core(target
);
1036 stm8_set_breakpoint(target
, breakpoint
);
1040 /* disable interrupts if we are debugging */
1041 if (debug_execution
)
1042 stm8_enable_interrupts(target
, 0);
1044 /* exit debug mode */
1045 stm8_exit_debug(target
);
1046 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1048 /* registers are now invalid */
1049 register_cache_invalidate(stm8
->core_cache
);
1051 if (!debug_execution
) {
1052 target
->state
= TARGET_RUNNING
;
1053 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1054 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
1056 target
->state
= TARGET_DEBUG_RUNNING
;
1057 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1058 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
1064 static int stm8_init_flash_regs(bool enable_stm8l
, struct stm8_common
*stm8
)
1066 stm8
->enable_stm8l
= enable_stm8l
;
1068 if (stm8
->enable_stm8l
) {
1069 stm8
->flash_cr2
= FLASH_CR2_STM8L
;
1070 stm8
->flash_ncr2
= FLASH_NCR2_STM8L
;
1071 stm8
->flash_iapsr
= FLASH_IAPSR_STM8L
;
1072 stm8
->flash_dukr
= FLASH_DUKR_STM8L
;
1073 stm8
->flash_pukr
= FLASH_PUKR_STM8L
;
1075 stm8
->flash_cr2
= FLASH_CR2_STM8S
;
1076 stm8
->flash_ncr2
= FLASH_NCR2_STM8S
;
1077 stm8
->flash_iapsr
= FLASH_IAPSR_STM8S
;
1078 stm8
->flash_dukr
= FLASH_DUKR_STM8S
;
1079 stm8
->flash_pukr
= FLASH_PUKR_STM8S
;
1084 static int stm8_init_arch_info(struct target
*target
,
1085 struct stm8_common
*stm8
, struct jtag_tap
*tap
)
1087 target
->endianness
= TARGET_BIG_ENDIAN
;
1088 target
->arch_info
= stm8
;
1089 stm8
->common_magic
= STM8_COMMON_MAGIC
;
1090 stm8
->fast_data_area
= NULL
;
1091 stm8
->blocksize
= 0x80;
1092 stm8
->flashstart
= 0x8000;
1093 stm8
->flashend
= 0xffff;
1094 stm8
->eepromstart
= 0x4000;
1095 stm8
->eepromend
= 0x43ff;
1096 stm8
->optionstart
= 0x4800;
1097 stm8
->optionend
= 0x487F;
1099 /* has breakpoint/watchpoint unit been scanned */
1100 stm8
->bp_scanned
= false;
1101 stm8
->hw_break_list
= NULL
;
1103 stm8
->read_core_reg
= stm8_read_core_reg
;
1104 stm8
->write_core_reg
= stm8_write_core_reg
;
1106 stm8_init_flash_regs(0, stm8
);
1111 static int stm8_target_create(struct target
*target
,
1115 struct stm8_common
*stm8
= calloc(1, sizeof(struct stm8_common
));
1117 stm8_init_arch_info(target
, stm8
, target
->tap
);
1118 stm8_configure_break_unit(target
);
1123 static int stm8_read_core_reg(struct target
*target
, unsigned int num
)
1127 /* get pointers to arch-specific information */
1128 struct stm8_common
*stm8
= target_to_stm8(target
);
1130 if (num
>= STM8_NUM_REGS
)
1131 return ERROR_COMMAND_SYNTAX_ERROR
;
1133 reg_value
= stm8
->core_regs
[num
];
1134 LOG_DEBUG("read core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1135 buf_set_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
1136 stm8
->core_cache
->reg_list
[num
].valid
= true;
1137 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1142 static int stm8_write_core_reg(struct target
*target
, unsigned int num
)
1146 /* get pointers to arch-specific information */
1147 struct stm8_common
*stm8
= target_to_stm8(target
);
1149 if (num
>= STM8_NUM_REGS
)
1150 return ERROR_COMMAND_SYNTAX_ERROR
;
1152 reg_value
= buf_get_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32);
1153 stm8
->core_regs
[num
] = reg_value
;
1154 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1155 stm8
->core_cache
->reg_list
[num
].valid
= true;
1156 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1161 static const char *stm8_get_gdb_arch(struct target
*target
)
1166 static int stm8_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1167 int *reg_list_size
, enum target_register_class reg_class
)
1169 /* get pointers to arch-specific information */
1170 struct stm8_common
*stm8
= target_to_stm8(target
);
1173 *reg_list_size
= STM8_NUM_REGS
;
1174 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1176 for (i
= 0; i
< STM8_NUM_REGS
; i
++)
1177 (*reg_list
)[i
] = &stm8
->core_cache
->reg_list
[i
];
1182 static const struct reg_arch_type stm8_reg_type
= {
1183 .get
= stm8_get_core_reg
,
1184 .set
= stm8_set_core_reg
,
1187 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
)
1189 /* get pointers to arch-specific information */
1190 struct stm8_common
*stm8
= target_to_stm8(target
);
1192 int num_regs
= STM8_NUM_REGS
;
1193 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1194 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1195 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1196 struct stm8_core_reg
*arch_info
= malloc(
1197 sizeof(struct stm8_core_reg
) * num_regs
);
1198 struct reg_feature
*feature
;
1201 /* Build the process context cache */
1202 cache
->name
= "stm8 registers";
1204 cache
->reg_list
= reg_list
;
1205 cache
->num_regs
= num_regs
;
1207 stm8
->core_cache
= cache
;
1209 for (i
= 0; i
< num_regs
; i
++) {
1210 arch_info
[i
].num
= stm8_regs
[i
].id
;
1211 arch_info
[i
].target
= target
;
1213 reg_list
[i
].name
= stm8_regs
[i
].name
;
1214 reg_list
[i
].size
= stm8_regs
[i
].bits
;
1216 reg_list
[i
].value
= calloc(1, 4);
1217 reg_list
[i
].valid
= false;
1218 reg_list
[i
].type
= &stm8_reg_type
;
1219 reg_list
[i
].arch_info
= &arch_info
[i
];
1221 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1222 if (reg_list
[i
].reg_data_type
)
1223 reg_list
[i
].reg_data_type
->type
= stm8_regs
[i
].type
;
1225 LOG_ERROR("unable to allocate reg type list");
1229 reg_list
[i
].dirty
= false;
1230 reg_list
[i
].group
= stm8_regs
[i
].group
;
1231 reg_list
[i
].number
= stm8_regs
[i
].id
;
1232 reg_list
[i
].exist
= true;
1233 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1235 feature
= calloc(1, sizeof(struct reg_feature
));
1237 feature
->name
= stm8_regs
[i
].feature
;
1238 reg_list
[i
].feature
= feature
;
1240 LOG_ERROR("unable to allocate feature list");
1246 static void stm8_free_reg_cache(struct target
*target
)
1248 struct stm8_common
*stm8
= target_to_stm8(target
);
1249 struct reg_cache
*cache
;
1253 cache
= stm8
->core_cache
;
1258 for (i
= 0; i
< cache
->num_regs
; i
++) {
1259 reg
= &cache
->reg_list
[i
];
1262 free(reg
->reg_data_type
);
1266 free(cache
->reg_list
[0].arch_info
);
1267 free(cache
->reg_list
);
1270 stm8
->core_cache
= NULL
;
1273 static void stm8_deinit(struct target
*target
)
1275 struct stm8_common
*stm8
= target_to_stm8(target
);
1277 free(stm8
->hw_break_list
);
1279 stm8_free_reg_cache(target
);
1284 static int stm8_arch_state(struct target
*target
)
1286 struct stm8_common
*stm8
= target_to_stm8(target
);
1288 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
1289 debug_reason_name(target
),
1290 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1295 static int stm8_step(struct target
*target
, int current
,
1296 target_addr_t address
, int handle_breakpoints
)
1298 LOG_DEBUG("%x " TARGET_ADDR_FMT
" %x",
1299 current
, address
, handle_breakpoints
);
1301 /* get pointers to arch-specific information */
1302 struct stm8_common
*stm8
= target_to_stm8(target
);
1303 struct breakpoint
*breakpoint
= NULL
;
1305 if (target
->state
!= TARGET_HALTED
) {
1306 LOG_WARNING("target not halted");
1307 return ERROR_TARGET_NOT_HALTED
;
1310 /* current = 1: continue on current pc, otherwise continue at <address> */
1312 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32, address
);
1313 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1314 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1317 /* the front-end may request us not to handle breakpoints */
1318 if (handle_breakpoints
) {
1319 breakpoint
= breakpoint_find(target
,
1320 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1322 stm8_unset_breakpoint(target
, breakpoint
);
1325 /* restore context */
1326 stm8_restore_context(target
);
1328 /* configure single step mode */
1329 stm8_config_step(target
, 1);
1331 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1333 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1335 /* disable interrupts while stepping */
1336 if (!stm8
->enable_step_irq
)
1337 stm8_enable_interrupts(target
, 0);
1339 /* exit debug mode */
1340 stm8_exit_debug(target
);
1342 /* registers are now invalid */
1343 register_cache_invalidate(stm8
->core_cache
);
1345 LOG_DEBUG("target stepped ");
1346 stm8_debug_entry(target
);
1349 stm8_set_breakpoint(target
, breakpoint
);
1351 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1356 static void stm8_enable_breakpoints(struct target
*target
)
1358 struct breakpoint
*breakpoint
= target
->breakpoints
;
1360 /* set any pending breakpoints */
1361 while (breakpoint
) {
1362 if (!breakpoint
->is_set
)
1363 stm8_set_breakpoint(target
, breakpoint
);
1364 breakpoint
= breakpoint
->next
;
1368 static int stm8_set_breakpoint(struct target
*target
,
1369 struct breakpoint
*breakpoint
)
1371 struct stm8_common
*stm8
= target_to_stm8(target
);
1372 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1375 if (breakpoint
->is_set
) {
1376 LOG_WARNING("breakpoint already set");
1380 if (breakpoint
->type
== BKPT_HARD
) {
1383 while (comparator_list
[bp_num
].used
&& (bp_num
< stm8
->num_hw_bpoints
))
1385 if (bp_num
>= stm8
->num_hw_bpoints
) {
1386 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32
")",
1387 breakpoint
->unique_id
);
1388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1390 breakpoint_hw_set(breakpoint
, bp_num
);
1391 comparator_list
[bp_num
].used
= true;
1392 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
1393 comparator_list
[bp_num
].type
= HWBRK_EXEC
;
1395 retval
= stm8_set_hwbreak(target
, comparator_list
);
1396 if (retval
!= ERROR_OK
)
1399 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1400 breakpoint
->unique_id
,
1401 bp_num
, comparator_list
[bp_num
].bp_value
);
1402 } else if (breakpoint
->type
== BKPT_SOFT
) {
1403 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1404 if (breakpoint
->length
== 1) {
1405 uint8_t verify
= 0x55;
1407 retval
= target_read_u8(target
, breakpoint
->address
,
1408 breakpoint
->orig_instr
);
1409 if (retval
!= ERROR_OK
)
1411 retval
= target_write_u8(target
, breakpoint
->address
, STM8_BREAK
);
1412 if (retval
!= ERROR_OK
)
1415 retval
= target_read_u8(target
, breakpoint
->address
, &verify
);
1416 if (retval
!= ERROR_OK
)
1418 if (verify
!= STM8_BREAK
) {
1419 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1420 " - check that memory is read/writable",
1421 breakpoint
->address
);
1422 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1425 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1427 breakpoint
->is_set
= true;
1433 static int stm8_add_breakpoint(struct target
*target
,
1434 struct breakpoint
*breakpoint
)
1436 struct stm8_common
*stm8
= target_to_stm8(target
);
1439 if (breakpoint
->type
== BKPT_HARD
) {
1440 if (stm8
->num_hw_bpoints_avail
< 1) {
1441 LOG_INFO("no hardware breakpoint available");
1442 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1445 ret
= stm8_set_breakpoint(target
, breakpoint
);
1446 if (ret
!= ERROR_OK
)
1449 stm8
->num_hw_bpoints_avail
--;
1453 ret
= stm8_set_breakpoint(target
, breakpoint
);
1454 if (ret
!= ERROR_OK
)
1460 static int stm8_unset_breakpoint(struct target
*target
,
1461 struct breakpoint
*breakpoint
)
1463 /* get pointers to arch-specific information */
1464 struct stm8_common
*stm8
= target_to_stm8(target
);
1465 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1468 if (!breakpoint
->is_set
) {
1469 LOG_WARNING("breakpoint not set");
1473 if (breakpoint
->type
== BKPT_HARD
) {
1474 int bp_num
= breakpoint
->number
;
1475 if (bp_num
>= stm8
->num_hw_bpoints
) {
1476 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1477 breakpoint
->unique_id
);
1480 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d",
1481 breakpoint
->unique_id
,
1483 comparator_list
[bp_num
].used
= false;
1484 retval
= stm8_set_hwbreak(target
, comparator_list
);
1485 if (retval
!= ERROR_OK
)
1488 /* restore original instruction (kept in target endianness) */
1489 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1490 if (breakpoint
->length
== 1) {
1491 uint8_t current_instr
;
1493 /* check that user program has not
1494 modified breakpoint instruction */
1495 retval
= target_read_memory(target
, breakpoint
->address
, 1, 1,
1496 (uint8_t *)¤t_instr
);
1497 if (retval
!= ERROR_OK
)
1500 if (current_instr
== STM8_BREAK
) {
1501 retval
= target_write_memory(target
, breakpoint
->address
, 1, 1,
1502 breakpoint
->orig_instr
);
1503 if (retval
!= ERROR_OK
)
1509 breakpoint
->is_set
= false;
1514 static int stm8_remove_breakpoint(struct target
*target
,
1515 struct breakpoint
*breakpoint
)
1517 /* get pointers to arch-specific information */
1518 struct stm8_common
*stm8
= target_to_stm8(target
);
1520 if (target
->state
!= TARGET_HALTED
) {
1521 LOG_WARNING("target not halted");
1522 return ERROR_TARGET_NOT_HALTED
;
1525 if (breakpoint
->is_set
)
1526 stm8_unset_breakpoint(target
, breakpoint
);
1528 if (breakpoint
->type
== BKPT_HARD
)
1529 stm8
->num_hw_bpoints_avail
++;
1534 static int stm8_set_watchpoint(struct target
*target
,
1535 struct watchpoint
*watchpoint
)
1537 struct stm8_common
*stm8
= target_to_stm8(target
);
1538 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1542 if (watchpoint
->is_set
) {
1543 LOG_WARNING("watchpoint already set");
1547 while (comparator_list
[wp_num
].used
&& (wp_num
< stm8
->num_hw_bpoints
))
1549 if (wp_num
>= stm8
->num_hw_bpoints
) {
1550 LOG_ERROR("Can not find free hw breakpoint");
1551 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1554 if (watchpoint
->length
!= 1) {
1555 LOG_ERROR("Only watchpoints of length 1 are supported");
1556 return ERROR_TARGET_UNALIGNED_ACCESS
;
1559 enum hw_break_type enable
= 0;
1561 switch (watchpoint
->rw
) {
1572 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1575 comparator_list
[wp_num
].used
= true;
1576 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
1577 comparator_list
[wp_num
].type
= enable
;
1579 ret
= stm8_set_hwbreak(target
, comparator_list
);
1580 if (ret
!= ERROR_OK
) {
1581 comparator_list
[wp_num
].used
= false;
1585 watchpoint_set(watchpoint
, wp_num
);
1587 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"",
1589 comparator_list
[wp_num
].bp_value
);
1594 static int stm8_add_watchpoint(struct target
*target
,
1595 struct watchpoint
*watchpoint
)
1598 struct stm8_common
*stm8
= target_to_stm8(target
);
1600 if (stm8
->num_hw_bpoints_avail
< 1) {
1601 LOG_INFO("no hardware watchpoints available");
1602 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1605 ret
= stm8_set_watchpoint(target
, watchpoint
);
1606 if (ret
!= ERROR_OK
)
1609 stm8
->num_hw_bpoints_avail
--;
1613 static void stm8_enable_watchpoints(struct target
*target
)
1615 struct watchpoint
*watchpoint
= target
->watchpoints
;
1617 /* set any pending watchpoints */
1618 while (watchpoint
) {
1619 if (!watchpoint
->is_set
)
1620 stm8_set_watchpoint(target
, watchpoint
);
1621 watchpoint
= watchpoint
->next
;
1625 static int stm8_unset_watchpoint(struct target
*target
,
1626 struct watchpoint
*watchpoint
)
1628 /* get pointers to arch-specific information */
1629 struct stm8_common
*stm8
= target_to_stm8(target
);
1630 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1632 if (!watchpoint
->is_set
) {
1633 LOG_WARNING("watchpoint not set");
1637 int wp_num
= watchpoint
->number
;
1638 if (wp_num
>= stm8
->num_hw_bpoints
) {
1639 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1642 comparator_list
[wp_num
].used
= false;
1643 watchpoint
->is_set
= false;
1645 stm8_set_hwbreak(target
, comparator_list
);
1650 static int stm8_remove_watchpoint(struct target
*target
,
1651 struct watchpoint
*watchpoint
)
1653 /* get pointers to arch-specific information */
1654 struct stm8_common
*stm8
= target_to_stm8(target
);
1656 if (target
->state
!= TARGET_HALTED
) {
1657 LOG_WARNING("target not halted");
1658 return ERROR_TARGET_NOT_HALTED
;
1661 if (watchpoint
->is_set
)
1662 stm8_unset_watchpoint(target
, watchpoint
);
1664 stm8
->num_hw_bpoints_avail
++;
1669 static int stm8_examine(struct target
*target
)
1673 /* get pointers to arch-specific information */
1674 struct stm8_common
*stm8
= target_to_stm8(target
);
1675 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1677 if (!target_was_examined(target
)) {
1678 if (!stm8
->swim_configured
) {
1679 stm8
->swim_configured
= true;
1681 Now is the time to deassert reset if connect_under_reset.
1682 Releasing reset line will cause the option bytes to load.
1683 The core will still be stalled.
1685 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
1686 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
1687 stm8_reset_deassert(target
);
1689 LOG_WARNING("\'srst_nogate\' reset_config option is required");
1692 LOG_INFO("trying to reconnect");
1694 retval
= swim_reconnect();
1695 if (retval
!= ERROR_OK
) {
1696 LOG_ERROR("reconnect failed");
1700 /* read dm_csrx control regs */
1701 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
1702 if (retval
!= ERROR_OK
) {
1703 LOG_ERROR("state query failed");
1708 target_set_examined(target
);
1716 /** Checks whether a memory region is erased. */
1717 static int stm8_blank_check_memory(struct target
*target
,
1718 struct target_memory_check_block
*blocks
, int num_blocks
, uint8_t erased_value
)
1720 struct working_area
*erase_check_algorithm
;
1721 struct reg_param reg_params
[2];
1722 struct mem_param mem_params
[2];
1723 struct stm8_algorithm stm8_info
;
1725 static const uint8_t stm8_erase_check_code
[] = {
1726 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1729 if (erased_value
!= 0xff) {
1730 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for STM8",
1735 /* make sure we have a working area */
1736 if (target_alloc_working_area(target
, sizeof(stm8_erase_check_code
),
1737 &erase_check_algorithm
) != ERROR_OK
)
1738 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1740 target_write_buffer(target
, erase_check_algorithm
->address
,
1741 sizeof(stm8_erase_check_code
), stm8_erase_check_code
);
1743 stm8_info
.common_magic
= STM8_COMMON_MAGIC
;
1745 init_mem_param(&mem_params
[0], 0x0, 3, PARAM_OUT
);
1746 buf_set_u32(mem_params
[0].value
, 0, 24, blocks
[0].address
);
1748 init_mem_param(&mem_params
[1], 0x3, 3, PARAM_OUT
);
1749 buf_set_u32(mem_params
[1].value
, 0, 24, blocks
[0].size
);
1751 init_reg_param(®_params
[0], "a", 32, PARAM_IN_OUT
);
1752 buf_set_u32(reg_params
[0].value
, 0, 32, erased_value
);
1754 init_reg_param(®_params
[1], "sp", 32, PARAM_OUT
);
1755 buf_set_u32(reg_params
[1].value
, 0, 32, erase_check_algorithm
->address
);
1757 int retval
= target_run_algorithm(target
, 2, mem_params
, 2, reg_params
,
1758 erase_check_algorithm
->address
+ 6,
1759 erase_check_algorithm
->address
+ (sizeof(stm8_erase_check_code
) - 1),
1762 if (retval
== ERROR_OK
)
1763 blocks
[0].result
= (*(reg_params
[0].value
) == 0xff);
1765 destroy_mem_param(&mem_params
[0]);
1766 destroy_mem_param(&mem_params
[1]);
1767 destroy_reg_param(®_params
[0]);
1768 destroy_reg_param(®_params
[1]);
1770 target_free_working_area(target
, erase_check_algorithm
);
1772 if (retval
!= ERROR_OK
)
1775 return 1; /* only one block has been checked */
1778 static int stm8_checksum_memory(struct target
*target
, target_addr_t address
,
1779 uint32_t count
, uint32_t *checksum
)
1781 /* let image_calculate_checksum() take care of business */
1782 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1785 /* run to exit point. return error if exit point was not reached. */
1786 static int stm8_run_and_wait(struct target
*target
, uint32_t entry_point
,
1787 int timeout_ms
, uint32_t exit_point
, struct stm8_common
*stm8
)
1791 /* This code relies on the target specific resume() and
1792 poll()->debug_entry() sequence to write register values to the
1793 processor and the read them back */
1794 retval
= target_resume(target
, 0, entry_point
, 0, 1);
1795 if (retval
!= ERROR_OK
)
1798 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1799 /* If the target fails to halt due to the breakpoint, force a halt */
1800 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
1801 retval
= target_halt(target
);
1802 if (retval
!= ERROR_OK
)
1804 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
1805 if (retval
!= ERROR_OK
)
1807 return ERROR_TARGET_TIMEOUT
;
1810 pc
= buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32);
1811 if (exit_point
&& (pc
!= exit_point
)) {
1812 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
1813 return ERROR_TARGET_TIMEOUT
;
1819 static int stm8_run_algorithm(struct target
*target
, int num_mem_params
,
1820 struct mem_param
*mem_params
, int num_reg_params
,
1821 struct reg_param
*reg_params
, target_addr_t entry_point
,
1822 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
1824 struct stm8_common
*stm8
= target_to_stm8(target
);
1826 uint32_t context
[STM8_NUM_REGS
];
1827 int retval
= ERROR_OK
;
1829 LOG_DEBUG("Running algorithm");
1831 /* NOTE: stm8_run_algorithm requires that each
1832 algorithm uses a software breakpoint
1833 at the exit point */
1835 if (stm8
->common_magic
!= STM8_COMMON_MAGIC
) {
1836 LOG_ERROR("current target isn't a STM8 target");
1837 return ERROR_TARGET_INVALID
;
1840 if (target
->state
!= TARGET_HALTED
) {
1841 LOG_WARNING("target not halted");
1842 return ERROR_TARGET_NOT_HALTED
;
1845 /* refresh core register cache */
1846 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1847 if (!stm8
->core_cache
->reg_list
[i
].valid
)
1848 stm8
->read_core_reg(target
, i
);
1849 context
[i
] = buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1852 for (int i
= 0; i
< num_mem_params
; i
++) {
1853 if (mem_params
[i
].direction
== PARAM_IN
)
1855 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1856 mem_params
[i
].size
, mem_params
[i
].value
);
1857 if (retval
!= ERROR_OK
)
1861 for (int i
= 0; i
< num_reg_params
; i
++) {
1862 if (reg_params
[i
].direction
== PARAM_IN
)
1865 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1866 reg_params
[i
].reg_name
, false);
1869 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1870 return ERROR_COMMAND_SYNTAX_ERROR
;
1873 if (reg_params
[i
].size
!= 32) {
1874 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1875 reg_params
[i
].reg_name
);
1876 return ERROR_COMMAND_SYNTAX_ERROR
;
1879 stm8_set_core_reg(reg
, reg_params
[i
].value
);
1882 retval
= stm8_run_and_wait(target
, entry_point
,
1883 timeout_ms
, exit_point
, stm8
);
1885 if (retval
!= ERROR_OK
)
1888 for (int i
= 0; i
< num_mem_params
; i
++) {
1889 if (mem_params
[i
].direction
!= PARAM_OUT
) {
1890 retval
= target_read_buffer(target
, mem_params
[i
].address
,
1891 mem_params
[i
].size
, mem_params
[i
].value
);
1892 if (retval
!= ERROR_OK
)
1897 for (int i
= 0; i
< num_reg_params
; i
++) {
1898 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1899 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1900 reg_params
[i
].reg_name
, false);
1902 LOG_ERROR("BUG: register '%s' not found",
1903 reg_params
[i
].reg_name
);
1904 return ERROR_COMMAND_SYNTAX_ERROR
;
1907 if (reg_params
[i
].size
!= 32) {
1908 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1909 reg_params
[i
].reg_name
);
1910 return ERROR_COMMAND_SYNTAX_ERROR
;
1913 buf_set_u32(reg_params
[i
].value
,
1914 0, 32, buf_get_u32(reg
->value
, 0, 32));
1918 /* restore everything we saved before */
1919 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1921 regvalue
= buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1922 if (regvalue
!= context
[i
]) {
1923 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
1924 stm8
->core_cache
->reg_list
[i
].name
, context
[i
]);
1925 buf_set_u32(stm8
->core_cache
->reg_list
[i
].value
,
1927 stm8
->core_cache
->reg_list
[i
].valid
= true;
1928 stm8
->core_cache
->reg_list
[i
].dirty
= true;
1935 static int stm8_jim_configure(struct target
*target
, struct jim_getopt_info
*goi
)
1937 struct stm8_common
*stm8
= target_to_stm8(target
);
1942 arg
= Jim_GetString(goi
->argv
[0], NULL
);
1943 if (!strcmp(arg
, "-blocksize")) {
1944 e
= jim_getopt_string(goi
, &arg
, NULL
);
1948 if (goi
->argc
== 0) {
1949 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1950 "-blocksize ?bytes? ...");
1954 e
= jim_getopt_wide(goi
, &w
);
1958 stm8
->blocksize
= w
;
1959 LOG_DEBUG("blocksize=%8.8" PRIx32
, stm8
->blocksize
);
1962 if (!strcmp(arg
, "-flashstart")) {
1963 e
= jim_getopt_string(goi
, &arg
, NULL
);
1967 if (goi
->argc
== 0) {
1968 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1969 "-flashstart ?address? ...");
1973 e
= jim_getopt_wide(goi
, &w
);
1977 stm8
->flashstart
= w
;
1978 LOG_DEBUG("flashstart=%8.8" PRIx32
, stm8
->flashstart
);
1981 if (!strcmp(arg
, "-flashend")) {
1982 e
= jim_getopt_string(goi
, &arg
, NULL
);
1986 if (goi
->argc
== 0) {
1987 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1988 "-flashend ?address? ...");
1992 e
= jim_getopt_wide(goi
, &w
);
1997 LOG_DEBUG("flashend=%8.8" PRIx32
, stm8
->flashend
);
2000 if (!strcmp(arg
, "-eepromstart")) {
2001 e
= jim_getopt_string(goi
, &arg
, NULL
);
2005 if (goi
->argc
== 0) {
2006 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2007 "-eepromstart ?address? ...");
2011 e
= jim_getopt_wide(goi
, &w
);
2015 stm8
->eepromstart
= w
;
2016 LOG_DEBUG("eepromstart=%8.8" PRIx32
, stm8
->eepromstart
);
2019 if (!strcmp(arg
, "-eepromend")) {
2020 e
= jim_getopt_string(goi
, &arg
, NULL
);
2024 if (goi
->argc
== 0) {
2025 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2026 "-eepromend ?address? ...");
2030 e
= jim_getopt_wide(goi
, &w
);
2034 stm8
->eepromend
= w
;
2035 LOG_DEBUG("eepromend=%8.8" PRIx32
, stm8
->eepromend
);
2038 if (!strcmp(arg
, "-optionstart")) {
2039 e
= jim_getopt_string(goi
, &arg
, NULL
);
2043 if (goi
->argc
== 0) {
2044 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2045 "-optionstart ?address? ...");
2049 e
= jim_getopt_wide(goi
, &w
);
2053 stm8
->optionstart
= w
;
2054 LOG_DEBUG("optionstart=%8.8" PRIx32
, stm8
->optionstart
);
2057 if (!strcmp(arg
, "-optionend")) {
2058 e
= jim_getopt_string(goi
, &arg
, NULL
);
2062 if (goi
->argc
== 0) {
2063 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2064 "-optionend ?address? ...");
2068 e
= jim_getopt_wide(goi
, &w
);
2072 stm8
->optionend
= w
;
2073 LOG_DEBUG("optionend=%8.8" PRIx32
, stm8
->optionend
);
2076 if (!strcmp(arg
, "-enable_step_irq")) {
2077 e
= jim_getopt_string(goi
, &arg
, NULL
);
2081 stm8
->enable_step_irq
= true;
2082 LOG_DEBUG("enable_step_irq=%8.8x", stm8
->enable_step_irq
);
2085 if (!strcmp(arg
, "-enable_stm8l")) {
2086 e
= jim_getopt_string(goi
, &arg
, NULL
);
2090 stm8
->enable_stm8l
= true;
2091 LOG_DEBUG("enable_stm8l=%8.8x", stm8
->enable_stm8l
);
2092 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2095 return JIM_CONTINUE
;
2098 COMMAND_HANDLER(stm8_handle_enable_step_irq_command
)
2101 struct target
*target
= get_current_target(CMD_CTX
);
2102 struct stm8_common
*stm8
= target_to_stm8(target
);
2103 bool enable
= stm8
->enable_step_irq
;
2106 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2107 stm8
->enable_step_irq
= enable
;
2109 msg
= stm8
->enable_step_irq
? "enabled" : "disabled";
2110 command_print(CMD
, "enable_step_irq = %s", msg
);
2114 COMMAND_HANDLER(stm8_handle_enable_stm8l_command
)
2117 struct target
*target
= get_current_target(CMD_CTX
);
2118 struct stm8_common
*stm8
= target_to_stm8(target
);
2119 bool enable
= stm8
->enable_stm8l
;
2122 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2123 stm8
->enable_stm8l
= enable
;
2125 msg
= stm8
->enable_stm8l
? "enabled" : "disabled";
2126 command_print(CMD
, "enable_stm8l = %s", msg
);
2127 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2131 static const struct command_registration stm8_exec_command_handlers
[] = {
2133 .name
= "enable_step_irq",
2134 .handler
= stm8_handle_enable_step_irq_command
,
2135 .mode
= COMMAND_ANY
,
2136 .help
= "Enable/disable irq handling during step",
2140 .name
= "enable_stm8l",
2141 .handler
= stm8_handle_enable_stm8l_command
,
2142 .mode
= COMMAND_ANY
,
2143 .help
= "Enable/disable STM8L flash programming",
2146 COMMAND_REGISTRATION_DONE
2149 static const struct command_registration stm8_command_handlers
[] = {
2152 .mode
= COMMAND_ANY
,
2153 .help
= "stm8 command group",
2155 .chain
= stm8_exec_command_handlers
,
2157 COMMAND_REGISTRATION_DONE
2160 struct target_type stm8_target
= {
2164 .arch_state
= stm8_arch_state
,
2167 .resume
= stm8_resume
,
2170 .assert_reset
= stm8_reset_assert
,
2171 .deassert_reset
= stm8_reset_deassert
,
2173 .get_gdb_arch
= stm8_get_gdb_arch
,
2174 .get_gdb_reg_list
= stm8_get_gdb_reg_list
,
2176 .read_memory
= stm8_read_memory
,
2177 .write_memory
= stm8_write_memory
,
2178 .checksum_memory
= stm8_checksum_memory
,
2179 .blank_check_memory
= stm8_blank_check_memory
,
2181 .run_algorithm
= stm8_run_algorithm
,
2183 .add_breakpoint
= stm8_add_breakpoint
,
2184 .remove_breakpoint
= stm8_remove_breakpoint
,
2185 .add_watchpoint
= stm8_add_watchpoint
,
2186 .remove_watchpoint
= stm8_remove_watchpoint
,
2188 .commands
= stm8_command_handlers
,
2189 .target_create
= stm8_target_create
,
2190 .init_target
= stm8_init
,
2191 .examine
= stm8_examine
,
2193 .deinit_target
= stm8_deinit
,
2194 .target_jim_configure
= stm8_jim_configure
,