flash/nor/stm32l4x: Remove redundant error messages
[openocd.git] / src / target / stm8.c
blobad4a45298106103c684d450ca79361adbee0c57b
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /*
4 * OpenOCD STM8 target driver
5 * Copyright (C) 2017 Ake Rehnman
6 * ake.rehnman(at)gmail.com
7 */
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
13 #include <helper/log.h>
14 #include "target.h"
15 #include "target_type.h"
16 #include "hello.h"
17 #include "jtag/interface.h"
18 #include "jtag/jtag.h"
19 #include "jtag/swim.h"
20 #include "register.h"
21 #include "breakpoints.h"
22 #include "algorithm.h"
23 #include "stm8.h"
25 static struct reg_cache *stm8_build_reg_cache(struct target *target);
26 static int stm8_read_core_reg(struct target *target, unsigned int num);
27 static int stm8_write_core_reg(struct target *target, unsigned int num);
28 static int stm8_save_context(struct target *target);
29 static void stm8_enable_breakpoints(struct target *target);
30 static int stm8_unset_breakpoint(struct target *target,
31 struct breakpoint *breakpoint);
32 static int stm8_set_breakpoint(struct target *target,
33 struct breakpoint *breakpoint);
34 static void stm8_enable_watchpoints(struct target *target);
35 static int stm8_unset_watchpoint(struct target *target,
36 struct watchpoint *watchpoint);
37 static int (*adapter_speed)(int speed);
38 extern struct adapter_driver *adapter_driver;
40 static const struct {
41 unsigned id;
42 const char *name;
43 const uint8_t bits;
44 enum reg_type type;
45 const char *group;
46 const char *feature;
47 int flag;
48 } stm8_regs[] = {
49 { 0, "pc", 32, REG_TYPE_UINT32, "general", "org.gnu.gdb.stm8.core", 0 },
50 { 1, "a", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
51 { 2, "x", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
52 { 3, "y", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
53 { 4, "sp", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
54 { 5, "cc", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
57 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
58 #define STM8_PC 0
59 #define STM8_A 1
60 #define STM8_X 2
61 #define STM8_Y 3
62 #define STM8_SP 4
63 #define STM8_CC 5
65 #define CC_I0 0x8
66 #define CC_I1 0x20
68 #define DM_REGS 0x7f00
69 #define DM_REG_A 0x7f00
70 #define DM_REG_PC 0x7f01
71 #define DM_REG_X 0x7f04
72 #define DM_REG_Y 0x7f06
73 #define DM_REG_SP 0x7f08
74 #define DM_REG_CC 0x7f0a
76 #define DM_BKR1E 0x7f90
77 #define DM_BKR2E 0x7f93
78 #define DM_CR1 0x7f96
79 #define DM_CR2 0x7f97
80 #define DM_CSR1 0x7f98
81 #define DM_CSR2 0x7f99
83 #define STE 0x40
84 #define STF 0x20
85 #define RST 0x10
86 #define BRW 0x08
87 #define BK2F 0x04
88 #define BK1F 0x02
90 #define SWBRK 0x20
91 #define SWBKF 0x10
92 #define STALL 0x08
93 #define FLUSH 0x01
95 #define FLASH_CR1_STM8S 0x505A
96 #define FLASH_CR2_STM8S 0x505B
97 #define FLASH_NCR2_STM8S 0x505C
98 #define FLASH_IAPSR_STM8S 0x505F
99 #define FLASH_PUKR_STM8S 0x5062
100 #define FLASH_DUKR_STM8S 0x5064
102 #define FLASH_CR1_STM8L 0x5050
103 #define FLASH_CR2_STM8L 0x5051
104 #define FLASH_NCR2_STM8L 0
105 #define FLASH_PUKR_STM8L 0x5052
106 #define FLASH_DUKR_STM8L 0x5053
107 #define FLASH_IAPSR_STM8L 0x5054
109 /* FLASH_IAPSR */
110 #define HVOFF 0x40
111 #define DUL 0x08
112 #define EOP 0x04
113 #define PUL 0x02
114 #define WR_PG_DIS 0x01
116 /* FLASH_CR2 */
117 #define OPT 0x80
118 #define WPRG 0x40
119 #define ERASE 0x20
120 #define FPRG 0x10
121 #define PRG 0x01
123 /* SWIM_CSR */
124 #define SAFE_MASK 0x80
125 #define NO_ACCESS 0x40
126 #define SWIM_DM 0x20
127 #define HS 0x10
128 #define OSCOFF 0x08
129 #define SWIM_RST 0x04
130 #define HSIT 0x02
131 #define PRI 0x01
133 #define SWIM_CSR 0x7f80
135 #define STM8_BREAK 0x8B
137 enum mem_type {
138 RAM,
139 FLASH,
140 EEPROM,
141 OPTION
144 struct stm8_algorithm {
145 int common_magic;
148 struct stm8_core_reg {
149 uint32_t num;
150 struct target *target;
153 enum hw_break_type {
154 /* break on execute */
155 HWBRK_EXEC,
156 /* break on read */
157 HWBRK_RD,
158 /* break on write */
159 HWBRK_WR,
160 /* break on read, write and execute */
161 HWBRK_ACC
164 struct stm8_comparator {
165 bool used;
166 uint32_t bp_value;
167 uint32_t reg_address;
168 enum hw_break_type type;
171 static int stm8_adapter_read_memory(struct target *target,
172 uint32_t addr, int size, int count, void *buf)
174 return swim_read_mem(addr, size, count, buf);
177 static int stm8_adapter_write_memory(struct target *target,
178 uint32_t addr, int size, int count, const void *buf)
180 return swim_write_mem(addr, size, count, buf);
183 static int stm8_write_u8(struct target *target,
184 uint32_t addr, uint8_t val)
186 uint8_t buf[1];
188 buf[0] = val;
189 return swim_write_mem(addr, 1, 1, buf);
192 static int stm8_read_u8(struct target *target,
193 uint32_t addr, uint8_t *val)
195 return swim_read_mem(addr, 1, 1, val);
199 <enable == 0> Disables interrupts.
200 If interrupts are enabled they are masked and the cc register
201 is saved.
203 <enable == 1> Enables interrupts.
204 Enable interrupts is actually restoring I1 I0 state from previous
205 call with enable == 0. Note that if stepping and breaking on a sim
206 instruction will NOT work since the interrupt flags are restored on
207 debug_entry. We don't have any way for the debugger to exclusively
208 disable the interrupts
210 static int stm8_enable_interrupts(struct target *target, int enable)
212 struct stm8_common *stm8 = target_to_stm8(target);
213 uint8_t cc;
215 if (enable) {
216 if (!stm8->cc_valid)
217 return ERROR_OK; /* cc was not stashed */
218 /* fetch current cc */
219 stm8_read_u8(target, DM_REG_CC, &cc);
220 /* clear I1 I0 */
221 cc &= ~(CC_I0 + CC_I1);
222 /* restore I1 & I0 from stash*/
223 cc |= (stm8->cc & (CC_I0+CC_I1));
224 /* update current cc */
225 stm8_write_u8(target, DM_REG_CC, cc);
226 stm8->cc_valid = false;
227 } else {
228 stm8_read_u8(target, DM_REG_CC, &cc);
229 if ((cc & CC_I0) && (cc & CC_I1))
230 return ERROR_OK; /* interrupts already masked */
231 /* stash cc */
232 stm8->cc = cc;
233 stm8->cc_valid = true;
234 /* mask interrupts (disable) */
235 cc |= (CC_I0 + CC_I1);
236 stm8_write_u8(target, DM_REG_CC, cc);
239 return ERROR_OK;
242 static int stm8_set_hwbreak(struct target *target,
243 struct stm8_comparator comparator_list[])
245 uint8_t buf[3];
246 int i, ret;
248 /* Refer to Table 4 in UM0470 */
249 uint8_t bc = 0x5;
250 uint8_t bir = 0;
251 uint8_t biw = 0;
253 uint32_t data;
254 uint32_t addr;
256 if (!comparator_list[0].used) {
257 comparator_list[0].type = HWBRK_EXEC;
258 comparator_list[0].bp_value = -1;
261 if (!comparator_list[1].used) {
262 comparator_list[1].type = HWBRK_EXEC;
263 comparator_list[1].bp_value = -1;
266 if ((comparator_list[0].type == HWBRK_EXEC)
267 && (comparator_list[1].type == HWBRK_EXEC)) {
268 comparator_list[0].reg_address = 0;
269 comparator_list[1].reg_address = 1;
272 if ((comparator_list[0].type == HWBRK_EXEC)
273 && (comparator_list[1].type != HWBRK_EXEC)) {
274 comparator_list[0].reg_address = 0;
275 comparator_list[1].reg_address = 1;
276 switch (comparator_list[1].type) {
277 case HWBRK_RD:
278 bir = 1;
279 break;
280 case HWBRK_WR:
281 biw = 1;
282 break;
283 default:
284 bir = 1;
285 biw = 1;
286 break;
290 if ((comparator_list[1].type == HWBRK_EXEC)
291 && (comparator_list[0].type != HWBRK_EXEC)) {
292 comparator_list[0].reg_address = 1;
293 comparator_list[1].reg_address = 0;
294 switch (comparator_list[0].type) {
295 case HWBRK_RD:
296 bir = 1;
297 break;
298 case HWBRK_WR:
299 biw = 1;
300 break;
301 default:
302 bir = 1;
303 biw = 1;
304 break;
308 if ((comparator_list[0].type != HWBRK_EXEC)
309 && (comparator_list[1].type != HWBRK_EXEC)) {
310 if (comparator_list[0].type != comparator_list[1].type) {
311 LOG_ERROR("data hw breakpoints must be of same type");
312 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
316 for (i = 0; i < 2; i++) {
317 data = comparator_list[i].bp_value;
318 addr = comparator_list[i].reg_address;
320 buf[0] = data >> 16;
321 buf[1] = data >> 8;
322 buf[2] = data;
324 if (addr == 0) {
325 ret = stm8_adapter_write_memory(target, DM_BKR1E, 1, 3, buf);
326 LOG_DEBUG("DM_BKR1E=%" PRIx32, data);
327 } else if (addr == 1) {
328 ret = stm8_adapter_write_memory(target, DM_BKR2E, 1, 3, buf);
329 LOG_DEBUG("DM_BKR2E=%" PRIx32, data);
330 } else {
331 LOG_DEBUG("addr=%" PRIu32, addr);
332 return ERROR_FAIL;
335 if (ret != ERROR_OK)
336 return ret;
338 ret = stm8_write_u8(target, DM_CR1,
339 (bc << 3) + (bir << 2) + (biw << 1));
340 LOG_DEBUG("DM_CR1=%" PRIx8, buf[0]);
341 if (ret != ERROR_OK)
342 return ret;
345 return ERROR_OK;
348 /* read DM control and status regs */
349 static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,
350 uint8_t *csr2)
352 int ret;
353 uint8_t buf[2];
355 ret = stm8_adapter_read_memory(target, DM_CSR1, 1, sizeof(buf), buf);
356 if (ret != ERROR_OK)
357 return ret;
358 if (csr1)
359 *csr1 = buf[0];
360 if (csr2)
361 *csr2 = buf[1];
362 return ERROR_OK;
365 /* set or clear the single step flag in DM */
366 static int stm8_config_step(struct target *target, int enable)
368 int ret;
369 uint8_t csr1, csr2;
371 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
372 if (ret != ERROR_OK)
373 return ret;
374 if (enable)
375 csr1 |= STE;
376 else
377 csr1 &= ~STE;
379 ret = stm8_write_u8(target, DM_CSR1, csr1);
380 if (ret != ERROR_OK)
381 return ret;
382 return ERROR_OK;
385 /* set the stall flag in DM */
386 static int stm8_debug_stall(struct target *target)
388 int ret;
389 uint8_t csr1, csr2;
391 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
392 if (ret != ERROR_OK)
393 return ret;
394 csr2 |= STALL;
395 ret = stm8_write_u8(target, DM_CSR2, csr2);
396 if (ret != ERROR_OK)
397 return ret;
398 return ERROR_OK;
401 static int stm8_configure_break_unit(struct target *target)
403 /* get pointers to arch-specific information */
404 struct stm8_common *stm8 = target_to_stm8(target);
406 if (stm8->bp_scanned)
407 return ERROR_OK;
409 stm8->num_hw_bpoints = 2;
410 stm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;
412 stm8->hw_break_list = calloc(stm8->num_hw_bpoints,
413 sizeof(struct stm8_comparator));
415 stm8->hw_break_list[0].reg_address = 0;
416 stm8->hw_break_list[1].reg_address = 1;
418 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8->num_hw_bpoints,
419 stm8->num_hw_bpoints);
421 stm8->bp_scanned = true;
423 return ERROR_OK;
426 static int stm8_examine_debug_reason(struct target *target)
428 int retval;
429 uint8_t csr1, csr2;
431 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
432 if (retval == ERROR_OK)
433 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
435 if ((target->debug_reason != DBG_REASON_DBGRQ)
436 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
438 if (retval != ERROR_OK)
439 return retval;
441 if (csr1 & RST)
442 /* halted on reset */
443 target->debug_reason = DBG_REASON_UNDEFINED;
445 if (csr1 & (BK1F+BK2F))
446 /* we have halted on a breakpoint (or wp)*/
447 target->debug_reason = DBG_REASON_BREAKPOINT;
449 if (csr2 & SWBKF)
450 /* we have halted on a breakpoint */
451 target->debug_reason = DBG_REASON_BREAKPOINT;
455 return ERROR_OK;
458 static int stm8_debug_entry(struct target *target)
460 struct stm8_common *stm8 = target_to_stm8(target);
462 /* restore interrupts */
463 stm8_enable_interrupts(target, 1);
465 stm8_save_context(target);
467 /* make sure stepping disabled STE bit in CSR1 cleared */
468 stm8_config_step(target, 0);
470 /* attempt to find halt reason */
471 stm8_examine_debug_reason(target);
473 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
474 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32),
475 target_state_name(target));
477 return ERROR_OK;
480 /* clear stall flag in DM and flush instruction pipe */
481 static int stm8_exit_debug(struct target *target)
483 int ret;
484 uint8_t csr1, csr2;
486 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
487 if (ret != ERROR_OK)
488 return ret;
489 csr2 |= FLUSH;
490 ret = stm8_write_u8(target, DM_CSR2, csr2);
491 if (ret != ERROR_OK)
492 return ret;
494 csr2 &= ~STALL;
495 csr2 |= SWBRK;
496 ret = stm8_write_u8(target, DM_CSR2, csr2);
497 if (ret != ERROR_OK)
498 return ret;
499 return ERROR_OK;
502 static int stm8_read_regs(struct target *target, uint32_t regs[])
504 int ret;
505 uint8_t buf[11];
507 ret = stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);
508 if (ret != ERROR_OK)
509 return ret;
511 regs[0] = be_to_h_u24(buf+DM_REG_PC-DM_REGS);
512 regs[1] = buf[DM_REG_A-DM_REGS];
513 regs[2] = be_to_h_u16(buf+DM_REG_X-DM_REGS);
514 regs[3] = be_to_h_u16(buf+DM_REG_Y-DM_REGS);
515 regs[4] = be_to_h_u16(buf+DM_REG_SP-DM_REGS);
516 regs[5] = buf[DM_REG_CC-DM_REGS];
518 return ERROR_OK;
521 static int stm8_write_regs(struct target *target, uint32_t regs[])
523 int ret;
524 uint8_t buf[11];
526 h_u24_to_be(buf+DM_REG_PC-DM_REGS, regs[0]);
527 buf[DM_REG_A-DM_REGS] = regs[1];
528 h_u16_to_be(buf+DM_REG_X-DM_REGS, regs[2]);
529 h_u16_to_be(buf+DM_REG_Y-DM_REGS, regs[3]);
530 h_u16_to_be(buf+DM_REG_SP-DM_REGS, regs[4]);
531 buf[DM_REG_CC-DM_REGS] = regs[5];
533 ret = stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);
534 if (ret != ERROR_OK)
535 return ret;
537 return ERROR_OK;
540 static int stm8_get_core_reg(struct reg *reg)
542 int retval;
543 struct stm8_core_reg *stm8_reg = reg->arch_info;
544 struct target *target = stm8_reg->target;
545 struct stm8_common *stm8 = target_to_stm8(target);
547 if (target->state != TARGET_HALTED)
548 return ERROR_TARGET_NOT_HALTED;
550 retval = stm8->read_core_reg(target, stm8_reg->num);
552 return retval;
555 static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
557 struct stm8_core_reg *stm8_reg = reg->arch_info;
558 struct target *target = stm8_reg->target;
559 uint32_t value = buf_get_u32(buf, 0, reg->size);
561 if (target->state != TARGET_HALTED)
562 return ERROR_TARGET_NOT_HALTED;
564 buf_set_u32(reg->value, 0, 32, value);
565 reg->dirty = true;
566 reg->valid = true;
568 return ERROR_OK;
571 static int stm8_save_context(struct target *target)
573 unsigned int i;
575 /* get pointers to arch-specific information */
576 struct stm8_common *stm8 = target_to_stm8(target);
578 /* read core registers */
579 stm8_read_regs(target, stm8->core_regs);
581 for (i = 0; i < STM8_NUM_REGS; i++) {
582 if (!stm8->core_cache->reg_list[i].valid)
583 stm8->read_core_reg(target, i);
586 return ERROR_OK;
589 static int stm8_restore_context(struct target *target)
591 unsigned int i;
593 /* get pointers to arch-specific information */
594 struct stm8_common *stm8 = target_to_stm8(target);
596 for (i = 0; i < STM8_NUM_REGS; i++) {
597 if (stm8->core_cache->reg_list[i].dirty)
598 stm8->write_core_reg(target, i);
601 /* write core regs */
602 stm8_write_regs(target, stm8->core_regs);
604 return ERROR_OK;
607 static int stm8_unlock_flash(struct target *target)
609 uint8_t data[1];
611 struct stm8_common *stm8 = target_to_stm8(target);
613 /* check if flash is unlocked */
614 stm8_read_u8(target, stm8->flash_iapsr, data);
615 if (~data[0] & PUL) {
616 /* unlock flash */
617 stm8_write_u8(target, stm8->flash_pukr, 0x56);
618 stm8_write_u8(target, stm8->flash_pukr, 0xae);
621 stm8_read_u8(target, stm8->flash_iapsr, data);
622 if (~data[0] & PUL)
623 return ERROR_FAIL;
624 return ERROR_OK;
627 static int stm8_unlock_eeprom(struct target *target)
629 uint8_t data[1];
631 struct stm8_common *stm8 = target_to_stm8(target);
633 /* check if eeprom is unlocked */
634 stm8_read_u8(target, stm8->flash_iapsr, data);
635 if (~data[0] & DUL) {
636 /* unlock eeprom */
637 stm8_write_u8(target, stm8->flash_dukr, 0xae);
638 stm8_write_u8(target, stm8->flash_dukr, 0x56);
641 stm8_read_u8(target, stm8->flash_iapsr, data);
642 if (~data[0] & DUL)
643 return ERROR_FAIL;
644 return ERROR_OK;
647 static int stm8_write_flash(struct target *target, enum mem_type type,
648 uint32_t address,
649 uint32_t size, uint32_t count, uint32_t blocksize_param,
650 const uint8_t *buffer)
652 struct stm8_common *stm8 = target_to_stm8(target);
654 uint8_t iapsr;
655 uint8_t opt = 0;
656 unsigned int i;
657 uint32_t blocksize = 0;
658 uint32_t bytecnt;
659 int res;
661 switch (type) {
662 case (FLASH):
663 stm8_unlock_flash(target);
664 break;
665 case (EEPROM):
666 stm8_unlock_eeprom(target);
667 break;
668 case (OPTION):
669 stm8_unlock_eeprom(target);
670 opt = OPT;
671 break;
672 default:
673 LOG_ERROR("BUG: wrong mem_type %d", type);
674 assert(0);
677 if (size == 2) {
678 /* we don't support short writes */
679 count = count * 2;
680 size = 1;
683 bytecnt = count * size;
685 while (bytecnt) {
686 if ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {
687 if (stm8->flash_cr2)
688 stm8_write_u8(target, stm8->flash_cr2, PRG + opt);
689 if (stm8->flash_ncr2)
690 stm8_write_u8(target, stm8->flash_ncr2, ~(PRG + opt));
691 blocksize = blocksize_param;
692 } else
693 if ((bytecnt >= 4) && ((address & 0x3) == 0)) {
694 if (stm8->flash_cr2)
695 stm8_write_u8(target, stm8->flash_cr2, WPRG + opt);
696 if (stm8->flash_ncr2)
697 stm8_write_u8(target, stm8->flash_ncr2, ~(WPRG + opt));
698 blocksize = 4;
699 } else
700 if (blocksize != 1) {
701 if (stm8->flash_cr2)
702 stm8_write_u8(target, stm8->flash_cr2, opt);
703 if (stm8->flash_ncr2)
704 stm8_write_u8(target, stm8->flash_ncr2, ~opt);
705 blocksize = 1;
708 res = stm8_adapter_write_memory(target, address, 1, blocksize, buffer);
709 if (res != ERROR_OK)
710 return res;
711 address += blocksize;
712 buffer += blocksize;
713 bytecnt -= blocksize;
715 /* lets hang here until end of program (EOP) */
716 for (i = 0; i < 16; i++) {
717 stm8_read_u8(target, stm8->flash_iapsr, &iapsr);
718 if (iapsr & EOP)
719 break;
720 else
721 usleep(1000);
723 if (i == 16)
724 return ERROR_FAIL;
727 /* disable write access */
728 res = stm8_write_u8(target, stm8->flash_iapsr, 0x0);
730 if (res != ERROR_OK)
731 return ERROR_FAIL;
733 return ERROR_OK;
736 static int stm8_write_memory(struct target *target, target_addr_t address,
737 uint32_t size, uint32_t count,
738 const uint8_t *buffer)
740 struct stm8_common *stm8 = target_to_stm8(target);
742 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
743 ", size: 0x%8.8" PRIx32
744 ", count: 0x%8.8" PRIx32,
745 address, size, count);
747 if (target->state != TARGET_HALTED)
748 LOG_WARNING("target not halted");
750 int retval;
752 if ((address >= stm8->flashstart) && (address <= stm8->flashend))
753 retval = stm8_write_flash(target, FLASH, address, size, count,
754 stm8->blocksize, buffer);
755 else if ((address >= stm8->eepromstart) && (address <= stm8->eepromend))
756 retval = stm8_write_flash(target, EEPROM, address, size, count,
757 stm8->blocksize, buffer);
758 else if ((address >= stm8->optionstart) && (address <= stm8->optionend))
759 retval = stm8_write_flash(target, OPTION, address, size, count, 0, buffer);
760 else
761 retval = stm8_adapter_write_memory(target, address, size, count,
762 buffer);
764 if (retval != ERROR_OK)
765 return ERROR_TARGET_FAILURE;
767 return retval;
770 static int stm8_read_memory(struct target *target, target_addr_t address,
771 uint32_t size, uint32_t count, uint8_t *buffer)
773 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
774 ", size: 0x%8.8" PRIx32
775 ", count: 0x%8.8" PRIx32,
776 address, size, count);
778 if (target->state != TARGET_HALTED)
779 LOG_WARNING("target not halted");
781 int retval;
782 retval = stm8_adapter_read_memory(target, address, size, count, buffer);
784 if (retval != ERROR_OK)
785 return ERROR_TARGET_FAILURE;
787 return retval;
790 static int stm8_speed(int speed)
792 int retval;
793 uint8_t csr;
795 LOG_DEBUG("stm8_speed: %d", speed);
797 csr = SAFE_MASK | SWIM_DM;
798 if (speed >= SWIM_FREQ_HIGH)
799 csr |= HS;
801 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)", csr & HS ? 1 : 0);
802 retval = stm8_write_u8(NULL, SWIM_CSR, csr);
803 if (retval != ERROR_OK)
804 return retval;
805 return adapter_speed(speed);
808 static int stm8_init(struct command_context *cmd_ctx, struct target *target)
811 * FIXME: this is a temporarily hack that needs better implementation.
812 * Being the only overwrite of adapter_driver, it prevents declaring const
813 * the struct adapter_driver.
814 * intercept adapter_driver->speed() calls
816 adapter_speed = adapter_driver->speed;
817 adapter_driver->speed = stm8_speed;
819 stm8_build_reg_cache(target);
821 return ERROR_OK;
824 static int stm8_poll(struct target *target)
826 int retval = ERROR_OK;
827 uint8_t csr1, csr2;
829 #ifdef LOG_STM8
830 LOG_DEBUG("target->state=%d", target->state);
831 #endif
833 /* read dm_csrx control regs */
834 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
835 if (retval != ERROR_OK) {
836 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval);
838 We return ERROR_OK here even if we didn't get an answer.
839 openocd will call target_wait_state until we get target state TARGET_HALTED
841 return ERROR_OK;
844 /* check for processor halted */
845 if (csr2 & STALL) {
846 if (target->state != TARGET_HALTED) {
847 if (target->state == TARGET_UNKNOWN)
848 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
850 retval = stm8_debug_entry(target);
851 if (retval != ERROR_OK) {
852 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval);
853 return ERROR_TARGET_FAILURE;
856 if (target->state == TARGET_DEBUG_RUNNING) {
857 target->state = TARGET_HALTED;
858 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
859 } else {
860 target->state = TARGET_HALTED;
861 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
864 } else
865 target->state = TARGET_RUNNING;
866 #ifdef LOG_STM8
867 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
868 #endif
869 return ERROR_OK;
872 static int stm8_halt(struct target *target)
874 LOG_DEBUG("target->state: %s", target_state_name(target));
876 if (target->state == TARGET_HALTED) {
877 LOG_DEBUG("target was already halted");
878 return ERROR_OK;
881 if (target->state == TARGET_UNKNOWN)
882 LOG_WARNING("target was in unknown state when halt was requested");
884 if (target->state == TARGET_RESET) {
885 /* we came here in a reset_halt or reset_init sequence
886 * debug entry was already prepared in stm8_assert_reset()
888 target->debug_reason = DBG_REASON_DBGRQ;
890 return ERROR_OK;
894 /* break processor */
895 stm8_debug_stall(target);
897 target->debug_reason = DBG_REASON_DBGRQ;
899 return ERROR_OK;
902 static int stm8_reset_assert(struct target *target)
904 int res = ERROR_OK;
905 struct stm8_common *stm8 = target_to_stm8(target);
906 bool use_srst_fallback = true;
908 enum reset_types jtag_reset_config = jtag_get_reset_config();
910 if (jtag_reset_config & RESET_HAS_SRST) {
911 res = adapter_assert_reset();
912 if (res == ERROR_OK)
913 /* hardware srst supported */
914 use_srst_fallback = false;
915 else if (res != ERROR_COMMAND_NOTFOUND)
916 /* some other failure */
917 return res;
920 if (use_srst_fallback) {
921 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
922 res = swim_system_reset();
923 if (res != ERROR_OK)
924 return res;
927 /* registers are now invalid */
928 register_cache_invalidate(stm8->core_cache);
930 target->state = TARGET_RESET;
931 target->debug_reason = DBG_REASON_NOTHALTED;
933 if (target->reset_halt) {
934 res = target_halt(target);
935 if (res != ERROR_OK)
936 return res;
939 return ERROR_OK;
942 static int stm8_reset_deassert(struct target *target)
944 int res;
945 enum reset_types jtag_reset_config = jtag_get_reset_config();
947 if (jtag_reset_config & RESET_HAS_SRST) {
948 res = adapter_deassert_reset();
949 if ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND))
950 return res;
953 /* The cpu should now be stalled. If halt was requested
954 let poll detect the stall */
955 if (target->reset_halt)
956 return ERROR_OK;
958 /* Instead of going through saving context, polling and
959 then resuming target again just clear stall and proceed. */
960 target->state = TARGET_RUNNING;
961 return stm8_exit_debug(target);
964 /* stm8_single_step_core() is only used for stepping over breakpoints
965 from stm8_resume() */
966 static int stm8_single_step_core(struct target *target)
968 struct stm8_common *stm8 = target_to_stm8(target);
970 /* configure single step mode */
971 stm8_config_step(target, 1);
973 /* disable interrupts while stepping */
974 if (!stm8->enable_step_irq)
975 stm8_enable_interrupts(target, 0);
977 /* exit debug mode */
978 stm8_exit_debug(target);
980 stm8_debug_entry(target);
982 return ERROR_OK;
985 static int stm8_resume(struct target *target, int current,
986 target_addr_t address, int handle_breakpoints,
987 int debug_execution)
989 struct stm8_common *stm8 = target_to_stm8(target);
990 struct breakpoint *breakpoint = NULL;
991 uint32_t resume_pc;
993 LOG_DEBUG("%d " TARGET_ADDR_FMT " %d %d", current, address,
994 handle_breakpoints, debug_execution);
996 if (target->state != TARGET_HALTED) {
997 LOG_TARGET_ERROR(target, "not halted");
998 return ERROR_TARGET_NOT_HALTED;
1001 if (!debug_execution) {
1002 target_free_all_working_areas(target);
1003 stm8_enable_breakpoints(target);
1004 stm8_enable_watchpoints(target);
1005 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1006 stm8_set_hwbreak(target, comparator_list);
1009 /* current = 1: continue on current pc,
1010 otherwise continue at <address> */
1011 if (!current) {
1012 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value,
1013 0, 32, address);
1014 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1015 stm8->core_cache->reg_list[STM8_PC].valid = true;
1018 if (!current)
1019 resume_pc = address;
1020 else
1021 resume_pc = buf_get_u32(
1022 stm8->core_cache->reg_list[STM8_PC].value,
1023 0, 32);
1025 stm8_restore_context(target);
1027 /* the front-end may request us not to handle breakpoints */
1028 if (handle_breakpoints) {
1029 /* Single step past breakpoint at current address */
1030 breakpoint = breakpoint_find(target, resume_pc);
1031 if (breakpoint) {
1032 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT,
1033 breakpoint->address);
1034 stm8_unset_breakpoint(target, breakpoint);
1035 stm8_single_step_core(target);
1036 stm8_set_breakpoint(target, breakpoint);
1040 /* disable interrupts if we are debugging */
1041 if (debug_execution)
1042 stm8_enable_interrupts(target, 0);
1044 /* exit debug mode */
1045 stm8_exit_debug(target);
1046 target->debug_reason = DBG_REASON_NOTHALTED;
1048 /* registers are now invalid */
1049 register_cache_invalidate(stm8->core_cache);
1051 if (!debug_execution) {
1052 target->state = TARGET_RUNNING;
1053 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1054 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
1055 } else {
1056 target->state = TARGET_DEBUG_RUNNING;
1057 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1058 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
1061 return ERROR_OK;
1064 static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
1066 stm8->enable_stm8l = enable_stm8l;
1068 if (stm8->enable_stm8l) {
1069 stm8->flash_cr2 = FLASH_CR2_STM8L;
1070 stm8->flash_ncr2 = FLASH_NCR2_STM8L;
1071 stm8->flash_iapsr = FLASH_IAPSR_STM8L;
1072 stm8->flash_dukr = FLASH_DUKR_STM8L;
1073 stm8->flash_pukr = FLASH_PUKR_STM8L;
1074 } else {
1075 stm8->flash_cr2 = FLASH_CR2_STM8S;
1076 stm8->flash_ncr2 = FLASH_NCR2_STM8S;
1077 stm8->flash_iapsr = FLASH_IAPSR_STM8S;
1078 stm8->flash_dukr = FLASH_DUKR_STM8S;
1079 stm8->flash_pukr = FLASH_PUKR_STM8S;
1081 return ERROR_OK;
1084 static int stm8_init_arch_info(struct target *target,
1085 struct stm8_common *stm8, struct jtag_tap *tap)
1087 target->endianness = TARGET_BIG_ENDIAN;
1088 target->arch_info = stm8;
1089 stm8->common_magic = STM8_COMMON_MAGIC;
1090 stm8->fast_data_area = NULL;
1091 stm8->blocksize = 0x80;
1092 stm8->flashstart = 0x8000;
1093 stm8->flashend = 0xffff;
1094 stm8->eepromstart = 0x4000;
1095 stm8->eepromend = 0x43ff;
1096 stm8->optionstart = 0x4800;
1097 stm8->optionend = 0x487F;
1099 /* has breakpoint/watchpoint unit been scanned */
1100 stm8->bp_scanned = false;
1101 stm8->hw_break_list = NULL;
1103 stm8->read_core_reg = stm8_read_core_reg;
1104 stm8->write_core_reg = stm8_write_core_reg;
1106 stm8_init_flash_regs(0, stm8);
1108 return ERROR_OK;
1111 static int stm8_target_create(struct target *target,
1112 Jim_Interp *interp)
1115 struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));
1117 stm8_init_arch_info(target, stm8, target->tap);
1118 stm8_configure_break_unit(target);
1120 return ERROR_OK;
1123 static int stm8_read_core_reg(struct target *target, unsigned int num)
1125 uint32_t reg_value;
1127 /* get pointers to arch-specific information */
1128 struct stm8_common *stm8 = target_to_stm8(target);
1130 if (num >= STM8_NUM_REGS)
1131 return ERROR_COMMAND_SYNTAX_ERROR;
1133 reg_value = stm8->core_regs[num];
1134 LOG_DEBUG("read core reg %i value 0x%" PRIx32 "", num, reg_value);
1135 buf_set_u32(stm8->core_cache->reg_list[num].value, 0, 32, reg_value);
1136 stm8->core_cache->reg_list[num].valid = true;
1137 stm8->core_cache->reg_list[num].dirty = false;
1139 return ERROR_OK;
1142 static int stm8_write_core_reg(struct target *target, unsigned int num)
1144 uint32_t reg_value;
1146 /* get pointers to arch-specific information */
1147 struct stm8_common *stm8 = target_to_stm8(target);
1149 if (num >= STM8_NUM_REGS)
1150 return ERROR_COMMAND_SYNTAX_ERROR;
1152 reg_value = buf_get_u32(stm8->core_cache->reg_list[num].value, 0, 32);
1153 stm8->core_regs[num] = reg_value;
1154 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
1155 stm8->core_cache->reg_list[num].valid = true;
1156 stm8->core_cache->reg_list[num].dirty = false;
1158 return ERROR_OK;
1161 static const char *stm8_get_gdb_arch(struct target *target)
1163 return "stm8";
1166 static int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
1167 int *reg_list_size, enum target_register_class reg_class)
1169 /* get pointers to arch-specific information */
1170 struct stm8_common *stm8 = target_to_stm8(target);
1171 unsigned int i;
1173 *reg_list_size = STM8_NUM_REGS;
1174 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1176 for (i = 0; i < STM8_NUM_REGS; i++)
1177 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1179 return ERROR_OK;
1182 static const struct reg_arch_type stm8_reg_type = {
1183 .get = stm8_get_core_reg,
1184 .set = stm8_set_core_reg,
1187 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1189 /* get pointers to arch-specific information */
1190 struct stm8_common *stm8 = target_to_stm8(target);
1192 int num_regs = STM8_NUM_REGS;
1193 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1194 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1195 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1196 struct stm8_core_reg *arch_info = malloc(
1197 sizeof(struct stm8_core_reg) * num_regs);
1198 struct reg_feature *feature;
1199 int i;
1201 /* Build the process context cache */
1202 cache->name = "stm8 registers";
1203 cache->next = NULL;
1204 cache->reg_list = reg_list;
1205 cache->num_regs = num_regs;
1206 (*cache_p) = cache;
1207 stm8->core_cache = cache;
1209 for (i = 0; i < num_regs; i++) {
1210 arch_info[i].num = stm8_regs[i].id;
1211 arch_info[i].target = target;
1213 reg_list[i].name = stm8_regs[i].name;
1214 reg_list[i].size = stm8_regs[i].bits;
1216 reg_list[i].value = calloc(1, 4);
1217 reg_list[i].valid = false;
1218 reg_list[i].type = &stm8_reg_type;
1219 reg_list[i].arch_info = &arch_info[i];
1221 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1222 if (reg_list[i].reg_data_type)
1223 reg_list[i].reg_data_type->type = stm8_regs[i].type;
1224 else {
1225 LOG_ERROR("unable to allocate reg type list");
1226 return NULL;
1229 reg_list[i].dirty = false;
1230 reg_list[i].group = stm8_regs[i].group;
1231 reg_list[i].number = stm8_regs[i].id;
1232 reg_list[i].exist = true;
1233 reg_list[i].caller_save = true; /* gdb defaults to true */
1235 feature = calloc(1, sizeof(struct reg_feature));
1236 if (feature) {
1237 feature->name = stm8_regs[i].feature;
1238 reg_list[i].feature = feature;
1239 } else
1240 LOG_ERROR("unable to allocate feature list");
1243 return cache;
1246 static void stm8_free_reg_cache(struct target *target)
1248 struct stm8_common *stm8 = target_to_stm8(target);
1249 struct reg_cache *cache;
1250 struct reg *reg;
1251 unsigned int i;
1253 cache = stm8->core_cache;
1255 if (!cache)
1256 return;
1258 for (i = 0; i < cache->num_regs; i++) {
1259 reg = &cache->reg_list[i];
1261 free(reg->feature);
1262 free(reg->reg_data_type);
1263 free(reg->value);
1266 free(cache->reg_list[0].arch_info);
1267 free(cache->reg_list);
1268 free(cache);
1270 stm8->core_cache = NULL;
1273 static void stm8_deinit(struct target *target)
1275 struct stm8_common *stm8 = target_to_stm8(target);
1277 free(stm8->hw_break_list);
1279 stm8_free_reg_cache(target);
1281 free(stm8);
1284 static int stm8_arch_state(struct target *target)
1286 struct stm8_common *stm8 = target_to_stm8(target);
1288 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
1289 debug_reason_name(target),
1290 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1292 return ERROR_OK;
1295 static int stm8_step(struct target *target, int current,
1296 target_addr_t address, int handle_breakpoints)
1298 LOG_DEBUG("%x " TARGET_ADDR_FMT " %x",
1299 current, address, handle_breakpoints);
1301 /* get pointers to arch-specific information */
1302 struct stm8_common *stm8 = target_to_stm8(target);
1303 struct breakpoint *breakpoint = NULL;
1305 if (target->state != TARGET_HALTED) {
1306 LOG_TARGET_ERROR(target, "not halted");
1307 return ERROR_TARGET_NOT_HALTED;
1310 /* current = 1: continue on current pc, otherwise continue at <address> */
1311 if (!current) {
1312 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);
1313 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1314 stm8->core_cache->reg_list[STM8_PC].valid = true;
1317 /* the front-end may request us not to handle breakpoints */
1318 if (handle_breakpoints) {
1319 breakpoint = breakpoint_find(target,
1320 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1321 if (breakpoint)
1322 stm8_unset_breakpoint(target, breakpoint);
1325 /* restore context */
1326 stm8_restore_context(target);
1328 /* configure single step mode */
1329 stm8_config_step(target, 1);
1331 target->debug_reason = DBG_REASON_SINGLESTEP;
1333 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1335 /* disable interrupts while stepping */
1336 if (!stm8->enable_step_irq)
1337 stm8_enable_interrupts(target, 0);
1339 /* exit debug mode */
1340 stm8_exit_debug(target);
1342 /* registers are now invalid */
1343 register_cache_invalidate(stm8->core_cache);
1345 LOG_DEBUG("target stepped ");
1346 stm8_debug_entry(target);
1348 if (breakpoint)
1349 stm8_set_breakpoint(target, breakpoint);
1351 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1353 return ERROR_OK;
1356 static void stm8_enable_breakpoints(struct target *target)
1358 struct breakpoint *breakpoint = target->breakpoints;
1360 /* set any pending breakpoints */
1361 while (breakpoint) {
1362 if (!breakpoint->is_set)
1363 stm8_set_breakpoint(target, breakpoint);
1364 breakpoint = breakpoint->next;
1368 static int stm8_set_breakpoint(struct target *target,
1369 struct breakpoint *breakpoint)
1371 struct stm8_common *stm8 = target_to_stm8(target);
1372 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1373 int retval;
1375 if (breakpoint->is_set) {
1376 LOG_WARNING("breakpoint already set");
1377 return ERROR_OK;
1380 if (breakpoint->type == BKPT_HARD) {
1381 int bp_num = 0;
1383 while (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))
1384 bp_num++;
1385 if (bp_num >= stm8->num_hw_bpoints) {
1386 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32 ")",
1387 breakpoint->unique_id);
1388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1390 breakpoint_hw_set(breakpoint, bp_num);
1391 comparator_list[bp_num].used = true;
1392 comparator_list[bp_num].bp_value = breakpoint->address;
1393 comparator_list[bp_num].type = HWBRK_EXEC;
1395 retval = stm8_set_hwbreak(target, comparator_list);
1396 if (retval != ERROR_OK)
1397 return retval;
1399 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
1400 breakpoint->unique_id,
1401 bp_num, comparator_list[bp_num].bp_value);
1402 } else if (breakpoint->type == BKPT_SOFT) {
1403 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1404 if (breakpoint->length == 1) {
1405 uint8_t verify = 0x55;
1407 retval = target_read_u8(target, breakpoint->address,
1408 breakpoint->orig_instr);
1409 if (retval != ERROR_OK)
1410 return retval;
1411 retval = target_write_u8(target, breakpoint->address, STM8_BREAK);
1412 if (retval != ERROR_OK)
1413 return retval;
1415 retval = target_read_u8(target, breakpoint->address, &verify);
1416 if (retval != ERROR_OK)
1417 return retval;
1418 if (verify != STM8_BREAK) {
1419 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1420 " - check that memory is read/writable",
1421 breakpoint->address);
1422 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1424 } else {
1425 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1427 breakpoint->is_set = true;
1430 return ERROR_OK;
1433 static int stm8_add_breakpoint(struct target *target,
1434 struct breakpoint *breakpoint)
1436 struct stm8_common *stm8 = target_to_stm8(target);
1437 int ret;
1439 if (breakpoint->type == BKPT_HARD) {
1440 if (stm8->num_hw_bpoints_avail < 1) {
1441 LOG_INFO("no hardware breakpoint available");
1442 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1445 ret = stm8_set_breakpoint(target, breakpoint);
1446 if (ret != ERROR_OK)
1447 return ret;
1449 stm8->num_hw_bpoints_avail--;
1450 return ERROR_OK;
1453 ret = stm8_set_breakpoint(target, breakpoint);
1454 if (ret != ERROR_OK)
1455 return ret;
1457 return ERROR_OK;
1460 static int stm8_unset_breakpoint(struct target *target,
1461 struct breakpoint *breakpoint)
1463 /* get pointers to arch-specific information */
1464 struct stm8_common *stm8 = target_to_stm8(target);
1465 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1466 int retval;
1468 if (!breakpoint->is_set) {
1469 LOG_WARNING("breakpoint not set");
1470 return ERROR_OK;
1473 if (breakpoint->type == BKPT_HARD) {
1474 int bp_num = breakpoint->number;
1475 if (bp_num >= stm8->num_hw_bpoints) {
1476 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
1477 breakpoint->unique_id);
1478 return ERROR_OK;
1480 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
1481 breakpoint->unique_id,
1482 bp_num);
1483 comparator_list[bp_num].used = false;
1484 retval = stm8_set_hwbreak(target, comparator_list);
1485 if (retval != ERROR_OK)
1486 return retval;
1487 } else {
1488 /* restore original instruction (kept in target endianness) */
1489 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1490 if (breakpoint->length == 1) {
1491 uint8_t current_instr;
1493 /* check that user program has not
1494 modified breakpoint instruction */
1495 retval = target_read_memory(target, breakpoint->address, 1, 1,
1496 (uint8_t *)&current_instr);
1497 if (retval != ERROR_OK)
1498 return retval;
1500 if (current_instr == STM8_BREAK) {
1501 retval = target_write_memory(target, breakpoint->address, 1, 1,
1502 breakpoint->orig_instr);
1503 if (retval != ERROR_OK)
1504 return retval;
1506 } else
1507 return ERROR_FAIL;
1509 breakpoint->is_set = false;
1511 return ERROR_OK;
1514 static int stm8_remove_breakpoint(struct target *target,
1515 struct breakpoint *breakpoint)
1517 /* get pointers to arch-specific information */
1518 struct stm8_common *stm8 = target_to_stm8(target);
1520 if (target->state != TARGET_HALTED) {
1521 LOG_TARGET_ERROR(target, "not halted");
1522 return ERROR_TARGET_NOT_HALTED;
1525 if (breakpoint->is_set)
1526 stm8_unset_breakpoint(target, breakpoint);
1528 if (breakpoint->type == BKPT_HARD)
1529 stm8->num_hw_bpoints_avail++;
1531 return ERROR_OK;
1534 static int stm8_set_watchpoint(struct target *target,
1535 struct watchpoint *watchpoint)
1537 struct stm8_common *stm8 = target_to_stm8(target);
1538 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1539 int wp_num = 0;
1540 int ret;
1542 if (watchpoint->is_set) {
1543 LOG_WARNING("watchpoint already set");
1544 return ERROR_OK;
1547 while (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))
1548 wp_num++;
1549 if (wp_num >= stm8->num_hw_bpoints) {
1550 LOG_ERROR("Can not find free hw breakpoint");
1551 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1554 if (watchpoint->length != 1) {
1555 LOG_ERROR("Only watchpoints of length 1 are supported");
1556 return ERROR_TARGET_UNALIGNED_ACCESS;
1559 enum hw_break_type enable = 0;
1561 switch (watchpoint->rw) {
1562 case WPT_READ:
1563 enable = HWBRK_RD;
1564 break;
1565 case WPT_WRITE:
1566 enable = HWBRK_WR;
1567 break;
1568 case WPT_ACCESS:
1569 enable = HWBRK_ACC;
1570 break;
1571 default:
1572 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1575 comparator_list[wp_num].used = true;
1576 comparator_list[wp_num].bp_value = watchpoint->address;
1577 comparator_list[wp_num].type = enable;
1579 ret = stm8_set_hwbreak(target, comparator_list);
1580 if (ret != ERROR_OK) {
1581 comparator_list[wp_num].used = false;
1582 return ret;
1585 watchpoint_set(watchpoint, wp_num);
1587 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1588 wp_num,
1589 comparator_list[wp_num].bp_value);
1591 return ERROR_OK;
1594 static int stm8_add_watchpoint(struct target *target,
1595 struct watchpoint *watchpoint)
1597 int ret;
1598 struct stm8_common *stm8 = target_to_stm8(target);
1600 if (stm8->num_hw_bpoints_avail < 1) {
1601 LOG_INFO("no hardware watchpoints available");
1602 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1605 ret = stm8_set_watchpoint(target, watchpoint);
1606 if (ret != ERROR_OK)
1607 return ret;
1609 stm8->num_hw_bpoints_avail--;
1610 return ERROR_OK;
1613 static void stm8_enable_watchpoints(struct target *target)
1615 struct watchpoint *watchpoint = target->watchpoints;
1617 /* set any pending watchpoints */
1618 while (watchpoint) {
1619 if (!watchpoint->is_set)
1620 stm8_set_watchpoint(target, watchpoint);
1621 watchpoint = watchpoint->next;
1625 static int stm8_unset_watchpoint(struct target *target,
1626 struct watchpoint *watchpoint)
1628 /* get pointers to arch-specific information */
1629 struct stm8_common *stm8 = target_to_stm8(target);
1630 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1632 if (!watchpoint->is_set) {
1633 LOG_WARNING("watchpoint not set");
1634 return ERROR_OK;
1637 int wp_num = watchpoint->number;
1638 if (wp_num >= stm8->num_hw_bpoints) {
1639 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1640 return ERROR_OK;
1642 comparator_list[wp_num].used = false;
1643 watchpoint->is_set = false;
1645 stm8_set_hwbreak(target, comparator_list);
1647 return ERROR_OK;
1650 static int stm8_remove_watchpoint(struct target *target,
1651 struct watchpoint *watchpoint)
1653 /* get pointers to arch-specific information */
1654 struct stm8_common *stm8 = target_to_stm8(target);
1656 if (target->state != TARGET_HALTED) {
1657 LOG_TARGET_ERROR(target, "not halted");
1658 return ERROR_TARGET_NOT_HALTED;
1661 if (watchpoint->is_set)
1662 stm8_unset_watchpoint(target, watchpoint);
1664 stm8->num_hw_bpoints_avail++;
1666 return ERROR_OK;
1669 static int stm8_examine(struct target *target)
1671 int retval;
1672 uint8_t csr1, csr2;
1673 /* get pointers to arch-specific information */
1674 struct stm8_common *stm8 = target_to_stm8(target);
1675 enum reset_types jtag_reset_config = jtag_get_reset_config();
1677 if (!target_was_examined(target)) {
1678 if (!stm8->swim_configured) {
1679 stm8->swim_configured = true;
1681 Now is the time to deassert reset if connect_under_reset.
1682 Releasing reset line will cause the option bytes to load.
1683 The core will still be stalled.
1685 if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
1686 if (jtag_reset_config & RESET_SRST_NO_GATING)
1687 stm8_reset_deassert(target);
1688 else
1689 LOG_WARNING("\'srst_nogate\' reset_config option is required");
1691 } else {
1692 LOG_INFO("trying to reconnect");
1694 retval = swim_reconnect();
1695 if (retval != ERROR_OK) {
1696 LOG_ERROR("reconnect failed");
1697 return ERROR_FAIL;
1700 /* read dm_csrx control regs */
1701 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
1702 if (retval != ERROR_OK) {
1703 LOG_ERROR("state query failed");
1704 return ERROR_FAIL;
1708 target_set_examined(target);
1710 return ERROR_OK;
1713 return ERROR_OK;
1716 /** Checks whether a memory region is erased. */
1717 static int stm8_blank_check_memory(struct target *target,
1718 struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
1720 struct working_area *erase_check_algorithm;
1721 struct reg_param reg_params[2];
1722 struct mem_param mem_params[2];
1723 struct stm8_algorithm stm8_info;
1725 static const uint8_t stm8_erase_check_code[] = {
1726 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1729 if (erased_value != 0xff) {
1730 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for STM8",
1731 erased_value);
1732 return ERROR_FAIL;
1735 /* make sure we have a working area */
1736 if (target_alloc_working_area(target, sizeof(stm8_erase_check_code),
1737 &erase_check_algorithm) != ERROR_OK)
1738 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1740 target_write_buffer(target, erase_check_algorithm->address,
1741 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1743 stm8_info.common_magic = STM8_COMMON_MAGIC;
1745 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1746 buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
1748 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1749 buf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);
1751 init_reg_param(&reg_params[0], "a", 32, PARAM_IN_OUT);
1752 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1754 init_reg_param(&reg_params[1], "sp", 32, PARAM_OUT);
1755 buf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);
1757 int retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,
1758 erase_check_algorithm->address + 6,
1759 erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
1760 10000, &stm8_info);
1762 if (retval == ERROR_OK)
1763 blocks[0].result = (*(reg_params[0].value) == 0xff);
1765 destroy_mem_param(&mem_params[0]);
1766 destroy_mem_param(&mem_params[1]);
1767 destroy_reg_param(&reg_params[0]);
1768 destroy_reg_param(&reg_params[1]);
1770 target_free_working_area(target, erase_check_algorithm);
1772 if (retval != ERROR_OK)
1773 return retval;
1775 return 1; /* only one block has been checked */
1778 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1779 uint32_t count, uint32_t *checksum)
1781 /* let image_calculate_checksum() take care of business */
1782 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1785 /* run to exit point. return error if exit point was not reached. */
1786 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1787 unsigned int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1789 uint32_t pc;
1790 int retval;
1791 /* This code relies on the target specific resume() and
1792 poll()->debug_entry() sequence to write register values to the
1793 processor and the read them back */
1794 retval = target_resume(target, 0, entry_point, 0, 1);
1795 if (retval != ERROR_OK)
1796 return retval;
1798 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1799 /* If the target fails to halt due to the breakpoint, force a halt */
1800 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1801 retval = target_halt(target);
1802 if (retval != ERROR_OK)
1803 return retval;
1804 retval = target_wait_state(target, TARGET_HALTED, 500);
1805 if (retval != ERROR_OK)
1806 return retval;
1807 return ERROR_TARGET_TIMEOUT;
1810 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1811 if (exit_point && (pc != exit_point)) {
1812 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1813 return ERROR_TARGET_TIMEOUT;
1816 return ERROR_OK;
1819 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1820 struct mem_param *mem_params, int num_reg_params,
1821 struct reg_param *reg_params, target_addr_t entry_point,
1822 target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
1824 struct stm8_common *stm8 = target_to_stm8(target);
1826 uint32_t context[STM8_NUM_REGS];
1827 int retval = ERROR_OK;
1829 LOG_DEBUG("Running algorithm");
1831 /* NOTE: stm8_run_algorithm requires that each
1832 algorithm uses a software breakpoint
1833 at the exit point */
1835 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1836 LOG_ERROR("current target isn't a STM8 target");
1837 return ERROR_TARGET_INVALID;
1840 if (target->state != TARGET_HALTED) {
1841 LOG_WARNING("target not halted");
1842 return ERROR_TARGET_NOT_HALTED;
1845 /* refresh core register cache */
1846 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1847 if (!stm8->core_cache->reg_list[i].valid)
1848 stm8->read_core_reg(target, i);
1849 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1852 for (int i = 0; i < num_mem_params; i++) {
1853 if (mem_params[i].direction == PARAM_IN)
1854 continue;
1855 retval = target_write_buffer(target, mem_params[i].address,
1856 mem_params[i].size, mem_params[i].value);
1857 if (retval != ERROR_OK)
1858 return retval;
1861 for (int i = 0; i < num_reg_params; i++) {
1862 if (reg_params[i].direction == PARAM_IN)
1863 continue;
1865 struct reg *reg = register_get_by_name(stm8->core_cache,
1866 reg_params[i].reg_name, false);
1868 if (!reg) {
1869 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1870 return ERROR_COMMAND_SYNTAX_ERROR;
1873 if (reg_params[i].size != 32) {
1874 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1875 reg_params[i].reg_name);
1876 return ERROR_COMMAND_SYNTAX_ERROR;
1879 stm8_set_core_reg(reg, reg_params[i].value);
1882 retval = stm8_run_and_wait(target, entry_point,
1883 timeout_ms, exit_point, stm8);
1885 if (retval != ERROR_OK)
1886 return retval;
1888 for (int i = 0; i < num_mem_params; i++) {
1889 if (mem_params[i].direction != PARAM_OUT) {
1890 retval = target_read_buffer(target, mem_params[i].address,
1891 mem_params[i].size, mem_params[i].value);
1892 if (retval != ERROR_OK)
1893 return retval;
1897 for (int i = 0; i < num_reg_params; i++) {
1898 if (reg_params[i].direction != PARAM_OUT) {
1899 struct reg *reg = register_get_by_name(stm8->core_cache,
1900 reg_params[i].reg_name, false);
1901 if (!reg) {
1902 LOG_ERROR("BUG: register '%s' not found",
1903 reg_params[i].reg_name);
1904 return ERROR_COMMAND_SYNTAX_ERROR;
1907 if (reg_params[i].size != 32) {
1908 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1909 reg_params[i].reg_name);
1910 return ERROR_COMMAND_SYNTAX_ERROR;
1913 buf_set_u32(reg_params[i].value,
1914 0, 32, buf_get_u32(reg->value, 0, 32));
1918 /* restore everything we saved before */
1919 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1920 uint32_t regvalue;
1921 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1922 if (regvalue != context[i]) {
1923 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1924 stm8->core_cache->reg_list[i].name, context[i]);
1925 buf_set_u32(stm8->core_cache->reg_list[i].value,
1926 0, 32, context[i]);
1927 stm8->core_cache->reg_list[i].valid = true;
1928 stm8->core_cache->reg_list[i].dirty = true;
1932 return ERROR_OK;
1935 static int stm8_jim_configure(struct target *target, struct jim_getopt_info *goi)
1937 struct stm8_common *stm8 = target_to_stm8(target);
1938 jim_wide w;
1939 int e;
1940 const char *arg;
1942 arg = Jim_GetString(goi->argv[0], NULL);
1943 if (!strcmp(arg, "-blocksize")) {
1944 e = jim_getopt_string(goi, &arg, NULL);
1945 if (e != JIM_OK)
1946 return e;
1948 if (goi->argc == 0) {
1949 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1950 "-blocksize ?bytes? ...");
1951 return JIM_ERR;
1954 e = jim_getopt_wide(goi, &w);
1955 if (e != JIM_OK)
1956 return e;
1958 stm8->blocksize = w;
1959 LOG_DEBUG("blocksize=%8.8" PRIx32, stm8->blocksize);
1960 return JIM_OK;
1962 if (!strcmp(arg, "-flashstart")) {
1963 e = jim_getopt_string(goi, &arg, NULL);
1964 if (e != JIM_OK)
1965 return e;
1967 if (goi->argc == 0) {
1968 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1969 "-flashstart ?address? ...");
1970 return JIM_ERR;
1973 e = jim_getopt_wide(goi, &w);
1974 if (e != JIM_OK)
1975 return e;
1977 stm8->flashstart = w;
1978 LOG_DEBUG("flashstart=%8.8" PRIx32, stm8->flashstart);
1979 return JIM_OK;
1981 if (!strcmp(arg, "-flashend")) {
1982 e = jim_getopt_string(goi, &arg, NULL);
1983 if (e != JIM_OK)
1984 return e;
1986 if (goi->argc == 0) {
1987 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1988 "-flashend ?address? ...");
1989 return JIM_ERR;
1992 e = jim_getopt_wide(goi, &w);
1993 if (e != JIM_OK)
1994 return e;
1996 stm8->flashend = w;
1997 LOG_DEBUG("flashend=%8.8" PRIx32, stm8->flashend);
1998 return JIM_OK;
2000 if (!strcmp(arg, "-eepromstart")) {
2001 e = jim_getopt_string(goi, &arg, NULL);
2002 if (e != JIM_OK)
2003 return e;
2005 if (goi->argc == 0) {
2006 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2007 "-eepromstart ?address? ...");
2008 return JIM_ERR;
2011 e = jim_getopt_wide(goi, &w);
2012 if (e != JIM_OK)
2013 return e;
2015 stm8->eepromstart = w;
2016 LOG_DEBUG("eepromstart=%8.8" PRIx32, stm8->eepromstart);
2017 return JIM_OK;
2019 if (!strcmp(arg, "-eepromend")) {
2020 e = jim_getopt_string(goi, &arg, NULL);
2021 if (e != JIM_OK)
2022 return e;
2024 if (goi->argc == 0) {
2025 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2026 "-eepromend ?address? ...");
2027 return JIM_ERR;
2030 e = jim_getopt_wide(goi, &w);
2031 if (e != JIM_OK)
2032 return e;
2034 stm8->eepromend = w;
2035 LOG_DEBUG("eepromend=%8.8" PRIx32, stm8->eepromend);
2036 return JIM_OK;
2038 if (!strcmp(arg, "-optionstart")) {
2039 e = jim_getopt_string(goi, &arg, NULL);
2040 if (e != JIM_OK)
2041 return e;
2043 if (goi->argc == 0) {
2044 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2045 "-optionstart ?address? ...");
2046 return JIM_ERR;
2049 e = jim_getopt_wide(goi, &w);
2050 if (e != JIM_OK)
2051 return e;
2053 stm8->optionstart = w;
2054 LOG_DEBUG("optionstart=%8.8" PRIx32, stm8->optionstart);
2055 return JIM_OK;
2057 if (!strcmp(arg, "-optionend")) {
2058 e = jim_getopt_string(goi, &arg, NULL);
2059 if (e != JIM_OK)
2060 return e;
2062 if (goi->argc == 0) {
2063 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2064 "-optionend ?address? ...");
2065 return JIM_ERR;
2068 e = jim_getopt_wide(goi, &w);
2069 if (e != JIM_OK)
2070 return e;
2072 stm8->optionend = w;
2073 LOG_DEBUG("optionend=%8.8" PRIx32, stm8->optionend);
2074 return JIM_OK;
2076 if (!strcmp(arg, "-enable_step_irq")) {
2077 e = jim_getopt_string(goi, &arg, NULL);
2078 if (e != JIM_OK)
2079 return e;
2081 stm8->enable_step_irq = true;
2082 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2083 return JIM_OK;
2085 if (!strcmp(arg, "-enable_stm8l")) {
2086 e = jim_getopt_string(goi, &arg, NULL);
2087 if (e != JIM_OK)
2088 return e;
2090 stm8->enable_stm8l = true;
2091 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2092 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2093 return JIM_OK;
2095 return JIM_CONTINUE;
2098 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2100 const char *msg;
2101 struct target *target = get_current_target(CMD_CTX);
2102 struct stm8_common *stm8 = target_to_stm8(target);
2103 bool enable = stm8->enable_step_irq;
2105 if (CMD_ARGC > 0) {
2106 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2107 stm8->enable_step_irq = enable;
2109 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2110 command_print(CMD, "enable_step_irq = %s", msg);
2111 return ERROR_OK;
2114 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2116 const char *msg;
2117 struct target *target = get_current_target(CMD_CTX);
2118 struct stm8_common *stm8 = target_to_stm8(target);
2119 bool enable = stm8->enable_stm8l;
2121 if (CMD_ARGC > 0) {
2122 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2123 stm8->enable_stm8l = enable;
2125 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2126 command_print(CMD, "enable_stm8l = %s", msg);
2127 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2128 return ERROR_OK;
2131 static const struct command_registration stm8_exec_command_handlers[] = {
2133 .name = "enable_step_irq",
2134 .handler = stm8_handle_enable_step_irq_command,
2135 .mode = COMMAND_ANY,
2136 .help = "Enable/disable irq handling during step",
2137 .usage = "[1/0]",
2140 .name = "enable_stm8l",
2141 .handler = stm8_handle_enable_stm8l_command,
2142 .mode = COMMAND_ANY,
2143 .help = "Enable/disable STM8L flash programming",
2144 .usage = "[1/0]",
2146 COMMAND_REGISTRATION_DONE
2149 static const struct command_registration stm8_command_handlers[] = {
2151 .name = "stm8",
2152 .mode = COMMAND_ANY,
2153 .help = "stm8 command group",
2154 .usage = "",
2155 .chain = stm8_exec_command_handlers,
2157 COMMAND_REGISTRATION_DONE
2160 struct target_type stm8_target = {
2161 .name = "stm8",
2163 .poll = stm8_poll,
2164 .arch_state = stm8_arch_state,
2166 .halt = stm8_halt,
2167 .resume = stm8_resume,
2168 .step = stm8_step,
2170 .assert_reset = stm8_reset_assert,
2171 .deassert_reset = stm8_reset_deassert,
2173 .get_gdb_arch = stm8_get_gdb_arch,
2174 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2176 .read_memory = stm8_read_memory,
2177 .write_memory = stm8_write_memory,
2178 .checksum_memory = stm8_checksum_memory,
2179 .blank_check_memory = stm8_blank_check_memory,
2181 .run_algorithm = stm8_run_algorithm,
2183 .add_breakpoint = stm8_add_breakpoint,
2184 .remove_breakpoint = stm8_remove_breakpoint,
2185 .add_watchpoint = stm8_add_watchpoint,
2186 .remove_watchpoint = stm8_remove_watchpoint,
2188 .commands = stm8_command_handlers,
2189 .target_create = stm8_target_create,
2190 .init_target = stm8_init,
2191 .examine = stm8_examine,
2193 .deinit_target = stm8_deinit,
2194 .target_jim_configure = stm8_jim_configure,