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 3 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/jtag.h"
29 #include "jtag/hla/hla_transport.h"
30 #include "jtag/hla/hla_interface.h"
31 #include "jtag/hla/hla_layout.h"
33 #include "breakpoints.h"
34 #include "algorithm.h"
37 static struct reg_cache *stm8_build_reg_cache(struct target *target);
38 static int stm8_read_core_reg(struct target *target, unsigned int num);
39 static int stm8_write_core_reg(struct target *target, unsigned int num);
40 static int stm8_save_context(struct target *target);
41 static void stm8_enable_breakpoints(struct target *target);
42 static int stm8_unset_breakpoint(struct target *target,
43 struct breakpoint *breakpoint);
44 static int stm8_set_breakpoint(struct target *target,
45 struct breakpoint *breakpoint);
46 static void stm8_enable_watchpoints(struct target *target);
47 static int stm8_unset_watchpoint(struct target *target,
48 struct watchpoint *watchpoint);
59 { 0, "pc", 32, REG_TYPE_UINT32, "general", "org.gnu.gdb.stm8.core", 0 },
60 { 1, "a", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
61 { 2, "x", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
62 { 3, "y", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
63 { 4, "sp", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
64 { 5, "cc", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
67 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
78 #define DM_REGS 0x7f00
79 #define DM_REG_A 0x7f00
80 #define DM_REG_PC 0x7f01
81 #define DM_REG_X 0x7f04
82 #define DM_REG_Y 0x7f06
83 #define DM_REG_SP 0x7f08
84 #define DM_REG_CC 0x7f0a
86 #define DM_BKR1E 0x7f90
87 #define DM_BKR2E 0x7f93
90 #define DM_CSR1 0x7f98
91 #define DM_CSR2 0x7f99
105 #define FLASH_CR1_STM8S 0x505A
106 #define FLASH_CR2_STM8S 0x505B
107 #define FLASH_NCR2_STM8S 0x505C
108 #define FLASH_IAPSR_STM8S 0x505F
109 #define FLASH_PUKR_STM8S 0x5062
110 #define FLASH_DUKR_STM8S 0x5064
112 #define FLASH_CR1_STM8L 0x5050
113 #define FLASH_CR2_STM8L 0x5051
114 #define FLASH_NCR2_STM8L 0
115 #define FLASH_PUKR_STM8L 0x5052
116 #define FLASH_DUKR_STM8L 0x5053
117 #define FLASH_IAPSR_STM8L 0x5054
124 #define WR_PG_DIS 0x01
134 #define SAFE_MASK 0x80
135 #define NO_ACCESS 0x40
139 #define SWIM_RST 0x04
143 #define SWIM_CSR 0x7f80
145 #define STM8_BREAK 0x8B
154 struct stm8_algorithm {
158 struct stm8_core_reg {
160 struct target *target;
161 struct stm8_common *stm8_common;
165 /* break on execute */
171 /* break on read, write and execute */
175 struct stm8_comparator {
178 uint32_t reg_address;
179 enum hw_break_type type;
182 static inline struct hl_interface_s *target_to_adapter(struct target *target)
184 return target->tap->priv;
187 static int stm8_adapter_read_memory(struct target *target,
188 uint32_t addr, int size, int count, void *buf)
191 struct hl_interface_s *adapter = target_to_adapter(target);
193 ret = adapter->layout->api->read_mem(adapter->handle,
194 addr, size, count, buf);
200 static int stm8_adapter_write_memory(struct target *target,
201 uint32_t addr, int size, int count, const void *buf)
204 struct hl_interface_s *adapter = target_to_adapter(target);
206 ret = adapter->layout->api->write_mem(adapter->handle,
207 addr, size, count, buf);
213 static int stm8_write_u8(struct target *target,
214 uint32_t addr, uint8_t val)
218 struct hl_interface_s *adapter = target_to_adapter(target);
221 ret = adapter->layout->api->write_mem(adapter->handle, addr, 1, 1, buf);
227 static int stm8_read_u8(struct target *target,
228 uint32_t addr, uint8_t *val)
231 struct hl_interface_s *adapter = target_to_adapter(target);
233 ret = adapter->layout->api->read_mem(adapter->handle, addr, 1, 1, val);
239 static int stm8_set_speed(struct target *target, int speed)
241 struct hl_interface_s *adapter = target_to_adapter(target);
242 adapter->layout->api->speed(adapter->handle, speed, 0);
247 <enable == 0> Disables interrupts.
248 If interrupts are enabled they are masked and the cc register
251 <enable == 1> Enables interrupts.
252 Enable interrupts is actually restoring I1 I0 state from previous
253 call with enable == 0. Note that if stepping and breaking on a sim
254 instruction will NOT work since the interrupt flags are restored on
255 debug_entry. We don't have any way for the debugger to exclusively
256 disable the interrupts
258 static int stm8_enable_interrupts(struct target *target, int enable)
260 struct stm8_common *stm8 = target_to_stm8(target);
265 return ERROR_OK; /* cc was not stashed */
266 /* fetch current cc */
267 stm8_read_u8(target, DM_REG_CC, &cc);
269 cc &= ~(CC_I0 + CC_I1);
270 /* restore I1 & I0 from stash*/
271 cc |= (stm8->cc & (CC_I0+CC_I1));
272 /* update current cc */
273 stm8_write_u8(target, DM_REG_CC, cc);
274 stm8->cc_valid = false;
276 stm8_read_u8(target, DM_REG_CC, &cc);
277 if ((cc & CC_I0) && (cc & CC_I1))
278 return ERROR_OK; /* interrupts already masked */
281 stm8->cc_valid = true;
282 /* mask interrupts (disable) */
283 cc |= (CC_I0 + CC_I1);
284 stm8_write_u8(target, DM_REG_CC, cc);
290 static int stm8_set_hwbreak(struct target *target,
291 struct stm8_comparator comparator_list[])
296 /* Refer to Table 4 in UM0470 */
304 if (!comparator_list[0].used) {
305 comparator_list[0].type = HWBRK_EXEC;
306 comparator_list[0].bp_value = -1;
309 if (!comparator_list[1].used) {
310 comparator_list[1].type = HWBRK_EXEC;
311 comparator_list[1].bp_value = -1;
314 if ((comparator_list[0].type == HWBRK_EXEC)
315 && (comparator_list[1].type == HWBRK_EXEC)) {
316 comparator_list[0].reg_address = 0;
317 comparator_list[1].reg_address = 1;
320 if ((comparator_list[0].type == HWBRK_EXEC)
321 && (comparator_list[1].type != HWBRK_EXEC)) {
322 comparator_list[0].reg_address = 0;
323 comparator_list[1].reg_address = 1;
324 switch (comparator_list[1].type) {
338 if ((comparator_list[1].type == HWBRK_EXEC)
339 && (comparator_list[0].type != HWBRK_EXEC)) {
340 comparator_list[0].reg_address = 1;
341 comparator_list[1].reg_address = 0;
342 switch (comparator_list[0].type) {
356 if ((comparator_list[0].type != HWBRK_EXEC)
357 && (comparator_list[1].type != HWBRK_EXEC)) {
358 if ((comparator_list[0].type != comparator_list[1].type)) {
359 LOG_ERROR("data hw breakpoints must be of same type");
360 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
364 for (i = 0; i < 2; i++) {
365 data = comparator_list[i].bp_value;
366 addr = comparator_list[i].reg_address;
373 ret = stm8_adapter_write_memory(target, DM_BKR1E, 1, 3, buf);
374 LOG_DEBUG("DM_BKR1E=%" PRIx32, data);
375 } else if (addr == 1) {
376 ret = stm8_adapter_write_memory(target, DM_BKR2E, 1, 3, buf);
377 LOG_DEBUG("DM_BKR2E=%" PRIx32, data);
379 LOG_DEBUG("addr=%" PRIu32, addr);
386 ret = stm8_write_u8(target, DM_CR1,
387 (bc << 3) + (bir << 2) + (biw << 1));
388 LOG_DEBUG("DM_CR1=%" PRIx8, buf[0]);
396 /* read DM control and status regs */
397 static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,
403 ret = stm8_adapter_read_memory(target, DM_CSR1, 1, sizeof(buf), buf);
413 /* set or clear the single step flag in DM */
414 static int stm8_config_step(struct target *target, int enable)
419 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
427 ret = stm8_write_u8(target, DM_CSR1, csr1);
433 /* set the stall flag in DM */
434 static int stm8_debug_stall(struct target *target)
439 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
443 ret = stm8_write_u8(target, DM_CSR2, csr2);
449 static int stm8_configure_break_unit(struct target *target)
451 /* get pointers to arch-specific information */
452 struct stm8_common *stm8 = target_to_stm8(target);
454 if (stm8->bp_scanned)
457 stm8->num_hw_bpoints = 2;
458 stm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;
460 stm8->hw_break_list = calloc(stm8->num_hw_bpoints,
461 sizeof(struct stm8_comparator));
463 stm8->hw_break_list[0].reg_address = 0;
464 stm8->hw_break_list[1].reg_address = 1;
466 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8->num_hw_bpoints,
467 stm8->num_hw_bpoints);
469 stm8->bp_scanned = true;
474 static int stm8_examine_debug_reason(struct target *target)
479 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
480 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
482 if ((target->debug_reason != DBG_REASON_DBGRQ)
483 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
485 if (retval != ERROR_OK)
489 /* halted on reset */
490 target->debug_reason = DBG_REASON_UNDEFINED;
492 if (csr1 & (BK1F+BK2F))
493 /* we have halted on a breakpoint (or wp)*/
494 target->debug_reason = DBG_REASON_BREAKPOINT;
497 /* we have halted on a breakpoint */
498 target->debug_reason = DBG_REASON_BREAKPOINT;
505 static int stm8_debug_entry(struct target *target)
507 struct stm8_common *stm8 = target_to_stm8(target);
509 /* restore interrupts */
510 stm8_enable_interrupts(target, 1);
512 stm8_save_context(target);
514 /* make sure stepping disabled STE bit in CSR1 cleared */
515 stm8_config_step(target, 0);
517 /* attempt to find halt reason */
518 stm8_examine_debug_reason(target);
520 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
521 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32),
522 target_state_name(target));
527 /* clear stall flag in DM and flush instruction pipe */
528 static int stm8_exit_debug(struct target *target)
533 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
537 ret = stm8_write_u8(target, DM_CSR2, csr2);
543 ret = stm8_write_u8(target, DM_CSR2, csr2);
549 static int stm8_read_regs(struct target *target, uint32_t regs[])
554 ret = stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);
558 regs[0] = be_to_h_u24(buf+DM_REG_PC-DM_REGS);
559 regs[1] = buf[DM_REG_A-DM_REGS];
560 regs[2] = be_to_h_u16(buf+DM_REG_X-DM_REGS);
561 regs[3] = be_to_h_u16(buf+DM_REG_Y-DM_REGS);
562 regs[4] = be_to_h_u16(buf+DM_REG_SP-DM_REGS);
563 regs[5] = buf[DM_REG_CC-DM_REGS];
568 static int stm8_write_regs(struct target *target, uint32_t regs[])
573 h_u24_to_be(buf+DM_REG_PC-DM_REGS, regs[0]);
574 buf[DM_REG_A-DM_REGS] = regs[1];
575 h_u16_to_be(buf+DM_REG_X-DM_REGS, regs[2]);
576 h_u16_to_be(buf+DM_REG_Y-DM_REGS, regs[3]);
577 h_u16_to_be(buf+DM_REG_SP-DM_REGS, regs[4]);
578 buf[DM_REG_CC-DM_REGS] = regs[5];
580 ret = stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);
587 static int stm8_get_core_reg(struct reg *reg)
590 struct stm8_core_reg *stm8_reg = reg->arch_info;
591 struct target *target = stm8_reg->target;
592 struct stm8_common *stm8_target = target_to_stm8(target);
594 if (target->state != TARGET_HALTED)
595 return ERROR_TARGET_NOT_HALTED;
597 retval = stm8_target->read_core_reg(target, stm8_reg->num);
602 static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
604 struct stm8_core_reg *stm8_reg = reg->arch_info;
605 struct target *target = stm8_reg->target;
606 uint32_t value = buf_get_u32(buf, 0, reg->size);
608 if (target->state != TARGET_HALTED)
609 return ERROR_TARGET_NOT_HALTED;
611 buf_set_u32(reg->value, 0, 32, value);
618 static int stm8_save_context(struct target *target)
622 /* get pointers to arch-specific information */
623 struct stm8_common *stm8 = target_to_stm8(target);
625 /* read core registers */
626 stm8_read_regs(target, stm8->core_regs);
628 for (i = 0; i < STM8_NUM_REGS; i++) {
629 if (!stm8->core_cache->reg_list[i].valid)
630 stm8->read_core_reg(target, i);
636 static int stm8_restore_context(struct target *target)
640 /* get pointers to arch-specific information */
641 struct stm8_common *stm8 = target_to_stm8(target);
643 for (i = 0; i < STM8_NUM_REGS; i++) {
644 if (stm8->core_cache->reg_list[i].dirty)
645 stm8->write_core_reg(target, i);
648 /* write core regs */
649 stm8_write_regs(target, stm8->core_regs);
654 static int stm8_unlock_flash(struct target *target)
658 struct stm8_common *stm8 = target_to_stm8(target);
660 /* check if flash is unlocked */
661 stm8_read_u8(target, stm8->flash_iapsr, data);
662 if (~data[0] & PUL) {
664 stm8_write_u8(target, stm8->flash_pukr, 0x56);
665 stm8_write_u8(target, stm8->flash_pukr, 0xae);
668 stm8_read_u8(target, stm8->flash_iapsr, data);
674 static int stm8_unlock_eeprom(struct target *target)
678 struct stm8_common *stm8 = target_to_stm8(target);
680 /* check if eeprom is unlocked */
681 stm8_read_u8(target, stm8->flash_iapsr, data);
682 if (~data[0] & DUL) {
684 stm8_write_u8(target, stm8->flash_dukr, 0xae);
685 stm8_write_u8(target, stm8->flash_dukr, 0x56);
688 stm8_read_u8(target, stm8->flash_iapsr, data);
694 static int stm8_write_flash(struct target *target, enum mem_type type,
696 uint32_t size, uint32_t count, uint32_t blocksize_param,
697 const uint8_t *buffer)
699 struct stm8_common *stm8 = target_to_stm8(target);
704 uint32_t blocksize = 0;
710 stm8_unlock_flash(target);
713 stm8_unlock_eeprom(target);
716 stm8_unlock_eeprom(target);
720 LOG_ERROR("BUG: wrong mem_type %d", type);
725 /* we don't support short writes */
730 bytecnt = count * size;
733 if ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {
735 stm8_write_u8(target, stm8->flash_cr2, PRG + opt);
736 if (stm8->flash_ncr2)
737 stm8_write_u8(target, stm8->flash_ncr2, ~(PRG + opt));
738 blocksize = blocksize_param;
740 if ((bytecnt >= 4) && ((address & 0x3) == 0)) {
742 stm8_write_u8(target, stm8->flash_cr2, WPRG + opt);
743 if (stm8->flash_ncr2)
744 stm8_write_u8(target, stm8->flash_ncr2, ~(WPRG + opt));
747 if (blocksize != 1) {
749 stm8_write_u8(target, stm8->flash_cr2, opt);
750 if (stm8->flash_ncr2)
751 stm8_write_u8(target, stm8->flash_ncr2, ~opt);
755 res = stm8_adapter_write_memory(target, address, 1, blocksize, buffer);
758 address += blocksize;
760 bytecnt -= blocksize;
762 /* lets hang here until end of program (EOP) */
763 for (i = 0; i < 16; i++) {
764 stm8_read_u8(target, stm8->flash_iapsr, &iapsr);
774 /* disable write access */
775 res = stm8_write_u8(target, stm8->flash_iapsr, 0x0);
783 static int stm8_write_memory(struct target *target, target_addr_t address,
784 uint32_t size, uint32_t count,
785 const uint8_t *buffer)
787 struct stm8_common *stm8 = target_to_stm8(target);
789 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
790 ", size: 0x%8.8" PRIx32
791 ", count: 0x%8.8" PRIx32,
792 address, size, count);
794 if (target->state != TARGET_HALTED)
795 LOG_WARNING("target not halted");
799 if ((address >= stm8->flashstart) && (address <= stm8->flashend))
800 retval = stm8_write_flash(target, FLASH, address, size, count,
801 stm8->blocksize, buffer);
802 else if ((address >= stm8->eepromstart) && (address <= stm8->eepromend))
803 retval = stm8_write_flash(target, EEPROM, address, size, count,
804 stm8->blocksize, buffer);
805 else if ((address >= stm8->optionstart) && (address <= stm8->optionend))
806 retval = stm8_write_flash(target, OPTION, address, size, count, 0, buffer);
808 retval = stm8_adapter_write_memory(target, address, size, count,
811 if (retval != ERROR_OK)
812 return ERROR_TARGET_FAILURE;
817 static int stm8_read_memory(struct target *target, target_addr_t address,
818 uint32_t size, uint32_t count, uint8_t *buffer)
820 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
821 ", size: 0x%8.8" PRIx32
822 ", count: 0x%8.8" PRIx32,
823 address, size, count);
825 if (target->state != TARGET_HALTED)
826 LOG_WARNING("target not halted");
829 retval = stm8_adapter_read_memory(target, address, size, count, buffer);
831 if (retval != ERROR_OK)
832 return ERROR_TARGET_FAILURE;
837 static int stm8_init(struct command_context *cmd_ctx, struct target *target)
839 stm8_build_reg_cache(target);
844 static int stm8_poll(struct target *target)
846 int retval = ERROR_OK;
850 LOG_DEBUG("target->state=%d", target->state);
853 /* read dm_csrx control regs */
854 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
855 if (retval != ERROR_OK) {
856 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval);
858 We return ERROR_OK here even if we didn't get an answer.
859 openocd will call target_wait_state until we get target state TARGET_HALTED
864 /* check for processor halted */
866 if (target->state != TARGET_HALTED) {
867 if (target->state == TARGET_UNKNOWN)
868 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
870 retval = stm8_debug_entry(target);
871 if (retval != ERROR_OK) {
872 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval);
873 return ERROR_TARGET_FAILURE;
876 if (target->state == TARGET_DEBUG_RUNNING) {
877 target->state = TARGET_HALTED;
878 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
880 target->state = TARGET_HALTED;
881 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
885 target->state = TARGET_RUNNING;
887 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
892 static int stm8_halt(struct target *target)
894 LOG_DEBUG("target->state: %s", target_state_name(target));
896 if (target->state == TARGET_HALTED) {
897 LOG_DEBUG("target was already halted");
901 if (target->state == TARGET_UNKNOWN)
902 LOG_WARNING("target was in unknown state when halt was requested");
904 if (target->state == TARGET_RESET) {
905 /* we came here in a reset_halt or reset_init sequence
906 * debug entry was already prepared in stm8_assert_reset()
908 target->debug_reason = DBG_REASON_DBGRQ;
914 /* break processor */
915 stm8_debug_stall(target);
917 target->debug_reason = DBG_REASON_DBGRQ;
922 static int stm8_reset_assert(struct target *target)
925 struct hl_interface_s *adapter = target_to_adapter(target);
926 struct stm8_common *stm8 = target_to_stm8(target);
927 bool use_srst_fallback = true;
929 enum reset_types jtag_reset_config = jtag_get_reset_config();
931 if (jtag_reset_config & RESET_HAS_SRST) {
932 jtag_add_reset(0, 1);
933 res = adapter->layout->api->assert_srst(adapter->handle, 0);
936 /* hardware srst supported */
937 use_srst_fallback = false;
938 else if (res != ERROR_COMMAND_NOTFOUND)
939 /* some other failure */
943 if (use_srst_fallback) {
944 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
945 res = adapter->layout->api->reset(adapter->handle);
950 /* registers are now invalid */
951 register_cache_invalidate(stm8->core_cache);
953 target->state = TARGET_RESET;
954 target->debug_reason = DBG_REASON_NOTHALTED;
956 if (target->reset_halt) {
957 res = target_halt(target);
965 static int stm8_reset_deassert(struct target *target)
968 struct hl_interface_s *adapter = target_to_adapter(target);
970 enum reset_types jtag_reset_config = jtag_get_reset_config();
972 if (jtag_reset_config & RESET_HAS_SRST) {
973 res = adapter->layout->api->assert_srst(adapter->handle, 1);
974 if ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND))
978 /* virtual deassert reset, we need it for the internal
981 jtag_add_reset(0, 0);
983 /* The cpu should now be stalled. If halt was requested
984 let poll detect the stall */
985 if (target->reset_halt)
988 /* Instead of going thrugh saving context, polling and
989 then resuming target again just clear stall and proceed. */
990 target->state = TARGET_RUNNING;
991 return stm8_exit_debug(target);
994 /* stm8_single_step_core() is only used for stepping over breakpoints
995 from stm8_resume() */
996 static int stm8_single_step_core(struct target *target)
998 struct stm8_common *stm8 = target_to_stm8(target);
1000 /* configure single step mode */
1001 stm8_config_step(target, 1);
1003 /* disable interrupts while stepping */
1004 if (!stm8->enable_step_irq)
1005 stm8_enable_interrupts(target, 0);
1007 /* exit debug mode */
1008 stm8_exit_debug(target);
1010 stm8_debug_entry(target);
1015 static int stm8_resume(struct target *target, int current,
1016 target_addr_t address, int handle_breakpoints,
1017 int debug_execution)
1019 struct stm8_common *stm8 = target_to_stm8(target);
1020 struct breakpoint *breakpoint = NULL;
1023 LOG_DEBUG("%d " TARGET_ADDR_FMT " %d %d", current, address,
1024 handle_breakpoints, debug_execution);
1026 if (target->state != TARGET_HALTED) {
1027 LOG_WARNING("target not halted");
1028 return ERROR_TARGET_NOT_HALTED;
1031 if (!debug_execution) {
1032 target_free_all_working_areas(target);
1033 stm8_enable_breakpoints(target);
1034 stm8_enable_watchpoints(target);
1035 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1036 stm8_set_hwbreak(target, comparator_list);
1039 /* current = 1: continue on current pc,
1040 otherwise continue at <address> */
1042 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value,
1044 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1045 stm8->core_cache->reg_list[STM8_PC].valid = true;
1049 resume_pc = address;
1051 resume_pc = buf_get_u32(
1052 stm8->core_cache->reg_list[STM8_PC].value,
1055 stm8_restore_context(target);
1057 /* the front-end may request us not to handle breakpoints */
1058 if (handle_breakpoints) {
1059 /* Single step past breakpoint at current address */
1060 breakpoint = breakpoint_find(target, resume_pc);
1062 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT,
1063 breakpoint->address);
1064 stm8_unset_breakpoint(target, breakpoint);
1065 stm8_single_step_core(target);
1066 stm8_set_breakpoint(target, breakpoint);
1070 /* disable interrupts if we are debugging */
1071 if (debug_execution)
1072 stm8_enable_interrupts(target, 0);
1074 /* exit debug mode */
1075 stm8_exit_debug(target);
1076 target->debug_reason = DBG_REASON_NOTHALTED;
1078 /* registers are now invalid */
1079 register_cache_invalidate(stm8->core_cache);
1081 if (!debug_execution) {
1082 target->state = TARGET_RUNNING;
1083 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1084 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
1086 target->state = TARGET_DEBUG_RUNNING;
1087 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1088 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
1094 static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
1096 stm8->enable_stm8l = enable_stm8l;
1098 if (stm8->enable_stm8l) {
1099 stm8->flash_cr2 = FLASH_CR2_STM8L;
1100 stm8->flash_ncr2 = FLASH_NCR2_STM8L;
1101 stm8->flash_iapsr = FLASH_IAPSR_STM8L;
1102 stm8->flash_dukr = FLASH_DUKR_STM8L;
1103 stm8->flash_pukr = FLASH_PUKR_STM8L;
1105 stm8->flash_cr2 = FLASH_CR2_STM8S;
1106 stm8->flash_ncr2 = FLASH_NCR2_STM8S;
1107 stm8->flash_iapsr = FLASH_IAPSR_STM8S;
1108 stm8->flash_dukr = FLASH_DUKR_STM8S;
1109 stm8->flash_pukr = FLASH_PUKR_STM8S;
1114 static int stm8_init_arch_info(struct target *target,
1115 struct stm8_common *stm8, struct jtag_tap *tap)
1117 target->endianness = TARGET_BIG_ENDIAN;
1118 target->arch_info = stm8;
1119 stm8->common_magic = STM8_COMMON_MAGIC;
1120 stm8->fast_data_area = NULL;
1121 stm8->blocksize = 0x80;
1122 stm8->flashstart = 0x8000;
1123 stm8->flashend = 0xffff;
1124 stm8->eepromstart = 0x4000;
1125 stm8->eepromend = 0x43ff;
1126 stm8->optionstart = 0x4800;
1127 stm8->optionend = 0x487F;
1129 /* has breakpoint/watchpoint unit been scanned */
1130 stm8->bp_scanned = false;
1131 stm8->hw_break_list = NULL;
1133 stm8->read_core_reg = stm8_read_core_reg;
1134 stm8->write_core_reg = stm8_write_core_reg;
1136 stm8_init_flash_regs(0, stm8);
1141 static int stm8_target_create(struct target *target,
1145 struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));
1147 stm8_init_arch_info(target, stm8, target->tap);
1148 stm8_configure_break_unit(target);
1153 static int stm8_read_core_reg(struct target *target, unsigned int num)
1157 /* get pointers to arch-specific information */
1158 struct stm8_common *stm8 = target_to_stm8(target);
1160 if (num >= STM8_NUM_REGS)
1161 return ERROR_COMMAND_SYNTAX_ERROR;
1163 reg_value = stm8->core_regs[num];
1164 LOG_DEBUG("read core reg %i value 0x%" PRIx32 "", num , reg_value);
1165 buf_set_u32(stm8->core_cache->reg_list[num].value, 0, 32, reg_value);
1166 stm8->core_cache->reg_list[num].valid = true;
1167 stm8->core_cache->reg_list[num].dirty = false;
1172 static int stm8_write_core_reg(struct target *target, unsigned int num)
1176 /* get pointers to arch-specific information */
1177 struct stm8_common *stm8 = target_to_stm8(target);
1179 if (num >= STM8_NUM_REGS)
1180 return ERROR_COMMAND_SYNTAX_ERROR;
1182 reg_value = buf_get_u32(stm8->core_cache->reg_list[num].value, 0, 32);
1183 stm8->core_regs[num] = reg_value;
1184 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
1185 stm8->core_cache->reg_list[num].valid = true;
1186 stm8->core_cache->reg_list[num].dirty = false;
1191 static int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
1192 int *reg_list_size, enum target_register_class reg_class)
1194 /* get pointers to arch-specific information */
1195 struct stm8_common *stm8 = target_to_stm8(target);
1198 *reg_list_size = STM8_NUM_REGS;
1199 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1201 for (i = 0; i < STM8_NUM_REGS; i++)
1202 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1207 static const struct reg_arch_type stm8_reg_type = {
1208 .get = stm8_get_core_reg,
1209 .set = stm8_set_core_reg,
1212 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1214 /* get pointers to arch-specific information */
1215 struct stm8_common *stm8 = target_to_stm8(target);
1217 int num_regs = STM8_NUM_REGS;
1218 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1219 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1220 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1221 struct stm8_core_reg *arch_info = malloc(
1222 sizeof(struct stm8_core_reg) * num_regs);
1223 struct reg_feature *feature;
1226 /* Build the process context cache */
1227 cache->name = "stm8 registers";
1229 cache->reg_list = reg_list;
1230 cache->num_regs = num_regs;
1232 stm8->core_cache = cache;
1234 for (i = 0; i < num_regs; i++) {
1235 arch_info[i].num = stm8_regs[i].id;
1236 arch_info[i].target = target;
1237 arch_info[i].stm8_common = stm8;
1239 reg_list[i].name = stm8_regs[i].name;
1240 reg_list[i].size = stm8_regs[i].bits;
1242 reg_list[i].value = calloc(1, 4);
1243 reg_list[i].valid = false;
1244 reg_list[i].type = &stm8_reg_type;
1245 reg_list[i].arch_info = &arch_info[i];
1247 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1248 if (reg_list[i].reg_data_type)
1249 reg_list[i].reg_data_type->type = stm8_regs[i].type;
1251 LOG_ERROR("unable to allocate reg type list");
1255 reg_list[i].dirty = false;
1256 reg_list[i].group = stm8_regs[i].group;
1257 reg_list[i].number = stm8_regs[i].id;
1258 reg_list[i].exist = true;
1259 reg_list[i].caller_save = true; /* gdb defaults to true */
1261 feature = calloc(1, sizeof(struct reg_feature));
1263 feature->name = stm8_regs[i].feature;
1264 reg_list[i].feature = feature;
1266 LOG_ERROR("unable to allocate feature list");
1272 static void stm8_free_reg_cache(struct target *target)
1274 struct stm8_common *stm8 = target_to_stm8(target);
1275 struct reg_cache *cache;
1279 cache = stm8->core_cache;
1284 for (i = 0; i < cache->num_regs; i++) {
1285 reg = &cache->reg_list[i];
1288 free(reg->reg_data_type);
1292 free(cache->reg_list[0].arch_info);
1293 free(cache->reg_list);
1296 stm8->core_cache = NULL;
1299 static void stm8_deinit(struct target *target)
1301 struct stm8_common *stm8 = target_to_stm8(target);
1303 free(stm8->hw_break_list);
1305 stm8_free_reg_cache(target);
1310 static int stm8_arch_state(struct target *target)
1312 struct stm8_common *stm8 = target_to_stm8(target);
1314 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
1315 debug_reason_name(target),
1316 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1321 static int stm8_step(struct target *target, int current,
1322 target_addr_t address, int handle_breakpoints)
1324 LOG_DEBUG("%" PRIx32 " " TARGET_ADDR_FMT " %" PRIx32,
1325 current, address, handle_breakpoints);
1327 /* get pointers to arch-specific information */
1328 struct stm8_common *stm8 = target_to_stm8(target);
1329 struct breakpoint *breakpoint = NULL;
1331 if (target->state != TARGET_HALTED) {
1332 LOG_WARNING("target not halted");
1333 return ERROR_TARGET_NOT_HALTED;
1336 /* current = 1: continue on current pc, otherwise continue at <address> */
1338 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);
1339 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1340 stm8->core_cache->reg_list[STM8_PC].valid = true;
1343 /* the front-end may request us not to handle breakpoints */
1344 if (handle_breakpoints) {
1345 breakpoint = breakpoint_find(target,
1346 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1348 stm8_unset_breakpoint(target, breakpoint);
1351 /* restore context */
1352 stm8_restore_context(target);
1354 /* configure single step mode */
1355 stm8_config_step(target, 1);
1357 target->debug_reason = DBG_REASON_SINGLESTEP;
1359 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1361 /* disable interrupts while stepping */
1362 if (!stm8->enable_step_irq)
1363 stm8_enable_interrupts(target, 0);
1365 /* exit debug mode */
1366 stm8_exit_debug(target);
1368 /* registers are now invalid */
1369 register_cache_invalidate(stm8->core_cache);
1371 LOG_DEBUG("target stepped ");
1372 stm8_debug_entry(target);
1375 stm8_set_breakpoint(target, breakpoint);
1377 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1382 static void stm8_enable_breakpoints(struct target *target)
1384 struct breakpoint *breakpoint = target->breakpoints;
1386 /* set any pending breakpoints */
1387 while (breakpoint) {
1388 if (breakpoint->set == 0)
1389 stm8_set_breakpoint(target, breakpoint);
1390 breakpoint = breakpoint->next;
1394 static int stm8_set_breakpoint(struct target *target,
1395 struct breakpoint *breakpoint)
1397 struct stm8_common *stm8 = target_to_stm8(target);
1398 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1401 if (breakpoint->set) {
1402 LOG_WARNING("breakpoint already set");
1406 if (breakpoint->type == BKPT_HARD) {
1409 while (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))
1411 if (bp_num >= stm8->num_hw_bpoints) {
1412 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32 ")",
1413 breakpoint->unique_id);
1414 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1416 breakpoint->set = bp_num + 1;
1417 comparator_list[bp_num].used = true;
1418 comparator_list[bp_num].bp_value = breakpoint->address;
1419 comparator_list[bp_num].type = HWBRK_EXEC;
1421 retval = stm8_set_hwbreak(target, comparator_list);
1422 if (retval != ERROR_OK)
1425 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
1426 breakpoint->unique_id,
1427 bp_num, comparator_list[bp_num].bp_value);
1428 } else if (breakpoint->type == BKPT_SOFT) {
1429 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1430 if (breakpoint->length == 1) {
1431 uint8_t verify = 0x55;
1433 retval = target_read_u8(target, breakpoint->address,
1434 breakpoint->orig_instr);
1435 if (retval != ERROR_OK)
1437 retval = target_write_u8(target, breakpoint->address, STM8_BREAK);
1438 if (retval != ERROR_OK)
1441 retval = target_read_u8(target, breakpoint->address, &verify);
1442 if (retval != ERROR_OK)
1444 if (verify != STM8_BREAK) {
1445 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1446 " - check that memory is read/writable",
1447 breakpoint->address);
1448 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1451 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1453 breakpoint->set = 1; /* Any nice value but 0 */
1459 static int stm8_add_breakpoint(struct target *target,
1460 struct breakpoint *breakpoint)
1462 struct stm8_common *stm8 = target_to_stm8(target);
1465 if (breakpoint->type == BKPT_HARD) {
1466 if (stm8->num_hw_bpoints_avail < 1) {
1467 LOG_INFO("no hardware breakpoint available");
1468 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1471 ret = stm8_set_breakpoint(target, breakpoint);
1472 if (ret != ERROR_OK)
1475 stm8->num_hw_bpoints_avail--;
1479 ret = stm8_set_breakpoint(target, breakpoint);
1480 if (ret != ERROR_OK)
1486 static int stm8_unset_breakpoint(struct target *target,
1487 struct breakpoint *breakpoint)
1489 /* get pointers to arch-specific information */
1490 struct stm8_common *stm8 = target_to_stm8(target);
1491 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1494 if (!breakpoint->set) {
1495 LOG_WARNING("breakpoint not set");
1499 if (breakpoint->type == BKPT_HARD) {
1500 int bp_num = breakpoint->set - 1;
1501 if ((bp_num < 0) || (bp_num >= stm8->num_hw_bpoints)) {
1502 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
1503 breakpoint->unique_id);
1506 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
1507 breakpoint->unique_id,
1509 comparator_list[bp_num].used = false;
1510 retval = stm8_set_hwbreak(target, comparator_list);
1511 if (retval != ERROR_OK)
1514 /* restore original instruction (kept in target endianness) */
1515 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1516 if (breakpoint->length == 1) {
1517 uint8_t current_instr;
1519 /* check that user program has not
1520 modified breakpoint instruction */
1521 retval = target_read_memory(target, breakpoint->address, 1, 1,
1522 (uint8_t *)¤t_instr);
1523 if (retval != ERROR_OK)
1526 if (current_instr == STM8_BREAK) {
1527 retval = target_write_memory(target, breakpoint->address, 1, 1,
1528 breakpoint->orig_instr);
1529 if (retval != ERROR_OK)
1535 breakpoint->set = 0;
1540 static int stm8_remove_breakpoint(struct target *target,
1541 struct breakpoint *breakpoint)
1543 /* get pointers to arch-specific information */
1544 struct stm8_common *stm8 = target_to_stm8(target);
1546 if (target->state != TARGET_HALTED) {
1547 LOG_WARNING("target not halted");
1548 return ERROR_TARGET_NOT_HALTED;
1551 if (breakpoint->set)
1552 stm8_unset_breakpoint(target, breakpoint);
1554 if (breakpoint->type == BKPT_HARD)
1555 stm8->num_hw_bpoints_avail++;
1560 static int stm8_set_watchpoint(struct target *target,
1561 struct watchpoint *watchpoint)
1563 struct stm8_common *stm8 = target_to_stm8(target);
1564 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1568 if (watchpoint->set) {
1569 LOG_WARNING("watchpoint already set");
1573 while (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))
1575 if (wp_num >= stm8->num_hw_bpoints) {
1576 LOG_ERROR("Can not find free hw breakpoint");
1577 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1580 if (watchpoint->length != 1) {
1581 LOG_ERROR("Only watchpoints of length 1 are supported");
1582 return ERROR_TARGET_UNALIGNED_ACCESS;
1585 enum hw_break_type enable = 0;
1587 switch (watchpoint->rw) {
1598 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1601 comparator_list[wp_num].used = true;
1602 comparator_list[wp_num].bp_value = watchpoint->address;
1603 comparator_list[wp_num].type = enable;
1605 ret = stm8_set_hwbreak(target, comparator_list);
1606 if (ret != ERROR_OK) {
1607 comparator_list[wp_num].used = false;
1611 watchpoint->set = wp_num + 1;
1613 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1615 comparator_list[wp_num].bp_value);
1620 static int stm8_add_watchpoint(struct target *target,
1621 struct watchpoint *watchpoint)
1624 struct stm8_common *stm8 = target_to_stm8(target);
1626 if (stm8->num_hw_bpoints_avail < 1) {
1627 LOG_INFO("no hardware watchpoints available");
1628 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1631 ret = stm8_set_watchpoint(target, watchpoint);
1632 if (ret != ERROR_OK)
1635 stm8->num_hw_bpoints_avail--;
1639 static void stm8_enable_watchpoints(struct target *target)
1641 struct watchpoint *watchpoint = target->watchpoints;
1643 /* set any pending watchpoints */
1644 while (watchpoint) {
1645 if (watchpoint->set == 0)
1646 stm8_set_watchpoint(target, watchpoint);
1647 watchpoint = watchpoint->next;
1651 static int stm8_unset_watchpoint(struct target *target,
1652 struct watchpoint *watchpoint)
1654 /* get pointers to arch-specific information */
1655 struct stm8_common *stm8 = target_to_stm8(target);
1656 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1658 if (!watchpoint->set) {
1659 LOG_WARNING("watchpoint not set");
1663 int wp_num = watchpoint->set - 1;
1664 if ((wp_num < 0) || (wp_num >= stm8->num_hw_bpoints)) {
1665 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1668 comparator_list[wp_num].used = false;
1669 watchpoint->set = 0;
1671 stm8_set_hwbreak(target, comparator_list);
1676 static int stm8_remove_watchpoint(struct target *target,
1677 struct watchpoint *watchpoint)
1679 /* get pointers to arch-specific information */
1680 struct stm8_common *stm8 = target_to_stm8(target);
1682 if (target->state != TARGET_HALTED) {
1683 LOG_WARNING("target not halted");
1684 return ERROR_TARGET_NOT_HALTED;
1687 if (watchpoint->set)
1688 stm8_unset_watchpoint(target, watchpoint);
1690 stm8->num_hw_bpoints_avail++;
1695 static int stm8_examine(struct target *target)
1699 /* get pointers to arch-specific information */
1700 struct stm8_common *stm8 = target_to_stm8(target);
1701 struct hl_interface_s *adapter = target_to_adapter(target);
1703 if (!target_was_examined(target)) {
1704 if (!stm8->swim_configured) {
1705 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1706 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1707 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM);
1708 if (retval != ERROR_OK)
1710 /* set high speed */
1711 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1712 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS);
1713 if (retval != ERROR_OK)
1715 retval = stm8_set_speed(target, 1);
1716 if (retval == ERROR_OK)
1717 stm8->swim_configured = true;
1719 Now is the time to deassert reset if connect_under_reset.
1720 Releasing reset line will cause the option bytes to load.
1721 The core will still be stalled.
1723 if (adapter->param.connect_under_reset)
1724 stm8_reset_deassert(target);
1726 LOG_INFO("trying to reconnect");
1728 retval = adapter->layout->api->state(adapter->handle);
1729 if (retval != ERROR_OK) {
1730 LOG_ERROR("reconnect failed");
1734 /* read dm_csrx control regs */
1735 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
1736 if (retval != ERROR_OK) {
1737 LOG_ERROR("state query failed");
1742 target_set_examined(target);
1750 /** Checks whether a memory region is erased. */
1751 static int stm8_blank_check_memory(struct target *target,
1752 target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
1754 struct working_area *erase_check_algorithm;
1755 struct reg_param reg_params[2];
1756 struct mem_param mem_params[2];
1757 struct stm8_algorithm stm8_info;
1759 static const uint8_t stm8_erase_check_code[] = {
1760 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1763 if (erased_value != 0xff) {
1764 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for STM8",
1769 /* make sure we have a working area */
1770 if (target_alloc_working_area(target, sizeof(stm8_erase_check_code),
1771 &erase_check_algorithm) != ERROR_OK)
1772 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1774 target_write_buffer(target, erase_check_algorithm->address,
1775 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1777 stm8_info.common_magic = STM8_COMMON_MAGIC;
1779 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1780 buf_set_u32(mem_params[0].value, 0, 24, address);
1782 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1783 buf_set_u32(mem_params[1].value, 0, 24, count);
1785 init_reg_param(®_params[0], "a", 32, PARAM_IN_OUT);
1786 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1788 init_reg_param(®_params[1], "sp", 32, PARAM_OUT);
1789 buf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);
1791 int retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,
1792 erase_check_algorithm->address + 6,
1793 erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
1796 if (retval == ERROR_OK)
1797 *blank = (*(reg_params[0].value) == 0xff);
1799 destroy_mem_param(&mem_params[0]);
1800 destroy_mem_param(&mem_params[1]);
1801 destroy_reg_param(®_params[0]);
1803 target_free_working_area(target, erase_check_algorithm);
1808 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1809 uint32_t count, uint32_t *checksum)
1811 /* let image_calculate_checksum() take care of business */
1812 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1815 /* run to exit point. return error if exit point was not reached. */
1816 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1817 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1821 /* This code relies on the target specific resume() and
1822 poll()->debug_entry() sequence to write register values to the
1823 processor and the read them back */
1824 retval = target_resume(target, 0, entry_point, 0, 1);
1825 if (retval != ERROR_OK)
1828 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1829 /* If the target fails to halt due to the breakpoint, force a halt */
1830 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1831 retval = target_halt(target);
1832 if (retval != ERROR_OK)
1834 retval = target_wait_state(target, TARGET_HALTED, 500);
1835 if (retval != ERROR_OK)
1837 return ERROR_TARGET_TIMEOUT;
1840 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1841 if (exit_point && (pc != exit_point)) {
1842 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1843 return ERROR_TARGET_TIMEOUT;
1849 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1850 struct mem_param *mem_params, int num_reg_params,
1851 struct reg_param *reg_params, target_addr_t entry_point,
1852 target_addr_t exit_point, int timeout_ms, void *arch_info)
1854 struct stm8_common *stm8 = target_to_stm8(target);
1856 uint32_t context[STM8_NUM_REGS];
1857 int retval = ERROR_OK;
1859 LOG_DEBUG("Running algorithm");
1861 /* NOTE: stm8_run_algorithm requires that each
1862 algorithm uses a software breakpoint
1863 at the exit point */
1865 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1866 LOG_ERROR("current target isn't a STM8 target");
1867 return ERROR_TARGET_INVALID;
1870 if (target->state != TARGET_HALTED) {
1871 LOG_WARNING("target not halted");
1872 return ERROR_TARGET_NOT_HALTED;
1875 /* refresh core register cache */
1876 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1877 if (!stm8->core_cache->reg_list[i].valid)
1878 stm8->read_core_reg(target, i);
1879 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1882 for (int i = 0; i < num_mem_params; i++) {
1883 retval = target_write_buffer(target, mem_params[i].address,
1884 mem_params[i].size, mem_params[i].value);
1885 if (retval != ERROR_OK)
1889 for (int i = 0; i < num_reg_params; i++) {
1890 struct reg *reg = register_get_by_name(stm8->core_cache,
1891 reg_params[i].reg_name, 0);
1894 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1895 return ERROR_COMMAND_SYNTAX_ERROR;
1898 if (reg_params[i].size != 32) {
1899 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1900 reg_params[i].reg_name);
1901 return ERROR_COMMAND_SYNTAX_ERROR;
1904 stm8_set_core_reg(reg, reg_params[i].value);
1907 retval = stm8_run_and_wait(target, entry_point,
1908 timeout_ms, exit_point, stm8);
1910 if (retval != ERROR_OK)
1913 for (int i = 0; i < num_mem_params; i++) {
1914 if (mem_params[i].direction != PARAM_OUT) {
1915 retval = target_read_buffer(target, mem_params[i].address,
1916 mem_params[i].size, mem_params[i].value);
1917 if (retval != ERROR_OK)
1922 for (int i = 0; i < num_reg_params; i++) {
1923 if (reg_params[i].direction != PARAM_OUT) {
1924 struct reg *reg = register_get_by_name(stm8->core_cache,
1925 reg_params[i].reg_name, 0);
1927 LOG_ERROR("BUG: register '%s' not found",
1928 reg_params[i].reg_name);
1929 return ERROR_COMMAND_SYNTAX_ERROR;
1932 if (reg_params[i].size != 32) {
1933 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1934 reg_params[i].reg_name);
1935 return ERROR_COMMAND_SYNTAX_ERROR;
1938 buf_set_u32(reg_params[i].value,
1939 0, 32, buf_get_u32(reg->value, 0, 32));
1943 /* restore everything we saved before */
1944 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1946 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1947 if (regvalue != context[i]) {
1948 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1949 stm8->core_cache->reg_list[i].name, context[i]);
1950 buf_set_u32(stm8->core_cache->reg_list[i].value,
1952 stm8->core_cache->reg_list[i].valid = true;
1953 stm8->core_cache->reg_list[i].dirty = true;
1960 int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi)
1962 struct stm8_common *stm8 = target_to_stm8(target);
1967 arg = Jim_GetString(goi->argv[0], NULL);
1968 if (!strcmp(arg, "-blocksize")) {
1969 e = Jim_GetOpt_String(goi, &arg, NULL);
1973 if (goi->argc == 0) {
1974 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1975 "-blocksize ?bytes? ...");
1979 e = Jim_GetOpt_Wide(goi, &w);
1983 stm8->blocksize = w;
1984 LOG_DEBUG("blocksize=%8.8x", stm8->blocksize);
1987 if (!strcmp(arg, "-flashstart")) {
1988 e = Jim_GetOpt_String(goi, &arg, NULL);
1992 if (goi->argc == 0) {
1993 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1994 "-flashstart ?address? ...");
1998 e = Jim_GetOpt_Wide(goi, &w);
2002 stm8->flashstart = w;
2003 LOG_DEBUG("flashstart=%8.8x", stm8->flashstart);
2006 if (!strcmp(arg, "-flashend")) {
2007 e = Jim_GetOpt_String(goi, &arg, NULL);
2011 if (goi->argc == 0) {
2012 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2013 "-flashend ?address? ...");
2017 e = Jim_GetOpt_Wide(goi, &w);
2022 LOG_DEBUG("flashend=%8.8x", stm8->flashend);
2025 if (!strcmp(arg, "-eepromstart")) {
2026 e = Jim_GetOpt_String(goi, &arg, NULL);
2030 if (goi->argc == 0) {
2031 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2032 "-eepromstart ?address? ...");
2036 e = Jim_GetOpt_Wide(goi, &w);
2040 stm8->eepromstart = w;
2041 LOG_DEBUG("eepromstart=%8.8x", stm8->eepromstart);
2044 if (!strcmp(arg, "-eepromend")) {
2045 e = Jim_GetOpt_String(goi, &arg, NULL);
2049 if (goi->argc == 0) {
2050 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2051 "-eepromend ?address? ...");
2055 e = Jim_GetOpt_Wide(goi, &w);
2059 stm8->eepromend = w;
2060 LOG_DEBUG("eepromend=%8.8x", stm8->eepromend);
2063 if (!strcmp(arg, "-optionstart")) {
2064 e = Jim_GetOpt_String(goi, &arg, NULL);
2068 if (goi->argc == 0) {
2069 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2070 "-optionstart ?address? ...");
2074 e = Jim_GetOpt_Wide(goi, &w);
2078 stm8->optionstart = w;
2079 LOG_DEBUG("optionstart=%8.8x", stm8->optionstart);
2082 if (!strcmp(arg, "-optionend")) {
2083 e = Jim_GetOpt_String(goi, &arg, NULL);
2087 if (goi->argc == 0) {
2088 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2089 "-optionend ?address? ...");
2093 e = Jim_GetOpt_Wide(goi, &w);
2097 stm8->optionend = w;
2098 LOG_DEBUG("optionend=%8.8x", stm8->optionend);
2101 if (!strcmp(arg, "-enable_step_irq")) {
2102 e = Jim_GetOpt_String(goi, &arg, NULL);
2106 stm8->enable_step_irq = true;
2107 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2110 if (!strcmp(arg, "-enable_stm8l")) {
2111 e = Jim_GetOpt_String(goi, &arg, NULL);
2115 stm8->enable_stm8l = true;
2116 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2117 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2120 return JIM_CONTINUE;
2123 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2126 struct target *target = get_current_target(CMD_CTX);
2127 struct stm8_common *stm8 = target_to_stm8(target);
2128 bool enable = stm8->enable_step_irq;
2131 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2132 stm8->enable_step_irq = enable;
2134 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2135 command_print(CMD_CTX, "enable_step_irq = %s", msg);
2139 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2142 struct target *target = get_current_target(CMD_CTX);
2143 struct stm8_common *stm8 = target_to_stm8(target);
2144 bool enable = stm8->enable_stm8l;
2147 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2148 stm8->enable_stm8l = enable;
2150 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2151 command_print(CMD_CTX, "enable_stm8l = %s", msg);
2152 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2156 static const struct command_registration stm8_exec_command_handlers[] = {
2158 .name = "enable_step_irq",
2159 .handler = stm8_handle_enable_step_irq_command,
2160 .mode = COMMAND_ANY,
2161 .help = "Enable/disable irq handling during step",
2165 .name = "enable_stm8l",
2166 .handler = stm8_handle_enable_stm8l_command,
2167 .mode = COMMAND_ANY,
2168 .help = "Enable/disable STM8L flash programming",
2171 COMMAND_REGISTRATION_DONE
2174 const struct command_registration stm8_command_handlers[] = {
2177 .mode = COMMAND_ANY,
2178 .help = "stm8 command group",
2180 .chain = stm8_exec_command_handlers,
2182 COMMAND_REGISTRATION_DONE
2185 struct target_type stm8_target = {
2189 .arch_state = stm8_arch_state,
2192 .resume = stm8_resume,
2195 .assert_reset = stm8_reset_assert,
2196 .deassert_reset = stm8_reset_deassert,
2198 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2200 .read_memory = stm8_read_memory,
2201 .write_memory = stm8_write_memory,
2202 .checksum_memory = stm8_checksum_memory,
2203 .blank_check_memory = stm8_blank_check_memory,
2205 .run_algorithm = stm8_run_algorithm,
2207 .add_breakpoint = stm8_add_breakpoint,
2208 .remove_breakpoint = stm8_remove_breakpoint,
2209 .add_watchpoint = stm8_add_watchpoint,
2210 .remove_watchpoint = stm8_remove_watchpoint,
2212 .commands = stm8_command_handlers,
2213 .target_create = stm8_target_create,
2214 .init_target = stm8_init,
2215 .examine = stm8_examine,
2217 .deinit_target = stm8_deinit,
2218 .target_jim_configure = stm8_jim_configure,