2 * OpenOCD STM8 target driver
3 * Copyright (C) 2017 Ake Rehnman
4 * ake.rehnman(at)gmail.com
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <helper/log.h>
26 #include "target_type.h"
28 #include "jtag/interface.h"
29 #include "jtag/jtag.h"
30 #include "jtag/swim.h"
32 #include "breakpoints.h"
33 #include "algorithm.h"
36 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
);
37 static int stm8_read_core_reg(struct target
*target
, unsigned int num
);
38 static int stm8_write_core_reg(struct target
*target
, unsigned int num
);
39 static int stm8_save_context(struct target
*target
);
40 static void stm8_enable_breakpoints(struct target
*target
);
41 static int stm8_unset_breakpoint(struct target
*target
,
42 struct breakpoint
*breakpoint
);
43 static int stm8_set_breakpoint(struct target
*target
,
44 struct breakpoint
*breakpoint
);
45 static void stm8_enable_watchpoints(struct target
*target
);
46 static int stm8_unset_watchpoint(struct target
*target
,
47 struct watchpoint
*watchpoint
);
58 { 0, "pc", 32, REG_TYPE_UINT32
, "general", "org.gnu.gdb.stm8.core", 0 },
59 { 1, "a", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
60 { 2, "x", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
61 { 3, "y", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
62 { 4, "sp", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
63 { 5, "cc", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
66 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
77 #define DM_REGS 0x7f00
78 #define DM_REG_A 0x7f00
79 #define DM_REG_PC 0x7f01
80 #define DM_REG_X 0x7f04
81 #define DM_REG_Y 0x7f06
82 #define DM_REG_SP 0x7f08
83 #define DM_REG_CC 0x7f0a
85 #define DM_BKR1E 0x7f90
86 #define DM_BKR2E 0x7f93
89 #define DM_CSR1 0x7f98
90 #define DM_CSR2 0x7f99
104 #define FLASH_CR1_STM8S 0x505A
105 #define FLASH_CR2_STM8S 0x505B
106 #define FLASH_NCR2_STM8S 0x505C
107 #define FLASH_IAPSR_STM8S 0x505F
108 #define FLASH_PUKR_STM8S 0x5062
109 #define FLASH_DUKR_STM8S 0x5064
111 #define FLASH_CR1_STM8L 0x5050
112 #define FLASH_CR2_STM8L 0x5051
113 #define FLASH_NCR2_STM8L 0
114 #define FLASH_PUKR_STM8L 0x5052
115 #define FLASH_DUKR_STM8L 0x5053
116 #define FLASH_IAPSR_STM8L 0x5054
123 #define WR_PG_DIS 0x01
133 #define SAFE_MASK 0x80
134 #define NO_ACCESS 0x40
138 #define SWIM_RST 0x04
142 #define SWIM_CSR 0x7f80
144 #define STM8_BREAK 0x8B
153 struct stm8_algorithm
{
157 struct stm8_core_reg
{
159 struct target
*target
;
160 struct stm8_common
*stm8_common
;
164 /* break on execute */
170 /* break on read, write and execute */
174 struct stm8_comparator
{
177 uint32_t reg_address
;
178 enum hw_break_type type
;
181 static int stm8_adapter_read_memory(struct target
*target
,
182 uint32_t addr
, int size
, int count
, void *buf
)
184 return swim_read_mem(addr
, size
, count
, buf
);
187 static int stm8_adapter_write_memory(struct target
*target
,
188 uint32_t addr
, int size
, int count
, const void *buf
)
190 return swim_write_mem(addr
, size
, count
, buf
);
193 static int stm8_write_u8(struct target
*target
,
194 uint32_t addr
, uint8_t val
)
199 return swim_write_mem(addr
, 1, 1, buf
);
202 static int stm8_read_u8(struct target
*target
,
203 uint32_t addr
, uint8_t *val
)
205 return swim_read_mem(addr
, 1, 1, val
);
209 <enable == 0> Disables interrupts.
210 If interrupts are enabled they are masked and the cc register
213 <enable == 1> Enables interrupts.
214 Enable interrupts is actually restoring I1 I0 state from previous
215 call with enable == 0. Note that if stepping and breaking on a sim
216 instruction will NOT work since the interrupt flags are restored on
217 debug_entry. We don't have any way for the debugger to exclusively
218 disable the interrupts
220 static int stm8_enable_interrupts(struct target
*target
, int enable
)
222 struct stm8_common
*stm8
= target_to_stm8(target
);
227 return ERROR_OK
; /* cc was not stashed */
228 /* fetch current cc */
229 stm8_read_u8(target
, DM_REG_CC
, &cc
);
231 cc
&= ~(CC_I0
+ CC_I1
);
232 /* restore I1 & I0 from stash*/
233 cc
|= (stm8
->cc
& (CC_I0
+CC_I1
));
234 /* update current cc */
235 stm8_write_u8(target
, DM_REG_CC
, cc
);
236 stm8
->cc_valid
= false;
238 stm8_read_u8(target
, DM_REG_CC
, &cc
);
239 if ((cc
& CC_I0
) && (cc
& CC_I1
))
240 return ERROR_OK
; /* interrupts already masked */
243 stm8
->cc_valid
= true;
244 /* mask interrupts (disable) */
245 cc
|= (CC_I0
+ CC_I1
);
246 stm8_write_u8(target
, DM_REG_CC
, cc
);
252 static int stm8_set_hwbreak(struct target
*target
,
253 struct stm8_comparator comparator_list
[])
258 /* Refer to Table 4 in UM0470 */
266 if (!comparator_list
[0].used
) {
267 comparator_list
[0].type
= HWBRK_EXEC
;
268 comparator_list
[0].bp_value
= -1;
271 if (!comparator_list
[1].used
) {
272 comparator_list
[1].type
= HWBRK_EXEC
;
273 comparator_list
[1].bp_value
= -1;
276 if ((comparator_list
[0].type
== HWBRK_EXEC
)
277 && (comparator_list
[1].type
== HWBRK_EXEC
)) {
278 comparator_list
[0].reg_address
= 0;
279 comparator_list
[1].reg_address
= 1;
282 if ((comparator_list
[0].type
== HWBRK_EXEC
)
283 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
284 comparator_list
[0].reg_address
= 0;
285 comparator_list
[1].reg_address
= 1;
286 switch (comparator_list
[1].type
) {
300 if ((comparator_list
[1].type
== HWBRK_EXEC
)
301 && (comparator_list
[0].type
!= HWBRK_EXEC
)) {
302 comparator_list
[0].reg_address
= 1;
303 comparator_list
[1].reg_address
= 0;
304 switch (comparator_list
[0].type
) {
318 if ((comparator_list
[0].type
!= HWBRK_EXEC
)
319 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
320 if (comparator_list
[0].type
!= comparator_list
[1].type
) {
321 LOG_ERROR("data hw breakpoints must be of same type");
322 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
326 for (i
= 0; i
< 2; i
++) {
327 data
= comparator_list
[i
].bp_value
;
328 addr
= comparator_list
[i
].reg_address
;
335 ret
= stm8_adapter_write_memory(target
, DM_BKR1E
, 1, 3, buf
);
336 LOG_DEBUG("DM_BKR1E=%" PRIx32
, data
);
337 } else if (addr
== 1) {
338 ret
= stm8_adapter_write_memory(target
, DM_BKR2E
, 1, 3, buf
);
339 LOG_DEBUG("DM_BKR2E=%" PRIx32
, data
);
341 LOG_DEBUG("addr=%" PRIu32
, addr
);
348 ret
= stm8_write_u8(target
, DM_CR1
,
349 (bc
<< 3) + (bir
<< 2) + (biw
<< 1));
350 LOG_DEBUG("DM_CR1=%" PRIx8
, buf
[0]);
358 /* read DM control and status regs */
359 static int stm8_read_dm_csrx(struct target
*target
, uint8_t *csr1
,
365 ret
= stm8_adapter_read_memory(target
, DM_CSR1
, 1, sizeof(buf
), buf
);
375 /* set or clear the single step flag in DM */
376 static int stm8_config_step(struct target
*target
, int enable
)
381 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
389 ret
= stm8_write_u8(target
, DM_CSR1
, csr1
);
395 /* set the stall flag in DM */
396 static int stm8_debug_stall(struct target
*target
)
401 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
405 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
411 static int stm8_configure_break_unit(struct target
*target
)
413 /* get pointers to arch-specific information */
414 struct stm8_common
*stm8
= target_to_stm8(target
);
416 if (stm8
->bp_scanned
)
419 stm8
->num_hw_bpoints
= 2;
420 stm8
->num_hw_bpoints_avail
= stm8
->num_hw_bpoints
;
422 stm8
->hw_break_list
= calloc(stm8
->num_hw_bpoints
,
423 sizeof(struct stm8_comparator
));
425 stm8
->hw_break_list
[0].reg_address
= 0;
426 stm8
->hw_break_list
[1].reg_address
= 1;
428 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8
->num_hw_bpoints
,
429 stm8
->num_hw_bpoints
);
431 stm8
->bp_scanned
= true;
436 static int stm8_examine_debug_reason(struct target
*target
)
441 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
442 if (retval
== ERROR_OK
)
443 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
445 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
446 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
448 if (retval
!= ERROR_OK
)
452 /* halted on reset */
453 target
->debug_reason
= DBG_REASON_UNDEFINED
;
455 if (csr1
& (BK1F
+BK2F
))
456 /* we have halted on a breakpoint (or wp)*/
457 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
460 /* we have halted on a breakpoint */
461 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
468 static int stm8_debug_entry(struct target
*target
)
470 struct stm8_common
*stm8
= target_to_stm8(target
);
472 /* restore interrupts */
473 stm8_enable_interrupts(target
, 1);
475 stm8_save_context(target
);
477 /* make sure stepping disabled STE bit in CSR1 cleared */
478 stm8_config_step(target
, 0);
480 /* attempt to find halt reason */
481 stm8_examine_debug_reason(target
);
483 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
484 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32),
485 target_state_name(target
));
490 /* clear stall flag in DM and flush instruction pipe */
491 static int stm8_exit_debug(struct target
*target
)
496 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
500 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
506 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
512 static int stm8_read_regs(struct target
*target
, uint32_t regs
[])
517 ret
= stm8_adapter_read_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
521 regs
[0] = be_to_h_u24(buf
+DM_REG_PC
-DM_REGS
);
522 regs
[1] = buf
[DM_REG_A
-DM_REGS
];
523 regs
[2] = be_to_h_u16(buf
+DM_REG_X
-DM_REGS
);
524 regs
[3] = be_to_h_u16(buf
+DM_REG_Y
-DM_REGS
);
525 regs
[4] = be_to_h_u16(buf
+DM_REG_SP
-DM_REGS
);
526 regs
[5] = buf
[DM_REG_CC
-DM_REGS
];
531 static int stm8_write_regs(struct target
*target
, uint32_t regs
[])
536 h_u24_to_be(buf
+DM_REG_PC
-DM_REGS
, regs
[0]);
537 buf
[DM_REG_A
-DM_REGS
] = regs
[1];
538 h_u16_to_be(buf
+DM_REG_X
-DM_REGS
, regs
[2]);
539 h_u16_to_be(buf
+DM_REG_Y
-DM_REGS
, regs
[3]);
540 h_u16_to_be(buf
+DM_REG_SP
-DM_REGS
, regs
[4]);
541 buf
[DM_REG_CC
-DM_REGS
] = regs
[5];
543 ret
= stm8_adapter_write_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
550 static int stm8_get_core_reg(struct reg
*reg
)
553 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
554 struct target
*target
= stm8_reg
->target
;
555 struct stm8_common
*stm8_target
= target_to_stm8(target
);
557 if (target
->state
!= TARGET_HALTED
)
558 return ERROR_TARGET_NOT_HALTED
;
560 retval
= stm8_target
->read_core_reg(target
, stm8_reg
->num
);
565 static int stm8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
567 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
568 struct target
*target
= stm8_reg
->target
;
569 uint32_t value
= buf_get_u32(buf
, 0, reg
->size
);
571 if (target
->state
!= TARGET_HALTED
)
572 return ERROR_TARGET_NOT_HALTED
;
574 buf_set_u32(reg
->value
, 0, 32, value
);
581 static int stm8_save_context(struct target
*target
)
585 /* get pointers to arch-specific information */
586 struct stm8_common
*stm8
= target_to_stm8(target
);
588 /* read core registers */
589 stm8_read_regs(target
, stm8
->core_regs
);
591 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
592 if (!stm8
->core_cache
->reg_list
[i
].valid
)
593 stm8
->read_core_reg(target
, i
);
599 static int stm8_restore_context(struct target
*target
)
603 /* get pointers to arch-specific information */
604 struct stm8_common
*stm8
= target_to_stm8(target
);
606 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
607 if (stm8
->core_cache
->reg_list
[i
].dirty
)
608 stm8
->write_core_reg(target
, i
);
611 /* write core regs */
612 stm8_write_regs(target
, stm8
->core_regs
);
617 static int stm8_unlock_flash(struct target
*target
)
621 struct stm8_common
*stm8
= target_to_stm8(target
);
623 /* check if flash is unlocked */
624 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
625 if (~data
[0] & PUL
) {
627 stm8_write_u8(target
, stm8
->flash_pukr
, 0x56);
628 stm8_write_u8(target
, stm8
->flash_pukr
, 0xae);
631 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
637 static int stm8_unlock_eeprom(struct target
*target
)
641 struct stm8_common
*stm8
= target_to_stm8(target
);
643 /* check if eeprom is unlocked */
644 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
645 if (~data
[0] & DUL
) {
647 stm8_write_u8(target
, stm8
->flash_dukr
, 0xae);
648 stm8_write_u8(target
, stm8
->flash_dukr
, 0x56);
651 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
657 static int stm8_write_flash(struct target
*target
, enum mem_type type
,
659 uint32_t size
, uint32_t count
, uint32_t blocksize_param
,
660 const uint8_t *buffer
)
662 struct stm8_common
*stm8
= target_to_stm8(target
);
667 uint32_t blocksize
= 0;
673 stm8_unlock_flash(target
);
676 stm8_unlock_eeprom(target
);
679 stm8_unlock_eeprom(target
);
683 LOG_ERROR("BUG: wrong mem_type %d", type
);
688 /* we don't support short writes */
693 bytecnt
= count
* size
;
696 if ((bytecnt
>= blocksize_param
) && ((address
& (blocksize_param
-1)) == 0)) {
698 stm8_write_u8(target
, stm8
->flash_cr2
, PRG
+ opt
);
699 if (stm8
->flash_ncr2
)
700 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(PRG
+ opt
));
701 blocksize
= blocksize_param
;
703 if ((bytecnt
>= 4) && ((address
& 0x3) == 0)) {
705 stm8_write_u8(target
, stm8
->flash_cr2
, WPRG
+ opt
);
706 if (stm8
->flash_ncr2
)
707 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(WPRG
+ opt
));
710 if (blocksize
!= 1) {
712 stm8_write_u8(target
, stm8
->flash_cr2
, opt
);
713 if (stm8
->flash_ncr2
)
714 stm8_write_u8(target
, stm8
->flash_ncr2
, ~opt
);
718 res
= stm8_adapter_write_memory(target
, address
, 1, blocksize
, buffer
);
721 address
+= blocksize
;
723 bytecnt
-= blocksize
;
725 /* lets hang here until end of program (EOP) */
726 for (i
= 0; i
< 16; i
++) {
727 stm8_read_u8(target
, stm8
->flash_iapsr
, &iapsr
);
737 /* disable write access */
738 res
= stm8_write_u8(target
, stm8
->flash_iapsr
, 0x0);
746 static int stm8_write_memory(struct target
*target
, target_addr_t address
,
747 uint32_t size
, uint32_t count
,
748 const uint8_t *buffer
)
750 struct stm8_common
*stm8
= target_to_stm8(target
);
752 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
753 ", size: 0x%8.8" PRIx32
754 ", count: 0x%8.8" PRIx32
,
755 address
, size
, count
);
757 if (target
->state
!= TARGET_HALTED
)
758 LOG_WARNING("target not halted");
762 if ((address
>= stm8
->flashstart
) && (address
<= stm8
->flashend
))
763 retval
= stm8_write_flash(target
, FLASH
, address
, size
, count
,
764 stm8
->blocksize
, buffer
);
765 else if ((address
>= stm8
->eepromstart
) && (address
<= stm8
->eepromend
))
766 retval
= stm8_write_flash(target
, EEPROM
, address
, size
, count
,
767 stm8
->blocksize
, buffer
);
768 else if ((address
>= stm8
->optionstart
) && (address
<= stm8
->optionend
))
769 retval
= stm8_write_flash(target
, OPTION
, address
, size
, count
, 0, buffer
);
771 retval
= stm8_adapter_write_memory(target
, address
, size
, count
,
774 if (retval
!= ERROR_OK
)
775 return ERROR_TARGET_FAILURE
;
780 static int stm8_read_memory(struct target
*target
, target_addr_t address
,
781 uint32_t size
, uint32_t count
, uint8_t *buffer
)
783 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
784 ", size: 0x%8.8" PRIx32
785 ", count: 0x%8.8" PRIx32
,
786 address
, size
, count
);
788 if (target
->state
!= TARGET_HALTED
)
789 LOG_WARNING("target not halted");
792 retval
= stm8_adapter_read_memory(target
, address
, size
, count
, buffer
);
794 if (retval
!= ERROR_OK
)
795 return ERROR_TARGET_FAILURE
;
800 static int stm8_init(struct command_context
*cmd_ctx
, struct target
*target
)
802 stm8_build_reg_cache(target
);
807 static int stm8_poll(struct target
*target
)
809 int retval
= ERROR_OK
;
813 LOG_DEBUG("target->state=%d", target
->state
);
816 /* read dm_csrx control regs */
817 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
818 if (retval
!= ERROR_OK
) {
819 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval
);
821 We return ERROR_OK here even if we didn't get an answer.
822 openocd will call target_wait_state until we get target state TARGET_HALTED
827 /* check for processor halted */
829 if (target
->state
!= TARGET_HALTED
) {
830 if (target
->state
== TARGET_UNKNOWN
)
831 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
833 retval
= stm8_debug_entry(target
);
834 if (retval
!= ERROR_OK
) {
835 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval
);
836 return ERROR_TARGET_FAILURE
;
839 if (target
->state
== TARGET_DEBUG_RUNNING
) {
840 target
->state
= TARGET_HALTED
;
841 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
843 target
->state
= TARGET_HALTED
;
844 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
848 target
->state
= TARGET_RUNNING
;
850 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
855 static int stm8_halt(struct target
*target
)
857 LOG_DEBUG("target->state: %s", target_state_name(target
));
859 if (target
->state
== TARGET_HALTED
) {
860 LOG_DEBUG("target was already halted");
864 if (target
->state
== TARGET_UNKNOWN
)
865 LOG_WARNING("target was in unknown state when halt was requested");
867 if (target
->state
== TARGET_RESET
) {
868 /* we came here in a reset_halt or reset_init sequence
869 * debug entry was already prepared in stm8_assert_reset()
871 target
->debug_reason
= DBG_REASON_DBGRQ
;
877 /* break processor */
878 stm8_debug_stall(target
);
880 target
->debug_reason
= DBG_REASON_DBGRQ
;
885 static int stm8_reset_assert(struct target
*target
)
888 struct stm8_common
*stm8
= target_to_stm8(target
);
889 bool use_srst_fallback
= true;
891 enum reset_types jtag_reset_config
= jtag_get_reset_config();
893 if (jtag_reset_config
& RESET_HAS_SRST
) {
894 res
= adapter_assert_reset();
896 /* hardware srst supported */
897 use_srst_fallback
= false;
898 else if (res
!= ERROR_COMMAND_NOTFOUND
)
899 /* some other failure */
903 if (use_srst_fallback
) {
904 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
905 res
= swim_system_reset();
910 /* registers are now invalid */
911 register_cache_invalidate(stm8
->core_cache
);
913 target
->state
= TARGET_RESET
;
914 target
->debug_reason
= DBG_REASON_NOTHALTED
;
916 if (target
->reset_halt
) {
917 res
= target_halt(target
);
925 static int stm8_reset_deassert(struct target
*target
)
928 enum reset_types jtag_reset_config
= jtag_get_reset_config();
930 if (jtag_reset_config
& RESET_HAS_SRST
) {
931 res
= adapter_deassert_reset();
932 if ((res
!= ERROR_OK
) && (res
!= ERROR_COMMAND_NOTFOUND
))
936 /* The cpu should now be stalled. If halt was requested
937 let poll detect the stall */
938 if (target
->reset_halt
)
941 /* Instead of going thrugh saving context, polling and
942 then resuming target again just clear stall and proceed. */
943 target
->state
= TARGET_RUNNING
;
944 return stm8_exit_debug(target
);
947 /* stm8_single_step_core() is only used for stepping over breakpoints
948 from stm8_resume() */
949 static int stm8_single_step_core(struct target
*target
)
951 struct stm8_common
*stm8
= target_to_stm8(target
);
953 /* configure single step mode */
954 stm8_config_step(target
, 1);
956 /* disable interrupts while stepping */
957 if (!stm8
->enable_step_irq
)
958 stm8_enable_interrupts(target
, 0);
960 /* exit debug mode */
961 stm8_exit_debug(target
);
963 stm8_debug_entry(target
);
968 static int stm8_resume(struct target
*target
, int current
,
969 target_addr_t address
, int handle_breakpoints
,
972 struct stm8_common
*stm8
= target_to_stm8(target
);
973 struct breakpoint
*breakpoint
= NULL
;
976 LOG_DEBUG("%d " TARGET_ADDR_FMT
" %d %d", current
, address
,
977 handle_breakpoints
, debug_execution
);
979 if (target
->state
!= TARGET_HALTED
) {
980 LOG_WARNING("target not halted");
981 return ERROR_TARGET_NOT_HALTED
;
984 if (!debug_execution
) {
985 target_free_all_working_areas(target
);
986 stm8_enable_breakpoints(target
);
987 stm8_enable_watchpoints(target
);
988 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
989 stm8_set_hwbreak(target
, comparator_list
);
992 /* current = 1: continue on current pc,
993 otherwise continue at <address> */
995 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
,
997 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
998 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1002 resume_pc
= address
;
1004 resume_pc
= buf_get_u32(
1005 stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1008 stm8_restore_context(target
);
1010 /* the front-end may request us not to handle breakpoints */
1011 if (handle_breakpoints
) {
1012 /* Single step past breakpoint at current address */
1013 breakpoint
= breakpoint_find(target
, resume_pc
);
1015 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
,
1016 breakpoint
->address
);
1017 stm8_unset_breakpoint(target
, breakpoint
);
1018 stm8_single_step_core(target
);
1019 stm8_set_breakpoint(target
, breakpoint
);
1023 /* disable interrupts if we are debugging */
1024 if (debug_execution
)
1025 stm8_enable_interrupts(target
, 0);
1027 /* exit debug mode */
1028 stm8_exit_debug(target
);
1029 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1031 /* registers are now invalid */
1032 register_cache_invalidate(stm8
->core_cache
);
1034 if (!debug_execution
) {
1035 target
->state
= TARGET_RUNNING
;
1036 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1037 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
1039 target
->state
= TARGET_DEBUG_RUNNING
;
1040 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1041 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
1047 static int stm8_init_flash_regs(bool enable_stm8l
, struct stm8_common
*stm8
)
1049 stm8
->enable_stm8l
= enable_stm8l
;
1051 if (stm8
->enable_stm8l
) {
1052 stm8
->flash_cr2
= FLASH_CR2_STM8L
;
1053 stm8
->flash_ncr2
= FLASH_NCR2_STM8L
;
1054 stm8
->flash_iapsr
= FLASH_IAPSR_STM8L
;
1055 stm8
->flash_dukr
= FLASH_DUKR_STM8L
;
1056 stm8
->flash_pukr
= FLASH_PUKR_STM8L
;
1058 stm8
->flash_cr2
= FLASH_CR2_STM8S
;
1059 stm8
->flash_ncr2
= FLASH_NCR2_STM8S
;
1060 stm8
->flash_iapsr
= FLASH_IAPSR_STM8S
;
1061 stm8
->flash_dukr
= FLASH_DUKR_STM8S
;
1062 stm8
->flash_pukr
= FLASH_PUKR_STM8S
;
1067 static int stm8_init_arch_info(struct target
*target
,
1068 struct stm8_common
*stm8
, struct jtag_tap
*tap
)
1070 target
->endianness
= TARGET_BIG_ENDIAN
;
1071 target
->arch_info
= stm8
;
1072 stm8
->common_magic
= STM8_COMMON_MAGIC
;
1073 stm8
->fast_data_area
= NULL
;
1074 stm8
->blocksize
= 0x80;
1075 stm8
->flashstart
= 0x8000;
1076 stm8
->flashend
= 0xffff;
1077 stm8
->eepromstart
= 0x4000;
1078 stm8
->eepromend
= 0x43ff;
1079 stm8
->optionstart
= 0x4800;
1080 stm8
->optionend
= 0x487F;
1082 /* has breakpoint/watchpoint unit been scanned */
1083 stm8
->bp_scanned
= false;
1084 stm8
->hw_break_list
= NULL
;
1086 stm8
->read_core_reg
= stm8_read_core_reg
;
1087 stm8
->write_core_reg
= stm8_write_core_reg
;
1089 stm8_init_flash_regs(0, stm8
);
1094 static int stm8_target_create(struct target
*target
,
1098 struct stm8_common
*stm8
= calloc(1, sizeof(struct stm8_common
));
1100 stm8_init_arch_info(target
, stm8
, target
->tap
);
1101 stm8_configure_break_unit(target
);
1106 static int stm8_read_core_reg(struct target
*target
, unsigned int num
)
1110 /* get pointers to arch-specific information */
1111 struct stm8_common
*stm8
= target_to_stm8(target
);
1113 if (num
>= STM8_NUM_REGS
)
1114 return ERROR_COMMAND_SYNTAX_ERROR
;
1116 reg_value
= stm8
->core_regs
[num
];
1117 LOG_DEBUG("read core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1118 buf_set_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
1119 stm8
->core_cache
->reg_list
[num
].valid
= true;
1120 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1125 static int stm8_write_core_reg(struct target
*target
, unsigned int num
)
1129 /* get pointers to arch-specific information */
1130 struct stm8_common
*stm8
= target_to_stm8(target
);
1132 if (num
>= STM8_NUM_REGS
)
1133 return ERROR_COMMAND_SYNTAX_ERROR
;
1135 reg_value
= buf_get_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32);
1136 stm8
->core_regs
[num
] = reg_value
;
1137 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1138 stm8
->core_cache
->reg_list
[num
].valid
= true;
1139 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1144 static const char *stm8_get_gdb_arch(struct target
*target
)
1149 static int stm8_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1150 int *reg_list_size
, enum target_register_class reg_class
)
1152 /* get pointers to arch-specific information */
1153 struct stm8_common
*stm8
= target_to_stm8(target
);
1156 *reg_list_size
= STM8_NUM_REGS
;
1157 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1159 for (i
= 0; i
< STM8_NUM_REGS
; i
++)
1160 (*reg_list
)[i
] = &stm8
->core_cache
->reg_list
[i
];
1165 static const struct reg_arch_type stm8_reg_type
= {
1166 .get
= stm8_get_core_reg
,
1167 .set
= stm8_set_core_reg
,
1170 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
)
1172 /* get pointers to arch-specific information */
1173 struct stm8_common
*stm8
= target_to_stm8(target
);
1175 int num_regs
= STM8_NUM_REGS
;
1176 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1177 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1178 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1179 struct stm8_core_reg
*arch_info
= malloc(
1180 sizeof(struct stm8_core_reg
) * num_regs
);
1181 struct reg_feature
*feature
;
1184 /* Build the process context cache */
1185 cache
->name
= "stm8 registers";
1187 cache
->reg_list
= reg_list
;
1188 cache
->num_regs
= num_regs
;
1190 stm8
->core_cache
= cache
;
1192 for (i
= 0; i
< num_regs
; i
++) {
1193 arch_info
[i
].num
= stm8_regs
[i
].id
;
1194 arch_info
[i
].target
= target
;
1195 arch_info
[i
].stm8_common
= stm8
;
1197 reg_list
[i
].name
= stm8_regs
[i
].name
;
1198 reg_list
[i
].size
= stm8_regs
[i
].bits
;
1200 reg_list
[i
].value
= calloc(1, 4);
1201 reg_list
[i
].valid
= false;
1202 reg_list
[i
].type
= &stm8_reg_type
;
1203 reg_list
[i
].arch_info
= &arch_info
[i
];
1205 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1206 if (reg_list
[i
].reg_data_type
)
1207 reg_list
[i
].reg_data_type
->type
= stm8_regs
[i
].type
;
1209 LOG_ERROR("unable to allocate reg type list");
1213 reg_list
[i
].dirty
= false;
1214 reg_list
[i
].group
= stm8_regs
[i
].group
;
1215 reg_list
[i
].number
= stm8_regs
[i
].id
;
1216 reg_list
[i
].exist
= true;
1217 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1219 feature
= calloc(1, sizeof(struct reg_feature
));
1221 feature
->name
= stm8_regs
[i
].feature
;
1222 reg_list
[i
].feature
= feature
;
1224 LOG_ERROR("unable to allocate feature list");
1230 static void stm8_free_reg_cache(struct target
*target
)
1232 struct stm8_common
*stm8
= target_to_stm8(target
);
1233 struct reg_cache
*cache
;
1237 cache
= stm8
->core_cache
;
1242 for (i
= 0; i
< cache
->num_regs
; i
++) {
1243 reg
= &cache
->reg_list
[i
];
1246 free(reg
->reg_data_type
);
1250 free(cache
->reg_list
[0].arch_info
);
1251 free(cache
->reg_list
);
1254 stm8
->core_cache
= NULL
;
1257 static void stm8_deinit(struct target
*target
)
1259 struct stm8_common
*stm8
= target_to_stm8(target
);
1261 free(stm8
->hw_break_list
);
1263 stm8_free_reg_cache(target
);
1268 static int stm8_arch_state(struct target
*target
)
1270 struct stm8_common
*stm8
= target_to_stm8(target
);
1272 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
1273 debug_reason_name(target
),
1274 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1279 static int stm8_step(struct target
*target
, int current
,
1280 target_addr_t address
, int handle_breakpoints
)
1282 LOG_DEBUG("%" PRIx32
" " TARGET_ADDR_FMT
" %" PRIx32
,
1283 current
, address
, handle_breakpoints
);
1285 /* get pointers to arch-specific information */
1286 struct stm8_common
*stm8
= target_to_stm8(target
);
1287 struct breakpoint
*breakpoint
= NULL
;
1289 if (target
->state
!= TARGET_HALTED
) {
1290 LOG_WARNING("target not halted");
1291 return ERROR_TARGET_NOT_HALTED
;
1294 /* current = 1: continue on current pc, otherwise continue at <address> */
1296 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32, address
);
1297 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1298 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1301 /* the front-end may request us not to handle breakpoints */
1302 if (handle_breakpoints
) {
1303 breakpoint
= breakpoint_find(target
,
1304 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1306 stm8_unset_breakpoint(target
, breakpoint
);
1309 /* restore context */
1310 stm8_restore_context(target
);
1312 /* configure single step mode */
1313 stm8_config_step(target
, 1);
1315 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1317 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1319 /* disable interrupts while stepping */
1320 if (!stm8
->enable_step_irq
)
1321 stm8_enable_interrupts(target
, 0);
1323 /* exit debug mode */
1324 stm8_exit_debug(target
);
1326 /* registers are now invalid */
1327 register_cache_invalidate(stm8
->core_cache
);
1329 LOG_DEBUG("target stepped ");
1330 stm8_debug_entry(target
);
1333 stm8_set_breakpoint(target
, breakpoint
);
1335 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1340 static void stm8_enable_breakpoints(struct target
*target
)
1342 struct breakpoint
*breakpoint
= target
->breakpoints
;
1344 /* set any pending breakpoints */
1345 while (breakpoint
) {
1346 if (breakpoint
->set
== 0)
1347 stm8_set_breakpoint(target
, breakpoint
);
1348 breakpoint
= breakpoint
->next
;
1352 static int stm8_set_breakpoint(struct target
*target
,
1353 struct breakpoint
*breakpoint
)
1355 struct stm8_common
*stm8
= target_to_stm8(target
);
1356 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1359 if (breakpoint
->set
) {
1360 LOG_WARNING("breakpoint already set");
1364 if (breakpoint
->type
== BKPT_HARD
) {
1367 while (comparator_list
[bp_num
].used
&& (bp_num
< stm8
->num_hw_bpoints
))
1369 if (bp_num
>= stm8
->num_hw_bpoints
) {
1370 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32
")",
1371 breakpoint
->unique_id
);
1372 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1374 breakpoint
->set
= bp_num
+ 1;
1375 comparator_list
[bp_num
].used
= true;
1376 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
1377 comparator_list
[bp_num
].type
= HWBRK_EXEC
;
1379 retval
= stm8_set_hwbreak(target
, comparator_list
);
1380 if (retval
!= ERROR_OK
)
1383 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1384 breakpoint
->unique_id
,
1385 bp_num
, comparator_list
[bp_num
].bp_value
);
1386 } else if (breakpoint
->type
== BKPT_SOFT
) {
1387 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1388 if (breakpoint
->length
== 1) {
1389 uint8_t verify
= 0x55;
1391 retval
= target_read_u8(target
, breakpoint
->address
,
1392 breakpoint
->orig_instr
);
1393 if (retval
!= ERROR_OK
)
1395 retval
= target_write_u8(target
, breakpoint
->address
, STM8_BREAK
);
1396 if (retval
!= ERROR_OK
)
1399 retval
= target_read_u8(target
, breakpoint
->address
, &verify
);
1400 if (retval
!= ERROR_OK
)
1402 if (verify
!= STM8_BREAK
) {
1403 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1404 " - check that memory is read/writable",
1405 breakpoint
->address
);
1406 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1409 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1411 breakpoint
->set
= 1; /* Any nice value but 0 */
1417 static int stm8_add_breakpoint(struct target
*target
,
1418 struct breakpoint
*breakpoint
)
1420 struct stm8_common
*stm8
= target_to_stm8(target
);
1423 if (breakpoint
->type
== BKPT_HARD
) {
1424 if (stm8
->num_hw_bpoints_avail
< 1) {
1425 LOG_INFO("no hardware breakpoint available");
1426 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1429 ret
= stm8_set_breakpoint(target
, breakpoint
);
1430 if (ret
!= ERROR_OK
)
1433 stm8
->num_hw_bpoints_avail
--;
1437 ret
= stm8_set_breakpoint(target
, breakpoint
);
1438 if (ret
!= ERROR_OK
)
1444 static int stm8_unset_breakpoint(struct target
*target
,
1445 struct breakpoint
*breakpoint
)
1447 /* get pointers to arch-specific information */
1448 struct stm8_common
*stm8
= target_to_stm8(target
);
1449 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1452 if (!breakpoint
->set
) {
1453 LOG_WARNING("breakpoint not set");
1457 if (breakpoint
->type
== BKPT_HARD
) {
1458 int bp_num
= breakpoint
->set
- 1;
1459 if ((bp_num
< 0) || (bp_num
>= stm8
->num_hw_bpoints
)) {
1460 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1461 breakpoint
->unique_id
);
1464 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d",
1465 breakpoint
->unique_id
,
1467 comparator_list
[bp_num
].used
= false;
1468 retval
= stm8_set_hwbreak(target
, comparator_list
);
1469 if (retval
!= ERROR_OK
)
1472 /* restore original instruction (kept in target endianness) */
1473 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1474 if (breakpoint
->length
== 1) {
1475 uint8_t current_instr
;
1477 /* check that user program has not
1478 modified breakpoint instruction */
1479 retval
= target_read_memory(target
, breakpoint
->address
, 1, 1,
1480 (uint8_t *)¤t_instr
);
1481 if (retval
!= ERROR_OK
)
1484 if (current_instr
== STM8_BREAK
) {
1485 retval
= target_write_memory(target
, breakpoint
->address
, 1, 1,
1486 breakpoint
->orig_instr
);
1487 if (retval
!= ERROR_OK
)
1493 breakpoint
->set
= 0;
1498 static int stm8_remove_breakpoint(struct target
*target
,
1499 struct breakpoint
*breakpoint
)
1501 /* get pointers to arch-specific information */
1502 struct stm8_common
*stm8
= target_to_stm8(target
);
1504 if (target
->state
!= TARGET_HALTED
) {
1505 LOG_WARNING("target not halted");
1506 return ERROR_TARGET_NOT_HALTED
;
1509 if (breakpoint
->set
)
1510 stm8_unset_breakpoint(target
, breakpoint
);
1512 if (breakpoint
->type
== BKPT_HARD
)
1513 stm8
->num_hw_bpoints_avail
++;
1518 static int stm8_set_watchpoint(struct target
*target
,
1519 struct watchpoint
*watchpoint
)
1521 struct stm8_common
*stm8
= target_to_stm8(target
);
1522 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1526 if (watchpoint
->set
) {
1527 LOG_WARNING("watchpoint already set");
1531 while (comparator_list
[wp_num
].used
&& (wp_num
< stm8
->num_hw_bpoints
))
1533 if (wp_num
>= stm8
->num_hw_bpoints
) {
1534 LOG_ERROR("Can not find free hw breakpoint");
1535 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1538 if (watchpoint
->length
!= 1) {
1539 LOG_ERROR("Only watchpoints of length 1 are supported");
1540 return ERROR_TARGET_UNALIGNED_ACCESS
;
1543 enum hw_break_type enable
= 0;
1545 switch (watchpoint
->rw
) {
1556 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1559 comparator_list
[wp_num
].used
= true;
1560 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
1561 comparator_list
[wp_num
].type
= enable
;
1563 ret
= stm8_set_hwbreak(target
, comparator_list
);
1564 if (ret
!= ERROR_OK
) {
1565 comparator_list
[wp_num
].used
= false;
1569 watchpoint
->set
= wp_num
+ 1;
1571 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"",
1573 comparator_list
[wp_num
].bp_value
);
1578 static int stm8_add_watchpoint(struct target
*target
,
1579 struct watchpoint
*watchpoint
)
1582 struct stm8_common
*stm8
= target_to_stm8(target
);
1584 if (stm8
->num_hw_bpoints_avail
< 1) {
1585 LOG_INFO("no hardware watchpoints available");
1586 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1589 ret
= stm8_set_watchpoint(target
, watchpoint
);
1590 if (ret
!= ERROR_OK
)
1593 stm8
->num_hw_bpoints_avail
--;
1597 static void stm8_enable_watchpoints(struct target
*target
)
1599 struct watchpoint
*watchpoint
= target
->watchpoints
;
1601 /* set any pending watchpoints */
1602 while (watchpoint
) {
1603 if (watchpoint
->set
== 0)
1604 stm8_set_watchpoint(target
, watchpoint
);
1605 watchpoint
= watchpoint
->next
;
1609 static int stm8_unset_watchpoint(struct target
*target
,
1610 struct watchpoint
*watchpoint
)
1612 /* get pointers to arch-specific information */
1613 struct stm8_common
*stm8
= target_to_stm8(target
);
1614 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1616 if (!watchpoint
->set
) {
1617 LOG_WARNING("watchpoint not set");
1621 int wp_num
= watchpoint
->set
- 1;
1622 if ((wp_num
< 0) || (wp_num
>= stm8
->num_hw_bpoints
)) {
1623 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1626 comparator_list
[wp_num
].used
= false;
1627 watchpoint
->set
= 0;
1629 stm8_set_hwbreak(target
, comparator_list
);
1634 static int stm8_remove_watchpoint(struct target
*target
,
1635 struct watchpoint
*watchpoint
)
1637 /* get pointers to arch-specific information */
1638 struct stm8_common
*stm8
= target_to_stm8(target
);
1640 if (target
->state
!= TARGET_HALTED
) {
1641 LOG_WARNING("target not halted");
1642 return ERROR_TARGET_NOT_HALTED
;
1645 if (watchpoint
->set
)
1646 stm8_unset_watchpoint(target
, watchpoint
);
1648 stm8
->num_hw_bpoints_avail
++;
1653 static int stm8_examine(struct target
*target
)
1657 /* get pointers to arch-specific information */
1658 struct stm8_common
*stm8
= target_to_stm8(target
);
1659 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1661 if (!target_was_examined(target
)) {
1662 if (!stm8
->swim_configured
) {
1663 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1664 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1665 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
);
1666 if (retval
!= ERROR_OK
)
1668 /* set high speed */
1669 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1670 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
+ HS
);
1671 if (retval
!= ERROR_OK
)
1674 stm8
->swim_configured
= true;
1676 Now is the time to deassert reset if connect_under_reset.
1677 Releasing reset line will cause the option bytes to load.
1678 The core will still be stalled.
1680 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
1681 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
1682 stm8_reset_deassert(target
);
1684 LOG_WARNING("\'srst_nogate\' reset_config option is required");
1687 LOG_INFO("trying to reconnect");
1689 retval
= swim_reconnect();
1690 if (retval
!= ERROR_OK
) {
1691 LOG_ERROR("reconnect failed");
1695 /* read dm_csrx control regs */
1696 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
1697 if (retval
!= ERROR_OK
) {
1698 LOG_ERROR("state query failed");
1703 target_set_examined(target
);
1711 /** Checks whether a memory region is erased. */
1712 static int stm8_blank_check_memory(struct target
*target
,
1713 struct target_memory_check_block
*blocks
, int num_blocks
, uint8_t erased_value
)
1715 struct working_area
*erase_check_algorithm
;
1716 struct reg_param reg_params
[2];
1717 struct mem_param mem_params
[2];
1718 struct stm8_algorithm stm8_info
;
1720 static const uint8_t stm8_erase_check_code
[] = {
1721 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1724 if (erased_value
!= 0xff) {
1725 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for STM8",
1730 /* make sure we have a working area */
1731 if (target_alloc_working_area(target
, sizeof(stm8_erase_check_code
),
1732 &erase_check_algorithm
) != ERROR_OK
)
1733 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1735 target_write_buffer(target
, erase_check_algorithm
->address
,
1736 sizeof(stm8_erase_check_code
), stm8_erase_check_code
);
1738 stm8_info
.common_magic
= STM8_COMMON_MAGIC
;
1740 init_mem_param(&mem_params
[0], 0x0, 3, PARAM_OUT
);
1741 buf_set_u32(mem_params
[0].value
, 0, 24, blocks
[0].address
);
1743 init_mem_param(&mem_params
[1], 0x3, 3, PARAM_OUT
);
1744 buf_set_u32(mem_params
[1].value
, 0, 24, blocks
[0].size
);
1746 init_reg_param(®_params
[0], "a", 32, PARAM_IN_OUT
);
1747 buf_set_u32(reg_params
[0].value
, 0, 32, erased_value
);
1749 init_reg_param(®_params
[1], "sp", 32, PARAM_OUT
);
1750 buf_set_u32(reg_params
[1].value
, 0, 32, erase_check_algorithm
->address
);
1752 int retval
= target_run_algorithm(target
, 2, mem_params
, 2, reg_params
,
1753 erase_check_algorithm
->address
+ 6,
1754 erase_check_algorithm
->address
+ (sizeof(stm8_erase_check_code
) - 1),
1757 if (retval
== ERROR_OK
)
1758 blocks
[0].result
= (*(reg_params
[0].value
) == 0xff);
1760 destroy_mem_param(&mem_params
[0]);
1761 destroy_mem_param(&mem_params
[1]);
1762 destroy_reg_param(®_params
[0]);
1763 destroy_reg_param(®_params
[1]);
1765 target_free_working_area(target
, erase_check_algorithm
);
1767 if (retval
!= ERROR_OK
)
1770 return 1; /* only one block has been checked */
1773 static int stm8_checksum_memory(struct target
*target
, target_addr_t address
,
1774 uint32_t count
, uint32_t *checksum
)
1776 /* let image_calculate_checksum() take care of business */
1777 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1780 /* run to exit point. return error if exit point was not reached. */
1781 static int stm8_run_and_wait(struct target
*target
, uint32_t entry_point
,
1782 int timeout_ms
, uint32_t exit_point
, struct stm8_common
*stm8
)
1786 /* This code relies on the target specific resume() and
1787 poll()->debug_entry() sequence to write register values to the
1788 processor and the read them back */
1789 retval
= target_resume(target
, 0, entry_point
, 0, 1);
1790 if (retval
!= ERROR_OK
)
1793 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1794 /* If the target fails to halt due to the breakpoint, force a halt */
1795 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
1796 retval
= target_halt(target
);
1797 if (retval
!= ERROR_OK
)
1799 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
1800 if (retval
!= ERROR_OK
)
1802 return ERROR_TARGET_TIMEOUT
;
1805 pc
= buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32);
1806 if (exit_point
&& (pc
!= exit_point
)) {
1807 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
1808 return ERROR_TARGET_TIMEOUT
;
1814 static int stm8_run_algorithm(struct target
*target
, int num_mem_params
,
1815 struct mem_param
*mem_params
, int num_reg_params
,
1816 struct reg_param
*reg_params
, target_addr_t entry_point
,
1817 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
1819 struct stm8_common
*stm8
= target_to_stm8(target
);
1821 uint32_t context
[STM8_NUM_REGS
];
1822 int retval
= ERROR_OK
;
1824 LOG_DEBUG("Running algorithm");
1826 /* NOTE: stm8_run_algorithm requires that each
1827 algorithm uses a software breakpoint
1828 at the exit point */
1830 if (stm8
->common_magic
!= STM8_COMMON_MAGIC
) {
1831 LOG_ERROR("current target isn't a STM8 target");
1832 return ERROR_TARGET_INVALID
;
1835 if (target
->state
!= TARGET_HALTED
) {
1836 LOG_WARNING("target not halted");
1837 return ERROR_TARGET_NOT_HALTED
;
1840 /* refresh core register cache */
1841 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1842 if (!stm8
->core_cache
->reg_list
[i
].valid
)
1843 stm8
->read_core_reg(target
, i
);
1844 context
[i
] = buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1847 for (int i
= 0; i
< num_mem_params
; i
++) {
1848 if (mem_params
[i
].direction
== PARAM_IN
)
1850 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1851 mem_params
[i
].size
, mem_params
[i
].value
);
1852 if (retval
!= ERROR_OK
)
1856 for (int i
= 0; i
< num_reg_params
; i
++) {
1857 if (reg_params
[i
].direction
== PARAM_IN
)
1860 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1861 reg_params
[i
].reg_name
, 0);
1864 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1865 return ERROR_COMMAND_SYNTAX_ERROR
;
1868 if (reg_params
[i
].size
!= 32) {
1869 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1870 reg_params
[i
].reg_name
);
1871 return ERROR_COMMAND_SYNTAX_ERROR
;
1874 stm8_set_core_reg(reg
, reg_params
[i
].value
);
1877 retval
= stm8_run_and_wait(target
, entry_point
,
1878 timeout_ms
, exit_point
, stm8
);
1880 if (retval
!= ERROR_OK
)
1883 for (int i
= 0; i
< num_mem_params
; i
++) {
1884 if (mem_params
[i
].direction
!= PARAM_OUT
) {
1885 retval
= target_read_buffer(target
, mem_params
[i
].address
,
1886 mem_params
[i
].size
, mem_params
[i
].value
);
1887 if (retval
!= ERROR_OK
)
1892 for (int i
= 0; i
< num_reg_params
; i
++) {
1893 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1894 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1895 reg_params
[i
].reg_name
, 0);
1897 LOG_ERROR("BUG: register '%s' not found",
1898 reg_params
[i
].reg_name
);
1899 return ERROR_COMMAND_SYNTAX_ERROR
;
1902 if (reg_params
[i
].size
!= 32) {
1903 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1904 reg_params
[i
].reg_name
);
1905 return ERROR_COMMAND_SYNTAX_ERROR
;
1908 buf_set_u32(reg_params
[i
].value
,
1909 0, 32, buf_get_u32(reg
->value
, 0, 32));
1913 /* restore everything we saved before */
1914 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1916 regvalue
= buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1917 if (regvalue
!= context
[i
]) {
1918 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
1919 stm8
->core_cache
->reg_list
[i
].name
, context
[i
]);
1920 buf_set_u32(stm8
->core_cache
->reg_list
[i
].value
,
1922 stm8
->core_cache
->reg_list
[i
].valid
= true;
1923 stm8
->core_cache
->reg_list
[i
].dirty
= true;
1930 int stm8_jim_configure(struct target
*target
, Jim_GetOptInfo
*goi
)
1932 struct stm8_common
*stm8
= target_to_stm8(target
);
1937 arg
= Jim_GetString(goi
->argv
[0], NULL
);
1938 if (!strcmp(arg
, "-blocksize")) {
1939 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1943 if (goi
->argc
== 0) {
1944 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1945 "-blocksize ?bytes? ...");
1949 e
= Jim_GetOpt_Wide(goi
, &w
);
1953 stm8
->blocksize
= w
;
1954 LOG_DEBUG("blocksize=%8.8x", stm8
->blocksize
);
1957 if (!strcmp(arg
, "-flashstart")) {
1958 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1962 if (goi
->argc
== 0) {
1963 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1964 "-flashstart ?address? ...");
1968 e
= Jim_GetOpt_Wide(goi
, &w
);
1972 stm8
->flashstart
= w
;
1973 LOG_DEBUG("flashstart=%8.8x", stm8
->flashstart
);
1976 if (!strcmp(arg
, "-flashend")) {
1977 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1981 if (goi
->argc
== 0) {
1982 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1983 "-flashend ?address? ...");
1987 e
= Jim_GetOpt_Wide(goi
, &w
);
1992 LOG_DEBUG("flashend=%8.8x", stm8
->flashend
);
1995 if (!strcmp(arg
, "-eepromstart")) {
1996 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2000 if (goi
->argc
== 0) {
2001 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2002 "-eepromstart ?address? ...");
2006 e
= Jim_GetOpt_Wide(goi
, &w
);
2010 stm8
->eepromstart
= w
;
2011 LOG_DEBUG("eepromstart=%8.8x", stm8
->eepromstart
);
2014 if (!strcmp(arg
, "-eepromend")) {
2015 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2019 if (goi
->argc
== 0) {
2020 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2021 "-eepromend ?address? ...");
2025 e
= Jim_GetOpt_Wide(goi
, &w
);
2029 stm8
->eepromend
= w
;
2030 LOG_DEBUG("eepromend=%8.8x", stm8
->eepromend
);
2033 if (!strcmp(arg
, "-optionstart")) {
2034 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2038 if (goi
->argc
== 0) {
2039 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2040 "-optionstart ?address? ...");
2044 e
= Jim_GetOpt_Wide(goi
, &w
);
2048 stm8
->optionstart
= w
;
2049 LOG_DEBUG("optionstart=%8.8x", stm8
->optionstart
);
2052 if (!strcmp(arg
, "-optionend")) {
2053 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2057 if (goi
->argc
== 0) {
2058 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2059 "-optionend ?address? ...");
2063 e
= Jim_GetOpt_Wide(goi
, &w
);
2067 stm8
->optionend
= w
;
2068 LOG_DEBUG("optionend=%8.8x", stm8
->optionend
);
2071 if (!strcmp(arg
, "-enable_step_irq")) {
2072 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2076 stm8
->enable_step_irq
= true;
2077 LOG_DEBUG("enable_step_irq=%8.8x", stm8
->enable_step_irq
);
2080 if (!strcmp(arg
, "-enable_stm8l")) {
2081 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2085 stm8
->enable_stm8l
= true;
2086 LOG_DEBUG("enable_stm8l=%8.8x", stm8
->enable_stm8l
);
2087 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2090 return JIM_CONTINUE
;
2093 COMMAND_HANDLER(stm8_handle_enable_step_irq_command
)
2096 struct target
*target
= get_current_target(CMD_CTX
);
2097 struct stm8_common
*stm8
= target_to_stm8(target
);
2098 bool enable
= stm8
->enable_step_irq
;
2101 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2102 stm8
->enable_step_irq
= enable
;
2104 msg
= stm8
->enable_step_irq
? "enabled" : "disabled";
2105 command_print(CMD
, "enable_step_irq = %s", msg
);
2109 COMMAND_HANDLER(stm8_handle_enable_stm8l_command
)
2112 struct target
*target
= get_current_target(CMD_CTX
);
2113 struct stm8_common
*stm8
= target_to_stm8(target
);
2114 bool enable
= stm8
->enable_stm8l
;
2117 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2118 stm8
->enable_stm8l
= enable
;
2120 msg
= stm8
->enable_stm8l
? "enabled" : "disabled";
2121 command_print(CMD
, "enable_stm8l = %s", msg
);
2122 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2126 static const struct command_registration stm8_exec_command_handlers
[] = {
2128 .name
= "enable_step_irq",
2129 .handler
= stm8_handle_enable_step_irq_command
,
2130 .mode
= COMMAND_ANY
,
2131 .help
= "Enable/disable irq handling during step",
2135 .name
= "enable_stm8l",
2136 .handler
= stm8_handle_enable_stm8l_command
,
2137 .mode
= COMMAND_ANY
,
2138 .help
= "Enable/disable STM8L flash programming",
2141 COMMAND_REGISTRATION_DONE
2144 const struct command_registration stm8_command_handlers
[] = {
2147 .mode
= COMMAND_ANY
,
2148 .help
= "stm8 command group",
2150 .chain
= stm8_exec_command_handlers
,
2152 COMMAND_REGISTRATION_DONE
2155 struct target_type stm8_target
= {
2159 .arch_state
= stm8_arch_state
,
2162 .resume
= stm8_resume
,
2165 .assert_reset
= stm8_reset_assert
,
2166 .deassert_reset
= stm8_reset_deassert
,
2168 .get_gdb_arch
= stm8_get_gdb_arch
,
2169 .get_gdb_reg_list
= stm8_get_gdb_reg_list
,
2171 .read_memory
= stm8_read_memory
,
2172 .write_memory
= stm8_write_memory
,
2173 .checksum_memory
= stm8_checksum_memory
,
2174 .blank_check_memory
= stm8_blank_check_memory
,
2176 .run_algorithm
= stm8_run_algorithm
,
2178 .add_breakpoint
= stm8_add_breakpoint
,
2179 .remove_breakpoint
= stm8_remove_breakpoint
,
2180 .add_watchpoint
= stm8_add_watchpoint
,
2181 .remove_watchpoint
= stm8_remove_watchpoint
,
2183 .commands
= stm8_command_handlers
,
2184 .target_create
= stm8_target_create
,
2185 .init_target
= stm8_init
,
2186 .examine
= stm8_examine
,
2188 .deinit_target
= stm8_deinit
,
2189 .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)