2 * OpenOCD STM8 target driver
3 * Copyright (C) 2017 Ake Rehnman
4 * ake.rehnman(at)gmail.com
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <helper/log.h>
26 #include "target_type.h"
28 #include "jtag/interface.h"
29 #include "jtag/jtag.h"
30 #include "jtag/swim.h"
32 #include "breakpoints.h"
33 #include "algorithm.h"
36 static struct reg_cache *stm8_build_reg_cache(struct target *target);
37 static int stm8_read_core_reg(struct target *target, unsigned int num);
38 static int stm8_write_core_reg(struct target *target, unsigned int num);
39 static int stm8_save_context(struct target *target);
40 static void stm8_enable_breakpoints(struct target *target);
41 static int stm8_unset_breakpoint(struct target *target,
42 struct breakpoint *breakpoint);
43 static int stm8_set_breakpoint(struct target *target,
44 struct breakpoint *breakpoint);
45 static void stm8_enable_watchpoints(struct target *target);
46 static int stm8_unset_watchpoint(struct target *target,
47 struct watchpoint *watchpoint);
48 static int (*adapter_speed)(int speed);
49 extern struct adapter_driver *adapter_driver;
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;
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 int stm8_adapter_read_memory(struct target *target,
183 uint32_t addr, int size, int count, void *buf)
185 return swim_read_mem(addr, size, count, buf);
188 static int stm8_adapter_write_memory(struct target *target,
189 uint32_t addr, int size, int count, const void *buf)
191 return swim_write_mem(addr, size, count, buf);
194 static int stm8_write_u8(struct target *target,
195 uint32_t addr, uint8_t val)
200 return swim_write_mem(addr, 1, 1, buf);
203 static int stm8_read_u8(struct target *target,
204 uint32_t addr, uint8_t *val)
206 return swim_read_mem(addr, 1, 1, val);
210 <enable == 0> Disables interrupts.
211 If interrupts are enabled they are masked and the cc register
214 <enable == 1> Enables interrupts.
215 Enable interrupts is actually restoring I1 I0 state from previous
216 call with enable == 0. Note that if stepping and breaking on a sim
217 instruction will NOT work since the interrupt flags are restored on
218 debug_entry. We don't have any way for the debugger to exclusively
219 disable the interrupts
221 static int stm8_enable_interrupts(struct target *target, int enable)
223 struct stm8_common *stm8 = target_to_stm8(target);
228 return ERROR_OK; /* cc was not stashed */
229 /* fetch current cc */
230 stm8_read_u8(target, DM_REG_CC, &cc);
232 cc &= ~(CC_I0 + CC_I1);
233 /* restore I1 & I0 from stash*/
234 cc |= (stm8->cc & (CC_I0+CC_I1));
235 /* update current cc */
236 stm8_write_u8(target, DM_REG_CC, cc);
237 stm8->cc_valid = false;
239 stm8_read_u8(target, DM_REG_CC, &cc);
240 if ((cc & CC_I0) && (cc & CC_I1))
241 return ERROR_OK; /* interrupts already masked */
244 stm8->cc_valid = true;
245 /* mask interrupts (disable) */
246 cc |= (CC_I0 + CC_I1);
247 stm8_write_u8(target, DM_REG_CC, cc);
253 static int stm8_set_hwbreak(struct target *target,
254 struct stm8_comparator comparator_list[])
259 /* Refer to Table 4 in UM0470 */
267 if (!comparator_list[0].used) {
268 comparator_list[0].type = HWBRK_EXEC;
269 comparator_list[0].bp_value = -1;
272 if (!comparator_list[1].used) {
273 comparator_list[1].type = HWBRK_EXEC;
274 comparator_list[1].bp_value = -1;
277 if ((comparator_list[0].type == HWBRK_EXEC)
278 && (comparator_list[1].type == HWBRK_EXEC)) {
279 comparator_list[0].reg_address = 0;
280 comparator_list[1].reg_address = 1;
283 if ((comparator_list[0].type == HWBRK_EXEC)
284 && (comparator_list[1].type != HWBRK_EXEC)) {
285 comparator_list[0].reg_address = 0;
286 comparator_list[1].reg_address = 1;
287 switch (comparator_list[1].type) {
301 if ((comparator_list[1].type == HWBRK_EXEC)
302 && (comparator_list[0].type != HWBRK_EXEC)) {
303 comparator_list[0].reg_address = 1;
304 comparator_list[1].reg_address = 0;
305 switch (comparator_list[0].type) {
319 if ((comparator_list[0].type != HWBRK_EXEC)
320 && (comparator_list[1].type != HWBRK_EXEC)) {
321 if (comparator_list[0].type != comparator_list[1].type) {
322 LOG_ERROR("data hw breakpoints must be of same type");
323 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
327 for (i = 0; i < 2; i++) {
328 data = comparator_list[i].bp_value;
329 addr = comparator_list[i].reg_address;
336 ret = stm8_adapter_write_memory(target, DM_BKR1E, 1, 3, buf);
337 LOG_DEBUG("DM_BKR1E=%" PRIx32, data);
338 } else if (addr == 1) {
339 ret = stm8_adapter_write_memory(target, DM_BKR2E, 1, 3, buf);
340 LOG_DEBUG("DM_BKR2E=%" PRIx32, data);
342 LOG_DEBUG("addr=%" PRIu32, addr);
349 ret = stm8_write_u8(target, DM_CR1,
350 (bc << 3) + (bir << 2) + (biw << 1));
351 LOG_DEBUG("DM_CR1=%" PRIx8, buf[0]);
359 /* read DM control and status regs */
360 static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,
366 ret = stm8_adapter_read_memory(target, DM_CSR1, 1, sizeof(buf), buf);
376 /* set or clear the single step flag in DM */
377 static int stm8_config_step(struct target *target, int enable)
382 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
390 ret = stm8_write_u8(target, DM_CSR1, csr1);
396 /* set the stall flag in DM */
397 static int stm8_debug_stall(struct target *target)
402 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
406 ret = stm8_write_u8(target, DM_CSR2, csr2);
412 static int stm8_configure_break_unit(struct target *target)
414 /* get pointers to arch-specific information */
415 struct stm8_common *stm8 = target_to_stm8(target);
417 if (stm8->bp_scanned)
420 stm8->num_hw_bpoints = 2;
421 stm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;
423 stm8->hw_break_list = calloc(stm8->num_hw_bpoints,
424 sizeof(struct stm8_comparator));
426 stm8->hw_break_list[0].reg_address = 0;
427 stm8->hw_break_list[1].reg_address = 1;
429 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8->num_hw_bpoints,
430 stm8->num_hw_bpoints);
432 stm8->bp_scanned = true;
437 static int stm8_examine_debug_reason(struct target *target)
442 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
443 if (retval == ERROR_OK)
444 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
446 if ((target->debug_reason != DBG_REASON_DBGRQ)
447 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
449 if (retval != ERROR_OK)
453 /* halted on reset */
454 target->debug_reason = DBG_REASON_UNDEFINED;
456 if (csr1 & (BK1F+BK2F))
457 /* we have halted on a breakpoint (or wp)*/
458 target->debug_reason = DBG_REASON_BREAKPOINT;
461 /* we have halted on a breakpoint */
462 target->debug_reason = DBG_REASON_BREAKPOINT;
469 static int stm8_debug_entry(struct target *target)
471 struct stm8_common *stm8 = target_to_stm8(target);
473 /* restore interrupts */
474 stm8_enable_interrupts(target, 1);
476 stm8_save_context(target);
478 /* make sure stepping disabled STE bit in CSR1 cleared */
479 stm8_config_step(target, 0);
481 /* attempt to find halt reason */
482 stm8_examine_debug_reason(target);
484 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
485 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32),
486 target_state_name(target));
491 /* clear stall flag in DM and flush instruction pipe */
492 static int stm8_exit_debug(struct target *target)
497 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
501 ret = stm8_write_u8(target, DM_CSR2, csr2);
507 ret = stm8_write_u8(target, DM_CSR2, csr2);
513 static int stm8_read_regs(struct target *target, uint32_t regs[])
518 ret = stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);
522 regs[0] = be_to_h_u24(buf+DM_REG_PC-DM_REGS);
523 regs[1] = buf[DM_REG_A-DM_REGS];
524 regs[2] = be_to_h_u16(buf+DM_REG_X-DM_REGS);
525 regs[3] = be_to_h_u16(buf+DM_REG_Y-DM_REGS);
526 regs[4] = be_to_h_u16(buf+DM_REG_SP-DM_REGS);
527 regs[5] = buf[DM_REG_CC-DM_REGS];
532 static int stm8_write_regs(struct target *target, uint32_t regs[])
537 h_u24_to_be(buf+DM_REG_PC-DM_REGS, regs[0]);
538 buf[DM_REG_A-DM_REGS] = regs[1];
539 h_u16_to_be(buf+DM_REG_X-DM_REGS, regs[2]);
540 h_u16_to_be(buf+DM_REG_Y-DM_REGS, regs[3]);
541 h_u16_to_be(buf+DM_REG_SP-DM_REGS, regs[4]);
542 buf[DM_REG_CC-DM_REGS] = regs[5];
544 ret = stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);
551 static int stm8_get_core_reg(struct reg *reg)
554 struct stm8_core_reg *stm8_reg = reg->arch_info;
555 struct target *target = stm8_reg->target;
556 struct stm8_common *stm8_target = target_to_stm8(target);
558 if (target->state != TARGET_HALTED)
559 return ERROR_TARGET_NOT_HALTED;
561 retval = stm8_target->read_core_reg(target, stm8_reg->num);
566 static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
568 struct stm8_core_reg *stm8_reg = reg->arch_info;
569 struct target *target = stm8_reg->target;
570 uint32_t value = buf_get_u32(buf, 0, reg->size);
572 if (target->state != TARGET_HALTED)
573 return ERROR_TARGET_NOT_HALTED;
575 buf_set_u32(reg->value, 0, 32, value);
582 static int stm8_save_context(struct target *target)
586 /* get pointers to arch-specific information */
587 struct stm8_common *stm8 = target_to_stm8(target);
589 /* read core registers */
590 stm8_read_regs(target, stm8->core_regs);
592 for (i = 0; i < STM8_NUM_REGS; i++) {
593 if (!stm8->core_cache->reg_list[i].valid)
594 stm8->read_core_reg(target, i);
600 static int stm8_restore_context(struct target *target)
604 /* get pointers to arch-specific information */
605 struct stm8_common *stm8 = target_to_stm8(target);
607 for (i = 0; i < STM8_NUM_REGS; i++) {
608 if (stm8->core_cache->reg_list[i].dirty)
609 stm8->write_core_reg(target, i);
612 /* write core regs */
613 stm8_write_regs(target, stm8->core_regs);
618 static int stm8_unlock_flash(struct target *target)
622 struct stm8_common *stm8 = target_to_stm8(target);
624 /* check if flash is unlocked */
625 stm8_read_u8(target, stm8->flash_iapsr, data);
626 if (~data[0] & PUL) {
628 stm8_write_u8(target, stm8->flash_pukr, 0x56);
629 stm8_write_u8(target, stm8->flash_pukr, 0xae);
632 stm8_read_u8(target, stm8->flash_iapsr, data);
638 static int stm8_unlock_eeprom(struct target *target)
642 struct stm8_common *stm8 = target_to_stm8(target);
644 /* check if eeprom is unlocked */
645 stm8_read_u8(target, stm8->flash_iapsr, data);
646 if (~data[0] & DUL) {
648 stm8_write_u8(target, stm8->flash_dukr, 0xae);
649 stm8_write_u8(target, stm8->flash_dukr, 0x56);
652 stm8_read_u8(target, stm8->flash_iapsr, data);
658 static int stm8_write_flash(struct target *target, enum mem_type type,
660 uint32_t size, uint32_t count, uint32_t blocksize_param,
661 const uint8_t *buffer)
663 struct stm8_common *stm8 = target_to_stm8(target);
668 uint32_t blocksize = 0;
674 stm8_unlock_flash(target);
677 stm8_unlock_eeprom(target);
680 stm8_unlock_eeprom(target);
684 LOG_ERROR("BUG: wrong mem_type %d", type);
689 /* we don't support short writes */
694 bytecnt = count * size;
697 if ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {
699 stm8_write_u8(target, stm8->flash_cr2, PRG + opt);
700 if (stm8->flash_ncr2)
701 stm8_write_u8(target, stm8->flash_ncr2, ~(PRG + opt));
702 blocksize = blocksize_param;
704 if ((bytecnt >= 4) && ((address & 0x3) == 0)) {
706 stm8_write_u8(target, stm8->flash_cr2, WPRG + opt);
707 if (stm8->flash_ncr2)
708 stm8_write_u8(target, stm8->flash_ncr2, ~(WPRG + opt));
711 if (blocksize != 1) {
713 stm8_write_u8(target, stm8->flash_cr2, opt);
714 if (stm8->flash_ncr2)
715 stm8_write_u8(target, stm8->flash_ncr2, ~opt);
719 res = stm8_adapter_write_memory(target, address, 1, blocksize, buffer);
722 address += blocksize;
724 bytecnt -= blocksize;
726 /* lets hang here until end of program (EOP) */
727 for (i = 0; i < 16; i++) {
728 stm8_read_u8(target, stm8->flash_iapsr, &iapsr);
738 /* disable write access */
739 res = stm8_write_u8(target, stm8->flash_iapsr, 0x0);
747 static int stm8_write_memory(struct target *target, target_addr_t address,
748 uint32_t size, uint32_t count,
749 const uint8_t *buffer)
751 struct stm8_common *stm8 = target_to_stm8(target);
753 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
754 ", size: 0x%8.8" PRIx32
755 ", count: 0x%8.8" PRIx32,
756 address, size, count);
758 if (target->state != TARGET_HALTED)
759 LOG_WARNING("target not halted");
763 if ((address >= stm8->flashstart) && (address <= stm8->flashend))
764 retval = stm8_write_flash(target, FLASH, address, size, count,
765 stm8->blocksize, buffer);
766 else if ((address >= stm8->eepromstart) && (address <= stm8->eepromend))
767 retval = stm8_write_flash(target, EEPROM, address, size, count,
768 stm8->blocksize, buffer);
769 else if ((address >= stm8->optionstart) && (address <= stm8->optionend))
770 retval = stm8_write_flash(target, OPTION, address, size, count, 0, buffer);
772 retval = stm8_adapter_write_memory(target, address, size, count,
775 if (retval != ERROR_OK)
776 return ERROR_TARGET_FAILURE;
781 static int stm8_read_memory(struct target *target, target_addr_t address,
782 uint32_t size, uint32_t count, uint8_t *buffer)
784 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
785 ", size: 0x%8.8" PRIx32
786 ", count: 0x%8.8" PRIx32,
787 address, size, count);
789 if (target->state != TARGET_HALTED)
790 LOG_WARNING("target not halted");
793 retval = stm8_adapter_read_memory(target, address, size, count, buffer);
795 if (retval != ERROR_OK)
796 return ERROR_TARGET_FAILURE;
801 static int stm8_speed(int speed)
806 LOG_DEBUG("stm8_speed: %d", speed);
808 csr = SAFE_MASK | SWIM_DM;
809 if (speed >= SWIM_FREQ_HIGH)
812 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)", csr & HS ? 1 : 0);
813 retval = stm8_write_u8(NULL, SWIM_CSR, csr);
814 if (retval != ERROR_OK)
816 return adapter_speed(speed);
819 static int stm8_init(struct command_context *cmd_ctx, struct target *target)
822 * FIXME: this is a temporarily hack that needs better implementation.
823 * Being the only overwrite of adapter_driver, it prevents declaring const
824 * the struct adapter_driver.
825 * intercept adapter_driver->speed() calls
827 adapter_speed = adapter_driver->speed;
828 adapter_driver->speed = stm8_speed;
830 stm8_build_reg_cache(target);
835 static int stm8_poll(struct target *target)
837 int retval = ERROR_OK;
841 LOG_DEBUG("target->state=%d", target->state);
844 /* read dm_csrx control regs */
845 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
846 if (retval != ERROR_OK) {
847 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval);
849 We return ERROR_OK here even if we didn't get an answer.
850 openocd will call target_wait_state until we get target state TARGET_HALTED
855 /* check for processor halted */
857 if (target->state != TARGET_HALTED) {
858 if (target->state == TARGET_UNKNOWN)
859 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
861 retval = stm8_debug_entry(target);
862 if (retval != ERROR_OK) {
863 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval);
864 return ERROR_TARGET_FAILURE;
867 if (target->state == TARGET_DEBUG_RUNNING) {
868 target->state = TARGET_HALTED;
869 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
871 target->state = TARGET_HALTED;
872 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
876 target->state = TARGET_RUNNING;
878 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
883 static int stm8_halt(struct target *target)
885 LOG_DEBUG("target->state: %s", target_state_name(target));
887 if (target->state == TARGET_HALTED) {
888 LOG_DEBUG("target was already halted");
892 if (target->state == TARGET_UNKNOWN)
893 LOG_WARNING("target was in unknown state when halt was requested");
895 if (target->state == TARGET_RESET) {
896 /* we came here in a reset_halt or reset_init sequence
897 * debug entry was already prepared in stm8_assert_reset()
899 target->debug_reason = DBG_REASON_DBGRQ;
905 /* break processor */
906 stm8_debug_stall(target);
908 target->debug_reason = DBG_REASON_DBGRQ;
913 static int stm8_reset_assert(struct target *target)
916 struct stm8_common *stm8 = target_to_stm8(target);
917 bool use_srst_fallback = true;
919 enum reset_types jtag_reset_config = jtag_get_reset_config();
921 if (jtag_reset_config & RESET_HAS_SRST) {
922 res = adapter_assert_reset();
924 /* hardware srst supported */
925 use_srst_fallback = false;
926 else if (res != ERROR_COMMAND_NOTFOUND)
927 /* some other failure */
931 if (use_srst_fallback) {
932 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
933 res = swim_system_reset();
938 /* registers are now invalid */
939 register_cache_invalidate(stm8->core_cache);
941 target->state = TARGET_RESET;
942 target->debug_reason = DBG_REASON_NOTHALTED;
944 if (target->reset_halt) {
945 res = target_halt(target);
953 static int stm8_reset_deassert(struct target *target)
956 enum reset_types jtag_reset_config = jtag_get_reset_config();
958 if (jtag_reset_config & RESET_HAS_SRST) {
959 res = adapter_deassert_reset();
960 if ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND))
964 /* The cpu should now be stalled. If halt was requested
965 let poll detect the stall */
966 if (target->reset_halt)
969 /* Instead of going through saving context, polling and
970 then resuming target again just clear stall and proceed. */
971 target->state = TARGET_RUNNING;
972 return stm8_exit_debug(target);
975 /* stm8_single_step_core() is only used for stepping over breakpoints
976 from stm8_resume() */
977 static int stm8_single_step_core(struct target *target)
979 struct stm8_common *stm8 = target_to_stm8(target);
981 /* configure single step mode */
982 stm8_config_step(target, 1);
984 /* disable interrupts while stepping */
985 if (!stm8->enable_step_irq)
986 stm8_enable_interrupts(target, 0);
988 /* exit debug mode */
989 stm8_exit_debug(target);
991 stm8_debug_entry(target);
996 static int stm8_resume(struct target *target, int current,
997 target_addr_t address, int handle_breakpoints,
1000 struct stm8_common *stm8 = target_to_stm8(target);
1001 struct breakpoint *breakpoint = NULL;
1004 LOG_DEBUG("%d " TARGET_ADDR_FMT " %d %d", current, address,
1005 handle_breakpoints, debug_execution);
1007 if (target->state != TARGET_HALTED) {
1008 LOG_WARNING("target not halted");
1009 return ERROR_TARGET_NOT_HALTED;
1012 if (!debug_execution) {
1013 target_free_all_working_areas(target);
1014 stm8_enable_breakpoints(target);
1015 stm8_enable_watchpoints(target);
1016 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1017 stm8_set_hwbreak(target, comparator_list);
1020 /* current = 1: continue on current pc,
1021 otherwise continue at <address> */
1023 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value,
1025 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1026 stm8->core_cache->reg_list[STM8_PC].valid = true;
1030 resume_pc = address;
1032 resume_pc = buf_get_u32(
1033 stm8->core_cache->reg_list[STM8_PC].value,
1036 stm8_restore_context(target);
1038 /* the front-end may request us not to handle breakpoints */
1039 if (handle_breakpoints) {
1040 /* Single step past breakpoint at current address */
1041 breakpoint = breakpoint_find(target, resume_pc);
1043 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT,
1044 breakpoint->address);
1045 stm8_unset_breakpoint(target, breakpoint);
1046 stm8_single_step_core(target);
1047 stm8_set_breakpoint(target, breakpoint);
1051 /* disable interrupts if we are debugging */
1052 if (debug_execution)
1053 stm8_enable_interrupts(target, 0);
1055 /* exit debug mode */
1056 stm8_exit_debug(target);
1057 target->debug_reason = DBG_REASON_NOTHALTED;
1059 /* registers are now invalid */
1060 register_cache_invalidate(stm8->core_cache);
1062 if (!debug_execution) {
1063 target->state = TARGET_RUNNING;
1064 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1065 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
1067 target->state = TARGET_DEBUG_RUNNING;
1068 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1069 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
1075 static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
1077 stm8->enable_stm8l = enable_stm8l;
1079 if (stm8->enable_stm8l) {
1080 stm8->flash_cr2 = FLASH_CR2_STM8L;
1081 stm8->flash_ncr2 = FLASH_NCR2_STM8L;
1082 stm8->flash_iapsr = FLASH_IAPSR_STM8L;
1083 stm8->flash_dukr = FLASH_DUKR_STM8L;
1084 stm8->flash_pukr = FLASH_PUKR_STM8L;
1086 stm8->flash_cr2 = FLASH_CR2_STM8S;
1087 stm8->flash_ncr2 = FLASH_NCR2_STM8S;
1088 stm8->flash_iapsr = FLASH_IAPSR_STM8S;
1089 stm8->flash_dukr = FLASH_DUKR_STM8S;
1090 stm8->flash_pukr = FLASH_PUKR_STM8S;
1095 static int stm8_init_arch_info(struct target *target,
1096 struct stm8_common *stm8, struct jtag_tap *tap)
1098 target->endianness = TARGET_BIG_ENDIAN;
1099 target->arch_info = stm8;
1100 stm8->common_magic = STM8_COMMON_MAGIC;
1101 stm8->fast_data_area = NULL;
1102 stm8->blocksize = 0x80;
1103 stm8->flashstart = 0x8000;
1104 stm8->flashend = 0xffff;
1105 stm8->eepromstart = 0x4000;
1106 stm8->eepromend = 0x43ff;
1107 stm8->optionstart = 0x4800;
1108 stm8->optionend = 0x487F;
1110 /* has breakpoint/watchpoint unit been scanned */
1111 stm8->bp_scanned = false;
1112 stm8->hw_break_list = NULL;
1114 stm8->read_core_reg = stm8_read_core_reg;
1115 stm8->write_core_reg = stm8_write_core_reg;
1117 stm8_init_flash_regs(0, stm8);
1122 static int stm8_target_create(struct target *target,
1126 struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));
1128 stm8_init_arch_info(target, stm8, target->tap);
1129 stm8_configure_break_unit(target);
1134 static int stm8_read_core_reg(struct target *target, unsigned int num)
1138 /* get pointers to arch-specific information */
1139 struct stm8_common *stm8 = target_to_stm8(target);
1141 if (num >= STM8_NUM_REGS)
1142 return ERROR_COMMAND_SYNTAX_ERROR;
1144 reg_value = stm8->core_regs[num];
1145 LOG_DEBUG("read core reg %i value 0x%" PRIx32 "", num, reg_value);
1146 buf_set_u32(stm8->core_cache->reg_list[num].value, 0, 32, reg_value);
1147 stm8->core_cache->reg_list[num].valid = true;
1148 stm8->core_cache->reg_list[num].dirty = false;
1153 static int stm8_write_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 = buf_get_u32(stm8->core_cache->reg_list[num].value, 0, 32);
1164 stm8->core_regs[num] = reg_value;
1165 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
1166 stm8->core_cache->reg_list[num].valid = true;
1167 stm8->core_cache->reg_list[num].dirty = false;
1172 static const char *stm8_get_gdb_arch(struct target *target)
1177 static int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
1178 int *reg_list_size, enum target_register_class reg_class)
1180 /* get pointers to arch-specific information */
1181 struct stm8_common *stm8 = target_to_stm8(target);
1184 *reg_list_size = STM8_NUM_REGS;
1185 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1187 for (i = 0; i < STM8_NUM_REGS; i++)
1188 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1193 static const struct reg_arch_type stm8_reg_type = {
1194 .get = stm8_get_core_reg,
1195 .set = stm8_set_core_reg,
1198 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1200 /* get pointers to arch-specific information */
1201 struct stm8_common *stm8 = target_to_stm8(target);
1203 int num_regs = STM8_NUM_REGS;
1204 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1205 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1206 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1207 struct stm8_core_reg *arch_info = malloc(
1208 sizeof(struct stm8_core_reg) * num_regs);
1209 struct reg_feature *feature;
1212 /* Build the process context cache */
1213 cache->name = "stm8 registers";
1215 cache->reg_list = reg_list;
1216 cache->num_regs = num_regs;
1218 stm8->core_cache = cache;
1220 for (i = 0; i < num_regs; i++) {
1221 arch_info[i].num = stm8_regs[i].id;
1222 arch_info[i].target = target;
1224 reg_list[i].name = stm8_regs[i].name;
1225 reg_list[i].size = stm8_regs[i].bits;
1227 reg_list[i].value = calloc(1, 4);
1228 reg_list[i].valid = false;
1229 reg_list[i].type = &stm8_reg_type;
1230 reg_list[i].arch_info = &arch_info[i];
1232 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1233 if (reg_list[i].reg_data_type)
1234 reg_list[i].reg_data_type->type = stm8_regs[i].type;
1236 LOG_ERROR("unable to allocate reg type list");
1240 reg_list[i].dirty = false;
1241 reg_list[i].group = stm8_regs[i].group;
1242 reg_list[i].number = stm8_regs[i].id;
1243 reg_list[i].exist = true;
1244 reg_list[i].caller_save = true; /* gdb defaults to true */
1246 feature = calloc(1, sizeof(struct reg_feature));
1248 feature->name = stm8_regs[i].feature;
1249 reg_list[i].feature = feature;
1251 LOG_ERROR("unable to allocate feature list");
1257 static void stm8_free_reg_cache(struct target *target)
1259 struct stm8_common *stm8 = target_to_stm8(target);
1260 struct reg_cache *cache;
1264 cache = stm8->core_cache;
1269 for (i = 0; i < cache->num_regs; i++) {
1270 reg = &cache->reg_list[i];
1273 free(reg->reg_data_type);
1277 free(cache->reg_list[0].arch_info);
1278 free(cache->reg_list);
1281 stm8->core_cache = NULL;
1284 static void stm8_deinit(struct target *target)
1286 struct stm8_common *stm8 = target_to_stm8(target);
1288 free(stm8->hw_break_list);
1290 stm8_free_reg_cache(target);
1295 static int stm8_arch_state(struct target *target)
1297 struct stm8_common *stm8 = target_to_stm8(target);
1299 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
1300 debug_reason_name(target),
1301 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1306 static int stm8_step(struct target *target, int current,
1307 target_addr_t address, int handle_breakpoints)
1309 LOG_DEBUG("%x " TARGET_ADDR_FMT " %x",
1310 current, address, handle_breakpoints);
1312 /* get pointers to arch-specific information */
1313 struct stm8_common *stm8 = target_to_stm8(target);
1314 struct breakpoint *breakpoint = NULL;
1316 if (target->state != TARGET_HALTED) {
1317 LOG_WARNING("target not halted");
1318 return ERROR_TARGET_NOT_HALTED;
1321 /* current = 1: continue on current pc, otherwise continue at <address> */
1323 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);
1324 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1325 stm8->core_cache->reg_list[STM8_PC].valid = true;
1328 /* the front-end may request us not to handle breakpoints */
1329 if (handle_breakpoints) {
1330 breakpoint = breakpoint_find(target,
1331 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1333 stm8_unset_breakpoint(target, breakpoint);
1336 /* restore context */
1337 stm8_restore_context(target);
1339 /* configure single step mode */
1340 stm8_config_step(target, 1);
1342 target->debug_reason = DBG_REASON_SINGLESTEP;
1344 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1346 /* disable interrupts while stepping */
1347 if (!stm8->enable_step_irq)
1348 stm8_enable_interrupts(target, 0);
1350 /* exit debug mode */
1351 stm8_exit_debug(target);
1353 /* registers are now invalid */
1354 register_cache_invalidate(stm8->core_cache);
1356 LOG_DEBUG("target stepped ");
1357 stm8_debug_entry(target);
1360 stm8_set_breakpoint(target, breakpoint);
1362 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1367 static void stm8_enable_breakpoints(struct target *target)
1369 struct breakpoint *breakpoint = target->breakpoints;
1371 /* set any pending breakpoints */
1372 while (breakpoint) {
1373 if (!breakpoint->is_set)
1374 stm8_set_breakpoint(target, breakpoint);
1375 breakpoint = breakpoint->next;
1379 static int stm8_set_breakpoint(struct target *target,
1380 struct breakpoint *breakpoint)
1382 struct stm8_common *stm8 = target_to_stm8(target);
1383 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1386 if (breakpoint->is_set) {
1387 LOG_WARNING("breakpoint already set");
1391 if (breakpoint->type == BKPT_HARD) {
1394 while (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))
1396 if (bp_num >= stm8->num_hw_bpoints) {
1397 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32 ")",
1398 breakpoint->unique_id);
1399 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1401 breakpoint_hw_set(breakpoint, bp_num);
1402 comparator_list[bp_num].used = true;
1403 comparator_list[bp_num].bp_value = breakpoint->address;
1404 comparator_list[bp_num].type = HWBRK_EXEC;
1406 retval = stm8_set_hwbreak(target, comparator_list);
1407 if (retval != ERROR_OK)
1410 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
1411 breakpoint->unique_id,
1412 bp_num, comparator_list[bp_num].bp_value);
1413 } else if (breakpoint->type == BKPT_SOFT) {
1414 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1415 if (breakpoint->length == 1) {
1416 uint8_t verify = 0x55;
1418 retval = target_read_u8(target, breakpoint->address,
1419 breakpoint->orig_instr);
1420 if (retval != ERROR_OK)
1422 retval = target_write_u8(target, breakpoint->address, STM8_BREAK);
1423 if (retval != ERROR_OK)
1426 retval = target_read_u8(target, breakpoint->address, &verify);
1427 if (retval != ERROR_OK)
1429 if (verify != STM8_BREAK) {
1430 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1431 " - check that memory is read/writable",
1432 breakpoint->address);
1433 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1436 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1438 breakpoint->is_set = true;
1444 static int stm8_add_breakpoint(struct target *target,
1445 struct breakpoint *breakpoint)
1447 struct stm8_common *stm8 = target_to_stm8(target);
1450 if (breakpoint->type == BKPT_HARD) {
1451 if (stm8->num_hw_bpoints_avail < 1) {
1452 LOG_INFO("no hardware breakpoint available");
1453 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1456 ret = stm8_set_breakpoint(target, breakpoint);
1457 if (ret != ERROR_OK)
1460 stm8->num_hw_bpoints_avail--;
1464 ret = stm8_set_breakpoint(target, breakpoint);
1465 if (ret != ERROR_OK)
1471 static int stm8_unset_breakpoint(struct target *target,
1472 struct breakpoint *breakpoint)
1474 /* get pointers to arch-specific information */
1475 struct stm8_common *stm8 = target_to_stm8(target);
1476 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1479 if (!breakpoint->is_set) {
1480 LOG_WARNING("breakpoint not set");
1484 if (breakpoint->type == BKPT_HARD) {
1485 int bp_num = breakpoint->number;
1486 if (bp_num >= stm8->num_hw_bpoints) {
1487 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
1488 breakpoint->unique_id);
1491 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
1492 breakpoint->unique_id,
1494 comparator_list[bp_num].used = false;
1495 retval = stm8_set_hwbreak(target, comparator_list);
1496 if (retval != ERROR_OK)
1499 /* restore original instruction (kept in target endianness) */
1500 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1501 if (breakpoint->length == 1) {
1502 uint8_t current_instr;
1504 /* check that user program has not
1505 modified breakpoint instruction */
1506 retval = target_read_memory(target, breakpoint->address, 1, 1,
1507 (uint8_t *)¤t_instr);
1508 if (retval != ERROR_OK)
1511 if (current_instr == STM8_BREAK) {
1512 retval = target_write_memory(target, breakpoint->address, 1, 1,
1513 breakpoint->orig_instr);
1514 if (retval != ERROR_OK)
1520 breakpoint->is_set = false;
1525 static int stm8_remove_breakpoint(struct target *target,
1526 struct breakpoint *breakpoint)
1528 /* get pointers to arch-specific information */
1529 struct stm8_common *stm8 = target_to_stm8(target);
1531 if (target->state != TARGET_HALTED) {
1532 LOG_WARNING("target not halted");
1533 return ERROR_TARGET_NOT_HALTED;
1536 if (breakpoint->is_set)
1537 stm8_unset_breakpoint(target, breakpoint);
1539 if (breakpoint->type == BKPT_HARD)
1540 stm8->num_hw_bpoints_avail++;
1545 static int stm8_set_watchpoint(struct target *target,
1546 struct watchpoint *watchpoint)
1548 struct stm8_common *stm8 = target_to_stm8(target);
1549 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1553 if (watchpoint->is_set) {
1554 LOG_WARNING("watchpoint already set");
1558 while (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))
1560 if (wp_num >= stm8->num_hw_bpoints) {
1561 LOG_ERROR("Can not find free hw breakpoint");
1562 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1565 if (watchpoint->length != 1) {
1566 LOG_ERROR("Only watchpoints of length 1 are supported");
1567 return ERROR_TARGET_UNALIGNED_ACCESS;
1570 enum hw_break_type enable = 0;
1572 switch (watchpoint->rw) {
1583 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1586 comparator_list[wp_num].used = true;
1587 comparator_list[wp_num].bp_value = watchpoint->address;
1588 comparator_list[wp_num].type = enable;
1590 ret = stm8_set_hwbreak(target, comparator_list);
1591 if (ret != ERROR_OK) {
1592 comparator_list[wp_num].used = false;
1596 watchpoint_set(watchpoint, wp_num);
1598 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1600 comparator_list[wp_num].bp_value);
1605 static int stm8_add_watchpoint(struct target *target,
1606 struct watchpoint *watchpoint)
1609 struct stm8_common *stm8 = target_to_stm8(target);
1611 if (stm8->num_hw_bpoints_avail < 1) {
1612 LOG_INFO("no hardware watchpoints available");
1613 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1616 ret = stm8_set_watchpoint(target, watchpoint);
1617 if (ret != ERROR_OK)
1620 stm8->num_hw_bpoints_avail--;
1624 static void stm8_enable_watchpoints(struct target *target)
1626 struct watchpoint *watchpoint = target->watchpoints;
1628 /* set any pending watchpoints */
1629 while (watchpoint) {
1630 if (!watchpoint->is_set)
1631 stm8_set_watchpoint(target, watchpoint);
1632 watchpoint = watchpoint->next;
1636 static int stm8_unset_watchpoint(struct target *target,
1637 struct watchpoint *watchpoint)
1639 /* get pointers to arch-specific information */
1640 struct stm8_common *stm8 = target_to_stm8(target);
1641 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1643 if (!watchpoint->is_set) {
1644 LOG_WARNING("watchpoint not set");
1648 int wp_num = watchpoint->number;
1649 if (wp_num >= stm8->num_hw_bpoints) {
1650 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1653 comparator_list[wp_num].used = false;
1654 watchpoint->is_set = false;
1656 stm8_set_hwbreak(target, comparator_list);
1661 static int stm8_remove_watchpoint(struct target *target,
1662 struct watchpoint *watchpoint)
1664 /* get pointers to arch-specific information */
1665 struct stm8_common *stm8 = target_to_stm8(target);
1667 if (target->state != TARGET_HALTED) {
1668 LOG_WARNING("target not halted");
1669 return ERROR_TARGET_NOT_HALTED;
1672 if (watchpoint->is_set)
1673 stm8_unset_watchpoint(target, watchpoint);
1675 stm8->num_hw_bpoints_avail++;
1680 static int stm8_examine(struct target *target)
1684 /* get pointers to arch-specific information */
1685 struct stm8_common *stm8 = target_to_stm8(target);
1686 enum reset_types jtag_reset_config = jtag_get_reset_config();
1688 if (!target_was_examined(target)) {
1689 if (!stm8->swim_configured) {
1690 stm8->swim_configured = true;
1692 Now is the time to deassert reset if connect_under_reset.
1693 Releasing reset line will cause the option bytes to load.
1694 The core will still be stalled.
1696 if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
1697 if (jtag_reset_config & RESET_SRST_NO_GATING)
1698 stm8_reset_deassert(target);
1700 LOG_WARNING("\'srst_nogate\' reset_config option is required");
1703 LOG_INFO("trying to reconnect");
1705 retval = swim_reconnect();
1706 if (retval != ERROR_OK) {
1707 LOG_ERROR("reconnect failed");
1711 /* read dm_csrx control regs */
1712 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
1713 if (retval != ERROR_OK) {
1714 LOG_ERROR("state query failed");
1719 target_set_examined(target);
1727 /** Checks whether a memory region is erased. */
1728 static int stm8_blank_check_memory(struct target *target,
1729 struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
1731 struct working_area *erase_check_algorithm;
1732 struct reg_param reg_params[2];
1733 struct mem_param mem_params[2];
1734 struct stm8_algorithm stm8_info;
1736 static const uint8_t stm8_erase_check_code[] = {
1737 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1740 if (erased_value != 0xff) {
1741 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for STM8",
1746 /* make sure we have a working area */
1747 if (target_alloc_working_area(target, sizeof(stm8_erase_check_code),
1748 &erase_check_algorithm) != ERROR_OK)
1749 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1751 target_write_buffer(target, erase_check_algorithm->address,
1752 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1754 stm8_info.common_magic = STM8_COMMON_MAGIC;
1756 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1757 buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
1759 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1760 buf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);
1762 init_reg_param(®_params[0], "a", 32, PARAM_IN_OUT);
1763 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1765 init_reg_param(®_params[1], "sp", 32, PARAM_OUT);
1766 buf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);
1768 int retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,
1769 erase_check_algorithm->address + 6,
1770 erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
1773 if (retval == ERROR_OK)
1774 blocks[0].result = (*(reg_params[0].value) == 0xff);
1776 destroy_mem_param(&mem_params[0]);
1777 destroy_mem_param(&mem_params[1]);
1778 destroy_reg_param(®_params[0]);
1779 destroy_reg_param(®_params[1]);
1781 target_free_working_area(target, erase_check_algorithm);
1783 if (retval != ERROR_OK)
1786 return 1; /* only one block has been checked */
1789 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1790 uint32_t count, uint32_t *checksum)
1792 /* let image_calculate_checksum() take care of business */
1793 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1796 /* run to exit point. return error if exit point was not reached. */
1797 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1798 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1802 /* This code relies on the target specific resume() and
1803 poll()->debug_entry() sequence to write register values to the
1804 processor and the read them back */
1805 retval = target_resume(target, 0, entry_point, 0, 1);
1806 if (retval != ERROR_OK)
1809 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1810 /* If the target fails to halt due to the breakpoint, force a halt */
1811 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1812 retval = target_halt(target);
1813 if (retval != ERROR_OK)
1815 retval = target_wait_state(target, TARGET_HALTED, 500);
1816 if (retval != ERROR_OK)
1818 return ERROR_TARGET_TIMEOUT;
1821 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1822 if (exit_point && (pc != exit_point)) {
1823 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1824 return ERROR_TARGET_TIMEOUT;
1830 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1831 struct mem_param *mem_params, int num_reg_params,
1832 struct reg_param *reg_params, target_addr_t entry_point,
1833 target_addr_t exit_point, int timeout_ms, void *arch_info)
1835 struct stm8_common *stm8 = target_to_stm8(target);
1837 uint32_t context[STM8_NUM_REGS];
1838 int retval = ERROR_OK;
1840 LOG_DEBUG("Running algorithm");
1842 /* NOTE: stm8_run_algorithm requires that each
1843 algorithm uses a software breakpoint
1844 at the exit point */
1846 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1847 LOG_ERROR("current target isn't a STM8 target");
1848 return ERROR_TARGET_INVALID;
1851 if (target->state != TARGET_HALTED) {
1852 LOG_WARNING("target not halted");
1853 return ERROR_TARGET_NOT_HALTED;
1856 /* refresh core register cache */
1857 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1858 if (!stm8->core_cache->reg_list[i].valid)
1859 stm8->read_core_reg(target, i);
1860 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1863 for (int i = 0; i < num_mem_params; i++) {
1864 if (mem_params[i].direction == PARAM_IN)
1866 retval = target_write_buffer(target, mem_params[i].address,
1867 mem_params[i].size, mem_params[i].value);
1868 if (retval != ERROR_OK)
1872 for (int i = 0; i < num_reg_params; i++) {
1873 if (reg_params[i].direction == PARAM_IN)
1876 struct reg *reg = register_get_by_name(stm8->core_cache,
1877 reg_params[i].reg_name, false);
1880 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1881 return ERROR_COMMAND_SYNTAX_ERROR;
1884 if (reg_params[i].size != 32) {
1885 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1886 reg_params[i].reg_name);
1887 return ERROR_COMMAND_SYNTAX_ERROR;
1890 stm8_set_core_reg(reg, reg_params[i].value);
1893 retval = stm8_run_and_wait(target, entry_point,
1894 timeout_ms, exit_point, stm8);
1896 if (retval != ERROR_OK)
1899 for (int i = 0; i < num_mem_params; i++) {
1900 if (mem_params[i].direction != PARAM_OUT) {
1901 retval = target_read_buffer(target, mem_params[i].address,
1902 mem_params[i].size, mem_params[i].value);
1903 if (retval != ERROR_OK)
1908 for (int i = 0; i < num_reg_params; i++) {
1909 if (reg_params[i].direction != PARAM_OUT) {
1910 struct reg *reg = register_get_by_name(stm8->core_cache,
1911 reg_params[i].reg_name, false);
1913 LOG_ERROR("BUG: register '%s' not found",
1914 reg_params[i].reg_name);
1915 return ERROR_COMMAND_SYNTAX_ERROR;
1918 if (reg_params[i].size != 32) {
1919 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1920 reg_params[i].reg_name);
1921 return ERROR_COMMAND_SYNTAX_ERROR;
1924 buf_set_u32(reg_params[i].value,
1925 0, 32, buf_get_u32(reg->value, 0, 32));
1929 /* restore everything we saved before */
1930 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1932 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1933 if (regvalue != context[i]) {
1934 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1935 stm8->core_cache->reg_list[i].name, context[i]);
1936 buf_set_u32(stm8->core_cache->reg_list[i].value,
1938 stm8->core_cache->reg_list[i].valid = true;
1939 stm8->core_cache->reg_list[i].dirty = true;
1946 static int stm8_jim_configure(struct target *target, struct jim_getopt_info *goi)
1948 struct stm8_common *stm8 = target_to_stm8(target);
1953 arg = Jim_GetString(goi->argv[0], NULL);
1954 if (!strcmp(arg, "-blocksize")) {
1955 e = jim_getopt_string(goi, &arg, NULL);
1959 if (goi->argc == 0) {
1960 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1961 "-blocksize ?bytes? ...");
1965 e = jim_getopt_wide(goi, &w);
1969 stm8->blocksize = w;
1970 LOG_DEBUG("blocksize=%8.8" PRIx32, stm8->blocksize);
1973 if (!strcmp(arg, "-flashstart")) {
1974 e = jim_getopt_string(goi, &arg, NULL);
1978 if (goi->argc == 0) {
1979 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1980 "-flashstart ?address? ...");
1984 e = jim_getopt_wide(goi, &w);
1988 stm8->flashstart = w;
1989 LOG_DEBUG("flashstart=%8.8" PRIx32, stm8->flashstart);
1992 if (!strcmp(arg, "-flashend")) {
1993 e = jim_getopt_string(goi, &arg, NULL);
1997 if (goi->argc == 0) {
1998 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1999 "-flashend ?address? ...");
2003 e = jim_getopt_wide(goi, &w);
2008 LOG_DEBUG("flashend=%8.8" PRIx32, stm8->flashend);
2011 if (!strcmp(arg, "-eepromstart")) {
2012 e = jim_getopt_string(goi, &arg, NULL);
2016 if (goi->argc == 0) {
2017 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2018 "-eepromstart ?address? ...");
2022 e = jim_getopt_wide(goi, &w);
2026 stm8->eepromstart = w;
2027 LOG_DEBUG("eepromstart=%8.8" PRIx32, stm8->eepromstart);
2030 if (!strcmp(arg, "-eepromend")) {
2031 e = jim_getopt_string(goi, &arg, NULL);
2035 if (goi->argc == 0) {
2036 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2037 "-eepromend ?address? ...");
2041 e = jim_getopt_wide(goi, &w);
2045 stm8->eepromend = w;
2046 LOG_DEBUG("eepromend=%8.8" PRIx32, stm8->eepromend);
2049 if (!strcmp(arg, "-optionstart")) {
2050 e = jim_getopt_string(goi, &arg, NULL);
2054 if (goi->argc == 0) {
2055 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2056 "-optionstart ?address? ...");
2060 e = jim_getopt_wide(goi, &w);
2064 stm8->optionstart = w;
2065 LOG_DEBUG("optionstart=%8.8" PRIx32, stm8->optionstart);
2068 if (!strcmp(arg, "-optionend")) {
2069 e = jim_getopt_string(goi, &arg, NULL);
2073 if (goi->argc == 0) {
2074 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2075 "-optionend ?address? ...");
2079 e = jim_getopt_wide(goi, &w);
2083 stm8->optionend = w;
2084 LOG_DEBUG("optionend=%8.8" PRIx32, stm8->optionend);
2087 if (!strcmp(arg, "-enable_step_irq")) {
2088 e = jim_getopt_string(goi, &arg, NULL);
2092 stm8->enable_step_irq = true;
2093 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2096 if (!strcmp(arg, "-enable_stm8l")) {
2097 e = jim_getopt_string(goi, &arg, NULL);
2101 stm8->enable_stm8l = true;
2102 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2103 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2106 return JIM_CONTINUE;
2109 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2112 struct target *target = get_current_target(CMD_CTX);
2113 struct stm8_common *stm8 = target_to_stm8(target);
2114 bool enable = stm8->enable_step_irq;
2117 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2118 stm8->enable_step_irq = enable;
2120 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2121 command_print(CMD, "enable_step_irq = %s", msg);
2125 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2128 struct target *target = get_current_target(CMD_CTX);
2129 struct stm8_common *stm8 = target_to_stm8(target);
2130 bool enable = stm8->enable_stm8l;
2133 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2134 stm8->enable_stm8l = enable;
2136 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2137 command_print(CMD, "enable_stm8l = %s", msg);
2138 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2142 static const struct command_registration stm8_exec_command_handlers[] = {
2144 .name = "enable_step_irq",
2145 .handler = stm8_handle_enable_step_irq_command,
2146 .mode = COMMAND_ANY,
2147 .help = "Enable/disable irq handling during step",
2151 .name = "enable_stm8l",
2152 .handler = stm8_handle_enable_stm8l_command,
2153 .mode = COMMAND_ANY,
2154 .help = "Enable/disable STM8L flash programming",
2157 COMMAND_REGISTRATION_DONE
2160 static const struct command_registration stm8_command_handlers[] = {
2163 .mode = COMMAND_ANY,
2164 .help = "stm8 command group",
2166 .chain = stm8_exec_command_handlers,
2168 COMMAND_REGISTRATION_DONE
2171 struct target_type stm8_target = {
2175 .arch_state = stm8_arch_state,
2178 .resume = stm8_resume,
2181 .assert_reset = stm8_reset_assert,
2182 .deassert_reset = stm8_reset_deassert,
2184 .get_gdb_arch = stm8_get_gdb_arch,
2185 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2187 .read_memory = stm8_read_memory,
2188 .write_memory = stm8_write_memory,
2189 .checksum_memory = stm8_checksum_memory,
2190 .blank_check_memory = stm8_blank_check_memory,
2192 .run_algorithm = stm8_run_algorithm,
2194 .add_breakpoint = stm8_add_breakpoint,
2195 .remove_breakpoint = stm8_remove_breakpoint,
2196 .add_watchpoint = stm8_add_watchpoint,
2197 .remove_watchpoint = stm8_remove_watchpoint,
2199 .commands = stm8_command_handlers,
2200 .target_create = stm8_target_create,
2201 .init_target = stm8_init,
2202 .examine = stm8_examine,
2204 .deinit_target = stm8_deinit,
2205 .target_jim_configure = stm8_jim_configure,