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
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)