stm8 : new target
[openocd.git] / src / target / stm8.c
blob262497b0d52ca727221230ebf378a014fd07fa2c
1 /*
2 OpenOCD STM8 target driver
3 Copyright (C) 2017 Ake Rehnman
4 ake.rehnman(at)gmail.com
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <helper/log.h>
25 #include "target.h"
26 #include "target_type.h"
27 #include "hello.h"
28 #include "jtag/jtag.h"
29 #include "jtag/hla/hla_transport.h"
30 #include "jtag/hla/hla_interface.h"
31 #include "jtag/hla/hla_layout.h"
32 #include "register.h"
33 #include "breakpoints.h"
34 #include "algorithm.h"
35 #include "stm8.h"
37 static struct reg_cache *stm8_build_reg_cache(struct target *target);
38 static int stm8_read_core_reg(struct target *target, unsigned int num);
39 static int stm8_write_core_reg(struct target *target, unsigned int num);
40 static int stm8_save_context(struct target *target);
41 static void stm8_enable_breakpoints(struct target *target);
42 static int stm8_unset_breakpoint(struct target *target,
43 struct breakpoint *breakpoint);
44 static int stm8_set_breakpoint(struct target *target,
45 struct breakpoint *breakpoint);
46 static void stm8_enable_watchpoints(struct target *target);
47 static int stm8_unset_watchpoint(struct target *target,
48 struct watchpoint *watchpoint);
50 static const struct {
51 unsigned id;
52 const char *name;
53 const uint8_t bits;
54 enum reg_type type;
55 const char *group;
56 const char *feature;
57 int flag;
58 } stm8_regs[] = {
59 { 0, "pc", 32, REG_TYPE_UINT32, "general", "org.gnu.gdb.stm8.core", 0 },
60 { 1, "a", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
61 { 2, "x", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
62 { 3, "y", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
63 { 4, "sp", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
64 { 5, "cc", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
67 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
68 #define STM8_PC 0
69 #define STM8_A 1
70 #define STM8_X 2
71 #define STM8_Y 3
72 #define STM8_SP 4
73 #define STM8_CC 5
75 #define CC_I0 0x8
76 #define CC_I1 0x20
78 #define DM_REGS 0x7f00
79 #define DM_REG_A 0x7f00
80 #define DM_REG_PC 0x7f01
81 #define DM_REG_X 0x7f04
82 #define DM_REG_Y 0x7f06
83 #define DM_REG_SP 0x7f08
84 #define DM_REG_CC 0x7f0a
86 #define DM_BKR1E 0x7f90
87 #define DM_BKR2E 0x7f93
88 #define DM_CR1 0x7f96
89 #define DM_CR2 0x7f97
90 #define DM_CSR1 0x7f98
91 #define DM_CSR2 0x7f99
93 #define STE 0x40
94 #define STF 0x20
95 #define RST 0x10
96 #define BRW 0x08
97 #define BK2F 0x04
98 #define BK1F 0x02
100 #define SWBRK 0x20
101 #define SWBKF 0x10
102 #define STALL 0x08
103 #define FLUSH 0x01
105 #define FLASH_CR1_STM8S 0x505A
106 #define FLASH_CR2_STM8S 0x505B
107 #define FLASH_NCR2_STM8S 0x505C
108 #define FLASH_IAPSR_STM8S 0x505F
109 #define FLASH_PUKR_STM8S 0x5062
110 #define FLASH_DUKR_STM8S 0x5064
112 #define FLASH_CR1_STM8L 0x5050
113 #define FLASH_CR2_STM8L 0x5051
114 #define FLASH_NCR2_STM8L 0
115 #define FLASH_PUKR_STM8L 0x5052
116 #define FLASH_DUKR_STM8L 0x5053
117 #define FLASH_IAPSR_STM8L 0x5054
119 /* FLASH_IAPSR */
120 #define HVOFF 0x40
121 #define DUL 0x08
122 #define EOP 0x04
123 #define PUL 0x02
124 #define WR_PG_DIS 0x01
126 /* FLASH_CR2 */
127 #define OPT 0x80
128 #define WPRG 0x40
129 #define ERASE 0x20
130 #define FPRG 0x10
131 #define PRG 0x01
133 /* SWIM_CSR */
134 #define SAFE_MASK 0x80
135 #define NO_ACCESS 0x40
136 #define SWIM_DM 0x20
137 #define HS 0x10
138 #define OSCOFF 0x08
139 #define SWIM_RST 0x04
140 #define HSIT 0x02
141 #define PRI 0x01
143 #define SWIM_CSR 0x7f80
145 #define STM8_BREAK 0x8B
147 enum mem_type {
148 RAM,
149 FLASH,
150 EEPROM,
151 OPTION
154 struct stm8_algorithm {
155 int common_magic;
158 struct stm8_core_reg {
159 uint32_t num;
160 struct target *target;
161 struct stm8_common *stm8_common;
164 enum hw_break_type {
165 /* break on execute */
166 HWBRK_EXEC,
167 /* break on read */
168 HWBRK_RD,
169 /* break on write */
170 HWBRK_WR,
171 /* break on read, write and execute */
172 HWBRK_ACC
175 struct stm8_comparator {
176 bool used;
177 uint32_t bp_value;
178 uint32_t reg_address;
179 enum hw_break_type type;
182 static inline struct hl_interface_s *target_to_adapter(struct target *target)
184 return target->tap->priv;
187 static int stm8_adapter_read_memory(struct target *target,
188 uint32_t addr, int size, int count, void *buf)
190 int ret;
191 struct hl_interface_s *adapter = target_to_adapter(target);
193 ret = adapter->layout->api->read_mem(adapter->handle,
194 addr, size, count, buf);
195 if (ret != ERROR_OK)
196 return ret;
197 return ERROR_OK;
200 static int stm8_adapter_write_memory(struct target *target,
201 uint32_t addr, int size, int count, const void *buf)
203 int ret;
204 struct hl_interface_s *adapter = target_to_adapter(target);
206 ret = adapter->layout->api->write_mem(adapter->handle,
207 addr, size, count, buf);
208 if (ret != ERROR_OK)
209 return ret;
210 return ERROR_OK;
213 static int stm8_write_u8(struct target *target,
214 uint32_t addr, uint8_t val)
216 int ret;
217 uint8_t buf[1];
218 struct hl_interface_s *adapter = target_to_adapter(target);
220 buf[0] = val;
221 ret = adapter->layout->api->write_mem(adapter->handle, addr, 1, 1, buf);
222 if (ret != ERROR_OK)
223 return ret;
224 return ERROR_OK;
227 static int stm8_read_u8(struct target *target,
228 uint32_t addr, uint8_t *val)
230 int ret;
231 struct hl_interface_s *adapter = target_to_adapter(target);
233 ret = adapter->layout->api->read_mem(adapter->handle, addr, 1, 1, val);
234 if (ret != ERROR_OK)
235 return ret;
236 return ERROR_OK;
239 static int stm8_set_speed(struct target *target, int speed)
241 struct hl_interface_s *adapter = target_to_adapter(target);
242 adapter->layout->api->speed(adapter->handle, speed, 0);
243 return ERROR_OK;
247 <enable == 0> Disables interrupts.
248 If interrupts are enabled they are masked and the cc register
249 is saved.
251 <enable == 1> Enables interrupts.
252 Enable interrupts is actually restoring I1 I0 state from previous
253 call with enable == 0. Note that if stepping and breaking on a sim
254 instruction will NOT work since the interrupt flags are restored on
255 debug_entry. We don't have any way for the debugger to exclusively
256 disable the interrupts
258 static int stm8_enable_interrupts(struct target *target, int enable)
260 struct stm8_common *stm8 = target_to_stm8(target);
261 uint8_t cc;
263 if (enable) {
264 if (!stm8->cc_valid)
265 return ERROR_OK; /* cc was not stashed */
266 /* fetch current cc */
267 stm8_read_u8(target, DM_REG_CC, &cc);
268 /* clear I1 I0 */
269 cc &= ~(CC_I0 + CC_I1);
270 /* restore I1 & I0 from stash*/
271 cc |= (stm8->cc & (CC_I0+CC_I1));
272 /* update current cc */
273 stm8_write_u8(target, DM_REG_CC, cc);
274 stm8->cc_valid = false;
275 } else {
276 stm8_read_u8(target, DM_REG_CC, &cc);
277 if ((cc & CC_I0) && (cc & CC_I1))
278 return ERROR_OK; /* interrupts already masked */
279 /* stash cc */
280 stm8->cc = cc;
281 stm8->cc_valid = true;
282 /* mask interrupts (disable) */
283 cc |= (CC_I0 + CC_I1);
284 stm8_write_u8(target, DM_REG_CC, cc);
287 return ERROR_OK;
290 static int stm8_set_hwbreak(struct target *target,
291 struct stm8_comparator comparator_list[])
293 uint8_t buf[3];
294 int i, ret;
296 /* Refer to Table 4 in UM0470 */
297 uint8_t bc = 0x5;
298 uint8_t bir = 0;
299 uint8_t biw = 0;
301 uint32_t data;
302 uint32_t addr;
304 if (!comparator_list[0].used) {
305 comparator_list[0].type = HWBRK_EXEC;
306 comparator_list[0].bp_value = -1;
309 if (!comparator_list[1].used) {
310 comparator_list[1].type = HWBRK_EXEC;
311 comparator_list[1].bp_value = -1;
314 if ((comparator_list[0].type == HWBRK_EXEC)
315 && (comparator_list[1].type == HWBRK_EXEC)) {
316 comparator_list[0].reg_address = 0;
317 comparator_list[1].reg_address = 1;
320 if ((comparator_list[0].type == HWBRK_EXEC)
321 && (comparator_list[1].type != HWBRK_EXEC)) {
322 comparator_list[0].reg_address = 0;
323 comparator_list[1].reg_address = 1;
324 switch (comparator_list[1].type) {
325 case HWBRK_RD:
326 bir = 1;
327 break;
328 case HWBRK_WR:
329 biw = 1;
330 break;
331 default:
332 bir = 1;
333 biw = 1;
334 break;
338 if ((comparator_list[1].type == HWBRK_EXEC)
339 && (comparator_list[0].type != HWBRK_EXEC)) {
340 comparator_list[0].reg_address = 1;
341 comparator_list[1].reg_address = 0;
342 switch (comparator_list[0].type) {
343 case HWBRK_RD:
344 bir = 1;
345 break;
346 case HWBRK_WR:
347 biw = 1;
348 break;
349 default:
350 bir = 1;
351 biw = 1;
352 break;
356 if ((comparator_list[0].type != HWBRK_EXEC)
357 && (comparator_list[1].type != HWBRK_EXEC)) {
358 if ((comparator_list[0].type != comparator_list[1].type)) {
359 LOG_ERROR("data hw breakpoints must be of same type");
360 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
364 for (i = 0; i < 2; i++) {
365 data = comparator_list[i].bp_value;
366 addr = comparator_list[i].reg_address;
368 buf[0] = data >> 16;
369 buf[1] = data >> 8;
370 buf[2] = data;
372 if (addr == 0) {
373 ret = stm8_adapter_write_memory(target, DM_BKR1E, 1, 3, buf);
374 LOG_DEBUG("DM_BKR1E=%" PRIx32, data);
375 } else if (addr == 1) {
376 ret = stm8_adapter_write_memory(target, DM_BKR2E, 1, 3, buf);
377 LOG_DEBUG("DM_BKR2E=%" PRIx32, data);
378 } else {
379 LOG_DEBUG("addr=%" PRIu32, addr);
380 return ERROR_FAIL;
383 if (ret != ERROR_OK)
384 return ret;
386 ret = stm8_write_u8(target, DM_CR1,
387 (bc << 3) + (bir << 2) + (biw << 1));
388 LOG_DEBUG("DM_CR1=%" PRIx8, buf[0]);
389 if (ret != ERROR_OK)
390 return ret;
393 return ERROR_OK;
396 /* read DM control and status regs */
397 static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,
398 uint8_t *csr2)
400 int ret;
401 uint8_t buf[2];
403 ret = stm8_adapter_read_memory(target, DM_CSR1, 1, sizeof(buf), buf);
404 if (ret != ERROR_OK)
405 return ret;
406 if (csr1)
407 *csr1 = buf[0];
408 if (csr2)
409 *csr2 = buf[1];
410 return ERROR_OK;
413 /* set or clear the single step flag in DM */
414 static int stm8_config_step(struct target *target, int enable)
416 int ret;
417 uint8_t csr1, csr2;
419 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
420 if (ret != ERROR_OK)
421 return ret;
422 if (enable)
423 csr1 |= STE;
424 else
425 csr1 &= ~STE;
427 ret = stm8_write_u8(target, DM_CSR1, csr1);
428 if (ret != ERROR_OK)
429 return ret;
430 return ERROR_OK;
433 /* set the stall flag in DM */
434 static int stm8_debug_stall(struct target *target)
436 int ret;
437 uint8_t csr1, csr2;
439 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
440 if (ret != ERROR_OK)
441 return ret;
442 csr2 |= STALL;
443 ret = stm8_write_u8(target, DM_CSR2, csr2);
444 if (ret != ERROR_OK)
445 return ret;
446 return ERROR_OK;
449 static int stm8_configure_break_unit(struct target *target)
451 /* get pointers to arch-specific information */
452 struct stm8_common *stm8 = target_to_stm8(target);
454 if (stm8->bp_scanned)
455 return ERROR_OK;
457 stm8->num_hw_bpoints = 2;
458 stm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;
460 stm8->hw_break_list = calloc(stm8->num_hw_bpoints,
461 sizeof(struct stm8_comparator));
463 stm8->hw_break_list[0].reg_address = 0;
464 stm8->hw_break_list[1].reg_address = 1;
466 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8->num_hw_bpoints,
467 stm8->num_hw_bpoints);
469 stm8->bp_scanned = true;
471 return ERROR_OK;
474 static int stm8_examine_debug_reason(struct target *target)
476 int retval;
477 uint8_t csr1, csr2;
479 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
480 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
482 if ((target->debug_reason != DBG_REASON_DBGRQ)
483 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
485 if (retval != ERROR_OK)
486 return retval;
488 if (csr1 & RST)
489 /* halted on reset */
490 target->debug_reason = DBG_REASON_UNDEFINED;
492 if (csr1 & (BK1F+BK2F))
493 /* we have halted on a breakpoint (or wp)*/
494 target->debug_reason = DBG_REASON_BREAKPOINT;
496 if (csr2 & SWBKF)
497 /* we have halted on a breakpoint */
498 target->debug_reason = DBG_REASON_BREAKPOINT;
502 return ERROR_OK;
505 static int stm8_debug_entry(struct target *target)
507 struct stm8_common *stm8 = target_to_stm8(target);
509 /* restore interrupts */
510 stm8_enable_interrupts(target, 1);
512 stm8_save_context(target);
514 /* make sure stepping disabled STE bit in CSR1 cleared */
515 stm8_config_step(target, 0);
517 /* attempt to find halt reason */
518 stm8_examine_debug_reason(target);
520 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
521 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32),
522 target_state_name(target));
524 return ERROR_OK;
527 /* clear stall flag in DM and flush instruction pipe */
528 static int stm8_exit_debug(struct target *target)
530 int ret;
531 uint8_t csr1, csr2;
533 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
534 if (ret != ERROR_OK)
535 return ret;
536 csr2 |= FLUSH;
537 ret = stm8_write_u8(target, DM_CSR2, csr2);
538 if (ret != ERROR_OK)
539 return ret;
541 csr2 &= ~STALL;
542 csr2 |= SWBRK;
543 ret = stm8_write_u8(target, DM_CSR2, csr2);
544 if (ret != ERROR_OK)
545 return ret;
546 return ERROR_OK;
549 static int stm8_read_regs(struct target *target, uint32_t regs[])
551 int ret;
552 uint8_t buf[11];
554 ret = stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);
555 if (ret != ERROR_OK)
556 return ret;
558 regs[0] = be_to_h_u24(buf+DM_REG_PC-DM_REGS);
559 regs[1] = buf[DM_REG_A-DM_REGS];
560 regs[2] = be_to_h_u16(buf+DM_REG_X-DM_REGS);
561 regs[3] = be_to_h_u16(buf+DM_REG_Y-DM_REGS);
562 regs[4] = be_to_h_u16(buf+DM_REG_SP-DM_REGS);
563 regs[5] = buf[DM_REG_CC-DM_REGS];
565 return ERROR_OK;
568 static int stm8_write_regs(struct target *target, uint32_t regs[])
570 int ret;
571 uint8_t buf[11];
573 h_u24_to_be(buf+DM_REG_PC-DM_REGS, regs[0]);
574 buf[DM_REG_A-DM_REGS] = regs[1];
575 h_u16_to_be(buf+DM_REG_X-DM_REGS, regs[2]);
576 h_u16_to_be(buf+DM_REG_Y-DM_REGS, regs[3]);
577 h_u16_to_be(buf+DM_REG_SP-DM_REGS, regs[4]);
578 buf[DM_REG_CC-DM_REGS] = regs[5];
580 ret = stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);
581 if (ret != ERROR_OK)
582 return ret;
584 return ERROR_OK;
587 static int stm8_get_core_reg(struct reg *reg)
589 int retval;
590 struct stm8_core_reg *stm8_reg = reg->arch_info;
591 struct target *target = stm8_reg->target;
592 struct stm8_common *stm8_target = target_to_stm8(target);
594 if (target->state != TARGET_HALTED)
595 return ERROR_TARGET_NOT_HALTED;
597 retval = stm8_target->read_core_reg(target, stm8_reg->num);
599 return retval;
602 static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
604 struct stm8_core_reg *stm8_reg = reg->arch_info;
605 struct target *target = stm8_reg->target;
606 uint32_t value = buf_get_u32(buf, 0, reg->size);
608 if (target->state != TARGET_HALTED)
609 return ERROR_TARGET_NOT_HALTED;
611 buf_set_u32(reg->value, 0, 32, value);
612 reg->dirty = true;
613 reg->valid = true;
615 return ERROR_OK;
618 static int stm8_save_context(struct target *target)
620 unsigned int i;
622 /* get pointers to arch-specific information */
623 struct stm8_common *stm8 = target_to_stm8(target);
625 /* read core registers */
626 stm8_read_regs(target, stm8->core_regs);
628 for (i = 0; i < STM8_NUM_REGS; i++) {
629 if (!stm8->core_cache->reg_list[i].valid)
630 stm8->read_core_reg(target, i);
633 return ERROR_OK;
636 static int stm8_restore_context(struct target *target)
638 unsigned int i;
640 /* get pointers to arch-specific information */
641 struct stm8_common *stm8 = target_to_stm8(target);
643 for (i = 0; i < STM8_NUM_REGS; i++) {
644 if (stm8->core_cache->reg_list[i].dirty)
645 stm8->write_core_reg(target, i);
648 /* write core regs */
649 stm8_write_regs(target, stm8->core_regs);
651 return ERROR_OK;
654 static int stm8_unlock_flash(struct target *target)
656 uint8_t data[1];
658 struct stm8_common *stm8 = target_to_stm8(target);
660 /* check if flash is unlocked */
661 stm8_read_u8(target, stm8->flash_iapsr, data);
662 if (~data[0] & PUL) {
663 /* unlock flash */
664 stm8_write_u8(target, stm8->flash_pukr, 0x56);
665 stm8_write_u8(target, stm8->flash_pukr, 0xae);
668 stm8_read_u8(target, stm8->flash_iapsr, data);
669 if (~data[0] & PUL)
670 return ERROR_FAIL;
671 return ERROR_OK;
674 static int stm8_unlock_eeprom(struct target *target)
676 uint8_t data[1];
678 struct stm8_common *stm8 = target_to_stm8(target);
680 /* check if eeprom is unlocked */
681 stm8_read_u8(target, stm8->flash_iapsr, data);
682 if (~data[0] & DUL) {
683 /* unlock eeprom */
684 stm8_write_u8(target, stm8->flash_dukr, 0xae);
685 stm8_write_u8(target, stm8->flash_dukr, 0x56);
688 stm8_read_u8(target, stm8->flash_iapsr, data);
689 if (~data[0] & DUL)
690 return ERROR_FAIL;
691 return ERROR_OK;
694 static int stm8_write_flash(struct target *target, enum mem_type type,
695 uint32_t address,
696 uint32_t size, uint32_t count, uint32_t blocksize_param,
697 const uint8_t *buffer)
699 struct stm8_common *stm8 = target_to_stm8(target);
701 uint8_t iapsr;
702 uint8_t opt = 0;
703 unsigned int i;
704 uint32_t blocksize = 0;
705 uint32_t bytecnt;
706 int res;
708 switch (type) {
709 case (FLASH):
710 stm8_unlock_flash(target);
711 break;
712 case (EEPROM):
713 stm8_unlock_eeprom(target);
714 break;
715 case (OPTION):
716 stm8_unlock_eeprom(target);
717 opt = OPT;
718 break;
719 default:
720 LOG_ERROR("BUG: wrong mem_type %d", type);
721 assert(0);
724 if (size == 2) {
725 /* we don't support short writes */
726 count = count * 2;
727 size = 1;
730 bytecnt = count * size;
732 while (bytecnt) {
733 if ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {
734 if (stm8->flash_cr2)
735 stm8_write_u8(target, stm8->flash_cr2, PRG + opt);
736 if (stm8->flash_ncr2)
737 stm8_write_u8(target, stm8->flash_ncr2, ~(PRG + opt));
738 blocksize = blocksize_param;
739 } else
740 if ((bytecnt >= 4) && ((address & 0x3) == 0)) {
741 if (stm8->flash_cr2)
742 stm8_write_u8(target, stm8->flash_cr2, WPRG + opt);
743 if (stm8->flash_ncr2)
744 stm8_write_u8(target, stm8->flash_ncr2, ~(WPRG + opt));
745 blocksize = 4;
746 } else
747 if (blocksize != 1) {
748 if (stm8->flash_cr2)
749 stm8_write_u8(target, stm8->flash_cr2, opt);
750 if (stm8->flash_ncr2)
751 stm8_write_u8(target, stm8->flash_ncr2, ~opt);
752 blocksize = 1;
755 res = stm8_adapter_write_memory(target, address, 1, blocksize, buffer);
756 if (res != ERROR_OK)
757 return res;
758 address += blocksize;
759 buffer += blocksize;
760 bytecnt -= blocksize;
762 /* lets hang here until end of program (EOP) */
763 for (i = 0; i < 16; i++) {
764 stm8_read_u8(target, stm8->flash_iapsr, &iapsr);
765 if (iapsr & EOP)
766 break;
767 else
768 usleep(1000);
770 if (i == 16)
771 return ERROR_FAIL;
774 /* disable write access */
775 res = stm8_write_u8(target, stm8->flash_iapsr, 0x0);
777 if (res != ERROR_OK)
778 return ERROR_FAIL;
780 return ERROR_OK;
783 static int stm8_write_memory(struct target *target, target_addr_t address,
784 uint32_t size, uint32_t count,
785 const uint8_t *buffer)
787 struct stm8_common *stm8 = target_to_stm8(target);
789 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
790 ", size: 0x%8.8" PRIx32
791 ", count: 0x%8.8" PRIx32,
792 address, size, count);
794 if (target->state != TARGET_HALTED)
795 LOG_WARNING("target not halted");
797 int retval;
799 if ((address >= stm8->flashstart) && (address <= stm8->flashend))
800 retval = stm8_write_flash(target, FLASH, address, size, count,
801 stm8->blocksize, buffer);
802 else if ((address >= stm8->eepromstart) && (address <= stm8->eepromend))
803 retval = stm8_write_flash(target, EEPROM, address, size, count,
804 stm8->blocksize, buffer);
805 else if ((address >= stm8->optionstart) && (address <= stm8->optionend))
806 retval = stm8_write_flash(target, OPTION, address, size, count, 0, buffer);
807 else
808 retval = stm8_adapter_write_memory(target, address, size, count,
809 buffer);
811 if (retval != ERROR_OK)
812 return ERROR_TARGET_FAILURE;
814 return retval;
817 static int stm8_read_memory(struct target *target, target_addr_t address,
818 uint32_t size, uint32_t count, uint8_t *buffer)
820 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
821 ", size: 0x%8.8" PRIx32
822 ", count: 0x%8.8" PRIx32,
823 address, size, count);
825 if (target->state != TARGET_HALTED)
826 LOG_WARNING("target not halted");
828 int retval;
829 retval = stm8_adapter_read_memory(target, address, size, count, buffer);
831 if (retval != ERROR_OK)
832 return ERROR_TARGET_FAILURE;
834 return retval;
837 static int stm8_init(struct command_context *cmd_ctx, struct target *target)
839 stm8_build_reg_cache(target);
841 return ERROR_OK;
844 static int stm8_poll(struct target *target)
846 int retval = ERROR_OK;
847 uint8_t csr1, csr2;
849 #ifdef LOG_STM8
850 LOG_DEBUG("target->state=%d", target->state);
851 #endif
853 /* read dm_csrx control regs */
854 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
855 if (retval != ERROR_OK) {
856 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval);
858 We return ERROR_OK here even if we didn't get an answer.
859 openocd will call target_wait_state until we get target state TARGET_HALTED
861 return ERROR_OK;
864 /* check for processor halted */
865 if (csr2 & STALL) {
866 if (target->state != TARGET_HALTED) {
867 if (target->state == TARGET_UNKNOWN)
868 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
870 retval = stm8_debug_entry(target);
871 if (retval != ERROR_OK) {
872 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval);
873 return ERROR_TARGET_FAILURE;
876 if (target->state == TARGET_DEBUG_RUNNING) {
877 target->state = TARGET_HALTED;
878 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
879 } else {
880 target->state = TARGET_HALTED;
881 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
884 } else
885 target->state = TARGET_RUNNING;
886 #ifdef LOG_STM8
887 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
888 #endif
889 return ERROR_OK;
892 static int stm8_halt(struct target *target)
894 LOG_DEBUG("target->state: %s", target_state_name(target));
896 if (target->state == TARGET_HALTED) {
897 LOG_DEBUG("target was already halted");
898 return ERROR_OK;
901 if (target->state == TARGET_UNKNOWN)
902 LOG_WARNING("target was in unknown state when halt was requested");
904 if (target->state == TARGET_RESET) {
905 /* we came here in a reset_halt or reset_init sequence
906 * debug entry was already prepared in stm8_assert_reset()
908 target->debug_reason = DBG_REASON_DBGRQ;
910 return ERROR_OK;
914 /* break processor */
915 stm8_debug_stall(target);
917 target->debug_reason = DBG_REASON_DBGRQ;
919 return ERROR_OK;
922 static int stm8_reset_assert(struct target *target)
924 int res = ERROR_OK;
925 struct hl_interface_s *adapter = target_to_adapter(target);
926 struct stm8_common *stm8 = target_to_stm8(target);
927 bool use_srst_fallback = true;
929 enum reset_types jtag_reset_config = jtag_get_reset_config();
931 if (jtag_reset_config & RESET_HAS_SRST) {
932 jtag_add_reset(0, 1);
933 res = adapter->layout->api->assert_srst(adapter->handle, 0);
935 if (res == ERROR_OK)
936 /* hardware srst supported */
937 use_srst_fallback = false;
938 else if (res != ERROR_COMMAND_NOTFOUND)
939 /* some other failure */
940 return res;
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);
946 if (res != ERROR_OK)
947 return res;
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);
958 if (res != ERROR_OK)
959 return res;
962 return ERROR_OK;
965 static int stm8_reset_deassert(struct target *target)
967 int res;
968 struct hl_interface_s *adapter = target_to_adapter(target);
970 enum reset_types jtag_reset_config = jtag_get_reset_config();
972 if (jtag_reset_config & RESET_HAS_SRST) {
973 res = adapter->layout->api->assert_srst(adapter->handle, 1);
974 if ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND))
975 return res;
978 /* virtual deassert reset, we need it for the internal
979 * jtag state machine
981 jtag_add_reset(0, 0);
983 /* The cpu should now be stalled. If halt was requested
984 let poll detect the stall */
985 if (target->reset_halt)
986 return ERROR_OK;
988 /* Instead of going thrugh saving context, polling and
989 then resuming target again just clear stall and proceed. */
990 target->state = TARGET_RUNNING;
991 return stm8_exit_debug(target);
994 /* stm8_single_step_core() is only used for stepping over breakpoints
995 from stm8_resume() */
996 static int stm8_single_step_core(struct target *target)
998 struct stm8_common *stm8 = target_to_stm8(target);
1000 /* configure single step mode */
1001 stm8_config_step(target, 1);
1003 /* disable interrupts while stepping */
1004 if (!stm8->enable_step_irq)
1005 stm8_enable_interrupts(target, 0);
1007 /* exit debug mode */
1008 stm8_exit_debug(target);
1010 stm8_debug_entry(target);
1012 return ERROR_OK;
1015 static int stm8_resume(struct target *target, int current,
1016 target_addr_t address, int handle_breakpoints,
1017 int debug_execution)
1019 struct stm8_common *stm8 = target_to_stm8(target);
1020 struct breakpoint *breakpoint = NULL;
1021 uint32_t resume_pc;
1023 LOG_DEBUG("%d " TARGET_ADDR_FMT " %d %d", current, address,
1024 handle_breakpoints, debug_execution);
1026 if (target->state != TARGET_HALTED) {
1027 LOG_WARNING("target not halted");
1028 return ERROR_TARGET_NOT_HALTED;
1031 if (!debug_execution) {
1032 target_free_all_working_areas(target);
1033 stm8_enable_breakpoints(target);
1034 stm8_enable_watchpoints(target);
1035 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1036 stm8_set_hwbreak(target, comparator_list);
1039 /* current = 1: continue on current pc,
1040 otherwise continue at <address> */
1041 if (!current) {
1042 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value,
1043 0, 32, address);
1044 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1045 stm8->core_cache->reg_list[STM8_PC].valid = true;
1048 if (!current)
1049 resume_pc = address;
1050 else
1051 resume_pc = buf_get_u32(
1052 stm8->core_cache->reg_list[STM8_PC].value,
1053 0, 32);
1055 stm8_restore_context(target);
1057 /* the front-end may request us not to handle breakpoints */
1058 if (handle_breakpoints) {
1059 /* Single step past breakpoint at current address */
1060 breakpoint = breakpoint_find(target, resume_pc);
1061 if (breakpoint) {
1062 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT,
1063 breakpoint->address);
1064 stm8_unset_breakpoint(target, breakpoint);
1065 stm8_single_step_core(target);
1066 stm8_set_breakpoint(target, breakpoint);
1070 /* disable interrupts if we are debugging */
1071 if (debug_execution)
1072 stm8_enable_interrupts(target, 0);
1074 /* exit debug mode */
1075 stm8_exit_debug(target);
1076 target->debug_reason = DBG_REASON_NOTHALTED;
1078 /* registers are now invalid */
1079 register_cache_invalidate(stm8->core_cache);
1081 if (!debug_execution) {
1082 target->state = TARGET_RUNNING;
1083 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1084 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
1085 } else {
1086 target->state = TARGET_DEBUG_RUNNING;
1087 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1088 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
1091 return ERROR_OK;
1094 static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
1096 stm8->enable_stm8l = enable_stm8l;
1098 if (stm8->enable_stm8l) {
1099 stm8->flash_cr2 = FLASH_CR2_STM8L;
1100 stm8->flash_ncr2 = FLASH_NCR2_STM8L;
1101 stm8->flash_iapsr = FLASH_IAPSR_STM8L;
1102 stm8->flash_dukr = FLASH_DUKR_STM8L;
1103 stm8->flash_pukr = FLASH_PUKR_STM8L;
1104 } else {
1105 stm8->flash_cr2 = FLASH_CR2_STM8S;
1106 stm8->flash_ncr2 = FLASH_NCR2_STM8S;
1107 stm8->flash_iapsr = FLASH_IAPSR_STM8S;
1108 stm8->flash_dukr = FLASH_DUKR_STM8S;
1109 stm8->flash_pukr = FLASH_PUKR_STM8S;
1111 return ERROR_OK;
1114 static int stm8_init_arch_info(struct target *target,
1115 struct stm8_common *stm8, struct jtag_tap *tap)
1117 target->endianness = TARGET_BIG_ENDIAN;
1118 target->arch_info = stm8;
1119 stm8->common_magic = STM8_COMMON_MAGIC;
1120 stm8->fast_data_area = NULL;
1121 stm8->blocksize = 0x80;
1122 stm8->flashstart = 0x8000;
1123 stm8->flashend = 0xffff;
1124 stm8->eepromstart = 0x4000;
1125 stm8->eepromend = 0x43ff;
1126 stm8->optionstart = 0x4800;
1127 stm8->optionend = 0x487F;
1129 /* has breakpoint/watchpoint unit been scanned */
1130 stm8->bp_scanned = false;
1131 stm8->hw_break_list = NULL;
1133 stm8->read_core_reg = stm8_read_core_reg;
1134 stm8->write_core_reg = stm8_write_core_reg;
1136 stm8_init_flash_regs(0, stm8);
1138 return ERROR_OK;
1141 static int stm8_target_create(struct target *target,
1142 Jim_Interp *interp)
1145 struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));
1147 stm8_init_arch_info(target, stm8, target->tap);
1148 stm8_configure_break_unit(target);
1150 return ERROR_OK;
1153 static int stm8_read_core_reg(struct target *target, unsigned int num)
1155 uint32_t reg_value;
1157 /* get pointers to arch-specific information */
1158 struct stm8_common *stm8 = target_to_stm8(target);
1160 if (num >= STM8_NUM_REGS)
1161 return ERROR_COMMAND_SYNTAX_ERROR;
1163 reg_value = stm8->core_regs[num];
1164 LOG_DEBUG("read core reg %i value 0x%" PRIx32 "", num , reg_value);
1165 buf_set_u32(stm8->core_cache->reg_list[num].value, 0, 32, reg_value);
1166 stm8->core_cache->reg_list[num].valid = true;
1167 stm8->core_cache->reg_list[num].dirty = false;
1169 return ERROR_OK;
1172 static int stm8_write_core_reg(struct target *target, unsigned int num)
1174 uint32_t reg_value;
1176 /* get pointers to arch-specific information */
1177 struct stm8_common *stm8 = target_to_stm8(target);
1179 if (num >= STM8_NUM_REGS)
1180 return ERROR_COMMAND_SYNTAX_ERROR;
1182 reg_value = buf_get_u32(stm8->core_cache->reg_list[num].value, 0, 32);
1183 stm8->core_regs[num] = reg_value;
1184 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
1185 stm8->core_cache->reg_list[num].valid = true;
1186 stm8->core_cache->reg_list[num].dirty = false;
1188 return ERROR_OK;
1191 static int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
1192 int *reg_list_size, enum target_register_class reg_class)
1194 /* get pointers to arch-specific information */
1195 struct stm8_common *stm8 = target_to_stm8(target);
1196 unsigned int i;
1198 *reg_list_size = STM8_NUM_REGS;
1199 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1201 for (i = 0; i < STM8_NUM_REGS; i++)
1202 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1204 return ERROR_OK;
1207 static const struct reg_arch_type stm8_reg_type = {
1208 .get = stm8_get_core_reg,
1209 .set = stm8_set_core_reg,
1212 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1214 /* get pointers to arch-specific information */
1215 struct stm8_common *stm8 = target_to_stm8(target);
1217 int num_regs = STM8_NUM_REGS;
1218 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1219 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1220 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1221 struct stm8_core_reg *arch_info = malloc(
1222 sizeof(struct stm8_core_reg) * num_regs);
1223 struct reg_feature *feature;
1224 int i;
1226 /* Build the process context cache */
1227 cache->name = "stm8 registers";
1228 cache->next = NULL;
1229 cache->reg_list = reg_list;
1230 cache->num_regs = num_regs;
1231 (*cache_p) = cache;
1232 stm8->core_cache = cache;
1234 for (i = 0; i < num_regs; i++) {
1235 arch_info[i].num = stm8_regs[i].id;
1236 arch_info[i].target = target;
1237 arch_info[i].stm8_common = stm8;
1239 reg_list[i].name = stm8_regs[i].name;
1240 reg_list[i].size = stm8_regs[i].bits;
1242 reg_list[i].value = calloc(1, 4);
1243 reg_list[i].valid = false;
1244 reg_list[i].type = &stm8_reg_type;
1245 reg_list[i].arch_info = &arch_info[i];
1247 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1248 if (reg_list[i].reg_data_type)
1249 reg_list[i].reg_data_type->type = stm8_regs[i].type;
1250 else {
1251 LOG_ERROR("unable to allocate reg type list");
1252 return NULL;
1255 reg_list[i].dirty = false;
1256 reg_list[i].group = stm8_regs[i].group;
1257 reg_list[i].number = stm8_regs[i].id;
1258 reg_list[i].exist = true;
1259 reg_list[i].caller_save = true; /* gdb defaults to true */
1261 feature = calloc(1, sizeof(struct reg_feature));
1262 if (feature) {
1263 feature->name = stm8_regs[i].feature;
1264 reg_list[i].feature = feature;
1265 } else
1266 LOG_ERROR("unable to allocate feature list");
1269 return cache;
1272 static void stm8_free_reg_cache(struct target *target)
1274 struct stm8_common *stm8 = target_to_stm8(target);
1275 struct reg_cache *cache;
1276 struct reg *reg;
1277 unsigned int i;
1279 cache = stm8->core_cache;
1281 if (!cache)
1282 return;
1284 for (i = 0; i < cache->num_regs; i++) {
1285 reg = &cache->reg_list[i];
1287 free(reg->feature);
1288 free(reg->reg_data_type);
1289 free(reg->value);
1292 free(cache->reg_list[0].arch_info);
1293 free(cache->reg_list);
1294 free(cache);
1296 stm8->core_cache = NULL;
1299 static void stm8_deinit(struct target *target)
1301 struct stm8_common *stm8 = target_to_stm8(target);
1303 free(stm8->hw_break_list);
1305 stm8_free_reg_cache(target);
1307 free(stm8);
1310 static int stm8_arch_state(struct target *target)
1312 struct stm8_common *stm8 = target_to_stm8(target);
1314 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
1315 debug_reason_name(target),
1316 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1318 return ERROR_OK;
1321 static int stm8_step(struct target *target, int current,
1322 target_addr_t address, int handle_breakpoints)
1324 LOG_DEBUG("%" PRIx32 " " TARGET_ADDR_FMT " %" PRIx32,
1325 current, address, handle_breakpoints);
1327 /* get pointers to arch-specific information */
1328 struct stm8_common *stm8 = target_to_stm8(target);
1329 struct breakpoint *breakpoint = NULL;
1331 if (target->state != TARGET_HALTED) {
1332 LOG_WARNING("target not halted");
1333 return ERROR_TARGET_NOT_HALTED;
1336 /* current = 1: continue on current pc, otherwise continue at <address> */
1337 if (!current) {
1338 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);
1339 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1340 stm8->core_cache->reg_list[STM8_PC].valid = true;
1343 /* the front-end may request us not to handle breakpoints */
1344 if (handle_breakpoints) {
1345 breakpoint = breakpoint_find(target,
1346 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1347 if (breakpoint)
1348 stm8_unset_breakpoint(target, breakpoint);
1351 /* restore context */
1352 stm8_restore_context(target);
1354 /* configure single step mode */
1355 stm8_config_step(target, 1);
1357 target->debug_reason = DBG_REASON_SINGLESTEP;
1359 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1361 /* disable interrupts while stepping */
1362 if (!stm8->enable_step_irq)
1363 stm8_enable_interrupts(target, 0);
1365 /* exit debug mode */
1366 stm8_exit_debug(target);
1368 /* registers are now invalid */
1369 register_cache_invalidate(stm8->core_cache);
1371 LOG_DEBUG("target stepped ");
1372 stm8_debug_entry(target);
1374 if (breakpoint)
1375 stm8_set_breakpoint(target, breakpoint);
1377 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1379 return ERROR_OK;
1382 static void stm8_enable_breakpoints(struct target *target)
1384 struct breakpoint *breakpoint = target->breakpoints;
1386 /* set any pending breakpoints */
1387 while (breakpoint) {
1388 if (breakpoint->set == 0)
1389 stm8_set_breakpoint(target, breakpoint);
1390 breakpoint = breakpoint->next;
1394 static int stm8_set_breakpoint(struct target *target,
1395 struct breakpoint *breakpoint)
1397 struct stm8_common *stm8 = target_to_stm8(target);
1398 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1399 int retval;
1401 if (breakpoint->set) {
1402 LOG_WARNING("breakpoint already set");
1403 return ERROR_OK;
1406 if (breakpoint->type == BKPT_HARD) {
1407 int bp_num = 0;
1409 while (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))
1410 bp_num++;
1411 if (bp_num >= stm8->num_hw_bpoints) {
1412 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32 ")",
1413 breakpoint->unique_id);
1414 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1416 breakpoint->set = bp_num + 1;
1417 comparator_list[bp_num].used = true;
1418 comparator_list[bp_num].bp_value = breakpoint->address;
1419 comparator_list[bp_num].type = HWBRK_EXEC;
1421 retval = stm8_set_hwbreak(target, comparator_list);
1422 if (retval != ERROR_OK)
1423 return retval;
1425 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
1426 breakpoint->unique_id,
1427 bp_num, comparator_list[bp_num].bp_value);
1428 } else if (breakpoint->type == BKPT_SOFT) {
1429 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1430 if (breakpoint->length == 1) {
1431 uint8_t verify = 0x55;
1433 retval = target_read_u8(target, breakpoint->address,
1434 breakpoint->orig_instr);
1435 if (retval != ERROR_OK)
1436 return retval;
1437 retval = target_write_u8(target, breakpoint->address, STM8_BREAK);
1438 if (retval != ERROR_OK)
1439 return retval;
1441 retval = target_read_u8(target, breakpoint->address, &verify);
1442 if (retval != ERROR_OK)
1443 return retval;
1444 if (verify != STM8_BREAK) {
1445 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1446 " - check that memory is read/writable",
1447 breakpoint->address);
1448 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1450 } else {
1451 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1453 breakpoint->set = 1; /* Any nice value but 0 */
1456 return ERROR_OK;
1459 static int stm8_add_breakpoint(struct target *target,
1460 struct breakpoint *breakpoint)
1462 struct stm8_common *stm8 = target_to_stm8(target);
1463 int ret;
1465 if (breakpoint->type == BKPT_HARD) {
1466 if (stm8->num_hw_bpoints_avail < 1) {
1467 LOG_INFO("no hardware breakpoint available");
1468 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1471 ret = stm8_set_breakpoint(target, breakpoint);
1472 if (ret != ERROR_OK)
1473 return ret;
1475 stm8->num_hw_bpoints_avail--;
1476 return ERROR_OK;
1479 ret = stm8_set_breakpoint(target, breakpoint);
1480 if (ret != ERROR_OK)
1481 return ret;
1483 return ERROR_OK;
1486 static int stm8_unset_breakpoint(struct target *target,
1487 struct breakpoint *breakpoint)
1489 /* get pointers to arch-specific information */
1490 struct stm8_common *stm8 = target_to_stm8(target);
1491 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1492 int retval;
1494 if (!breakpoint->set) {
1495 LOG_WARNING("breakpoint not set");
1496 return ERROR_OK;
1499 if (breakpoint->type == BKPT_HARD) {
1500 int bp_num = breakpoint->set - 1;
1501 if ((bp_num < 0) || (bp_num >= stm8->num_hw_bpoints)) {
1502 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
1503 breakpoint->unique_id);
1504 return ERROR_OK;
1506 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
1507 breakpoint->unique_id,
1508 bp_num);
1509 comparator_list[bp_num].used = false;
1510 retval = stm8_set_hwbreak(target, comparator_list);
1511 if (retval != ERROR_OK)
1512 return retval;
1513 } else {
1514 /* restore original instruction (kept in target endianness) */
1515 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1516 if (breakpoint->length == 1) {
1517 uint8_t current_instr;
1519 /* check that user program has not
1520 modified breakpoint instruction */
1521 retval = target_read_memory(target, breakpoint->address, 1, 1,
1522 (uint8_t *)&current_instr);
1523 if (retval != ERROR_OK)
1524 return retval;
1526 if (current_instr == STM8_BREAK) {
1527 retval = target_write_memory(target, breakpoint->address, 1, 1,
1528 breakpoint->orig_instr);
1529 if (retval != ERROR_OK)
1530 return retval;
1532 } else
1533 return ERROR_FAIL;
1535 breakpoint->set = 0;
1537 return ERROR_OK;
1540 static int stm8_remove_breakpoint(struct target *target,
1541 struct breakpoint *breakpoint)
1543 /* get pointers to arch-specific information */
1544 struct stm8_common *stm8 = target_to_stm8(target);
1546 if (target->state != TARGET_HALTED) {
1547 LOG_WARNING("target not halted");
1548 return ERROR_TARGET_NOT_HALTED;
1551 if (breakpoint->set)
1552 stm8_unset_breakpoint(target, breakpoint);
1554 if (breakpoint->type == BKPT_HARD)
1555 stm8->num_hw_bpoints_avail++;
1557 return ERROR_OK;
1560 static int stm8_set_watchpoint(struct target *target,
1561 struct watchpoint *watchpoint)
1563 struct stm8_common *stm8 = target_to_stm8(target);
1564 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1565 int wp_num = 0;
1566 int ret;
1568 if (watchpoint->set) {
1569 LOG_WARNING("watchpoint already set");
1570 return ERROR_OK;
1573 while (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))
1574 wp_num++;
1575 if (wp_num >= stm8->num_hw_bpoints) {
1576 LOG_ERROR("Can not find free hw breakpoint");
1577 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1580 if (watchpoint->length != 1) {
1581 LOG_ERROR("Only watchpoints of length 1 are supported");
1582 return ERROR_TARGET_UNALIGNED_ACCESS;
1585 enum hw_break_type enable = 0;
1587 switch (watchpoint->rw) {
1588 case WPT_READ:
1589 enable = HWBRK_RD;
1590 break;
1591 case WPT_WRITE:
1592 enable = HWBRK_WR;
1593 break;
1594 case WPT_ACCESS:
1595 enable = HWBRK_ACC;
1596 break;
1597 default:
1598 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1601 comparator_list[wp_num].used = true;
1602 comparator_list[wp_num].bp_value = watchpoint->address;
1603 comparator_list[wp_num].type = enable;
1605 ret = stm8_set_hwbreak(target, comparator_list);
1606 if (ret != ERROR_OK) {
1607 comparator_list[wp_num].used = false;
1608 return ret;
1611 watchpoint->set = wp_num + 1;
1613 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1614 wp_num,
1615 comparator_list[wp_num].bp_value);
1617 return ERROR_OK;
1620 static int stm8_add_watchpoint(struct target *target,
1621 struct watchpoint *watchpoint)
1623 int ret;
1624 struct stm8_common *stm8 = target_to_stm8(target);
1626 if (stm8->num_hw_bpoints_avail < 1) {
1627 LOG_INFO("no hardware watchpoints available");
1628 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1631 ret = stm8_set_watchpoint(target, watchpoint);
1632 if (ret != ERROR_OK)
1633 return ret;
1635 stm8->num_hw_bpoints_avail--;
1636 return ERROR_OK;
1639 static void stm8_enable_watchpoints(struct target *target)
1641 struct watchpoint *watchpoint = target->watchpoints;
1643 /* set any pending watchpoints */
1644 while (watchpoint) {
1645 if (watchpoint->set == 0)
1646 stm8_set_watchpoint(target, watchpoint);
1647 watchpoint = watchpoint->next;
1651 static int stm8_unset_watchpoint(struct target *target,
1652 struct watchpoint *watchpoint)
1654 /* get pointers to arch-specific information */
1655 struct stm8_common *stm8 = target_to_stm8(target);
1656 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1658 if (!watchpoint->set) {
1659 LOG_WARNING("watchpoint not set");
1660 return ERROR_OK;
1663 int wp_num = watchpoint->set - 1;
1664 if ((wp_num < 0) || (wp_num >= stm8->num_hw_bpoints)) {
1665 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1666 return ERROR_OK;
1668 comparator_list[wp_num].used = false;
1669 watchpoint->set = 0;
1671 stm8_set_hwbreak(target, comparator_list);
1673 return ERROR_OK;
1676 static int stm8_remove_watchpoint(struct target *target,
1677 struct watchpoint *watchpoint)
1679 /* get pointers to arch-specific information */
1680 struct stm8_common *stm8 = target_to_stm8(target);
1682 if (target->state != TARGET_HALTED) {
1683 LOG_WARNING("target not halted");
1684 return ERROR_TARGET_NOT_HALTED;
1687 if (watchpoint->set)
1688 stm8_unset_watchpoint(target, watchpoint);
1690 stm8->num_hw_bpoints_avail++;
1692 return ERROR_OK;
1695 static int stm8_examine(struct target *target)
1697 int retval;
1698 uint8_t csr1, csr2;
1699 /* get pointers to arch-specific information */
1700 struct stm8_common *stm8 = target_to_stm8(target);
1701 struct hl_interface_s *adapter = target_to_adapter(target);
1703 if (!target_was_examined(target)) {
1704 if (!stm8->swim_configured) {
1705 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1706 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1707 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM);
1708 if (retval != ERROR_OK)
1709 return retval;
1710 /* set high speed */
1711 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1712 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS);
1713 if (retval != ERROR_OK)
1714 return retval;
1715 retval = stm8_set_speed(target, 1);
1716 if (retval == ERROR_OK)
1717 stm8->swim_configured = true;
1719 Now is the time to deassert reset if connect_under_reset.
1720 Releasing reset line will cause the option bytes to load.
1721 The core will still be stalled.
1723 if (adapter->param.connect_under_reset)
1724 stm8_reset_deassert(target);
1725 } else {
1726 LOG_INFO("trying to reconnect");
1728 retval = adapter->layout->api->state(adapter->handle);
1729 if (retval != ERROR_OK) {
1730 LOG_ERROR("reconnect failed");
1731 return ERROR_FAIL;
1734 /* read dm_csrx control regs */
1735 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
1736 if (retval != ERROR_OK) {
1737 LOG_ERROR("state query failed");
1738 return ERROR_FAIL;
1742 target_set_examined(target);
1744 return ERROR_OK;
1747 return ERROR_OK;
1750 /** Checks whether a memory region is erased. */
1751 static int stm8_blank_check_memory(struct target *target,
1752 target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
1754 struct working_area *erase_check_algorithm;
1755 struct reg_param reg_params[2];
1756 struct mem_param mem_params[2];
1757 struct stm8_algorithm stm8_info;
1759 static const uint8_t stm8_erase_check_code[] = {
1760 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1763 if (erased_value != 0xff) {
1764 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for STM8",
1765 erased_value);
1766 return ERROR_FAIL;
1769 /* make sure we have a working area */
1770 if (target_alloc_working_area(target, sizeof(stm8_erase_check_code),
1771 &erase_check_algorithm) != ERROR_OK)
1772 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1774 target_write_buffer(target, erase_check_algorithm->address,
1775 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1777 stm8_info.common_magic = STM8_COMMON_MAGIC;
1779 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1780 buf_set_u32(mem_params[0].value, 0, 24, address);
1782 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1783 buf_set_u32(mem_params[1].value, 0, 24, count);
1785 init_reg_param(&reg_params[0], "a", 32, PARAM_IN_OUT);
1786 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1788 init_reg_param(&reg_params[1], "sp", 32, PARAM_OUT);
1789 buf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);
1791 int retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,
1792 erase_check_algorithm->address + 6,
1793 erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
1794 10000, &stm8_info);
1796 if (retval == ERROR_OK)
1797 *blank = (*(reg_params[0].value) == 0xff);
1799 destroy_mem_param(&mem_params[0]);
1800 destroy_mem_param(&mem_params[1]);
1801 destroy_reg_param(&reg_params[0]);
1803 target_free_working_area(target, erase_check_algorithm);
1805 return retval;
1808 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1809 uint32_t count, uint32_t *checksum)
1811 /* let image_calculate_checksum() take care of business */
1812 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1815 /* run to exit point. return error if exit point was not reached. */
1816 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1817 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1819 uint32_t pc;
1820 int retval;
1821 /* This code relies on the target specific resume() and
1822 poll()->debug_entry() sequence to write register values to the
1823 processor and the read them back */
1824 retval = target_resume(target, 0, entry_point, 0, 1);
1825 if (retval != ERROR_OK)
1826 return retval;
1828 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1829 /* If the target fails to halt due to the breakpoint, force a halt */
1830 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1831 retval = target_halt(target);
1832 if (retval != ERROR_OK)
1833 return retval;
1834 retval = target_wait_state(target, TARGET_HALTED, 500);
1835 if (retval != ERROR_OK)
1836 return retval;
1837 return ERROR_TARGET_TIMEOUT;
1840 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1841 if (exit_point && (pc != exit_point)) {
1842 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1843 return ERROR_TARGET_TIMEOUT;
1846 return ERROR_OK;
1849 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1850 struct mem_param *mem_params, int num_reg_params,
1851 struct reg_param *reg_params, target_addr_t entry_point,
1852 target_addr_t exit_point, int timeout_ms, void *arch_info)
1854 struct stm8_common *stm8 = target_to_stm8(target);
1856 uint32_t context[STM8_NUM_REGS];
1857 int retval = ERROR_OK;
1859 LOG_DEBUG("Running algorithm");
1861 /* NOTE: stm8_run_algorithm requires that each
1862 algorithm uses a software breakpoint
1863 at the exit point */
1865 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1866 LOG_ERROR("current target isn't a STM8 target");
1867 return ERROR_TARGET_INVALID;
1870 if (target->state != TARGET_HALTED) {
1871 LOG_WARNING("target not halted");
1872 return ERROR_TARGET_NOT_HALTED;
1875 /* refresh core register cache */
1876 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1877 if (!stm8->core_cache->reg_list[i].valid)
1878 stm8->read_core_reg(target, i);
1879 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1882 for (int i = 0; i < num_mem_params; i++) {
1883 retval = target_write_buffer(target, mem_params[i].address,
1884 mem_params[i].size, mem_params[i].value);
1885 if (retval != ERROR_OK)
1886 return retval;
1889 for (int i = 0; i < num_reg_params; i++) {
1890 struct reg *reg = register_get_by_name(stm8->core_cache,
1891 reg_params[i].reg_name, 0);
1893 if (!reg) {
1894 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1895 return ERROR_COMMAND_SYNTAX_ERROR;
1898 if (reg_params[i].size != 32) {
1899 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1900 reg_params[i].reg_name);
1901 return ERROR_COMMAND_SYNTAX_ERROR;
1904 stm8_set_core_reg(reg, reg_params[i].value);
1907 retval = stm8_run_and_wait(target, entry_point,
1908 timeout_ms, exit_point, stm8);
1910 if (retval != ERROR_OK)
1911 return retval;
1913 for (int i = 0; i < num_mem_params; i++) {
1914 if (mem_params[i].direction != PARAM_OUT) {
1915 retval = target_read_buffer(target, mem_params[i].address,
1916 mem_params[i].size, mem_params[i].value);
1917 if (retval != ERROR_OK)
1918 return retval;
1922 for (int i = 0; i < num_reg_params; i++) {
1923 if (reg_params[i].direction != PARAM_OUT) {
1924 struct reg *reg = register_get_by_name(stm8->core_cache,
1925 reg_params[i].reg_name, 0);
1926 if (!reg) {
1927 LOG_ERROR("BUG: register '%s' not found",
1928 reg_params[i].reg_name);
1929 return ERROR_COMMAND_SYNTAX_ERROR;
1932 if (reg_params[i].size != 32) {
1933 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1934 reg_params[i].reg_name);
1935 return ERROR_COMMAND_SYNTAX_ERROR;
1938 buf_set_u32(reg_params[i].value,
1939 0, 32, buf_get_u32(reg->value, 0, 32));
1943 /* restore everything we saved before */
1944 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1945 uint32_t regvalue;
1946 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1947 if (regvalue != context[i]) {
1948 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1949 stm8->core_cache->reg_list[i].name, context[i]);
1950 buf_set_u32(stm8->core_cache->reg_list[i].value,
1951 0, 32, context[i]);
1952 stm8->core_cache->reg_list[i].valid = true;
1953 stm8->core_cache->reg_list[i].dirty = true;
1957 return ERROR_OK;
1960 int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi)
1962 struct stm8_common *stm8 = target_to_stm8(target);
1963 jim_wide w;
1964 int e;
1965 const char *arg;
1967 arg = Jim_GetString(goi->argv[0], NULL);
1968 if (!strcmp(arg, "-blocksize")) {
1969 e = Jim_GetOpt_String(goi, &arg, NULL);
1970 if (e != JIM_OK)
1971 return e;
1973 if (goi->argc == 0) {
1974 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1975 "-blocksize ?bytes? ...");
1976 return JIM_ERR;
1979 e = Jim_GetOpt_Wide(goi, &w);
1980 if (e != JIM_OK)
1981 return e;
1983 stm8->blocksize = w;
1984 LOG_DEBUG("blocksize=%8.8x", stm8->blocksize);
1985 return JIM_OK;
1987 if (!strcmp(arg, "-flashstart")) {
1988 e = Jim_GetOpt_String(goi, &arg, NULL);
1989 if (e != JIM_OK)
1990 return e;
1992 if (goi->argc == 0) {
1993 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1994 "-flashstart ?address? ...");
1995 return JIM_ERR;
1998 e = Jim_GetOpt_Wide(goi, &w);
1999 if (e != JIM_OK)
2000 return e;
2002 stm8->flashstart = w;
2003 LOG_DEBUG("flashstart=%8.8x", stm8->flashstart);
2004 return JIM_OK;
2006 if (!strcmp(arg, "-flashend")) {
2007 e = Jim_GetOpt_String(goi, &arg, NULL);
2008 if (e != JIM_OK)
2009 return e;
2011 if (goi->argc == 0) {
2012 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2013 "-flashend ?address? ...");
2014 return JIM_ERR;
2017 e = Jim_GetOpt_Wide(goi, &w);
2018 if (e != JIM_OK)
2019 return e;
2021 stm8->flashend = w;
2022 LOG_DEBUG("flashend=%8.8x", stm8->flashend);
2023 return JIM_OK;
2025 if (!strcmp(arg, "-eepromstart")) {
2026 e = Jim_GetOpt_String(goi, &arg, NULL);
2027 if (e != JIM_OK)
2028 return e;
2030 if (goi->argc == 0) {
2031 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2032 "-eepromstart ?address? ...");
2033 return JIM_ERR;
2036 e = Jim_GetOpt_Wide(goi, &w);
2037 if (e != JIM_OK)
2038 return e;
2040 stm8->eepromstart = w;
2041 LOG_DEBUG("eepromstart=%8.8x", stm8->eepromstart);
2042 return JIM_OK;
2044 if (!strcmp(arg, "-eepromend")) {
2045 e = Jim_GetOpt_String(goi, &arg, NULL);
2046 if (e != JIM_OK)
2047 return e;
2049 if (goi->argc == 0) {
2050 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2051 "-eepromend ?address? ...");
2052 return JIM_ERR;
2055 e = Jim_GetOpt_Wide(goi, &w);
2056 if (e != JIM_OK)
2057 return e;
2059 stm8->eepromend = w;
2060 LOG_DEBUG("eepromend=%8.8x", stm8->eepromend);
2061 return JIM_OK;
2063 if (!strcmp(arg, "-optionstart")) {
2064 e = Jim_GetOpt_String(goi, &arg, NULL);
2065 if (e != JIM_OK)
2066 return e;
2068 if (goi->argc == 0) {
2069 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2070 "-optionstart ?address? ...");
2071 return JIM_ERR;
2074 e = Jim_GetOpt_Wide(goi, &w);
2075 if (e != JIM_OK)
2076 return e;
2078 stm8->optionstart = w;
2079 LOG_DEBUG("optionstart=%8.8x", stm8->optionstart);
2080 return JIM_OK;
2082 if (!strcmp(arg, "-optionend")) {
2083 e = Jim_GetOpt_String(goi, &arg, NULL);
2084 if (e != JIM_OK)
2085 return e;
2087 if (goi->argc == 0) {
2088 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2089 "-optionend ?address? ...");
2090 return JIM_ERR;
2093 e = Jim_GetOpt_Wide(goi, &w);
2094 if (e != JIM_OK)
2095 return e;
2097 stm8->optionend = w;
2098 LOG_DEBUG("optionend=%8.8x", stm8->optionend);
2099 return JIM_OK;
2101 if (!strcmp(arg, "-enable_step_irq")) {
2102 e = Jim_GetOpt_String(goi, &arg, NULL);
2103 if (e != JIM_OK)
2104 return e;
2106 stm8->enable_step_irq = true;
2107 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2108 return JIM_OK;
2110 if (!strcmp(arg, "-enable_stm8l")) {
2111 e = Jim_GetOpt_String(goi, &arg, NULL);
2112 if (e != JIM_OK)
2113 return e;
2115 stm8->enable_stm8l = true;
2116 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2117 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2118 return JIM_OK;
2120 return JIM_CONTINUE;
2123 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2125 const char *msg;
2126 struct target *target = get_current_target(CMD_CTX);
2127 struct stm8_common *stm8 = target_to_stm8(target);
2128 bool enable = stm8->enable_step_irq;
2130 if (CMD_ARGC > 0) {
2131 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2132 stm8->enable_step_irq = enable;
2134 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2135 command_print(CMD_CTX, "enable_step_irq = %s", msg);
2136 return ERROR_OK;
2139 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2141 const char *msg;
2142 struct target *target = get_current_target(CMD_CTX);
2143 struct stm8_common *stm8 = target_to_stm8(target);
2144 bool enable = stm8->enable_stm8l;
2146 if (CMD_ARGC > 0) {
2147 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2148 stm8->enable_stm8l = enable;
2150 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2151 command_print(CMD_CTX, "enable_stm8l = %s", msg);
2152 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2153 return ERROR_OK;
2156 static const struct command_registration stm8_exec_command_handlers[] = {
2158 .name = "enable_step_irq",
2159 .handler = stm8_handle_enable_step_irq_command,
2160 .mode = COMMAND_ANY,
2161 .help = "Enable/disable irq handling during step",
2162 .usage = "[1/0]",
2165 .name = "enable_stm8l",
2166 .handler = stm8_handle_enable_stm8l_command,
2167 .mode = COMMAND_ANY,
2168 .help = "Enable/disable STM8L flash programming",
2169 .usage = "[1/0]",
2171 COMMAND_REGISTRATION_DONE
2174 const struct command_registration stm8_command_handlers[] = {
2176 .name = "stm8",
2177 .mode = COMMAND_ANY,
2178 .help = "stm8 command group",
2179 .usage = "",
2180 .chain = stm8_exec_command_handlers,
2182 COMMAND_REGISTRATION_DONE
2185 struct target_type stm8_target = {
2186 .name = "stm8",
2188 .poll = stm8_poll,
2189 .arch_state = stm8_arch_state,
2191 .halt = stm8_halt,
2192 .resume = stm8_resume,
2193 .step = stm8_step,
2195 .assert_reset = stm8_reset_assert,
2196 .deassert_reset = stm8_reset_deassert,
2198 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2200 .read_memory = stm8_read_memory,
2201 .write_memory = stm8_write_memory,
2202 .checksum_memory = stm8_checksum_memory,
2203 .blank_check_memory = stm8_blank_check_memory,
2205 .run_algorithm = stm8_run_algorithm,
2207 .add_breakpoint = stm8_add_breakpoint,
2208 .remove_breakpoint = stm8_remove_breakpoint,
2209 .add_watchpoint = stm8_add_watchpoint,
2210 .remove_watchpoint = stm8_remove_watchpoint,
2212 .commands = stm8_command_handlers,
2213 .target_create = stm8_target_create,
2214 .init_target = stm8_init,
2215 .examine = stm8_examine,
2217 .deinit_target = stm8_deinit,
2218 .target_jim_configure = stm8_jim_configure,