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/hla/hla_transport.h"
31 #include "jtag/hla/hla_interface.h"
32 #include "jtag/hla/hla_layout.h"
34 #include "breakpoints.h"
35 #include "algorithm.h"
38 static struct reg_cache *stm8_build_reg_cache(struct target *target);
39 static int stm8_read_core_reg(struct target *target, unsigned int num);
40 static int stm8_write_core_reg(struct target *target, unsigned int num);
41 static int stm8_save_context(struct target *target);
42 static void stm8_enable_breakpoints(struct target *target);
43 static int stm8_unset_breakpoint(struct target *target,
44 struct breakpoint *breakpoint);
45 static int stm8_set_breakpoint(struct target *target,
46 struct breakpoint *breakpoint);
47 static void stm8_enable_watchpoints(struct target *target);
48 static int stm8_unset_watchpoint(struct target *target,
49 struct watchpoint *watchpoint);
60 { 0, "pc", 32, REG_TYPE_UINT32, "general", "org.gnu.gdb.stm8.core", 0 },
61 { 1, "a", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
62 { 2, "x", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
63 { 3, "y", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
64 { 4, "sp", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
65 { 5, "cc", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
68 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
79 #define DM_REGS 0x7f00
80 #define DM_REG_A 0x7f00
81 #define DM_REG_PC 0x7f01
82 #define DM_REG_X 0x7f04
83 #define DM_REG_Y 0x7f06
84 #define DM_REG_SP 0x7f08
85 #define DM_REG_CC 0x7f0a
87 #define DM_BKR1E 0x7f90
88 #define DM_BKR2E 0x7f93
91 #define DM_CSR1 0x7f98
92 #define DM_CSR2 0x7f99
106 #define FLASH_CR1_STM8S 0x505A
107 #define FLASH_CR2_STM8S 0x505B
108 #define FLASH_NCR2_STM8S 0x505C
109 #define FLASH_IAPSR_STM8S 0x505F
110 #define FLASH_PUKR_STM8S 0x5062
111 #define FLASH_DUKR_STM8S 0x5064
113 #define FLASH_CR1_STM8L 0x5050
114 #define FLASH_CR2_STM8L 0x5051
115 #define FLASH_NCR2_STM8L 0
116 #define FLASH_PUKR_STM8L 0x5052
117 #define FLASH_DUKR_STM8L 0x5053
118 #define FLASH_IAPSR_STM8L 0x5054
125 #define WR_PG_DIS 0x01
135 #define SAFE_MASK 0x80
136 #define NO_ACCESS 0x40
140 #define SWIM_RST 0x04
144 #define SWIM_CSR 0x7f80
146 #define STM8_BREAK 0x8B
155 struct stm8_algorithm {
159 struct stm8_core_reg {
161 struct target *target;
162 struct stm8_common *stm8_common;
166 /* break on execute */
172 /* break on read, write and execute */
176 struct stm8_comparator {
179 uint32_t reg_address;
180 enum hw_break_type type;
183 static inline struct hl_interface_s *target_to_adapter(struct target *target)
185 return target->tap->priv;
188 static int stm8_adapter_read_memory(struct target *target,
189 uint32_t addr, int size, int count, void *buf)
192 struct hl_interface_s *adapter = target_to_adapter(target);
194 ret = adapter->layout->api->read_mem(adapter->handle,
195 addr, size, count, buf);
201 static int stm8_adapter_write_memory(struct target *target,
202 uint32_t addr, int size, int count, const void *buf)
205 struct hl_interface_s *adapter = target_to_adapter(target);
207 ret = adapter->layout->api->write_mem(adapter->handle,
208 addr, size, count, buf);
214 static int stm8_write_u8(struct target *target,
215 uint32_t addr, uint8_t val)
219 struct hl_interface_s *adapter = target_to_adapter(target);
222 ret = adapter->layout->api->write_mem(adapter->handle, addr, 1, 1, buf);
228 static int stm8_read_u8(struct target *target,
229 uint32_t addr, uint8_t *val)
232 struct hl_interface_s *adapter = target_to_adapter(target);
234 ret = adapter->layout->api->read_mem(adapter->handle, addr, 1, 1, val);
240 static int stm8_set_speed(struct target *target, int speed)
242 struct hl_interface_s *adapter = target_to_adapter(target);
243 adapter->layout->api->speed(adapter->handle, speed, 0);
248 <enable == 0> Disables interrupts.
249 If interrupts are enabled they are masked and the cc register
252 <enable == 1> Enables interrupts.
253 Enable interrupts is actually restoring I1 I0 state from previous
254 call with enable == 0. Note that if stepping and breaking on a sim
255 instruction will NOT work since the interrupt flags are restored on
256 debug_entry. We don't have any way for the debugger to exclusively
257 disable the interrupts
259 static int stm8_enable_interrupts(struct target *target, int enable)
261 struct stm8_common *stm8 = target_to_stm8(target);
266 return ERROR_OK; /* cc was not stashed */
267 /* fetch current cc */
268 stm8_read_u8(target, DM_REG_CC, &cc);
270 cc &= ~(CC_I0 + CC_I1);
271 /* restore I1 & I0 from stash*/
272 cc |= (stm8->cc & (CC_I0+CC_I1));
273 /* update current cc */
274 stm8_write_u8(target, DM_REG_CC, cc);
275 stm8->cc_valid = false;
277 stm8_read_u8(target, DM_REG_CC, &cc);
278 if ((cc & CC_I0) && (cc & CC_I1))
279 return ERROR_OK; /* interrupts already masked */
282 stm8->cc_valid = true;
283 /* mask interrupts (disable) */
284 cc |= (CC_I0 + CC_I1);
285 stm8_write_u8(target, DM_REG_CC, cc);
291 static int stm8_set_hwbreak(struct target *target,
292 struct stm8_comparator comparator_list[])
297 /* Refer to Table 4 in UM0470 */
305 if (!comparator_list[0].used) {
306 comparator_list[0].type = HWBRK_EXEC;
307 comparator_list[0].bp_value = -1;
310 if (!comparator_list[1].used) {
311 comparator_list[1].type = HWBRK_EXEC;
312 comparator_list[1].bp_value = -1;
315 if ((comparator_list[0].type == HWBRK_EXEC)
316 && (comparator_list[1].type == HWBRK_EXEC)) {
317 comparator_list[0].reg_address = 0;
318 comparator_list[1].reg_address = 1;
321 if ((comparator_list[0].type == HWBRK_EXEC)
322 && (comparator_list[1].type != HWBRK_EXEC)) {
323 comparator_list[0].reg_address = 0;
324 comparator_list[1].reg_address = 1;
325 switch (comparator_list[1].type) {
339 if ((comparator_list[1].type == HWBRK_EXEC)
340 && (comparator_list[0].type != HWBRK_EXEC)) {
341 comparator_list[0].reg_address = 1;
342 comparator_list[1].reg_address = 0;
343 switch (comparator_list[0].type) {
357 if ((comparator_list[0].type != HWBRK_EXEC)
358 && (comparator_list[1].type != HWBRK_EXEC)) {
359 if ((comparator_list[0].type != comparator_list[1].type)) {
360 LOG_ERROR("data hw breakpoints must be of same type");
361 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
365 for (i = 0; i < 2; i++) {
366 data = comparator_list[i].bp_value;
367 addr = comparator_list[i].reg_address;
374 ret = stm8_adapter_write_memory(target, DM_BKR1E, 1, 3, buf);
375 LOG_DEBUG("DM_BKR1E=%" PRIx32, data);
376 } else if (addr == 1) {
377 ret = stm8_adapter_write_memory(target, DM_BKR2E, 1, 3, buf);
378 LOG_DEBUG("DM_BKR2E=%" PRIx32, data);
380 LOG_DEBUG("addr=%" PRIu32, addr);
387 ret = stm8_write_u8(target, DM_CR1,
388 (bc << 3) + (bir << 2) + (biw << 1));
389 LOG_DEBUG("DM_CR1=%" PRIx8, buf[0]);
397 /* read DM control and status regs */
398 static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,
404 ret = stm8_adapter_read_memory(target, DM_CSR1, 1, sizeof(buf), buf);
414 /* set or clear the single step flag in DM */
415 static int stm8_config_step(struct target *target, int enable)
420 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
428 ret = stm8_write_u8(target, DM_CSR1, csr1);
434 /* set the stall flag in DM */
435 static int stm8_debug_stall(struct target *target)
440 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
444 ret = stm8_write_u8(target, DM_CSR2, csr2);
450 static int stm8_configure_break_unit(struct target *target)
452 /* get pointers to arch-specific information */
453 struct stm8_common *stm8 = target_to_stm8(target);
455 if (stm8->bp_scanned)
458 stm8->num_hw_bpoints = 2;
459 stm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;
461 stm8->hw_break_list = calloc(stm8->num_hw_bpoints,
462 sizeof(struct stm8_comparator));
464 stm8->hw_break_list[0].reg_address = 0;
465 stm8->hw_break_list[1].reg_address = 1;
467 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8->num_hw_bpoints,
468 stm8->num_hw_bpoints);
470 stm8->bp_scanned = true;
475 static int stm8_examine_debug_reason(struct target *target)
480 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
481 if (retval == ERROR_OK)
482 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
484 if ((target->debug_reason != DBG_REASON_DBGRQ)
485 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
487 if (retval != ERROR_OK)
491 /* halted on reset */
492 target->debug_reason = DBG_REASON_UNDEFINED;
494 if (csr1 & (BK1F+BK2F))
495 /* we have halted on a breakpoint (or wp)*/
496 target->debug_reason = DBG_REASON_BREAKPOINT;
499 /* we have halted on a breakpoint */
500 target->debug_reason = DBG_REASON_BREAKPOINT;
507 static int stm8_debug_entry(struct target *target)
509 struct stm8_common *stm8 = target_to_stm8(target);
511 /* restore interrupts */
512 stm8_enable_interrupts(target, 1);
514 stm8_save_context(target);
516 /* make sure stepping disabled STE bit in CSR1 cleared */
517 stm8_config_step(target, 0);
519 /* attempt to find halt reason */
520 stm8_examine_debug_reason(target);
522 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
523 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32),
524 target_state_name(target));
529 /* clear stall flag in DM and flush instruction pipe */
530 static int stm8_exit_debug(struct target *target)
535 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
539 ret = stm8_write_u8(target, DM_CSR2, csr2);
545 ret = stm8_write_u8(target, DM_CSR2, csr2);
551 static int stm8_read_regs(struct target *target, uint32_t regs[])
556 ret = stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);
560 regs[0] = be_to_h_u24(buf+DM_REG_PC-DM_REGS);
561 regs[1] = buf[DM_REG_A-DM_REGS];
562 regs[2] = be_to_h_u16(buf+DM_REG_X-DM_REGS);
563 regs[3] = be_to_h_u16(buf+DM_REG_Y-DM_REGS);
564 regs[4] = be_to_h_u16(buf+DM_REG_SP-DM_REGS);
565 regs[5] = buf[DM_REG_CC-DM_REGS];
570 static int stm8_write_regs(struct target *target, uint32_t regs[])
575 h_u24_to_be(buf+DM_REG_PC-DM_REGS, regs[0]);
576 buf[DM_REG_A-DM_REGS] = regs[1];
577 h_u16_to_be(buf+DM_REG_X-DM_REGS, regs[2]);
578 h_u16_to_be(buf+DM_REG_Y-DM_REGS, regs[3]);
579 h_u16_to_be(buf+DM_REG_SP-DM_REGS, regs[4]);
580 buf[DM_REG_CC-DM_REGS] = regs[5];
582 ret = stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);
589 static int stm8_get_core_reg(struct reg *reg)
592 struct stm8_core_reg *stm8_reg = reg->arch_info;
593 struct target *target = stm8_reg->target;
594 struct stm8_common *stm8_target = target_to_stm8(target);
596 if (target->state != TARGET_HALTED)
597 return ERROR_TARGET_NOT_HALTED;
599 retval = stm8_target->read_core_reg(target, stm8_reg->num);
604 static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
606 struct stm8_core_reg *stm8_reg = reg->arch_info;
607 struct target *target = stm8_reg->target;
608 uint32_t value = buf_get_u32(buf, 0, reg->size);
610 if (target->state != TARGET_HALTED)
611 return ERROR_TARGET_NOT_HALTED;
613 buf_set_u32(reg->value, 0, 32, value);
620 static int stm8_save_context(struct target *target)
624 /* get pointers to arch-specific information */
625 struct stm8_common *stm8 = target_to_stm8(target);
627 /* read core registers */
628 stm8_read_regs(target, stm8->core_regs);
630 for (i = 0; i < STM8_NUM_REGS; i++) {
631 if (!stm8->core_cache->reg_list[i].valid)
632 stm8->read_core_reg(target, i);
638 static int stm8_restore_context(struct target *target)
642 /* get pointers to arch-specific information */
643 struct stm8_common *stm8 = target_to_stm8(target);
645 for (i = 0; i < STM8_NUM_REGS; i++) {
646 if (stm8->core_cache->reg_list[i].dirty)
647 stm8->write_core_reg(target, i);
650 /* write core regs */
651 stm8_write_regs(target, stm8->core_regs);
656 static int stm8_unlock_flash(struct target *target)
660 struct stm8_common *stm8 = target_to_stm8(target);
662 /* check if flash is unlocked */
663 stm8_read_u8(target, stm8->flash_iapsr, data);
664 if (~data[0] & PUL) {
666 stm8_write_u8(target, stm8->flash_pukr, 0x56);
667 stm8_write_u8(target, stm8->flash_pukr, 0xae);
670 stm8_read_u8(target, stm8->flash_iapsr, data);
676 static int stm8_unlock_eeprom(struct target *target)
680 struct stm8_common *stm8 = target_to_stm8(target);
682 /* check if eeprom is unlocked */
683 stm8_read_u8(target, stm8->flash_iapsr, data);
684 if (~data[0] & DUL) {
686 stm8_write_u8(target, stm8->flash_dukr, 0xae);
687 stm8_write_u8(target, stm8->flash_dukr, 0x56);
690 stm8_read_u8(target, stm8->flash_iapsr, data);
696 static int stm8_write_flash(struct target *target, enum mem_type type,
698 uint32_t size, uint32_t count, uint32_t blocksize_param,
699 const uint8_t *buffer)
701 struct stm8_common *stm8 = target_to_stm8(target);
706 uint32_t blocksize = 0;
712 stm8_unlock_flash(target);
715 stm8_unlock_eeprom(target);
718 stm8_unlock_eeprom(target);
722 LOG_ERROR("BUG: wrong mem_type %d", type);
727 /* we don't support short writes */
732 bytecnt = count * size;
735 if ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {
737 stm8_write_u8(target, stm8->flash_cr2, PRG + opt);
738 if (stm8->flash_ncr2)
739 stm8_write_u8(target, stm8->flash_ncr2, ~(PRG + opt));
740 blocksize = blocksize_param;
742 if ((bytecnt >= 4) && ((address & 0x3) == 0)) {
744 stm8_write_u8(target, stm8->flash_cr2, WPRG + opt);
745 if (stm8->flash_ncr2)
746 stm8_write_u8(target, stm8->flash_ncr2, ~(WPRG + opt));
749 if (blocksize != 1) {
751 stm8_write_u8(target, stm8->flash_cr2, opt);
752 if (stm8->flash_ncr2)
753 stm8_write_u8(target, stm8->flash_ncr2, ~opt);
757 res = stm8_adapter_write_memory(target, address, 1, blocksize, buffer);
760 address += blocksize;
762 bytecnt -= blocksize;
764 /* lets hang here until end of program (EOP) */
765 for (i = 0; i < 16; i++) {
766 stm8_read_u8(target, stm8->flash_iapsr, &iapsr);
776 /* disable write access */
777 res = stm8_write_u8(target, stm8->flash_iapsr, 0x0);
785 static int stm8_write_memory(struct target *target, target_addr_t address,
786 uint32_t size, uint32_t count,
787 const uint8_t *buffer)
789 struct stm8_common *stm8 = target_to_stm8(target);
791 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
792 ", size: 0x%8.8" PRIx32
793 ", count: 0x%8.8" PRIx32,
794 address, size, count);
796 if (target->state != TARGET_HALTED)
797 LOG_WARNING("target not halted");
801 if ((address >= stm8->flashstart) && (address <= stm8->flashend))
802 retval = stm8_write_flash(target, FLASH, address, size, count,
803 stm8->blocksize, buffer);
804 else if ((address >= stm8->eepromstart) && (address <= stm8->eepromend))
805 retval = stm8_write_flash(target, EEPROM, address, size, count,
806 stm8->blocksize, buffer);
807 else if ((address >= stm8->optionstart) && (address <= stm8->optionend))
808 retval = stm8_write_flash(target, OPTION, address, size, count, 0, buffer);
810 retval = stm8_adapter_write_memory(target, address, size, count,
813 if (retval != ERROR_OK)
814 return ERROR_TARGET_FAILURE;
819 static int stm8_read_memory(struct target *target, target_addr_t address,
820 uint32_t size, uint32_t count, uint8_t *buffer)
822 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
823 ", size: 0x%8.8" PRIx32
824 ", count: 0x%8.8" PRIx32,
825 address, size, count);
827 if (target->state != TARGET_HALTED)
828 LOG_WARNING("target not halted");
831 retval = stm8_adapter_read_memory(target, address, size, count, buffer);
833 if (retval != ERROR_OK)
834 return ERROR_TARGET_FAILURE;
839 static int stm8_init(struct command_context *cmd_ctx, struct target *target)
841 stm8_build_reg_cache(target);
846 static int stm8_poll(struct target *target)
848 int retval = ERROR_OK;
852 LOG_DEBUG("target->state=%d", target->state);
855 /* read dm_csrx control regs */
856 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
857 if (retval != ERROR_OK) {
858 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval);
860 We return ERROR_OK here even if we didn't get an answer.
861 openocd will call target_wait_state until we get target state TARGET_HALTED
866 /* check for processor halted */
868 if (target->state != TARGET_HALTED) {
869 if (target->state == TARGET_UNKNOWN)
870 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
872 retval = stm8_debug_entry(target);
873 if (retval != ERROR_OK) {
874 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval);
875 return ERROR_TARGET_FAILURE;
878 if (target->state == TARGET_DEBUG_RUNNING) {
879 target->state = TARGET_HALTED;
880 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
882 target->state = TARGET_HALTED;
883 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
887 target->state = TARGET_RUNNING;
889 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
894 static int stm8_halt(struct target *target)
896 LOG_DEBUG("target->state: %s", target_state_name(target));
898 if (target->state == TARGET_HALTED) {
899 LOG_DEBUG("target was already halted");
903 if (target->state == TARGET_UNKNOWN)
904 LOG_WARNING("target was in unknown state when halt was requested");
906 if (target->state == TARGET_RESET) {
907 /* we came here in a reset_halt or reset_init sequence
908 * debug entry was already prepared in stm8_assert_reset()
910 target->debug_reason = DBG_REASON_DBGRQ;
916 /* break processor */
917 stm8_debug_stall(target);
919 target->debug_reason = DBG_REASON_DBGRQ;
924 static int stm8_reset_assert(struct target *target)
927 struct hl_interface_s *adapter = target_to_adapter(target);
928 struct stm8_common *stm8 = target_to_stm8(target);
929 bool use_srst_fallback = true;
931 enum reset_types jtag_reset_config = jtag_get_reset_config();
933 if (jtag_reset_config & RESET_HAS_SRST) {
934 res = adapter_assert_reset();
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 enum reset_types jtag_reset_config = jtag_get_reset_config();
970 if (jtag_reset_config & RESET_HAS_SRST) {
971 res = adapter_deassert_reset();
972 if ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND))
976 /* The cpu should now be stalled. If halt was requested
977 let poll detect the stall */
978 if (target->reset_halt)
981 /* Instead of going thrugh saving context, polling and
982 then resuming target again just clear stall and proceed. */
983 target->state = TARGET_RUNNING;
984 return stm8_exit_debug(target);
987 /* stm8_single_step_core() is only used for stepping over breakpoints
988 from stm8_resume() */
989 static int stm8_single_step_core(struct target *target)
991 struct stm8_common *stm8 = target_to_stm8(target);
993 /* configure single step mode */
994 stm8_config_step(target, 1);
996 /* disable interrupts while stepping */
997 if (!stm8->enable_step_irq)
998 stm8_enable_interrupts(target, 0);
1000 /* exit debug mode */
1001 stm8_exit_debug(target);
1003 stm8_debug_entry(target);
1008 static int stm8_resume(struct target *target, int current,
1009 target_addr_t address, int handle_breakpoints,
1010 int debug_execution)
1012 struct stm8_common *stm8 = target_to_stm8(target);
1013 struct breakpoint *breakpoint = NULL;
1016 LOG_DEBUG("%d " TARGET_ADDR_FMT " %d %d", current, address,
1017 handle_breakpoints, debug_execution);
1019 if (target->state != TARGET_HALTED) {
1020 LOG_WARNING("target not halted");
1021 return ERROR_TARGET_NOT_HALTED;
1024 if (!debug_execution) {
1025 target_free_all_working_areas(target);
1026 stm8_enable_breakpoints(target);
1027 stm8_enable_watchpoints(target);
1028 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1029 stm8_set_hwbreak(target, comparator_list);
1032 /* current = 1: continue on current pc,
1033 otherwise continue at <address> */
1035 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value,
1037 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1038 stm8->core_cache->reg_list[STM8_PC].valid = true;
1042 resume_pc = address;
1044 resume_pc = buf_get_u32(
1045 stm8->core_cache->reg_list[STM8_PC].value,
1048 stm8_restore_context(target);
1050 /* the front-end may request us not to handle breakpoints */
1051 if (handle_breakpoints) {
1052 /* Single step past breakpoint at current address */
1053 breakpoint = breakpoint_find(target, resume_pc);
1055 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT,
1056 breakpoint->address);
1057 stm8_unset_breakpoint(target, breakpoint);
1058 stm8_single_step_core(target);
1059 stm8_set_breakpoint(target, breakpoint);
1063 /* disable interrupts if we are debugging */
1064 if (debug_execution)
1065 stm8_enable_interrupts(target, 0);
1067 /* exit debug mode */
1068 stm8_exit_debug(target);
1069 target->debug_reason = DBG_REASON_NOTHALTED;
1071 /* registers are now invalid */
1072 register_cache_invalidate(stm8->core_cache);
1074 if (!debug_execution) {
1075 target->state = TARGET_RUNNING;
1076 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1077 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
1079 target->state = TARGET_DEBUG_RUNNING;
1080 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1081 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
1087 static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
1089 stm8->enable_stm8l = enable_stm8l;
1091 if (stm8->enable_stm8l) {
1092 stm8->flash_cr2 = FLASH_CR2_STM8L;
1093 stm8->flash_ncr2 = FLASH_NCR2_STM8L;
1094 stm8->flash_iapsr = FLASH_IAPSR_STM8L;
1095 stm8->flash_dukr = FLASH_DUKR_STM8L;
1096 stm8->flash_pukr = FLASH_PUKR_STM8L;
1098 stm8->flash_cr2 = FLASH_CR2_STM8S;
1099 stm8->flash_ncr2 = FLASH_NCR2_STM8S;
1100 stm8->flash_iapsr = FLASH_IAPSR_STM8S;
1101 stm8->flash_dukr = FLASH_DUKR_STM8S;
1102 stm8->flash_pukr = FLASH_PUKR_STM8S;
1107 static int stm8_init_arch_info(struct target *target,
1108 struct stm8_common *stm8, struct jtag_tap *tap)
1110 target->endianness = TARGET_BIG_ENDIAN;
1111 target->arch_info = stm8;
1112 stm8->common_magic = STM8_COMMON_MAGIC;
1113 stm8->fast_data_area = NULL;
1114 stm8->blocksize = 0x80;
1115 stm8->flashstart = 0x8000;
1116 stm8->flashend = 0xffff;
1117 stm8->eepromstart = 0x4000;
1118 stm8->eepromend = 0x43ff;
1119 stm8->optionstart = 0x4800;
1120 stm8->optionend = 0x487F;
1122 /* has breakpoint/watchpoint unit been scanned */
1123 stm8->bp_scanned = false;
1124 stm8->hw_break_list = NULL;
1126 stm8->read_core_reg = stm8_read_core_reg;
1127 stm8->write_core_reg = stm8_write_core_reg;
1129 stm8_init_flash_regs(0, stm8);
1134 static int stm8_target_create(struct target *target,
1138 struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));
1140 stm8_init_arch_info(target, stm8, target->tap);
1141 stm8_configure_break_unit(target);
1146 static int stm8_read_core_reg(struct target *target, unsigned int num)
1150 /* get pointers to arch-specific information */
1151 struct stm8_common *stm8 = target_to_stm8(target);
1153 if (num >= STM8_NUM_REGS)
1154 return ERROR_COMMAND_SYNTAX_ERROR;
1156 reg_value = stm8->core_regs[num];
1157 LOG_DEBUG("read core reg %i value 0x%" PRIx32 "", num , reg_value);
1158 buf_set_u32(stm8->core_cache->reg_list[num].value, 0, 32, reg_value);
1159 stm8->core_cache->reg_list[num].valid = true;
1160 stm8->core_cache->reg_list[num].dirty = false;
1165 static int stm8_write_core_reg(struct target *target, unsigned int num)
1169 /* get pointers to arch-specific information */
1170 struct stm8_common *stm8 = target_to_stm8(target);
1172 if (num >= STM8_NUM_REGS)
1173 return ERROR_COMMAND_SYNTAX_ERROR;
1175 reg_value = buf_get_u32(stm8->core_cache->reg_list[num].value, 0, 32);
1176 stm8->core_regs[num] = reg_value;
1177 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
1178 stm8->core_cache->reg_list[num].valid = true;
1179 stm8->core_cache->reg_list[num].dirty = false;
1184 static const char *stm8_get_gdb_arch(struct target *target)
1189 static int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
1190 int *reg_list_size, enum target_register_class reg_class)
1192 /* get pointers to arch-specific information */
1193 struct stm8_common *stm8 = target_to_stm8(target);
1196 *reg_list_size = STM8_NUM_REGS;
1197 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1199 for (i = 0; i < STM8_NUM_REGS; i++)
1200 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1205 static const struct reg_arch_type stm8_reg_type = {
1206 .get = stm8_get_core_reg,
1207 .set = stm8_set_core_reg,
1210 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1212 /* get pointers to arch-specific information */
1213 struct stm8_common *stm8 = target_to_stm8(target);
1215 int num_regs = STM8_NUM_REGS;
1216 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1217 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1218 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1219 struct stm8_core_reg *arch_info = malloc(
1220 sizeof(struct stm8_core_reg) * num_regs);
1221 struct reg_feature *feature;
1224 /* Build the process context cache */
1225 cache->name = "stm8 registers";
1227 cache->reg_list = reg_list;
1228 cache->num_regs = num_regs;
1230 stm8->core_cache = cache;
1232 for (i = 0; i < num_regs; i++) {
1233 arch_info[i].num = stm8_regs[i].id;
1234 arch_info[i].target = target;
1235 arch_info[i].stm8_common = stm8;
1237 reg_list[i].name = stm8_regs[i].name;
1238 reg_list[i].size = stm8_regs[i].bits;
1240 reg_list[i].value = calloc(1, 4);
1241 reg_list[i].valid = false;
1242 reg_list[i].type = &stm8_reg_type;
1243 reg_list[i].arch_info = &arch_info[i];
1245 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1246 if (reg_list[i].reg_data_type)
1247 reg_list[i].reg_data_type->type = stm8_regs[i].type;
1249 LOG_ERROR("unable to allocate reg type list");
1253 reg_list[i].dirty = false;
1254 reg_list[i].group = stm8_regs[i].group;
1255 reg_list[i].number = stm8_regs[i].id;
1256 reg_list[i].exist = true;
1257 reg_list[i].caller_save = true; /* gdb defaults to true */
1259 feature = calloc(1, sizeof(struct reg_feature));
1261 feature->name = stm8_regs[i].feature;
1262 reg_list[i].feature = feature;
1264 LOG_ERROR("unable to allocate feature list");
1270 static void stm8_free_reg_cache(struct target *target)
1272 struct stm8_common *stm8 = target_to_stm8(target);
1273 struct reg_cache *cache;
1277 cache = stm8->core_cache;
1282 for (i = 0; i < cache->num_regs; i++) {
1283 reg = &cache->reg_list[i];
1286 free(reg->reg_data_type);
1290 free(cache->reg_list[0].arch_info);
1291 free(cache->reg_list);
1294 stm8->core_cache = NULL;
1297 static void stm8_deinit(struct target *target)
1299 struct stm8_common *stm8 = target_to_stm8(target);
1301 free(stm8->hw_break_list);
1303 stm8_free_reg_cache(target);
1308 static int stm8_arch_state(struct target *target)
1310 struct stm8_common *stm8 = target_to_stm8(target);
1312 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
1313 debug_reason_name(target),
1314 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1319 static int stm8_step(struct target *target, int current,
1320 target_addr_t address, int handle_breakpoints)
1322 LOG_DEBUG("%" PRIx32 " " TARGET_ADDR_FMT " %" PRIx32,
1323 current, address, handle_breakpoints);
1325 /* get pointers to arch-specific information */
1326 struct stm8_common *stm8 = target_to_stm8(target);
1327 struct breakpoint *breakpoint = NULL;
1329 if (target->state != TARGET_HALTED) {
1330 LOG_WARNING("target not halted");
1331 return ERROR_TARGET_NOT_HALTED;
1334 /* current = 1: continue on current pc, otherwise continue at <address> */
1336 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);
1337 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1338 stm8->core_cache->reg_list[STM8_PC].valid = true;
1341 /* the front-end may request us not to handle breakpoints */
1342 if (handle_breakpoints) {
1343 breakpoint = breakpoint_find(target,
1344 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1346 stm8_unset_breakpoint(target, breakpoint);
1349 /* restore context */
1350 stm8_restore_context(target);
1352 /* configure single step mode */
1353 stm8_config_step(target, 1);
1355 target->debug_reason = DBG_REASON_SINGLESTEP;
1357 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1359 /* disable interrupts while stepping */
1360 if (!stm8->enable_step_irq)
1361 stm8_enable_interrupts(target, 0);
1363 /* exit debug mode */
1364 stm8_exit_debug(target);
1366 /* registers are now invalid */
1367 register_cache_invalidate(stm8->core_cache);
1369 LOG_DEBUG("target stepped ");
1370 stm8_debug_entry(target);
1373 stm8_set_breakpoint(target, breakpoint);
1375 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1380 static void stm8_enable_breakpoints(struct target *target)
1382 struct breakpoint *breakpoint = target->breakpoints;
1384 /* set any pending breakpoints */
1385 while (breakpoint) {
1386 if (breakpoint->set == 0)
1387 stm8_set_breakpoint(target, breakpoint);
1388 breakpoint = breakpoint->next;
1392 static int stm8_set_breakpoint(struct target *target,
1393 struct breakpoint *breakpoint)
1395 struct stm8_common *stm8 = target_to_stm8(target);
1396 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1399 if (breakpoint->set) {
1400 LOG_WARNING("breakpoint already set");
1404 if (breakpoint->type == BKPT_HARD) {
1407 while (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))
1409 if (bp_num >= stm8->num_hw_bpoints) {
1410 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32 ")",
1411 breakpoint->unique_id);
1412 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1414 breakpoint->set = bp_num + 1;
1415 comparator_list[bp_num].used = true;
1416 comparator_list[bp_num].bp_value = breakpoint->address;
1417 comparator_list[bp_num].type = HWBRK_EXEC;
1419 retval = stm8_set_hwbreak(target, comparator_list);
1420 if (retval != ERROR_OK)
1423 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
1424 breakpoint->unique_id,
1425 bp_num, comparator_list[bp_num].bp_value);
1426 } else if (breakpoint->type == BKPT_SOFT) {
1427 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1428 if (breakpoint->length == 1) {
1429 uint8_t verify = 0x55;
1431 retval = target_read_u8(target, breakpoint->address,
1432 breakpoint->orig_instr);
1433 if (retval != ERROR_OK)
1435 retval = target_write_u8(target, breakpoint->address, STM8_BREAK);
1436 if (retval != ERROR_OK)
1439 retval = target_read_u8(target, breakpoint->address, &verify);
1440 if (retval != ERROR_OK)
1442 if (verify != STM8_BREAK) {
1443 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1444 " - check that memory is read/writable",
1445 breakpoint->address);
1446 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1449 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1451 breakpoint->set = 1; /* Any nice value but 0 */
1457 static int stm8_add_breakpoint(struct target *target,
1458 struct breakpoint *breakpoint)
1460 struct stm8_common *stm8 = target_to_stm8(target);
1463 if (breakpoint->type == BKPT_HARD) {
1464 if (stm8->num_hw_bpoints_avail < 1) {
1465 LOG_INFO("no hardware breakpoint available");
1466 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1469 ret = stm8_set_breakpoint(target, breakpoint);
1470 if (ret != ERROR_OK)
1473 stm8->num_hw_bpoints_avail--;
1477 ret = stm8_set_breakpoint(target, breakpoint);
1478 if (ret != ERROR_OK)
1484 static int stm8_unset_breakpoint(struct target *target,
1485 struct breakpoint *breakpoint)
1487 /* get pointers to arch-specific information */
1488 struct stm8_common *stm8 = target_to_stm8(target);
1489 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1492 if (!breakpoint->set) {
1493 LOG_WARNING("breakpoint not set");
1497 if (breakpoint->type == BKPT_HARD) {
1498 int bp_num = breakpoint->set - 1;
1499 if ((bp_num < 0) || (bp_num >= stm8->num_hw_bpoints)) {
1500 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
1501 breakpoint->unique_id);
1504 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
1505 breakpoint->unique_id,
1507 comparator_list[bp_num].used = false;
1508 retval = stm8_set_hwbreak(target, comparator_list);
1509 if (retval != ERROR_OK)
1512 /* restore original instruction (kept in target endianness) */
1513 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1514 if (breakpoint->length == 1) {
1515 uint8_t current_instr;
1517 /* check that user program has not
1518 modified breakpoint instruction */
1519 retval = target_read_memory(target, breakpoint->address, 1, 1,
1520 (uint8_t *)¤t_instr);
1521 if (retval != ERROR_OK)
1524 if (current_instr == STM8_BREAK) {
1525 retval = target_write_memory(target, breakpoint->address, 1, 1,
1526 breakpoint->orig_instr);
1527 if (retval != ERROR_OK)
1533 breakpoint->set = 0;
1538 static int stm8_remove_breakpoint(struct target *target,
1539 struct breakpoint *breakpoint)
1541 /* get pointers to arch-specific information */
1542 struct stm8_common *stm8 = target_to_stm8(target);
1544 if (target->state != TARGET_HALTED) {
1545 LOG_WARNING("target not halted");
1546 return ERROR_TARGET_NOT_HALTED;
1549 if (breakpoint->set)
1550 stm8_unset_breakpoint(target, breakpoint);
1552 if (breakpoint->type == BKPT_HARD)
1553 stm8->num_hw_bpoints_avail++;
1558 static int stm8_set_watchpoint(struct target *target,
1559 struct watchpoint *watchpoint)
1561 struct stm8_common *stm8 = target_to_stm8(target);
1562 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1566 if (watchpoint->set) {
1567 LOG_WARNING("watchpoint already set");
1571 while (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))
1573 if (wp_num >= stm8->num_hw_bpoints) {
1574 LOG_ERROR("Can not find free hw breakpoint");
1575 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1578 if (watchpoint->length != 1) {
1579 LOG_ERROR("Only watchpoints of length 1 are supported");
1580 return ERROR_TARGET_UNALIGNED_ACCESS;
1583 enum hw_break_type enable = 0;
1585 switch (watchpoint->rw) {
1596 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1599 comparator_list[wp_num].used = true;
1600 comparator_list[wp_num].bp_value = watchpoint->address;
1601 comparator_list[wp_num].type = enable;
1603 ret = stm8_set_hwbreak(target, comparator_list);
1604 if (ret != ERROR_OK) {
1605 comparator_list[wp_num].used = false;
1609 watchpoint->set = wp_num + 1;
1611 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1613 comparator_list[wp_num].bp_value);
1618 static int stm8_add_watchpoint(struct target *target,
1619 struct watchpoint *watchpoint)
1622 struct stm8_common *stm8 = target_to_stm8(target);
1624 if (stm8->num_hw_bpoints_avail < 1) {
1625 LOG_INFO("no hardware watchpoints available");
1626 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1629 ret = stm8_set_watchpoint(target, watchpoint);
1630 if (ret != ERROR_OK)
1633 stm8->num_hw_bpoints_avail--;
1637 static void stm8_enable_watchpoints(struct target *target)
1639 struct watchpoint *watchpoint = target->watchpoints;
1641 /* set any pending watchpoints */
1642 while (watchpoint) {
1643 if (watchpoint->set == 0)
1644 stm8_set_watchpoint(target, watchpoint);
1645 watchpoint = watchpoint->next;
1649 static int stm8_unset_watchpoint(struct target *target,
1650 struct watchpoint *watchpoint)
1652 /* get pointers to arch-specific information */
1653 struct stm8_common *stm8 = target_to_stm8(target);
1654 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1656 if (!watchpoint->set) {
1657 LOG_WARNING("watchpoint not set");
1661 int wp_num = watchpoint->set - 1;
1662 if ((wp_num < 0) || (wp_num >= stm8->num_hw_bpoints)) {
1663 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1666 comparator_list[wp_num].used = false;
1667 watchpoint->set = 0;
1669 stm8_set_hwbreak(target, comparator_list);
1674 static int stm8_remove_watchpoint(struct target *target,
1675 struct watchpoint *watchpoint)
1677 /* get pointers to arch-specific information */
1678 struct stm8_common *stm8 = target_to_stm8(target);
1680 if (target->state != TARGET_HALTED) {
1681 LOG_WARNING("target not halted");
1682 return ERROR_TARGET_NOT_HALTED;
1685 if (watchpoint->set)
1686 stm8_unset_watchpoint(target, watchpoint);
1688 stm8->num_hw_bpoints_avail++;
1693 static int stm8_examine(struct target *target)
1697 /* get pointers to arch-specific information */
1698 struct stm8_common *stm8 = target_to_stm8(target);
1699 struct hl_interface_s *adapter = target_to_adapter(target);
1701 if (!target_was_examined(target)) {
1702 if (!stm8->swim_configured) {
1703 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1704 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1705 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM);
1706 if (retval != ERROR_OK)
1708 /* set high speed */
1709 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1710 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS);
1711 if (retval != ERROR_OK)
1713 retval = stm8_set_speed(target, 1);
1714 if (retval == ERROR_OK)
1715 stm8->swim_configured = true;
1717 Now is the time to deassert reset if connect_under_reset.
1718 Releasing reset line will cause the option bytes to load.
1719 The core will still be stalled.
1721 if (adapter->param.connect_under_reset)
1722 stm8_reset_deassert(target);
1724 LOG_INFO("trying to reconnect");
1726 retval = adapter->layout->api->state(adapter->handle);
1727 if (retval != ERROR_OK) {
1728 LOG_ERROR("reconnect failed");
1732 /* read dm_csrx control regs */
1733 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
1734 if (retval != ERROR_OK) {
1735 LOG_ERROR("state query failed");
1740 target_set_examined(target);
1748 /** Checks whether a memory region is erased. */
1749 static int stm8_blank_check_memory(struct target *target,
1750 struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
1752 struct working_area *erase_check_algorithm;
1753 struct reg_param reg_params[2];
1754 struct mem_param mem_params[2];
1755 struct stm8_algorithm stm8_info;
1757 static const uint8_t stm8_erase_check_code[] = {
1758 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1761 if (erased_value != 0xff) {
1762 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for STM8",
1767 /* make sure we have a working area */
1768 if (target_alloc_working_area(target, sizeof(stm8_erase_check_code),
1769 &erase_check_algorithm) != ERROR_OK)
1770 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1772 target_write_buffer(target, erase_check_algorithm->address,
1773 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1775 stm8_info.common_magic = STM8_COMMON_MAGIC;
1777 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1778 buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
1780 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1781 buf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);
1783 init_reg_param(®_params[0], "a", 32, PARAM_IN_OUT);
1784 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1786 init_reg_param(®_params[1], "sp", 32, PARAM_OUT);
1787 buf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);
1789 int retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,
1790 erase_check_algorithm->address + 6,
1791 erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
1794 if (retval == ERROR_OK)
1795 blocks[0].result = (*(reg_params[0].value) == 0xff);
1797 destroy_mem_param(&mem_params[0]);
1798 destroy_mem_param(&mem_params[1]);
1799 destroy_reg_param(®_params[0]);
1800 destroy_reg_param(®_params[1]);
1802 target_free_working_area(target, erase_check_algorithm);
1804 if (retval != ERROR_OK)
1807 return 1; /* only one block has been checked */
1810 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1811 uint32_t count, uint32_t *checksum)
1813 /* let image_calculate_checksum() take care of business */
1814 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1817 /* run to exit point. return error if exit point was not reached. */
1818 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1819 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1823 /* This code relies on the target specific resume() and
1824 poll()->debug_entry() sequence to write register values to the
1825 processor and the read them back */
1826 retval = target_resume(target, 0, entry_point, 0, 1);
1827 if (retval != ERROR_OK)
1830 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1831 /* If the target fails to halt due to the breakpoint, force a halt */
1832 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1833 retval = target_halt(target);
1834 if (retval != ERROR_OK)
1836 retval = target_wait_state(target, TARGET_HALTED, 500);
1837 if (retval != ERROR_OK)
1839 return ERROR_TARGET_TIMEOUT;
1842 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1843 if (exit_point && (pc != exit_point)) {
1844 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1845 return ERROR_TARGET_TIMEOUT;
1851 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1852 struct mem_param *mem_params, int num_reg_params,
1853 struct reg_param *reg_params, target_addr_t entry_point,
1854 target_addr_t exit_point, int timeout_ms, void *arch_info)
1856 struct stm8_common *stm8 = target_to_stm8(target);
1858 uint32_t context[STM8_NUM_REGS];
1859 int retval = ERROR_OK;
1861 LOG_DEBUG("Running algorithm");
1863 /* NOTE: stm8_run_algorithm requires that each
1864 algorithm uses a software breakpoint
1865 at the exit point */
1867 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1868 LOG_ERROR("current target isn't a STM8 target");
1869 return ERROR_TARGET_INVALID;
1872 if (target->state != TARGET_HALTED) {
1873 LOG_WARNING("target not halted");
1874 return ERROR_TARGET_NOT_HALTED;
1877 /* refresh core register cache */
1878 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1879 if (!stm8->core_cache->reg_list[i].valid)
1880 stm8->read_core_reg(target, i);
1881 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1884 for (int i = 0; i < num_mem_params; i++) {
1885 if (mem_params[i].direction == PARAM_IN)
1887 retval = target_write_buffer(target, mem_params[i].address,
1888 mem_params[i].size, mem_params[i].value);
1889 if (retval != ERROR_OK)
1893 for (int i = 0; i < num_reg_params; i++) {
1894 if (reg_params[i].direction == PARAM_IN)
1897 struct reg *reg = register_get_by_name(stm8->core_cache,
1898 reg_params[i].reg_name, 0);
1901 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1902 return ERROR_COMMAND_SYNTAX_ERROR;
1905 if (reg_params[i].size != 32) {
1906 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1907 reg_params[i].reg_name);
1908 return ERROR_COMMAND_SYNTAX_ERROR;
1911 stm8_set_core_reg(reg, reg_params[i].value);
1914 retval = stm8_run_and_wait(target, entry_point,
1915 timeout_ms, exit_point, stm8);
1917 if (retval != ERROR_OK)
1920 for (int i = 0; i < num_mem_params; i++) {
1921 if (mem_params[i].direction != PARAM_OUT) {
1922 retval = target_read_buffer(target, mem_params[i].address,
1923 mem_params[i].size, mem_params[i].value);
1924 if (retval != ERROR_OK)
1929 for (int i = 0; i < num_reg_params; i++) {
1930 if (reg_params[i].direction != PARAM_OUT) {
1931 struct reg *reg = register_get_by_name(stm8->core_cache,
1932 reg_params[i].reg_name, 0);
1934 LOG_ERROR("BUG: register '%s' not found",
1935 reg_params[i].reg_name);
1936 return ERROR_COMMAND_SYNTAX_ERROR;
1939 if (reg_params[i].size != 32) {
1940 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1941 reg_params[i].reg_name);
1942 return ERROR_COMMAND_SYNTAX_ERROR;
1945 buf_set_u32(reg_params[i].value,
1946 0, 32, buf_get_u32(reg->value, 0, 32));
1950 /* restore everything we saved before */
1951 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1953 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1954 if (regvalue != context[i]) {
1955 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1956 stm8->core_cache->reg_list[i].name, context[i]);
1957 buf_set_u32(stm8->core_cache->reg_list[i].value,
1959 stm8->core_cache->reg_list[i].valid = true;
1960 stm8->core_cache->reg_list[i].dirty = true;
1967 int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi)
1969 struct stm8_common *stm8 = target_to_stm8(target);
1974 arg = Jim_GetString(goi->argv[0], NULL);
1975 if (!strcmp(arg, "-blocksize")) {
1976 e = Jim_GetOpt_String(goi, &arg, NULL);
1980 if (goi->argc == 0) {
1981 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1982 "-blocksize ?bytes? ...");
1986 e = Jim_GetOpt_Wide(goi, &w);
1990 stm8->blocksize = w;
1991 LOG_DEBUG("blocksize=%8.8x", stm8->blocksize);
1994 if (!strcmp(arg, "-flashstart")) {
1995 e = Jim_GetOpt_String(goi, &arg, NULL);
1999 if (goi->argc == 0) {
2000 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2001 "-flashstart ?address? ...");
2005 e = Jim_GetOpt_Wide(goi, &w);
2009 stm8->flashstart = w;
2010 LOG_DEBUG("flashstart=%8.8x", stm8->flashstart);
2013 if (!strcmp(arg, "-flashend")) {
2014 e = Jim_GetOpt_String(goi, &arg, NULL);
2018 if (goi->argc == 0) {
2019 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2020 "-flashend ?address? ...");
2024 e = Jim_GetOpt_Wide(goi, &w);
2029 LOG_DEBUG("flashend=%8.8x", stm8->flashend);
2032 if (!strcmp(arg, "-eepromstart")) {
2033 e = Jim_GetOpt_String(goi, &arg, NULL);
2037 if (goi->argc == 0) {
2038 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2039 "-eepromstart ?address? ...");
2043 e = Jim_GetOpt_Wide(goi, &w);
2047 stm8->eepromstart = w;
2048 LOG_DEBUG("eepromstart=%8.8x", stm8->eepromstart);
2051 if (!strcmp(arg, "-eepromend")) {
2052 e = Jim_GetOpt_String(goi, &arg, NULL);
2056 if (goi->argc == 0) {
2057 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2058 "-eepromend ?address? ...");
2062 e = Jim_GetOpt_Wide(goi, &w);
2066 stm8->eepromend = w;
2067 LOG_DEBUG("eepromend=%8.8x", stm8->eepromend);
2070 if (!strcmp(arg, "-optionstart")) {
2071 e = Jim_GetOpt_String(goi, &arg, NULL);
2075 if (goi->argc == 0) {
2076 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2077 "-optionstart ?address? ...");
2081 e = Jim_GetOpt_Wide(goi, &w);
2085 stm8->optionstart = w;
2086 LOG_DEBUG("optionstart=%8.8x", stm8->optionstart);
2089 if (!strcmp(arg, "-optionend")) {
2090 e = Jim_GetOpt_String(goi, &arg, NULL);
2094 if (goi->argc == 0) {
2095 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2096 "-optionend ?address? ...");
2100 e = Jim_GetOpt_Wide(goi, &w);
2104 stm8->optionend = w;
2105 LOG_DEBUG("optionend=%8.8x", stm8->optionend);
2108 if (!strcmp(arg, "-enable_step_irq")) {
2109 e = Jim_GetOpt_String(goi, &arg, NULL);
2113 stm8->enable_step_irq = true;
2114 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2117 if (!strcmp(arg, "-enable_stm8l")) {
2118 e = Jim_GetOpt_String(goi, &arg, NULL);
2122 stm8->enable_stm8l = true;
2123 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2124 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2127 return JIM_CONTINUE;
2130 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2133 struct target *target = get_current_target(CMD_CTX);
2134 struct stm8_common *stm8 = target_to_stm8(target);
2135 bool enable = stm8->enable_step_irq;
2138 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2139 stm8->enable_step_irq = enable;
2141 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2142 command_print(CMD, "enable_step_irq = %s", msg);
2146 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2149 struct target *target = get_current_target(CMD_CTX);
2150 struct stm8_common *stm8 = target_to_stm8(target);
2151 bool enable = stm8->enable_stm8l;
2154 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2155 stm8->enable_stm8l = enable;
2157 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2158 command_print(CMD, "enable_stm8l = %s", msg);
2159 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2163 static const struct command_registration stm8_exec_command_handlers[] = {
2165 .name = "enable_step_irq",
2166 .handler = stm8_handle_enable_step_irq_command,
2167 .mode = COMMAND_ANY,
2168 .help = "Enable/disable irq handling during step",
2172 .name = "enable_stm8l",
2173 .handler = stm8_handle_enable_stm8l_command,
2174 .mode = COMMAND_ANY,
2175 .help = "Enable/disable STM8L flash programming",
2178 COMMAND_REGISTRATION_DONE
2181 const struct command_registration stm8_command_handlers[] = {
2184 .mode = COMMAND_ANY,
2185 .help = "stm8 command group",
2187 .chain = stm8_exec_command_handlers,
2189 COMMAND_REGISTRATION_DONE
2192 struct target_type stm8_target = {
2196 .arch_state = stm8_arch_state,
2199 .resume = stm8_resume,
2202 .assert_reset = stm8_reset_assert,
2203 .deassert_reset = stm8_reset_deassert,
2205 .get_gdb_arch = stm8_get_gdb_arch,
2206 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2208 .read_memory = stm8_read_memory,
2209 .write_memory = stm8_write_memory,
2210 .checksum_memory = stm8_checksum_memory,
2211 .blank_check_memory = stm8_blank_check_memory,
2213 .run_algorithm = stm8_run_algorithm,
2215 .add_breakpoint = stm8_add_breakpoint,
2216 .remove_breakpoint = stm8_remove_breakpoint,
2217 .add_watchpoint = stm8_add_watchpoint,
2218 .remove_watchpoint = stm8_remove_watchpoint,
2220 .commands = stm8_command_handlers,
2221 .target_create = stm8_target_create,
2222 .init_target = stm8_init,
2223 .examine = stm8_examine,
2225 .deinit_target = stm8_deinit,
2226 .target_jim_configure = stm8_jim_configure,