jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / stm8.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /*
4 * OpenOCD STM8 target driver
5 * Copyright (C) 2017 Ake Rehnman
6 * ake.rehnman(at)gmail.com
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
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"
24
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;
39
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 },
55 };
56
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
64
65 #define CC_I0 0x8
66 #define CC_I1 0x20
67
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
75
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
82
83 #define STE 0x40
84 #define STF 0x20
85 #define RST 0x10
86 #define BRW 0x08
87 #define BK2F 0x04
88 #define BK1F 0x02
89
90 #define SWBRK 0x20
91 #define SWBKF 0x10
92 #define STALL 0x08
93 #define FLUSH 0x01
94
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
101
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
108
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
115
116 /* FLASH_CR2 */
117 #define OPT 0x80
118 #define WPRG 0x40
119 #define ERASE 0x20
120 #define FPRG 0x10
121 #define PRG 0x01
122
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
132
133 #define SWIM_CSR 0x7f80
134
135 #define STM8_BREAK 0x8B
136
137 enum mem_type {
138 RAM,
139 FLASH,
140 EEPROM,
141 OPTION
142 };
143
144 struct stm8_algorithm {
145 int common_magic;
146 };
147
148 struct stm8_core_reg {
149 uint32_t num;
150 struct target *target;
151 };
152
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
162 };
163
164 struct stm8_comparator {
165 bool used;
166 uint32_t bp_value;
167 uint32_t reg_address;
168 enum hw_break_type type;
169 };
170
171 static int stm8_adapter_read_memory(struct target *target,
172 uint32_t addr, int size, int count, void *buf)
173 {
174 return swim_read_mem(addr, size, count, buf);
175 }
176
177 static int stm8_adapter_write_memory(struct target *target,
178 uint32_t addr, int size, int count, const void *buf)
179 {
180 return swim_write_mem(addr, size, count, buf);
181 }
182
183 static int stm8_write_u8(struct target *target,
184 uint32_t addr, uint8_t val)
185 {
186 uint8_t buf[1];
187
188 buf[0] = val;
189 return swim_write_mem(addr, 1, 1, buf);
190 }
191
192 static int stm8_read_u8(struct target *target,
193 uint32_t addr, uint8_t *val)
194 {
195 return swim_read_mem(addr, 1, 1, val);
196 }
197
198 /*
199 <enable == 0> Disables interrupts.
200 If interrupts are enabled they are masked and the cc register
201 is saved.
202
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
209 */
210 static int stm8_enable_interrupts(struct target *target, int enable)
211 {
212 struct stm8_common *stm8 = target_to_stm8(target);
213 uint8_t cc;
214
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);
237 }
238
239 return ERROR_OK;
240 }
241
242 static int stm8_set_hwbreak(struct target *target,
243 struct stm8_comparator comparator_list[])
244 {
245 uint8_t buf[3];
246 int i, ret;
247
248 /* Refer to Table 4 in UM0470 */
249 uint8_t bc = 0x5;
250 uint8_t bir = 0;
251 uint8_t biw = 0;
252
253 uint32_t data;
254 uint32_t addr;
255
256 if (!comparator_list[0].used) {
257 comparator_list[0].type = HWBRK_EXEC;
258 comparator_list[0].bp_value = -1;
259 }
260
261 if (!comparator_list[1].used) {
262 comparator_list[1].type = HWBRK_EXEC;
263 comparator_list[1].bp_value = -1;
264 }
265
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;
270 }
271
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;
287 }
288 }
289
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;
305 }
306 }
307
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;
313 }
314 }
315
316 for (i = 0; i < 2; i++) {
317 data = comparator_list[i].bp_value;
318 addr = comparator_list[i].reg_address;
319
320 buf[0] = data >> 16;
321 buf[1] = data >> 8;
322 buf[2] = data;
323
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;
333 }
334
335 if (ret != ERROR_OK)
336 return ret;
337
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;
343
344 }
345 return ERROR_OK;
346 }
347
348 /* read DM control and status regs */
349 static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,
350 uint8_t *csr2)
351 {
352 int ret;
353 uint8_t buf[2];
354
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;
363 }
364
365 /* set or clear the single step flag in DM */
366 static int stm8_config_step(struct target *target, int enable)
367 {
368 int ret;
369 uint8_t csr1, csr2;
370
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;
378
379 ret = stm8_write_u8(target, DM_CSR1, csr1);
380 if (ret != ERROR_OK)
381 return ret;
382 return ERROR_OK;
383 }
384
385 /* set the stall flag in DM */
386 static int stm8_debug_stall(struct target *target)
387 {
388 int ret;
389 uint8_t csr1, csr2;
390
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;
399 }
400
401 static int stm8_configure_break_unit(struct target *target)
402 {
403 /* get pointers to arch-specific information */
404 struct stm8_common *stm8 = target_to_stm8(target);
405
406 if (stm8->bp_scanned)
407 return ERROR_OK;
408
409 stm8->num_hw_bpoints = 2;
410 stm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;
411
412 stm8->hw_break_list = calloc(stm8->num_hw_bpoints,
413 sizeof(struct stm8_comparator));
414
415 stm8->hw_break_list[0].reg_address = 0;
416 stm8->hw_break_list[1].reg_address = 1;
417
418 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8->num_hw_bpoints,
419 stm8->num_hw_bpoints);
420
421 stm8->bp_scanned = true;
422
423 return ERROR_OK;
424 }
425
426 static int stm8_examine_debug_reason(struct target *target)
427 {
428 int retval;
429 uint8_t csr1, csr2;
430
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);
434
435 if ((target->debug_reason != DBG_REASON_DBGRQ)
436 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
437
438 if (retval != ERROR_OK)
439 return retval;
440
441 if (csr1 & RST)
442 /* halted on reset */
443 target->debug_reason = DBG_REASON_UNDEFINED;
444
445 if (csr1 & (BK1F+BK2F))
446 /* we have halted on a breakpoint (or wp)*/
447 target->debug_reason = DBG_REASON_BREAKPOINT;
448
449 if (csr2 & SWBKF)
450 /* we have halted on a breakpoint */
451 target->debug_reason = DBG_REASON_BREAKPOINT;
452
453 }
454
455 return ERROR_OK;
456 }
457
458 static int stm8_debug_entry(struct target *target)
459 {
460 struct stm8_common *stm8 = target_to_stm8(target);
461
462 /* restore interrupts */
463 stm8_enable_interrupts(target, 1);
464
465 stm8_save_context(target);
466
467 /* make sure stepping disabled STE bit in CSR1 cleared */
468 stm8_config_step(target, 0);
469
470 /* attempt to find halt reason */
471 stm8_examine_debug_reason(target);
472
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));
476
477 return ERROR_OK;
478 }
479
480 /* clear stall flag in DM and flush instruction pipe */
481 static int stm8_exit_debug(struct target *target)
482 {
483 int ret;
484 uint8_t csr1, csr2;
485
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;
493
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;
500 }
501
502 static int stm8_read_regs(struct target *target, uint32_t regs[])
503 {
504 int ret;
505 uint8_t buf[11];
506
507 ret = stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);
508 if (ret != ERROR_OK)
509 return ret;
510
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];
517
518 return ERROR_OK;
519 }
520
521 static int stm8_write_regs(struct target *target, uint32_t regs[])
522 {
523 int ret;
524 uint8_t buf[11];
525
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];
532
533 ret = stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);
534 if (ret != ERROR_OK)
535 return ret;
536
537 return ERROR_OK;
538 }
539
540 static int stm8_get_core_reg(struct reg *reg)
541 {
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 = target_to_stm8(target);
546
547 if (target->state != TARGET_HALTED)
548 return ERROR_TARGET_NOT_HALTED;
549
550 retval = stm8_target->read_core_reg(target, stm8_reg->num);
551
552 return retval;
553 }
554
555 static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
556 {
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);
560
561 if (target->state != TARGET_HALTED)
562 return ERROR_TARGET_NOT_HALTED;
563
564 buf_set_u32(reg->value, 0, 32, value);
565 reg->dirty = true;
566 reg->valid = true;
567
568 return ERROR_OK;
569 }
570
571 static int stm8_save_context(struct target *target)
572 {
573 unsigned int i;
574
575 /* get pointers to arch-specific information */
576 struct stm8_common *stm8 = target_to_stm8(target);
577
578 /* read core registers */
579 stm8_read_regs(target, stm8->core_regs);
580
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);
584 }
585
586 return ERROR_OK;
587 }
588
589 static int stm8_restore_context(struct target *target)
590 {
591 unsigned int i;
592
593 /* get pointers to arch-specific information */
594 struct stm8_common *stm8 = target_to_stm8(target);
595
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);
599 }
600
601 /* write core regs */
602 stm8_write_regs(target, stm8->core_regs);
603
604 return ERROR_OK;
605 }
606
607 static int stm8_unlock_flash(struct target *target)
608 {
609 uint8_t data[1];
610
611 struct stm8_common *stm8 = target_to_stm8(target);
612
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);
619 }
620
621 stm8_read_u8(target, stm8->flash_iapsr, data);
622 if (~data[0] & PUL)
623 return ERROR_FAIL;
624 return ERROR_OK;
625 }
626
627 static int stm8_unlock_eeprom(struct target *target)
628 {
629 uint8_t data[1];
630
631 struct stm8_common *stm8 = target_to_stm8(target);
632
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);
639 }
640
641 stm8_read_u8(target, stm8->flash_iapsr, data);
642 if (~data[0] & DUL)
643 return ERROR_FAIL;
644 return ERROR_OK;
645 }
646
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)
651 {
652 struct stm8_common *stm8 = target_to_stm8(target);
653
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;
660
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);
675 }
676
677 if (size == 2) {
678 /* we don't support short writes */
679 count = count * 2;
680 size = 1;
681 }
682
683 bytecnt = count * size;
684
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;
706 }
707
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;
714
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);
722 }
723 if (i == 16)
724 return ERROR_FAIL;
725 }
726
727 /* disable write access */
728 res = stm8_write_u8(target, stm8->flash_iapsr, 0x0);
729
730 if (res != ERROR_OK)
731 return ERROR_FAIL;
732
733 return ERROR_OK;
734 }
735
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)
739 {
740 struct stm8_common *stm8 = target_to_stm8(target);
741
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);
746
747 if (target->state != TARGET_HALTED)
748 LOG_WARNING("target not halted");
749
750 int retval;
751
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);
763
764 if (retval != ERROR_OK)
765 return ERROR_TARGET_FAILURE;
766
767 return retval;
768 }
769
770 static int stm8_read_memory(struct target *target, target_addr_t address,
771 uint32_t size, uint32_t count, uint8_t *buffer)
772 {
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);
777
778 if (target->state != TARGET_HALTED)
779 LOG_WARNING("target not halted");
780
781 int retval;
782 retval = stm8_adapter_read_memory(target, address, size, count, buffer);
783
784 if (retval != ERROR_OK)
785 return ERROR_TARGET_FAILURE;
786
787 return retval;
788 }
789
790 static int stm8_speed(int speed)
791 {
792 int retval;
793 uint8_t csr;
794
795 LOG_DEBUG("stm8_speed: %d", speed);
796
797 csr = SAFE_MASK | SWIM_DM;
798 if (speed >= SWIM_FREQ_HIGH)
799 csr |= HS;
800
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);
806 }
807
808 static int stm8_init(struct command_context *cmd_ctx, struct target *target)
809 {
810 /*
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
815 */
816 adapter_speed = adapter_driver->speed;
817 adapter_driver->speed = stm8_speed;
818
819 stm8_build_reg_cache(target);
820
821 return ERROR_OK;
822 }
823
824 static int stm8_poll(struct target *target)
825 {
826 int retval = ERROR_OK;
827 uint8_t csr1, csr2;
828
829 #ifdef LOG_STM8
830 LOG_DEBUG("target->state=%d", target->state);
831 #endif
832
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);
837 /*
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
840 */
841 return ERROR_OK;
842 }
843
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.");
849
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;
854 }
855
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);
862 }
863 }
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;
870 }
871
872 static int stm8_halt(struct target *target)
873 {
874 LOG_DEBUG("target->state: %s", target_state_name(target));
875
876 if (target->state == TARGET_HALTED) {
877 LOG_DEBUG("target was already halted");
878 return ERROR_OK;
879 }
880
881 if (target->state == TARGET_UNKNOWN)
882 LOG_WARNING("target was in unknown state when halt was requested");
883
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()
887 */
888 target->debug_reason = DBG_REASON_DBGRQ;
889
890 return ERROR_OK;
891 }
892
893
894 /* break processor */
895 stm8_debug_stall(target);
896
897 target->debug_reason = DBG_REASON_DBGRQ;
898
899 return ERROR_OK;
900 }
901
902 static int stm8_reset_assert(struct target *target)
903 {
904 int res = ERROR_OK;
905 struct stm8_common *stm8 = target_to_stm8(target);
906 bool use_srst_fallback = true;
907
908 enum reset_types jtag_reset_config = jtag_get_reset_config();
909
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;
918 }
919
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;
925 }
926
927 /* registers are now invalid */
928 register_cache_invalidate(stm8->core_cache);
929
930 target->state = TARGET_RESET;
931 target->debug_reason = DBG_REASON_NOTHALTED;
932
933 if (target->reset_halt) {
934 res = target_halt(target);
935 if (res != ERROR_OK)
936 return res;
937 }
938
939 return ERROR_OK;
940 }
941
942 static int stm8_reset_deassert(struct target *target)
943 {
944 int res;
945 enum reset_types jtag_reset_config = jtag_get_reset_config();
946
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;
951 }
952
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;
957
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);
962 }
963
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)
967 {
968 struct stm8_common *stm8 = target_to_stm8(target);
969
970 /* configure single step mode */
971 stm8_config_step(target, 1);
972
973 /* disable interrupts while stepping */
974 if (!stm8->enable_step_irq)
975 stm8_enable_interrupts(target, 0);
976
977 /* exit debug mode */
978 stm8_exit_debug(target);
979
980 stm8_debug_entry(target);
981
982 return ERROR_OK;
983 }
984
985 static int stm8_resume(struct target *target, int current,
986 target_addr_t address, int handle_breakpoints,
987 int debug_execution)
988 {
989 struct stm8_common *stm8 = target_to_stm8(target);
990 struct breakpoint *breakpoint = NULL;
991 uint32_t resume_pc;
992
993 LOG_DEBUG("%d " TARGET_ADDR_FMT " %d %d", current, address,
994 handle_breakpoints, debug_execution);
995
996 if (target->state != TARGET_HALTED) {
997 LOG_WARNING("target not halted");
998 return ERROR_TARGET_NOT_HALTED;
999 }
1000
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);
1007 }
1008
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;
1016 }
1017
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);
1024
1025 stm8_restore_context(target);
1026
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);
1037 }
1038 }
1039
1040 /* disable interrupts if we are debugging */
1041 if (debug_execution)
1042 stm8_enable_interrupts(target, 0);
1043
1044 /* exit debug mode */
1045 stm8_exit_debug(target);
1046 target->debug_reason = DBG_REASON_NOTHALTED;
1047
1048 /* registers are now invalid */
1049 register_cache_invalidate(stm8->core_cache);
1050
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);
1059 }
1060
1061 return ERROR_OK;
1062 }
1063
1064 static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
1065 {
1066 stm8->enable_stm8l = enable_stm8l;
1067
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;
1080 }
1081 return ERROR_OK;
1082 }
1083
1084 static int stm8_init_arch_info(struct target *target,
1085 struct stm8_common *stm8, struct jtag_tap *tap)
1086 {
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;
1098
1099 /* has breakpoint/watchpoint unit been scanned */
1100 stm8->bp_scanned = false;
1101 stm8->hw_break_list = NULL;
1102
1103 stm8->read_core_reg = stm8_read_core_reg;
1104 stm8->write_core_reg = stm8_write_core_reg;
1105
1106 stm8_init_flash_regs(0, stm8);
1107
1108 return ERROR_OK;
1109 }
1110
1111 static int stm8_target_create(struct target *target,
1112 Jim_Interp *interp)
1113 {
1114
1115 struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));
1116
1117 stm8_init_arch_info(target, stm8, target->tap);
1118 stm8_configure_break_unit(target);
1119
1120 return ERROR_OK;
1121 }
1122
1123 static int stm8_read_core_reg(struct target *target, unsigned int num)
1124 {
1125 uint32_t reg_value;
1126
1127 /* get pointers to arch-specific information */
1128 struct stm8_common *stm8 = target_to_stm8(target);
1129
1130 if (num >= STM8_NUM_REGS)
1131 return ERROR_COMMAND_SYNTAX_ERROR;
1132
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;
1138
1139 return ERROR_OK;
1140 }
1141
1142 static int stm8_write_core_reg(struct target *target, unsigned int num)
1143 {
1144 uint32_t reg_value;
1145
1146 /* get pointers to arch-specific information */
1147 struct stm8_common *stm8 = target_to_stm8(target);
1148
1149 if (num >= STM8_NUM_REGS)
1150 return ERROR_COMMAND_SYNTAX_ERROR;
1151
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;
1157
1158 return ERROR_OK;
1159 }
1160
1161 static const char *stm8_get_gdb_arch(struct target *target)
1162 {
1163 return "stm8";
1164 }
1165
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)
1168 {
1169 /* get pointers to arch-specific information */
1170 struct stm8_common *stm8 = target_to_stm8(target);
1171 unsigned int i;
1172
1173 *reg_list_size = STM8_NUM_REGS;
1174 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1175
1176 for (i = 0; i < STM8_NUM_REGS; i++)
1177 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1178
1179 return ERROR_OK;
1180 }
1181
1182 static const struct reg_arch_type stm8_reg_type = {
1183 .get = stm8_get_core_reg,
1184 .set = stm8_set_core_reg,
1185 };
1186
1187 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1188 {
1189 /* get pointers to arch-specific information */
1190 struct stm8_common *stm8 = target_to_stm8(target);
1191
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;
1200
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;
1208
1209 for (i = 0; i < num_regs; i++) {
1210 arch_info[i].num = stm8_regs[i].id;
1211 arch_info[i].target = target;
1212
1213 reg_list[i].name = stm8_regs[i].name;
1214 reg_list[i].size = stm8_regs[i].bits;
1215
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];
1220
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;
1227 }
1228
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 */
1234
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");
1241 }
1242
1243 return cache;
1244 }
1245
1246 static void stm8_free_reg_cache(struct target *target)
1247 {
1248 struct stm8_common *stm8 = target_to_stm8(target);
1249 struct reg_cache *cache;
1250 struct reg *reg;
1251 unsigned int i;
1252
1253 cache = stm8->core_cache;
1254
1255 if (!cache)
1256 return;
1257
1258 for (i = 0; i < cache->num_regs; i++) {
1259 reg = &cache->reg_list[i];
1260
1261 free(reg->feature);
1262 free(reg->reg_data_type);
1263 free(reg->value);
1264 }
1265
1266 free(cache->reg_list[0].arch_info);
1267 free(cache->reg_list);
1268 free(cache);
1269
1270 stm8->core_cache = NULL;
1271 }
1272
1273 static void stm8_deinit(struct target *target)
1274 {
1275 struct stm8_common *stm8 = target_to_stm8(target);
1276
1277 free(stm8->hw_break_list);
1278
1279 stm8_free_reg_cache(target);
1280
1281 free(stm8);
1282 }
1283
1284 static int stm8_arch_state(struct target *target)
1285 {
1286 struct stm8_common *stm8 = target_to_stm8(target);
1287
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));
1291
1292 return ERROR_OK;
1293 }
1294
1295 static int stm8_step(struct target *target, int current,
1296 target_addr_t address, int handle_breakpoints)
1297 {
1298 LOG_DEBUG("%x " TARGET_ADDR_FMT " %x",
1299 current, address, handle_breakpoints);
1300
1301 /* get pointers to arch-specific information */
1302 struct stm8_common *stm8 = target_to_stm8(target);
1303 struct breakpoint *breakpoint = NULL;
1304
1305 if (target->state != TARGET_HALTED) {
1306 LOG_WARNING("target not halted");
1307 return ERROR_TARGET_NOT_HALTED;
1308 }
1309
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;
1315 }
1316
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);
1323 }
1324
1325 /* restore context */
1326 stm8_restore_context(target);
1327
1328 /* configure single step mode */
1329 stm8_config_step(target, 1);
1330
1331 target->debug_reason = DBG_REASON_SINGLESTEP;
1332
1333 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1334
1335 /* disable interrupts while stepping */
1336 if (!stm8->enable_step_irq)
1337 stm8_enable_interrupts(target, 0);
1338
1339 /* exit debug mode */
1340 stm8_exit_debug(target);
1341
1342 /* registers are now invalid */
1343 register_cache_invalidate(stm8->core_cache);
1344
1345 LOG_DEBUG("target stepped ");
1346 stm8_debug_entry(target);
1347
1348 if (breakpoint)
1349 stm8_set_breakpoint(target, breakpoint);
1350
1351 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1352
1353 return ERROR_OK;
1354 }
1355
1356 static void stm8_enable_breakpoints(struct target *target)
1357 {
1358 struct breakpoint *breakpoint = target->breakpoints;
1359
1360 /* set any pending breakpoints */
1361 while (breakpoint) {
1362 if (!breakpoint->is_set)
1363 stm8_set_breakpoint(target, breakpoint);
1364 breakpoint = breakpoint->next;
1365 }
1366 }
1367
1368 static int stm8_set_breakpoint(struct target *target,
1369 struct breakpoint *breakpoint)
1370 {
1371 struct stm8_common *stm8 = target_to_stm8(target);
1372 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1373 int retval;
1374
1375 if (breakpoint->is_set) {
1376 LOG_WARNING("breakpoint already set");
1377 return ERROR_OK;
1378 }
1379
1380 if (breakpoint->type == BKPT_HARD) {
1381 int bp_num = 0;
1382
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;
1389 }
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;
1394
1395 retval = stm8_set_hwbreak(target, comparator_list);
1396 if (retval != ERROR_OK)
1397 return retval;
1398
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;
1406
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;
1414
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;
1423 }
1424 } else {
1425 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1426 }
1427 breakpoint->is_set = true;
1428 }
1429
1430 return ERROR_OK;
1431 }
1432
1433 static int stm8_add_breakpoint(struct target *target,
1434 struct breakpoint *breakpoint)
1435 {
1436 struct stm8_common *stm8 = target_to_stm8(target);
1437 int ret;
1438
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;
1443 }
1444
1445 ret = stm8_set_breakpoint(target, breakpoint);
1446 if (ret != ERROR_OK)
1447 return ret;
1448
1449 stm8->num_hw_bpoints_avail--;
1450 return ERROR_OK;
1451 }
1452
1453 ret = stm8_set_breakpoint(target, breakpoint);
1454 if (ret != ERROR_OK)
1455 return ret;
1456
1457 return ERROR_OK;
1458 }
1459
1460 static int stm8_unset_breakpoint(struct target *target,
1461 struct breakpoint *breakpoint)
1462 {
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;
1467
1468 if (!breakpoint->is_set) {
1469 LOG_WARNING("breakpoint not set");
1470 return ERROR_OK;
1471 }
1472
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;
1479 }
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;
1492
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;
1499
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;
1505 }
1506 } else
1507 return ERROR_FAIL;
1508 }
1509 breakpoint->is_set = false;
1510
1511 return ERROR_OK;
1512 }
1513
1514 static int stm8_remove_breakpoint(struct target *target,
1515 struct breakpoint *breakpoint)
1516 {
1517 /* get pointers to arch-specific information */
1518 struct stm8_common *stm8 = target_to_stm8(target);
1519
1520 if (target->state != TARGET_HALTED) {
1521 LOG_WARNING("target not halted");
1522 return ERROR_TARGET_NOT_HALTED;
1523 }
1524
1525 if (breakpoint->is_set)
1526 stm8_unset_breakpoint(target, breakpoint);
1527
1528 if (breakpoint->type == BKPT_HARD)
1529 stm8->num_hw_bpoints_avail++;
1530
1531 return ERROR_OK;
1532 }
1533
1534 static int stm8_set_watchpoint(struct target *target,
1535 struct watchpoint *watchpoint)
1536 {
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;
1541
1542 if (watchpoint->is_set) {
1543 LOG_WARNING("watchpoint already set");
1544 return ERROR_OK;
1545 }
1546
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;
1552 }
1553
1554 if (watchpoint->length != 1) {
1555 LOG_ERROR("Only watchpoints of length 1 are supported");
1556 return ERROR_TARGET_UNALIGNED_ACCESS;
1557 }
1558
1559 enum hw_break_type enable = 0;
1560
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");
1573 }
1574
1575 comparator_list[wp_num].used = true;
1576 comparator_list[wp_num].bp_value = watchpoint->address;
1577 comparator_list[wp_num].type = enable;
1578
1579 ret = stm8_set_hwbreak(target, comparator_list);
1580 if (ret != ERROR_OK) {
1581 comparator_list[wp_num].used = false;
1582 return ret;
1583 }
1584
1585 watchpoint_set(watchpoint, wp_num);
1586
1587 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1588 wp_num,
1589 comparator_list[wp_num].bp_value);
1590
1591 return ERROR_OK;
1592 }
1593
1594 static int stm8_add_watchpoint(struct target *target,
1595 struct watchpoint *watchpoint)
1596 {
1597 int ret;
1598 struct stm8_common *stm8 = target_to_stm8(target);
1599
1600 if (stm8->num_hw_bpoints_avail < 1) {
1601 LOG_INFO("no hardware watchpoints available");
1602 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1603 }
1604
1605 ret = stm8_set_watchpoint(target, watchpoint);
1606 if (ret != ERROR_OK)
1607 return ret;
1608
1609 stm8->num_hw_bpoints_avail--;
1610 return ERROR_OK;
1611 }
1612
1613 static void stm8_enable_watchpoints(struct target *target)
1614 {
1615 struct watchpoint *watchpoint = target->watchpoints;
1616
1617 /* set any pending watchpoints */
1618 while (watchpoint) {
1619 if (!watchpoint->is_set)
1620 stm8_set_watchpoint(target, watchpoint);
1621 watchpoint = watchpoint->next;
1622 }
1623 }
1624
1625 static int stm8_unset_watchpoint(struct target *target,
1626 struct watchpoint *watchpoint)
1627 {
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;
1631
1632 if (!watchpoint->is_set) {
1633 LOG_WARNING("watchpoint not set");
1634 return ERROR_OK;
1635 }
1636
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;
1641 }
1642 comparator_list[wp_num].used = false;
1643 watchpoint->is_set = false;
1644
1645 stm8_set_hwbreak(target, comparator_list);
1646
1647 return ERROR_OK;
1648 }
1649
1650 static int stm8_remove_watchpoint(struct target *target,
1651 struct watchpoint *watchpoint)
1652 {
1653 /* get pointers to arch-specific information */
1654 struct stm8_common *stm8 = target_to_stm8(target);
1655
1656 if (target->state != TARGET_HALTED) {
1657 LOG_WARNING("target not halted");
1658 return ERROR_TARGET_NOT_HALTED;
1659 }
1660
1661 if (watchpoint->is_set)
1662 stm8_unset_watchpoint(target, watchpoint);
1663
1664 stm8->num_hw_bpoints_avail++;
1665
1666 return ERROR_OK;
1667 }
1668
1669 static int stm8_examine(struct target *target)
1670 {
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();
1676
1677 if (!target_was_examined(target)) {
1678 if (!stm8->swim_configured) {
1679 stm8->swim_configured = true;
1680 /*
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.
1684 */
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");
1690 }
1691 } else {
1692 LOG_INFO("trying to reconnect");
1693
1694 retval = swim_reconnect();
1695 if (retval != ERROR_OK) {
1696 LOG_ERROR("reconnect failed");
1697 return ERROR_FAIL;
1698 }
1699
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;
1705 }
1706 }
1707
1708 target_set_examined(target);
1709
1710 return ERROR_OK;
1711 }
1712
1713 return ERROR_OK;
1714 }
1715
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)
1719 {
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;
1724
1725 static const uint8_t stm8_erase_check_code[] = {
1726 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1727 };
1728
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;
1733 }
1734
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;
1739
1740 target_write_buffer(target, erase_check_algorithm->address,
1741 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1742
1743 stm8_info.common_magic = STM8_COMMON_MAGIC;
1744
1745 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1746 buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
1747
1748 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1749 buf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);
1750
1751 init_reg_param(&reg_params[0], "a", 32, PARAM_IN_OUT);
1752 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1753
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);
1756
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);
1761
1762 if (retval == ERROR_OK)
1763 blocks[0].result = (*(reg_params[0].value) == 0xff);
1764
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]);
1769
1770 target_free_working_area(target, erase_check_algorithm);
1771
1772 if (retval != ERROR_OK)
1773 return retval;
1774
1775 return 1; /* only one block has been checked */
1776 }
1777
1778 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1779 uint32_t count, uint32_t *checksum)
1780 {
1781 /* let image_calculate_checksum() take care of business */
1782 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1783 }
1784
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 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1788 {
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;
1797
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;
1808 }
1809
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;
1814 }
1815
1816 return ERROR_OK;
1817 }
1818
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, int timeout_ms, void *arch_info)
1823 {
1824 struct stm8_common *stm8 = target_to_stm8(target);
1825
1826 uint32_t context[STM8_NUM_REGS];
1827 int retval = ERROR_OK;
1828
1829 LOG_DEBUG("Running algorithm");
1830
1831 /* NOTE: stm8_run_algorithm requires that each
1832 algorithm uses a software breakpoint
1833 at the exit point */
1834
1835 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1836 LOG_ERROR("current target isn't a STM8 target");
1837 return ERROR_TARGET_INVALID;
1838 }
1839
1840 if (target->state != TARGET_HALTED) {
1841 LOG_WARNING("target not halted");
1842 return ERROR_TARGET_NOT_HALTED;
1843 }
1844
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);
1850 }
1851
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;
1859 }
1860
1861 for (int i = 0; i < num_reg_params; i++) {
1862 if (reg_params[i].direction == PARAM_IN)
1863 continue;
1864
1865 struct reg *reg = register_get_by_name(stm8->core_cache,
1866 reg_params[i].reg_name, false);
1867
1868 if (!reg) {
1869 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1870 return ERROR_COMMAND_SYNTAX_ERROR;
1871 }
1872
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;
1877 }
1878
1879 stm8_set_core_reg(reg, reg_params[i].value);
1880 }
1881
1882 retval = stm8_run_and_wait(target, entry_point,
1883 timeout_ms, exit_point, stm8);
1884
1885 if (retval != ERROR_OK)
1886 return retval;
1887
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;
1894 }
1895 }
1896
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;
1905 }
1906
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;
1911 }
1912
1913 buf_set_u32(reg_params[i].value,
1914 0, 32, buf_get_u32(reg->value, 0, 32));
1915 }
1916 }
1917
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;
1929 }
1930 }
1931
1932 return ERROR_OK;
1933 }
1934
1935 static int stm8_jim_configure(struct target *target, struct jim_getopt_info *goi)
1936 {
1937 struct stm8_common *stm8 = target_to_stm8(target);
1938 jim_wide w;
1939 int e;
1940 const char *arg;
1941
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;
1947
1948 if (goi->argc == 0) {
1949 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1950 "-blocksize ?bytes? ...");
1951 return JIM_ERR;
1952 }
1953
1954 e = jim_getopt_wide(goi, &w);
1955 if (e != JIM_OK)
1956 return e;
1957
1958 stm8->blocksize = w;
1959 LOG_DEBUG("blocksize=%8.8" PRIx32, stm8->blocksize);
1960 return JIM_OK;
1961 }
1962 if (!strcmp(arg, "-flashstart")) {
1963 e = jim_getopt_string(goi, &arg, NULL);
1964 if (e != JIM_OK)
1965 return e;
1966
1967 if (goi->argc == 0) {
1968 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1969 "-flashstart ?address? ...");
1970 return JIM_ERR;
1971 }
1972
1973 e = jim_getopt_wide(goi, &w);
1974 if (e != JIM_OK)
1975 return e;
1976
1977 stm8->flashstart = w;
1978 LOG_DEBUG("flashstart=%8.8" PRIx32, stm8->flashstart);
1979 return JIM_OK;
1980 }
1981 if (!strcmp(arg, "-flashend")) {
1982 e = jim_getopt_string(goi, &arg, NULL);
1983 if (e != JIM_OK)
1984 return e;
1985
1986 if (goi->argc == 0) {
1987 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1988 "-flashend ?address? ...");
1989 return JIM_ERR;
1990 }
1991
1992 e = jim_getopt_wide(goi, &w);
1993 if (e != JIM_OK)
1994 return e;
1995
1996 stm8->flashend = w;
1997 LOG_DEBUG("flashend=%8.8" PRIx32, stm8->flashend);
1998 return JIM_OK;
1999 }
2000 if (!strcmp(arg, "-eepromstart")) {
2001 e = jim_getopt_string(goi, &arg, NULL);
2002 if (e != JIM_OK)
2003 return e;
2004
2005 if (goi->argc == 0) {
2006 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2007 "-eepromstart ?address? ...");
2008 return JIM_ERR;
2009 }
2010
2011 e = jim_getopt_wide(goi, &w);
2012 if (e != JIM_OK)
2013 return e;
2014
2015 stm8->eepromstart = w;
2016 LOG_DEBUG("eepromstart=%8.8" PRIx32, stm8->eepromstart);
2017 return JIM_OK;
2018 }
2019 if (!strcmp(arg, "-eepromend")) {
2020 e = jim_getopt_string(goi, &arg, NULL);
2021 if (e != JIM_OK)
2022 return e;
2023
2024 if (goi->argc == 0) {
2025 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2026 "-eepromend ?address? ...");
2027 return JIM_ERR;
2028 }
2029
2030 e = jim_getopt_wide(goi, &w);
2031 if (e != JIM_OK)
2032 return e;
2033
2034 stm8->eepromend = w;
2035 LOG_DEBUG("eepromend=%8.8" PRIx32, stm8->eepromend);
2036 return JIM_OK;
2037 }
2038 if (!strcmp(arg, "-optionstart")) {
2039 e = jim_getopt_string(goi, &arg, NULL);
2040 if (e != JIM_OK)
2041 return e;
2042
2043 if (goi->argc == 0) {
2044 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2045 "-optionstart ?address? ...");
2046 return JIM_ERR;
2047 }
2048
2049 e = jim_getopt_wide(goi, &w);
2050 if (e != JIM_OK)
2051 return e;
2052
2053 stm8->optionstart = w;
2054 LOG_DEBUG("optionstart=%8.8" PRIx32, stm8->optionstart);
2055 return JIM_OK;
2056 }
2057 if (!strcmp(arg, "-optionend")) {
2058 e = jim_getopt_string(goi, &arg, NULL);
2059 if (e != JIM_OK)
2060 return e;
2061
2062 if (goi->argc == 0) {
2063 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2064 "-optionend ?address? ...");
2065 return JIM_ERR;
2066 }
2067
2068 e = jim_getopt_wide(goi, &w);
2069 if (e != JIM_OK)
2070 return e;
2071
2072 stm8->optionend = w;
2073 LOG_DEBUG("optionend=%8.8" PRIx32, stm8->optionend);
2074 return JIM_OK;
2075 }
2076 if (!strcmp(arg, "-enable_step_irq")) {
2077 e = jim_getopt_string(goi, &arg, NULL);
2078 if (e != JIM_OK)
2079 return e;
2080
2081 stm8->enable_step_irq = true;
2082 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2083 return JIM_OK;
2084 }
2085 if (!strcmp(arg, "-enable_stm8l")) {
2086 e = jim_getopt_string(goi, &arg, NULL);
2087 if (e != JIM_OK)
2088 return e;
2089
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;
2094 }
2095 return JIM_CONTINUE;
2096 }
2097
2098 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2099 {
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;
2104
2105 if (CMD_ARGC > 0) {
2106 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2107 stm8->enable_step_irq = enable;
2108 }
2109 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2110 command_print(CMD, "enable_step_irq = %s", msg);
2111 return ERROR_OK;
2112 }
2113
2114 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2115 {
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;
2120
2121 if (CMD_ARGC > 0) {
2122 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2123 stm8->enable_stm8l = enable;
2124 }
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;
2129 }
2130
2131 static const struct command_registration stm8_exec_command_handlers[] = {
2132 {
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]",
2138 },
2139 {
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]",
2145 },
2146 COMMAND_REGISTRATION_DONE
2147 };
2148
2149 static const struct command_registration stm8_command_handlers[] = {
2150 {
2151 .name = "stm8",
2152 .mode = COMMAND_ANY,
2153 .help = "stm8 command group",
2154 .usage = "",
2155 .chain = stm8_exec_command_handlers,
2156 },
2157 COMMAND_REGISTRATION_DONE
2158 };
2159
2160 struct target_type stm8_target = {
2161 .name = "stm8",
2162
2163 .poll = stm8_poll,
2164 .arch_state = stm8_arch_state,
2165
2166 .halt = stm8_halt,
2167 .resume = stm8_resume,
2168 .step = stm8_step,
2169
2170 .assert_reset = stm8_reset_assert,
2171 .deassert_reset = stm8_reset_deassert,
2172
2173 .get_gdb_arch = stm8_get_gdb_arch,
2174 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2175
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,
2180
2181 .run_algorithm = stm8_run_algorithm,
2182
2183 .add_breakpoint = stm8_add_breakpoint,
2184 .remove_breakpoint = stm8_remove_breakpoint,
2185 .add_watchpoint = stm8_add_watchpoint,
2186 .remove_watchpoint = stm8_remove_watchpoint,
2187
2188 .commands = stm8_command_handlers,
2189 .target_create = stm8_target_create,
2190 .init_target = stm8_init,
2191 .examine = stm8_examine,
2192
2193 .deinit_target = stm8_deinit,
2194 .target_jim_configure = stm8_jim_configure,
2195 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)