stm8 target: make adapter speed settings work
[openocd.git] / src / target / stm8.c
1 /*
2 * OpenOCD STM8 target driver
3 * Copyright (C) 2017 Ake Rehnman
4 * ake.rehnman(at)gmail.com
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <helper/log.h>
25 #include "target.h"
26 #include "target_type.h"
27 #include "hello.h"
28 #include "jtag/interface.h"
29 #include "jtag/jtag.h"
30 #include "jtag/swim.h"
31 #include "register.h"
32 #include "breakpoints.h"
33 #include "algorithm.h"
34 #include "stm8.h"
35
36 static struct reg_cache *stm8_build_reg_cache(struct target *target);
37 static int stm8_read_core_reg(struct target *target, unsigned int num);
38 static int stm8_write_core_reg(struct target *target, unsigned int num);
39 static int stm8_save_context(struct target *target);
40 static void stm8_enable_breakpoints(struct target *target);
41 static int stm8_unset_breakpoint(struct target *target,
42 struct breakpoint *breakpoint);
43 static int stm8_set_breakpoint(struct target *target,
44 struct breakpoint *breakpoint);
45 static void stm8_enable_watchpoints(struct target *target);
46 static int stm8_unset_watchpoint(struct target *target,
47 struct watchpoint *watchpoint);
48 static int (*adapter_speed)(int speed);
49 extern struct adapter_driver *adapter_driver;
50
51 static const struct {
52 unsigned id;
53 const char *name;
54 const uint8_t bits;
55 enum reg_type type;
56 const char *group;
57 const char *feature;
58 int flag;
59 } stm8_regs[] = {
60 { 0, "pc", 32, REG_TYPE_UINT32, "general", "org.gnu.gdb.stm8.core", 0 },
61 { 1, "a", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
62 { 2, "x", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
63 { 3, "y", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
64 { 4, "sp", 16, REG_TYPE_UINT16, "general", "org.gnu.gdb.stm8.core", 0 },
65 { 5, "cc", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 },
66 };
67
68 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
69 #define STM8_PC 0
70 #define STM8_A 1
71 #define STM8_X 2
72 #define STM8_Y 3
73 #define STM8_SP 4
74 #define STM8_CC 5
75
76 #define CC_I0 0x8
77 #define CC_I1 0x20
78
79 #define DM_REGS 0x7f00
80 #define DM_REG_A 0x7f00
81 #define DM_REG_PC 0x7f01
82 #define DM_REG_X 0x7f04
83 #define DM_REG_Y 0x7f06
84 #define DM_REG_SP 0x7f08
85 #define DM_REG_CC 0x7f0a
86
87 #define DM_BKR1E 0x7f90
88 #define DM_BKR2E 0x7f93
89 #define DM_CR1 0x7f96
90 #define DM_CR2 0x7f97
91 #define DM_CSR1 0x7f98
92 #define DM_CSR2 0x7f99
93
94 #define STE 0x40
95 #define STF 0x20
96 #define RST 0x10
97 #define BRW 0x08
98 #define BK2F 0x04
99 #define BK1F 0x02
100
101 #define SWBRK 0x20
102 #define SWBKF 0x10
103 #define STALL 0x08
104 #define FLUSH 0x01
105
106 #define FLASH_CR1_STM8S 0x505A
107 #define FLASH_CR2_STM8S 0x505B
108 #define FLASH_NCR2_STM8S 0x505C
109 #define FLASH_IAPSR_STM8S 0x505F
110 #define FLASH_PUKR_STM8S 0x5062
111 #define FLASH_DUKR_STM8S 0x5064
112
113 #define FLASH_CR1_STM8L 0x5050
114 #define FLASH_CR2_STM8L 0x5051
115 #define FLASH_NCR2_STM8L 0
116 #define FLASH_PUKR_STM8L 0x5052
117 #define FLASH_DUKR_STM8L 0x5053
118 #define FLASH_IAPSR_STM8L 0x5054
119
120 /* FLASH_IAPSR */
121 #define HVOFF 0x40
122 #define DUL 0x08
123 #define EOP 0x04
124 #define PUL 0x02
125 #define WR_PG_DIS 0x01
126
127 /* FLASH_CR2 */
128 #define OPT 0x80
129 #define WPRG 0x40
130 #define ERASE 0x20
131 #define FPRG 0x10
132 #define PRG 0x01
133
134 /* SWIM_CSR */
135 #define SAFE_MASK 0x80
136 #define NO_ACCESS 0x40
137 #define SWIM_DM 0x20
138 #define HS 0x10
139 #define OSCOFF 0x08
140 #define SWIM_RST 0x04
141 #define HSIT 0x02
142 #define PRI 0x01
143
144 #define SWIM_CSR 0x7f80
145
146 #define STM8_BREAK 0x8B
147
148 enum mem_type {
149 RAM,
150 FLASH,
151 EEPROM,
152 OPTION
153 };
154
155 struct stm8_algorithm {
156 int common_magic;
157 };
158
159 struct stm8_core_reg {
160 uint32_t num;
161 struct target *target;
162 struct stm8_common *stm8_common;
163 };
164
165 enum hw_break_type {
166 /* break on execute */
167 HWBRK_EXEC,
168 /* break on read */
169 HWBRK_RD,
170 /* break on write */
171 HWBRK_WR,
172 /* break on read, write and execute */
173 HWBRK_ACC
174 };
175
176 struct stm8_comparator {
177 bool used;
178 uint32_t bp_value;
179 uint32_t reg_address;
180 enum hw_break_type type;
181 };
182
183 static int stm8_adapter_read_memory(struct target *target,
184 uint32_t addr, int size, int count, void *buf)
185 {
186 return swim_read_mem(addr, size, count, buf);
187 }
188
189 static int stm8_adapter_write_memory(struct target *target,
190 uint32_t addr, int size, int count, const void *buf)
191 {
192 return swim_write_mem(addr, size, count, buf);
193 }
194
195 static int stm8_write_u8(struct target *target,
196 uint32_t addr, uint8_t val)
197 {
198 uint8_t buf[1];
199
200 buf[0] = val;
201 return swim_write_mem(addr, 1, 1, buf);
202 }
203
204 static int stm8_read_u8(struct target *target,
205 uint32_t addr, uint8_t *val)
206 {
207 return swim_read_mem(addr, 1, 1, val);
208 }
209
210 /*
211 <enable == 0> Disables interrupts.
212 If interrupts are enabled they are masked and the cc register
213 is saved.
214
215 <enable == 1> Enables interrupts.
216 Enable interrupts is actually restoring I1 I0 state from previous
217 call with enable == 0. Note that if stepping and breaking on a sim
218 instruction will NOT work since the interrupt flags are restored on
219 debug_entry. We don't have any way for the debugger to exclusively
220 disable the interrupts
221 */
222 static int stm8_enable_interrupts(struct target *target, int enable)
223 {
224 struct stm8_common *stm8 = target_to_stm8(target);
225 uint8_t cc;
226
227 if (enable) {
228 if (!stm8->cc_valid)
229 return ERROR_OK; /* cc was not stashed */
230 /* fetch current cc */
231 stm8_read_u8(target, DM_REG_CC, &cc);
232 /* clear I1 I0 */
233 cc &= ~(CC_I0 + CC_I1);
234 /* restore I1 & I0 from stash*/
235 cc |= (stm8->cc & (CC_I0+CC_I1));
236 /* update current cc */
237 stm8_write_u8(target, DM_REG_CC, cc);
238 stm8->cc_valid = false;
239 } else {
240 stm8_read_u8(target, DM_REG_CC, &cc);
241 if ((cc & CC_I0) && (cc & CC_I1))
242 return ERROR_OK; /* interrupts already masked */
243 /* stash cc */
244 stm8->cc = cc;
245 stm8->cc_valid = true;
246 /* mask interrupts (disable) */
247 cc |= (CC_I0 + CC_I1);
248 stm8_write_u8(target, DM_REG_CC, cc);
249 }
250
251 return ERROR_OK;
252 }
253
254 static int stm8_set_hwbreak(struct target *target,
255 struct stm8_comparator comparator_list[])
256 {
257 uint8_t buf[3];
258 int i, ret;
259
260 /* Refer to Table 4 in UM0470 */
261 uint8_t bc = 0x5;
262 uint8_t bir = 0;
263 uint8_t biw = 0;
264
265 uint32_t data;
266 uint32_t addr;
267
268 if (!comparator_list[0].used) {
269 comparator_list[0].type = HWBRK_EXEC;
270 comparator_list[0].bp_value = -1;
271 }
272
273 if (!comparator_list[1].used) {
274 comparator_list[1].type = HWBRK_EXEC;
275 comparator_list[1].bp_value = -1;
276 }
277
278 if ((comparator_list[0].type == HWBRK_EXEC)
279 && (comparator_list[1].type == HWBRK_EXEC)) {
280 comparator_list[0].reg_address = 0;
281 comparator_list[1].reg_address = 1;
282 }
283
284 if ((comparator_list[0].type == HWBRK_EXEC)
285 && (comparator_list[1].type != HWBRK_EXEC)) {
286 comparator_list[0].reg_address = 0;
287 comparator_list[1].reg_address = 1;
288 switch (comparator_list[1].type) {
289 case HWBRK_RD:
290 bir = 1;
291 break;
292 case HWBRK_WR:
293 biw = 1;
294 break;
295 default:
296 bir = 1;
297 biw = 1;
298 break;
299 }
300 }
301
302 if ((comparator_list[1].type == HWBRK_EXEC)
303 && (comparator_list[0].type != HWBRK_EXEC)) {
304 comparator_list[0].reg_address = 1;
305 comparator_list[1].reg_address = 0;
306 switch (comparator_list[0].type) {
307 case HWBRK_RD:
308 bir = 1;
309 break;
310 case HWBRK_WR:
311 biw = 1;
312 break;
313 default:
314 bir = 1;
315 biw = 1;
316 break;
317 }
318 }
319
320 if ((comparator_list[0].type != HWBRK_EXEC)
321 && (comparator_list[1].type != HWBRK_EXEC)) {
322 if (comparator_list[0].type != comparator_list[1].type) {
323 LOG_ERROR("data hw breakpoints must be of same type");
324 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
325 }
326 }
327
328 for (i = 0; i < 2; i++) {
329 data = comparator_list[i].bp_value;
330 addr = comparator_list[i].reg_address;
331
332 buf[0] = data >> 16;
333 buf[1] = data >> 8;
334 buf[2] = data;
335
336 if (addr == 0) {
337 ret = stm8_adapter_write_memory(target, DM_BKR1E, 1, 3, buf);
338 LOG_DEBUG("DM_BKR1E=%" PRIx32, data);
339 } else if (addr == 1) {
340 ret = stm8_adapter_write_memory(target, DM_BKR2E, 1, 3, buf);
341 LOG_DEBUG("DM_BKR2E=%" PRIx32, data);
342 } else {
343 LOG_DEBUG("addr=%" PRIu32, addr);
344 return ERROR_FAIL;
345 }
346
347 if (ret != ERROR_OK)
348 return ret;
349
350 ret = stm8_write_u8(target, DM_CR1,
351 (bc << 3) + (bir << 2) + (biw << 1));
352 LOG_DEBUG("DM_CR1=%" PRIx8, buf[0]);
353 if (ret != ERROR_OK)
354 return ret;
355
356 }
357 return ERROR_OK;
358 }
359
360 /* read DM control and status regs */
361 static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,
362 uint8_t *csr2)
363 {
364 int ret;
365 uint8_t buf[2];
366
367 ret = stm8_adapter_read_memory(target, DM_CSR1, 1, sizeof(buf), buf);
368 if (ret != ERROR_OK)
369 return ret;
370 if (csr1)
371 *csr1 = buf[0];
372 if (csr2)
373 *csr2 = buf[1];
374 return ERROR_OK;
375 }
376
377 /* set or clear the single step flag in DM */
378 static int stm8_config_step(struct target *target, int enable)
379 {
380 int ret;
381 uint8_t csr1, csr2;
382
383 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
384 if (ret != ERROR_OK)
385 return ret;
386 if (enable)
387 csr1 |= STE;
388 else
389 csr1 &= ~STE;
390
391 ret = stm8_write_u8(target, DM_CSR1, csr1);
392 if (ret != ERROR_OK)
393 return ret;
394 return ERROR_OK;
395 }
396
397 /* set the stall flag in DM */
398 static int stm8_debug_stall(struct target *target)
399 {
400 int ret;
401 uint8_t csr1, csr2;
402
403 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
404 if (ret != ERROR_OK)
405 return ret;
406 csr2 |= STALL;
407 ret = stm8_write_u8(target, DM_CSR2, csr2);
408 if (ret != ERROR_OK)
409 return ret;
410 return ERROR_OK;
411 }
412
413 static int stm8_configure_break_unit(struct target *target)
414 {
415 /* get pointers to arch-specific information */
416 struct stm8_common *stm8 = target_to_stm8(target);
417
418 if (stm8->bp_scanned)
419 return ERROR_OK;
420
421 stm8->num_hw_bpoints = 2;
422 stm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;
423
424 stm8->hw_break_list = calloc(stm8->num_hw_bpoints,
425 sizeof(struct stm8_comparator));
426
427 stm8->hw_break_list[0].reg_address = 0;
428 stm8->hw_break_list[1].reg_address = 1;
429
430 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8->num_hw_bpoints,
431 stm8->num_hw_bpoints);
432
433 stm8->bp_scanned = true;
434
435 return ERROR_OK;
436 }
437
438 static int stm8_examine_debug_reason(struct target *target)
439 {
440 int retval;
441 uint8_t csr1, csr2;
442
443 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
444 if (retval == ERROR_OK)
445 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
446
447 if ((target->debug_reason != DBG_REASON_DBGRQ)
448 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
449
450 if (retval != ERROR_OK)
451 return retval;
452
453 if (csr1 & RST)
454 /* halted on reset */
455 target->debug_reason = DBG_REASON_UNDEFINED;
456
457 if (csr1 & (BK1F+BK2F))
458 /* we have halted on a breakpoint (or wp)*/
459 target->debug_reason = DBG_REASON_BREAKPOINT;
460
461 if (csr2 & SWBKF)
462 /* we have halted on a breakpoint */
463 target->debug_reason = DBG_REASON_BREAKPOINT;
464
465 }
466
467 return ERROR_OK;
468 }
469
470 static int stm8_debug_entry(struct target *target)
471 {
472 struct stm8_common *stm8 = target_to_stm8(target);
473
474 /* restore interrupts */
475 stm8_enable_interrupts(target, 1);
476
477 stm8_save_context(target);
478
479 /* make sure stepping disabled STE bit in CSR1 cleared */
480 stm8_config_step(target, 0);
481
482 /* attempt to find halt reason */
483 stm8_examine_debug_reason(target);
484
485 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
486 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32),
487 target_state_name(target));
488
489 return ERROR_OK;
490 }
491
492 /* clear stall flag in DM and flush instruction pipe */
493 static int stm8_exit_debug(struct target *target)
494 {
495 int ret;
496 uint8_t csr1, csr2;
497
498 ret = stm8_read_dm_csrx(target, &csr1, &csr2);
499 if (ret != ERROR_OK)
500 return ret;
501 csr2 |= FLUSH;
502 ret = stm8_write_u8(target, DM_CSR2, csr2);
503 if (ret != ERROR_OK)
504 return ret;
505
506 csr2 &= ~STALL;
507 csr2 |= SWBRK;
508 ret = stm8_write_u8(target, DM_CSR2, csr2);
509 if (ret != ERROR_OK)
510 return ret;
511 return ERROR_OK;
512 }
513
514 static int stm8_read_regs(struct target *target, uint32_t regs[])
515 {
516 int ret;
517 uint8_t buf[11];
518
519 ret = stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);
520 if (ret != ERROR_OK)
521 return ret;
522
523 regs[0] = be_to_h_u24(buf+DM_REG_PC-DM_REGS);
524 regs[1] = buf[DM_REG_A-DM_REGS];
525 regs[2] = be_to_h_u16(buf+DM_REG_X-DM_REGS);
526 regs[3] = be_to_h_u16(buf+DM_REG_Y-DM_REGS);
527 regs[4] = be_to_h_u16(buf+DM_REG_SP-DM_REGS);
528 regs[5] = buf[DM_REG_CC-DM_REGS];
529
530 return ERROR_OK;
531 }
532
533 static int stm8_write_regs(struct target *target, uint32_t regs[])
534 {
535 int ret;
536 uint8_t buf[11];
537
538 h_u24_to_be(buf+DM_REG_PC-DM_REGS, regs[0]);
539 buf[DM_REG_A-DM_REGS] = regs[1];
540 h_u16_to_be(buf+DM_REG_X-DM_REGS, regs[2]);
541 h_u16_to_be(buf+DM_REG_Y-DM_REGS, regs[3]);
542 h_u16_to_be(buf+DM_REG_SP-DM_REGS, regs[4]);
543 buf[DM_REG_CC-DM_REGS] = regs[5];
544
545 ret = stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);
546 if (ret != ERROR_OK)
547 return ret;
548
549 return ERROR_OK;
550 }
551
552 static int stm8_get_core_reg(struct reg *reg)
553 {
554 int retval;
555 struct stm8_core_reg *stm8_reg = reg->arch_info;
556 struct target *target = stm8_reg->target;
557 struct stm8_common *stm8_target = target_to_stm8(target);
558
559 if (target->state != TARGET_HALTED)
560 return ERROR_TARGET_NOT_HALTED;
561
562 retval = stm8_target->read_core_reg(target, stm8_reg->num);
563
564 return retval;
565 }
566
567 static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
568 {
569 struct stm8_core_reg *stm8_reg = reg->arch_info;
570 struct target *target = stm8_reg->target;
571 uint32_t value = buf_get_u32(buf, 0, reg->size);
572
573 if (target->state != TARGET_HALTED)
574 return ERROR_TARGET_NOT_HALTED;
575
576 buf_set_u32(reg->value, 0, 32, value);
577 reg->dirty = true;
578 reg->valid = true;
579
580 return ERROR_OK;
581 }
582
583 static int stm8_save_context(struct target *target)
584 {
585 unsigned int i;
586
587 /* get pointers to arch-specific information */
588 struct stm8_common *stm8 = target_to_stm8(target);
589
590 /* read core registers */
591 stm8_read_regs(target, stm8->core_regs);
592
593 for (i = 0; i < STM8_NUM_REGS; i++) {
594 if (!stm8->core_cache->reg_list[i].valid)
595 stm8->read_core_reg(target, i);
596 }
597
598 return ERROR_OK;
599 }
600
601 static int stm8_restore_context(struct target *target)
602 {
603 unsigned int i;
604
605 /* get pointers to arch-specific information */
606 struct stm8_common *stm8 = target_to_stm8(target);
607
608 for (i = 0; i < STM8_NUM_REGS; i++) {
609 if (stm8->core_cache->reg_list[i].dirty)
610 stm8->write_core_reg(target, i);
611 }
612
613 /* write core regs */
614 stm8_write_regs(target, stm8->core_regs);
615
616 return ERROR_OK;
617 }
618
619 static int stm8_unlock_flash(struct target *target)
620 {
621 uint8_t data[1];
622
623 struct stm8_common *stm8 = target_to_stm8(target);
624
625 /* check if flash is unlocked */
626 stm8_read_u8(target, stm8->flash_iapsr, data);
627 if (~data[0] & PUL) {
628 /* unlock flash */
629 stm8_write_u8(target, stm8->flash_pukr, 0x56);
630 stm8_write_u8(target, stm8->flash_pukr, 0xae);
631 }
632
633 stm8_read_u8(target, stm8->flash_iapsr, data);
634 if (~data[0] & PUL)
635 return ERROR_FAIL;
636 return ERROR_OK;
637 }
638
639 static int stm8_unlock_eeprom(struct target *target)
640 {
641 uint8_t data[1];
642
643 struct stm8_common *stm8 = target_to_stm8(target);
644
645 /* check if eeprom is unlocked */
646 stm8_read_u8(target, stm8->flash_iapsr, data);
647 if (~data[0] & DUL) {
648 /* unlock eeprom */
649 stm8_write_u8(target, stm8->flash_dukr, 0xae);
650 stm8_write_u8(target, stm8->flash_dukr, 0x56);
651 }
652
653 stm8_read_u8(target, stm8->flash_iapsr, data);
654 if (~data[0] & DUL)
655 return ERROR_FAIL;
656 return ERROR_OK;
657 }
658
659 static int stm8_write_flash(struct target *target, enum mem_type type,
660 uint32_t address,
661 uint32_t size, uint32_t count, uint32_t blocksize_param,
662 const uint8_t *buffer)
663 {
664 struct stm8_common *stm8 = target_to_stm8(target);
665
666 uint8_t iapsr;
667 uint8_t opt = 0;
668 unsigned int i;
669 uint32_t blocksize = 0;
670 uint32_t bytecnt;
671 int res;
672
673 switch (type) {
674 case (FLASH):
675 stm8_unlock_flash(target);
676 break;
677 case (EEPROM):
678 stm8_unlock_eeprom(target);
679 break;
680 case (OPTION):
681 stm8_unlock_eeprom(target);
682 opt = OPT;
683 break;
684 default:
685 LOG_ERROR("BUG: wrong mem_type %d", type);
686 assert(0);
687 }
688
689 if (size == 2) {
690 /* we don't support short writes */
691 count = count * 2;
692 size = 1;
693 }
694
695 bytecnt = count * size;
696
697 while (bytecnt) {
698 if ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {
699 if (stm8->flash_cr2)
700 stm8_write_u8(target, stm8->flash_cr2, PRG + opt);
701 if (stm8->flash_ncr2)
702 stm8_write_u8(target, stm8->flash_ncr2, ~(PRG + opt));
703 blocksize = blocksize_param;
704 } else
705 if ((bytecnt >= 4) && ((address & 0x3) == 0)) {
706 if (stm8->flash_cr2)
707 stm8_write_u8(target, stm8->flash_cr2, WPRG + opt);
708 if (stm8->flash_ncr2)
709 stm8_write_u8(target, stm8->flash_ncr2, ~(WPRG + opt));
710 blocksize = 4;
711 } else
712 if (blocksize != 1) {
713 if (stm8->flash_cr2)
714 stm8_write_u8(target, stm8->flash_cr2, opt);
715 if (stm8->flash_ncr2)
716 stm8_write_u8(target, stm8->flash_ncr2, ~opt);
717 blocksize = 1;
718 }
719
720 res = stm8_adapter_write_memory(target, address, 1, blocksize, buffer);
721 if (res != ERROR_OK)
722 return res;
723 address += blocksize;
724 buffer += blocksize;
725 bytecnt -= blocksize;
726
727 /* lets hang here until end of program (EOP) */
728 for (i = 0; i < 16; i++) {
729 stm8_read_u8(target, stm8->flash_iapsr, &iapsr);
730 if (iapsr & EOP)
731 break;
732 else
733 usleep(1000);
734 }
735 if (i == 16)
736 return ERROR_FAIL;
737 }
738
739 /* disable write access */
740 res = stm8_write_u8(target, stm8->flash_iapsr, 0x0);
741
742 if (res != ERROR_OK)
743 return ERROR_FAIL;
744
745 return ERROR_OK;
746 }
747
748 static int stm8_write_memory(struct target *target, target_addr_t address,
749 uint32_t size, uint32_t count,
750 const uint8_t *buffer)
751 {
752 struct stm8_common *stm8 = target_to_stm8(target);
753
754 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
755 ", size: 0x%8.8" PRIx32
756 ", count: 0x%8.8" PRIx32,
757 address, size, count);
758
759 if (target->state != TARGET_HALTED)
760 LOG_WARNING("target not halted");
761
762 int retval;
763
764 if ((address >= stm8->flashstart) && (address <= stm8->flashend))
765 retval = stm8_write_flash(target, FLASH, address, size, count,
766 stm8->blocksize, buffer);
767 else if ((address >= stm8->eepromstart) && (address <= stm8->eepromend))
768 retval = stm8_write_flash(target, EEPROM, address, size, count,
769 stm8->blocksize, buffer);
770 else if ((address >= stm8->optionstart) && (address <= stm8->optionend))
771 retval = stm8_write_flash(target, OPTION, address, size, count, 0, buffer);
772 else
773 retval = stm8_adapter_write_memory(target, address, size, count,
774 buffer);
775
776 if (retval != ERROR_OK)
777 return ERROR_TARGET_FAILURE;
778
779 return retval;
780 }
781
782 static int stm8_read_memory(struct target *target, target_addr_t address,
783 uint32_t size, uint32_t count, uint8_t *buffer)
784 {
785 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
786 ", size: 0x%8.8" PRIx32
787 ", count: 0x%8.8" PRIx32,
788 address, size, count);
789
790 if (target->state != TARGET_HALTED)
791 LOG_WARNING("target not halted");
792
793 int retval;
794 retval = stm8_adapter_read_memory(target, address, size, count, buffer);
795
796 if (retval != ERROR_OK)
797 return ERROR_TARGET_FAILURE;
798
799 return retval;
800 }
801
802 static int stm8_speed(int speed)
803 {
804 int retval;
805 uint8_t csr;
806
807 LOG_DEBUG("stm8_speed: %d", speed);
808
809 csr = SAFE_MASK | SWIM_DM;
810 if (speed >= SWIM_FREQ_HIGH)
811 csr |= HS;
812
813 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)", csr & HS ? 1 : 0);
814 retval = stm8_write_u8(NULL, SWIM_CSR, csr);
815 if (retval != ERROR_OK)
816 return retval;
817 return adapter_speed(speed);
818 }
819
820 static int stm8_init(struct command_context *cmd_ctx, struct target *target)
821 {
822 /*
823 * FIXME: this is a temporarily hack that needs better implementation.
824 * Being the only overwrite of adapter_driver, it prevents declaring const
825 * the struct adapter_driver.
826 * intercept adapter_driver->speed() calls
827 */
828 adapter_speed = adapter_driver->speed;
829 adapter_driver->speed = stm8_speed;
830
831 stm8_build_reg_cache(target);
832
833 return ERROR_OK;
834 }
835
836 static int stm8_poll(struct target *target)
837 {
838 int retval = ERROR_OK;
839 uint8_t csr1, csr2;
840
841 #ifdef LOG_STM8
842 LOG_DEBUG("target->state=%d", target->state);
843 #endif
844
845 /* read dm_csrx control regs */
846 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
847 if (retval != ERROR_OK) {
848 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval);
849 /*
850 We return ERROR_OK here even if we didn't get an answer.
851 openocd will call target_wait_state until we get target state TARGET_HALTED
852 */
853 return ERROR_OK;
854 }
855
856 /* check for processor halted */
857 if (csr2 & STALL) {
858 if (target->state != TARGET_HALTED) {
859 if (target->state == TARGET_UNKNOWN)
860 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
861
862 retval = stm8_debug_entry(target);
863 if (retval != ERROR_OK) {
864 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval);
865 return ERROR_TARGET_FAILURE;
866 }
867
868 if (target->state == TARGET_DEBUG_RUNNING) {
869 target->state = TARGET_HALTED;
870 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
871 } else {
872 target->state = TARGET_HALTED;
873 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
874 }
875 }
876 } else
877 target->state = TARGET_RUNNING;
878 #ifdef LOG_STM8
879 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
880 #endif
881 return ERROR_OK;
882 }
883
884 static int stm8_halt(struct target *target)
885 {
886 LOG_DEBUG("target->state: %s", target_state_name(target));
887
888 if (target->state == TARGET_HALTED) {
889 LOG_DEBUG("target was already halted");
890 return ERROR_OK;
891 }
892
893 if (target->state == TARGET_UNKNOWN)
894 LOG_WARNING("target was in unknown state when halt was requested");
895
896 if (target->state == TARGET_RESET) {
897 /* we came here in a reset_halt or reset_init sequence
898 * debug entry was already prepared in stm8_assert_reset()
899 */
900 target->debug_reason = DBG_REASON_DBGRQ;
901
902 return ERROR_OK;
903 }
904
905
906 /* break processor */
907 stm8_debug_stall(target);
908
909 target->debug_reason = DBG_REASON_DBGRQ;
910
911 return ERROR_OK;
912 }
913
914 static int stm8_reset_assert(struct target *target)
915 {
916 int res = ERROR_OK;
917 struct stm8_common *stm8 = target_to_stm8(target);
918 bool use_srst_fallback = true;
919
920 enum reset_types jtag_reset_config = jtag_get_reset_config();
921
922 if (jtag_reset_config & RESET_HAS_SRST) {
923 res = adapter_assert_reset();
924 if (res == ERROR_OK)
925 /* hardware srst supported */
926 use_srst_fallback = false;
927 else if (res != ERROR_COMMAND_NOTFOUND)
928 /* some other failure */
929 return res;
930 }
931
932 if (use_srst_fallback) {
933 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
934 res = swim_system_reset();
935 if (res != ERROR_OK)
936 return res;
937 }
938
939 /* registers are now invalid */
940 register_cache_invalidate(stm8->core_cache);
941
942 target->state = TARGET_RESET;
943 target->debug_reason = DBG_REASON_NOTHALTED;
944
945 if (target->reset_halt) {
946 res = target_halt(target);
947 if (res != ERROR_OK)
948 return res;
949 }
950
951 return ERROR_OK;
952 }
953
954 static int stm8_reset_deassert(struct target *target)
955 {
956 int res;
957 enum reset_types jtag_reset_config = jtag_get_reset_config();
958
959 if (jtag_reset_config & RESET_HAS_SRST) {
960 res = adapter_deassert_reset();
961 if ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND))
962 return res;
963 }
964
965 /* The cpu should now be stalled. If halt was requested
966 let poll detect the stall */
967 if (target->reset_halt)
968 return ERROR_OK;
969
970 /* Instead of going thrugh saving context, polling and
971 then resuming target again just clear stall and proceed. */
972 target->state = TARGET_RUNNING;
973 return stm8_exit_debug(target);
974 }
975
976 /* stm8_single_step_core() is only used for stepping over breakpoints
977 from stm8_resume() */
978 static int stm8_single_step_core(struct target *target)
979 {
980 struct stm8_common *stm8 = target_to_stm8(target);
981
982 /* configure single step mode */
983 stm8_config_step(target, 1);
984
985 /* disable interrupts while stepping */
986 if (!stm8->enable_step_irq)
987 stm8_enable_interrupts(target, 0);
988
989 /* exit debug mode */
990 stm8_exit_debug(target);
991
992 stm8_debug_entry(target);
993
994 return ERROR_OK;
995 }
996
997 static int stm8_resume(struct target *target, int current,
998 target_addr_t address, int handle_breakpoints,
999 int debug_execution)
1000 {
1001 struct stm8_common *stm8 = target_to_stm8(target);
1002 struct breakpoint *breakpoint = NULL;
1003 uint32_t resume_pc;
1004
1005 LOG_DEBUG("%d " TARGET_ADDR_FMT " %d %d", current, address,
1006 handle_breakpoints, debug_execution);
1007
1008 if (target->state != TARGET_HALTED) {
1009 LOG_WARNING("target not halted");
1010 return ERROR_TARGET_NOT_HALTED;
1011 }
1012
1013 if (!debug_execution) {
1014 target_free_all_working_areas(target);
1015 stm8_enable_breakpoints(target);
1016 stm8_enable_watchpoints(target);
1017 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1018 stm8_set_hwbreak(target, comparator_list);
1019 }
1020
1021 /* current = 1: continue on current pc,
1022 otherwise continue at <address> */
1023 if (!current) {
1024 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value,
1025 0, 32, address);
1026 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1027 stm8->core_cache->reg_list[STM8_PC].valid = true;
1028 }
1029
1030 if (!current)
1031 resume_pc = address;
1032 else
1033 resume_pc = buf_get_u32(
1034 stm8->core_cache->reg_list[STM8_PC].value,
1035 0, 32);
1036
1037 stm8_restore_context(target);
1038
1039 /* the front-end may request us not to handle breakpoints */
1040 if (handle_breakpoints) {
1041 /* Single step past breakpoint at current address */
1042 breakpoint = breakpoint_find(target, resume_pc);
1043 if (breakpoint) {
1044 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT,
1045 breakpoint->address);
1046 stm8_unset_breakpoint(target, breakpoint);
1047 stm8_single_step_core(target);
1048 stm8_set_breakpoint(target, breakpoint);
1049 }
1050 }
1051
1052 /* disable interrupts if we are debugging */
1053 if (debug_execution)
1054 stm8_enable_interrupts(target, 0);
1055
1056 /* exit debug mode */
1057 stm8_exit_debug(target);
1058 target->debug_reason = DBG_REASON_NOTHALTED;
1059
1060 /* registers are now invalid */
1061 register_cache_invalidate(stm8->core_cache);
1062
1063 if (!debug_execution) {
1064 target->state = TARGET_RUNNING;
1065 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1066 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
1067 } else {
1068 target->state = TARGET_DEBUG_RUNNING;
1069 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1070 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
1071 }
1072
1073 return ERROR_OK;
1074 }
1075
1076 static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
1077 {
1078 stm8->enable_stm8l = enable_stm8l;
1079
1080 if (stm8->enable_stm8l) {
1081 stm8->flash_cr2 = FLASH_CR2_STM8L;
1082 stm8->flash_ncr2 = FLASH_NCR2_STM8L;
1083 stm8->flash_iapsr = FLASH_IAPSR_STM8L;
1084 stm8->flash_dukr = FLASH_DUKR_STM8L;
1085 stm8->flash_pukr = FLASH_PUKR_STM8L;
1086 } else {
1087 stm8->flash_cr2 = FLASH_CR2_STM8S;
1088 stm8->flash_ncr2 = FLASH_NCR2_STM8S;
1089 stm8->flash_iapsr = FLASH_IAPSR_STM8S;
1090 stm8->flash_dukr = FLASH_DUKR_STM8S;
1091 stm8->flash_pukr = FLASH_PUKR_STM8S;
1092 }
1093 return ERROR_OK;
1094 }
1095
1096 static int stm8_init_arch_info(struct target *target,
1097 struct stm8_common *stm8, struct jtag_tap *tap)
1098 {
1099 target->endianness = TARGET_BIG_ENDIAN;
1100 target->arch_info = stm8;
1101 stm8->common_magic = STM8_COMMON_MAGIC;
1102 stm8->fast_data_area = NULL;
1103 stm8->blocksize = 0x80;
1104 stm8->flashstart = 0x8000;
1105 stm8->flashend = 0xffff;
1106 stm8->eepromstart = 0x4000;
1107 stm8->eepromend = 0x43ff;
1108 stm8->optionstart = 0x4800;
1109 stm8->optionend = 0x487F;
1110
1111 /* has breakpoint/watchpoint unit been scanned */
1112 stm8->bp_scanned = false;
1113 stm8->hw_break_list = NULL;
1114
1115 stm8->read_core_reg = stm8_read_core_reg;
1116 stm8->write_core_reg = stm8_write_core_reg;
1117
1118 stm8_init_flash_regs(0, stm8);
1119
1120 return ERROR_OK;
1121 }
1122
1123 static int stm8_target_create(struct target *target,
1124 Jim_Interp *interp)
1125 {
1126
1127 struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));
1128
1129 stm8_init_arch_info(target, stm8, target->tap);
1130 stm8_configure_break_unit(target);
1131
1132 return ERROR_OK;
1133 }
1134
1135 static int stm8_read_core_reg(struct target *target, unsigned int num)
1136 {
1137 uint32_t reg_value;
1138
1139 /* get pointers to arch-specific information */
1140 struct stm8_common *stm8 = target_to_stm8(target);
1141
1142 if (num >= STM8_NUM_REGS)
1143 return ERROR_COMMAND_SYNTAX_ERROR;
1144
1145 reg_value = stm8->core_regs[num];
1146 LOG_DEBUG("read core reg %i value 0x%" PRIx32 "", num , reg_value);
1147 buf_set_u32(stm8->core_cache->reg_list[num].value, 0, 32, reg_value);
1148 stm8->core_cache->reg_list[num].valid = true;
1149 stm8->core_cache->reg_list[num].dirty = false;
1150
1151 return ERROR_OK;
1152 }
1153
1154 static int stm8_write_core_reg(struct target *target, unsigned int num)
1155 {
1156 uint32_t reg_value;
1157
1158 /* get pointers to arch-specific information */
1159 struct stm8_common *stm8 = target_to_stm8(target);
1160
1161 if (num >= STM8_NUM_REGS)
1162 return ERROR_COMMAND_SYNTAX_ERROR;
1163
1164 reg_value = buf_get_u32(stm8->core_cache->reg_list[num].value, 0, 32);
1165 stm8->core_regs[num] = reg_value;
1166 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
1167 stm8->core_cache->reg_list[num].valid = true;
1168 stm8->core_cache->reg_list[num].dirty = false;
1169
1170 return ERROR_OK;
1171 }
1172
1173 static const char *stm8_get_gdb_arch(struct target *target)
1174 {
1175 return "stm8";
1176 }
1177
1178 static int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
1179 int *reg_list_size, enum target_register_class reg_class)
1180 {
1181 /* get pointers to arch-specific information */
1182 struct stm8_common *stm8 = target_to_stm8(target);
1183 unsigned int i;
1184
1185 *reg_list_size = STM8_NUM_REGS;
1186 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1187
1188 for (i = 0; i < STM8_NUM_REGS; i++)
1189 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1190
1191 return ERROR_OK;
1192 }
1193
1194 static const struct reg_arch_type stm8_reg_type = {
1195 .get = stm8_get_core_reg,
1196 .set = stm8_set_core_reg,
1197 };
1198
1199 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1200 {
1201 /* get pointers to arch-specific information */
1202 struct stm8_common *stm8 = target_to_stm8(target);
1203
1204 int num_regs = STM8_NUM_REGS;
1205 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1206 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1207 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1208 struct stm8_core_reg *arch_info = malloc(
1209 sizeof(struct stm8_core_reg) * num_regs);
1210 struct reg_feature *feature;
1211 int i;
1212
1213 /* Build the process context cache */
1214 cache->name = "stm8 registers";
1215 cache->next = NULL;
1216 cache->reg_list = reg_list;
1217 cache->num_regs = num_regs;
1218 (*cache_p) = cache;
1219 stm8->core_cache = cache;
1220
1221 for (i = 0; i < num_regs; i++) {
1222 arch_info[i].num = stm8_regs[i].id;
1223 arch_info[i].target = target;
1224 arch_info[i].stm8_common = stm8;
1225
1226 reg_list[i].name = stm8_regs[i].name;
1227 reg_list[i].size = stm8_regs[i].bits;
1228
1229 reg_list[i].value = calloc(1, 4);
1230 reg_list[i].valid = false;
1231 reg_list[i].type = &stm8_reg_type;
1232 reg_list[i].arch_info = &arch_info[i];
1233
1234 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1235 if (reg_list[i].reg_data_type)
1236 reg_list[i].reg_data_type->type = stm8_regs[i].type;
1237 else {
1238 LOG_ERROR("unable to allocate reg type list");
1239 return NULL;
1240 }
1241
1242 reg_list[i].dirty = false;
1243 reg_list[i].group = stm8_regs[i].group;
1244 reg_list[i].number = stm8_regs[i].id;
1245 reg_list[i].exist = true;
1246 reg_list[i].caller_save = true; /* gdb defaults to true */
1247
1248 feature = calloc(1, sizeof(struct reg_feature));
1249 if (feature) {
1250 feature->name = stm8_regs[i].feature;
1251 reg_list[i].feature = feature;
1252 } else
1253 LOG_ERROR("unable to allocate feature list");
1254 }
1255
1256 return cache;
1257 }
1258
1259 static void stm8_free_reg_cache(struct target *target)
1260 {
1261 struct stm8_common *stm8 = target_to_stm8(target);
1262 struct reg_cache *cache;
1263 struct reg *reg;
1264 unsigned int i;
1265
1266 cache = stm8->core_cache;
1267
1268 if (!cache)
1269 return;
1270
1271 for (i = 0; i < cache->num_regs; i++) {
1272 reg = &cache->reg_list[i];
1273
1274 free(reg->feature);
1275 free(reg->reg_data_type);
1276 free(reg->value);
1277 }
1278
1279 free(cache->reg_list[0].arch_info);
1280 free(cache->reg_list);
1281 free(cache);
1282
1283 stm8->core_cache = NULL;
1284 }
1285
1286 static void stm8_deinit(struct target *target)
1287 {
1288 struct stm8_common *stm8 = target_to_stm8(target);
1289
1290 free(stm8->hw_break_list);
1291
1292 stm8_free_reg_cache(target);
1293
1294 free(stm8);
1295 }
1296
1297 static int stm8_arch_state(struct target *target)
1298 {
1299 struct stm8_common *stm8 = target_to_stm8(target);
1300
1301 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
1302 debug_reason_name(target),
1303 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1304
1305 return ERROR_OK;
1306 }
1307
1308 static int stm8_step(struct target *target, int current,
1309 target_addr_t address, int handle_breakpoints)
1310 {
1311 LOG_DEBUG("%" PRIx32 " " TARGET_ADDR_FMT " %" PRIx32,
1312 current, address, handle_breakpoints);
1313
1314 /* get pointers to arch-specific information */
1315 struct stm8_common *stm8 = target_to_stm8(target);
1316 struct breakpoint *breakpoint = NULL;
1317
1318 if (target->state != TARGET_HALTED) {
1319 LOG_WARNING("target not halted");
1320 return ERROR_TARGET_NOT_HALTED;
1321 }
1322
1323 /* current = 1: continue on current pc, otherwise continue at <address> */
1324 if (!current) {
1325 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);
1326 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1327 stm8->core_cache->reg_list[STM8_PC].valid = true;
1328 }
1329
1330 /* the front-end may request us not to handle breakpoints */
1331 if (handle_breakpoints) {
1332 breakpoint = breakpoint_find(target,
1333 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1334 if (breakpoint)
1335 stm8_unset_breakpoint(target, breakpoint);
1336 }
1337
1338 /* restore context */
1339 stm8_restore_context(target);
1340
1341 /* configure single step mode */
1342 stm8_config_step(target, 1);
1343
1344 target->debug_reason = DBG_REASON_SINGLESTEP;
1345
1346 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1347
1348 /* disable interrupts while stepping */
1349 if (!stm8->enable_step_irq)
1350 stm8_enable_interrupts(target, 0);
1351
1352 /* exit debug mode */
1353 stm8_exit_debug(target);
1354
1355 /* registers are now invalid */
1356 register_cache_invalidate(stm8->core_cache);
1357
1358 LOG_DEBUG("target stepped ");
1359 stm8_debug_entry(target);
1360
1361 if (breakpoint)
1362 stm8_set_breakpoint(target, breakpoint);
1363
1364 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1365
1366 return ERROR_OK;
1367 }
1368
1369 static void stm8_enable_breakpoints(struct target *target)
1370 {
1371 struct breakpoint *breakpoint = target->breakpoints;
1372
1373 /* set any pending breakpoints */
1374 while (breakpoint) {
1375 if (breakpoint->set == 0)
1376 stm8_set_breakpoint(target, breakpoint);
1377 breakpoint = breakpoint->next;
1378 }
1379 }
1380
1381 static int stm8_set_breakpoint(struct target *target,
1382 struct breakpoint *breakpoint)
1383 {
1384 struct stm8_common *stm8 = target_to_stm8(target);
1385 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1386 int retval;
1387
1388 if (breakpoint->set) {
1389 LOG_WARNING("breakpoint already set");
1390 return ERROR_OK;
1391 }
1392
1393 if (breakpoint->type == BKPT_HARD) {
1394 int bp_num = 0;
1395
1396 while (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))
1397 bp_num++;
1398 if (bp_num >= stm8->num_hw_bpoints) {
1399 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32 ")",
1400 breakpoint->unique_id);
1401 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1402 }
1403 breakpoint->set = bp_num + 1;
1404 comparator_list[bp_num].used = true;
1405 comparator_list[bp_num].bp_value = breakpoint->address;
1406 comparator_list[bp_num].type = HWBRK_EXEC;
1407
1408 retval = stm8_set_hwbreak(target, comparator_list);
1409 if (retval != ERROR_OK)
1410 return retval;
1411
1412 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
1413 breakpoint->unique_id,
1414 bp_num, comparator_list[bp_num].bp_value);
1415 } else if (breakpoint->type == BKPT_SOFT) {
1416 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1417 if (breakpoint->length == 1) {
1418 uint8_t verify = 0x55;
1419
1420 retval = target_read_u8(target, breakpoint->address,
1421 breakpoint->orig_instr);
1422 if (retval != ERROR_OK)
1423 return retval;
1424 retval = target_write_u8(target, breakpoint->address, STM8_BREAK);
1425 if (retval != ERROR_OK)
1426 return retval;
1427
1428 retval = target_read_u8(target, breakpoint->address, &verify);
1429 if (retval != ERROR_OK)
1430 return retval;
1431 if (verify != STM8_BREAK) {
1432 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1433 " - check that memory is read/writable",
1434 breakpoint->address);
1435 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1436 }
1437 } else {
1438 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1439 }
1440 breakpoint->set = 1; /* Any nice value but 0 */
1441 }
1442
1443 return ERROR_OK;
1444 }
1445
1446 static int stm8_add_breakpoint(struct target *target,
1447 struct breakpoint *breakpoint)
1448 {
1449 struct stm8_common *stm8 = target_to_stm8(target);
1450 int ret;
1451
1452 if (breakpoint->type == BKPT_HARD) {
1453 if (stm8->num_hw_bpoints_avail < 1) {
1454 LOG_INFO("no hardware breakpoint available");
1455 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1456 }
1457
1458 ret = stm8_set_breakpoint(target, breakpoint);
1459 if (ret != ERROR_OK)
1460 return ret;
1461
1462 stm8->num_hw_bpoints_avail--;
1463 return ERROR_OK;
1464 }
1465
1466 ret = stm8_set_breakpoint(target, breakpoint);
1467 if (ret != ERROR_OK)
1468 return ret;
1469
1470 return ERROR_OK;
1471 }
1472
1473 static int stm8_unset_breakpoint(struct target *target,
1474 struct breakpoint *breakpoint)
1475 {
1476 /* get pointers to arch-specific information */
1477 struct stm8_common *stm8 = target_to_stm8(target);
1478 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1479 int retval;
1480
1481 if (!breakpoint->set) {
1482 LOG_WARNING("breakpoint not set");
1483 return ERROR_OK;
1484 }
1485
1486 if (breakpoint->type == BKPT_HARD) {
1487 int bp_num = breakpoint->set - 1;
1488 if ((bp_num < 0) || (bp_num >= stm8->num_hw_bpoints)) {
1489 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
1490 breakpoint->unique_id);
1491 return ERROR_OK;
1492 }
1493 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
1494 breakpoint->unique_id,
1495 bp_num);
1496 comparator_list[bp_num].used = false;
1497 retval = stm8_set_hwbreak(target, comparator_list);
1498 if (retval != ERROR_OK)
1499 return retval;
1500 } else {
1501 /* restore original instruction (kept in target endianness) */
1502 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1503 if (breakpoint->length == 1) {
1504 uint8_t current_instr;
1505
1506 /* check that user program has not
1507 modified breakpoint instruction */
1508 retval = target_read_memory(target, breakpoint->address, 1, 1,
1509 (uint8_t *)&current_instr);
1510 if (retval != ERROR_OK)
1511 return retval;
1512
1513 if (current_instr == STM8_BREAK) {
1514 retval = target_write_memory(target, breakpoint->address, 1, 1,
1515 breakpoint->orig_instr);
1516 if (retval != ERROR_OK)
1517 return retval;
1518 }
1519 } else
1520 return ERROR_FAIL;
1521 }
1522 breakpoint->set = 0;
1523
1524 return ERROR_OK;
1525 }
1526
1527 static int stm8_remove_breakpoint(struct target *target,
1528 struct breakpoint *breakpoint)
1529 {
1530 /* get pointers to arch-specific information */
1531 struct stm8_common *stm8 = target_to_stm8(target);
1532
1533 if (target->state != TARGET_HALTED) {
1534 LOG_WARNING("target not halted");
1535 return ERROR_TARGET_NOT_HALTED;
1536 }
1537
1538 if (breakpoint->set)
1539 stm8_unset_breakpoint(target, breakpoint);
1540
1541 if (breakpoint->type == BKPT_HARD)
1542 stm8->num_hw_bpoints_avail++;
1543
1544 return ERROR_OK;
1545 }
1546
1547 static int stm8_set_watchpoint(struct target *target,
1548 struct watchpoint *watchpoint)
1549 {
1550 struct stm8_common *stm8 = target_to_stm8(target);
1551 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1552 int wp_num = 0;
1553 int ret;
1554
1555 if (watchpoint->set) {
1556 LOG_WARNING("watchpoint already set");
1557 return ERROR_OK;
1558 }
1559
1560 while (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))
1561 wp_num++;
1562 if (wp_num >= stm8->num_hw_bpoints) {
1563 LOG_ERROR("Can not find free hw breakpoint");
1564 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1565 }
1566
1567 if (watchpoint->length != 1) {
1568 LOG_ERROR("Only watchpoints of length 1 are supported");
1569 return ERROR_TARGET_UNALIGNED_ACCESS;
1570 }
1571
1572 enum hw_break_type enable = 0;
1573
1574 switch (watchpoint->rw) {
1575 case WPT_READ:
1576 enable = HWBRK_RD;
1577 break;
1578 case WPT_WRITE:
1579 enable = HWBRK_WR;
1580 break;
1581 case WPT_ACCESS:
1582 enable = HWBRK_ACC;
1583 break;
1584 default:
1585 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1586 }
1587
1588 comparator_list[wp_num].used = true;
1589 comparator_list[wp_num].bp_value = watchpoint->address;
1590 comparator_list[wp_num].type = enable;
1591
1592 ret = stm8_set_hwbreak(target, comparator_list);
1593 if (ret != ERROR_OK) {
1594 comparator_list[wp_num].used = false;
1595 return ret;
1596 }
1597
1598 watchpoint->set = wp_num + 1;
1599
1600 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1601 wp_num,
1602 comparator_list[wp_num].bp_value);
1603
1604 return ERROR_OK;
1605 }
1606
1607 static int stm8_add_watchpoint(struct target *target,
1608 struct watchpoint *watchpoint)
1609 {
1610 int ret;
1611 struct stm8_common *stm8 = target_to_stm8(target);
1612
1613 if (stm8->num_hw_bpoints_avail < 1) {
1614 LOG_INFO("no hardware watchpoints available");
1615 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1616 }
1617
1618 ret = stm8_set_watchpoint(target, watchpoint);
1619 if (ret != ERROR_OK)
1620 return ret;
1621
1622 stm8->num_hw_bpoints_avail--;
1623 return ERROR_OK;
1624 }
1625
1626 static void stm8_enable_watchpoints(struct target *target)
1627 {
1628 struct watchpoint *watchpoint = target->watchpoints;
1629
1630 /* set any pending watchpoints */
1631 while (watchpoint) {
1632 if (watchpoint->set == 0)
1633 stm8_set_watchpoint(target, watchpoint);
1634 watchpoint = watchpoint->next;
1635 }
1636 }
1637
1638 static int stm8_unset_watchpoint(struct target *target,
1639 struct watchpoint *watchpoint)
1640 {
1641 /* get pointers to arch-specific information */
1642 struct stm8_common *stm8 = target_to_stm8(target);
1643 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1644
1645 if (!watchpoint->set) {
1646 LOG_WARNING("watchpoint not set");
1647 return ERROR_OK;
1648 }
1649
1650 int wp_num = watchpoint->set - 1;
1651 if ((wp_num < 0) || (wp_num >= stm8->num_hw_bpoints)) {
1652 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1653 return ERROR_OK;
1654 }
1655 comparator_list[wp_num].used = false;
1656 watchpoint->set = 0;
1657
1658 stm8_set_hwbreak(target, comparator_list);
1659
1660 return ERROR_OK;
1661 }
1662
1663 static int stm8_remove_watchpoint(struct target *target,
1664 struct watchpoint *watchpoint)
1665 {
1666 /* get pointers to arch-specific information */
1667 struct stm8_common *stm8 = target_to_stm8(target);
1668
1669 if (target->state != TARGET_HALTED) {
1670 LOG_WARNING("target not halted");
1671 return ERROR_TARGET_NOT_HALTED;
1672 }
1673
1674 if (watchpoint->set)
1675 stm8_unset_watchpoint(target, watchpoint);
1676
1677 stm8->num_hw_bpoints_avail++;
1678
1679 return ERROR_OK;
1680 }
1681
1682 static int stm8_examine(struct target *target)
1683 {
1684 int retval;
1685 uint8_t csr1, csr2;
1686 /* get pointers to arch-specific information */
1687 struct stm8_common *stm8 = target_to_stm8(target);
1688 enum reset_types jtag_reset_config = jtag_get_reset_config();
1689
1690 if (!target_was_examined(target)) {
1691 if (!stm8->swim_configured) {
1692 stm8->swim_configured = true;
1693 /*
1694 Now is the time to deassert reset if connect_under_reset.
1695 Releasing reset line will cause the option bytes to load.
1696 The core will still be stalled.
1697 */
1698 if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
1699 if (jtag_reset_config & RESET_SRST_NO_GATING)
1700 stm8_reset_deassert(target);
1701 else
1702 LOG_WARNING("\'srst_nogate\' reset_config option is required");
1703 }
1704 } else {
1705 LOG_INFO("trying to reconnect");
1706
1707 retval = swim_reconnect();
1708 if (retval != ERROR_OK) {
1709 LOG_ERROR("reconnect failed");
1710 return ERROR_FAIL;
1711 }
1712
1713 /* read dm_csrx control regs */
1714 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
1715 if (retval != ERROR_OK) {
1716 LOG_ERROR("state query failed");
1717 return ERROR_FAIL;
1718 }
1719 }
1720
1721 target_set_examined(target);
1722
1723 return ERROR_OK;
1724 }
1725
1726 return ERROR_OK;
1727 }
1728
1729 /** Checks whether a memory region is erased. */
1730 static int stm8_blank_check_memory(struct target *target,
1731 struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
1732 {
1733 struct working_area *erase_check_algorithm;
1734 struct reg_param reg_params[2];
1735 struct mem_param mem_params[2];
1736 struct stm8_algorithm stm8_info;
1737
1738 static const uint8_t stm8_erase_check_code[] = {
1739 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1740 };
1741
1742 if (erased_value != 0xff) {
1743 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for STM8",
1744 erased_value);
1745 return ERROR_FAIL;
1746 }
1747
1748 /* make sure we have a working area */
1749 if (target_alloc_working_area(target, sizeof(stm8_erase_check_code),
1750 &erase_check_algorithm) != ERROR_OK)
1751 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1752
1753 target_write_buffer(target, erase_check_algorithm->address,
1754 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1755
1756 stm8_info.common_magic = STM8_COMMON_MAGIC;
1757
1758 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1759 buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
1760
1761 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1762 buf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);
1763
1764 init_reg_param(&reg_params[0], "a", 32, PARAM_IN_OUT);
1765 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1766
1767 init_reg_param(&reg_params[1], "sp", 32, PARAM_OUT);
1768 buf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);
1769
1770 int retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,
1771 erase_check_algorithm->address + 6,
1772 erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
1773 10000, &stm8_info);
1774
1775 if (retval == ERROR_OK)
1776 blocks[0].result = (*(reg_params[0].value) == 0xff);
1777
1778 destroy_mem_param(&mem_params[0]);
1779 destroy_mem_param(&mem_params[1]);
1780 destroy_reg_param(&reg_params[0]);
1781 destroy_reg_param(&reg_params[1]);
1782
1783 target_free_working_area(target, erase_check_algorithm);
1784
1785 if (retval != ERROR_OK)
1786 return retval;
1787
1788 return 1; /* only one block has been checked */
1789 }
1790
1791 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1792 uint32_t count, uint32_t *checksum)
1793 {
1794 /* let image_calculate_checksum() take care of business */
1795 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1796 }
1797
1798 /* run to exit point. return error if exit point was not reached. */
1799 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1800 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1801 {
1802 uint32_t pc;
1803 int retval;
1804 /* This code relies on the target specific resume() and
1805 poll()->debug_entry() sequence to write register values to the
1806 processor and the read them back */
1807 retval = target_resume(target, 0, entry_point, 0, 1);
1808 if (retval != ERROR_OK)
1809 return retval;
1810
1811 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1812 /* If the target fails to halt due to the breakpoint, force a halt */
1813 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1814 retval = target_halt(target);
1815 if (retval != ERROR_OK)
1816 return retval;
1817 retval = target_wait_state(target, TARGET_HALTED, 500);
1818 if (retval != ERROR_OK)
1819 return retval;
1820 return ERROR_TARGET_TIMEOUT;
1821 }
1822
1823 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1824 if (exit_point && (pc != exit_point)) {
1825 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1826 return ERROR_TARGET_TIMEOUT;
1827 }
1828
1829 return ERROR_OK;
1830 }
1831
1832 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1833 struct mem_param *mem_params, int num_reg_params,
1834 struct reg_param *reg_params, target_addr_t entry_point,
1835 target_addr_t exit_point, int timeout_ms, void *arch_info)
1836 {
1837 struct stm8_common *stm8 = target_to_stm8(target);
1838
1839 uint32_t context[STM8_NUM_REGS];
1840 int retval = ERROR_OK;
1841
1842 LOG_DEBUG("Running algorithm");
1843
1844 /* NOTE: stm8_run_algorithm requires that each
1845 algorithm uses a software breakpoint
1846 at the exit point */
1847
1848 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1849 LOG_ERROR("current target isn't a STM8 target");
1850 return ERROR_TARGET_INVALID;
1851 }
1852
1853 if (target->state != TARGET_HALTED) {
1854 LOG_WARNING("target not halted");
1855 return ERROR_TARGET_NOT_HALTED;
1856 }
1857
1858 /* refresh core register cache */
1859 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1860 if (!stm8->core_cache->reg_list[i].valid)
1861 stm8->read_core_reg(target, i);
1862 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1863 }
1864
1865 for (int i = 0; i < num_mem_params; i++) {
1866 if (mem_params[i].direction == PARAM_IN)
1867 continue;
1868 retval = target_write_buffer(target, mem_params[i].address,
1869 mem_params[i].size, mem_params[i].value);
1870 if (retval != ERROR_OK)
1871 return retval;
1872 }
1873
1874 for (int i = 0; i < num_reg_params; i++) {
1875 if (reg_params[i].direction == PARAM_IN)
1876 continue;
1877
1878 struct reg *reg = register_get_by_name(stm8->core_cache,
1879 reg_params[i].reg_name, 0);
1880
1881 if (!reg) {
1882 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1883 return ERROR_COMMAND_SYNTAX_ERROR;
1884 }
1885
1886 if (reg_params[i].size != 32) {
1887 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1888 reg_params[i].reg_name);
1889 return ERROR_COMMAND_SYNTAX_ERROR;
1890 }
1891
1892 stm8_set_core_reg(reg, reg_params[i].value);
1893 }
1894
1895 retval = stm8_run_and_wait(target, entry_point,
1896 timeout_ms, exit_point, stm8);
1897
1898 if (retval != ERROR_OK)
1899 return retval;
1900
1901 for (int i = 0; i < num_mem_params; i++) {
1902 if (mem_params[i].direction != PARAM_OUT) {
1903 retval = target_read_buffer(target, mem_params[i].address,
1904 mem_params[i].size, mem_params[i].value);
1905 if (retval != ERROR_OK)
1906 return retval;
1907 }
1908 }
1909
1910 for (int i = 0; i < num_reg_params; i++) {
1911 if (reg_params[i].direction != PARAM_OUT) {
1912 struct reg *reg = register_get_by_name(stm8->core_cache,
1913 reg_params[i].reg_name, 0);
1914 if (!reg) {
1915 LOG_ERROR("BUG: register '%s' not found",
1916 reg_params[i].reg_name);
1917 return ERROR_COMMAND_SYNTAX_ERROR;
1918 }
1919
1920 if (reg_params[i].size != 32) {
1921 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1922 reg_params[i].reg_name);
1923 return ERROR_COMMAND_SYNTAX_ERROR;
1924 }
1925
1926 buf_set_u32(reg_params[i].value,
1927 0, 32, buf_get_u32(reg->value, 0, 32));
1928 }
1929 }
1930
1931 /* restore everything we saved before */
1932 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1933 uint32_t regvalue;
1934 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1935 if (regvalue != context[i]) {
1936 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1937 stm8->core_cache->reg_list[i].name, context[i]);
1938 buf_set_u32(stm8->core_cache->reg_list[i].value,
1939 0, 32, context[i]);
1940 stm8->core_cache->reg_list[i].valid = true;
1941 stm8->core_cache->reg_list[i].dirty = true;
1942 }
1943 }
1944
1945 return ERROR_OK;
1946 }
1947
1948 int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi)
1949 {
1950 struct stm8_common *stm8 = target_to_stm8(target);
1951 jim_wide w;
1952 int e;
1953 const char *arg;
1954
1955 arg = Jim_GetString(goi->argv[0], NULL);
1956 if (!strcmp(arg, "-blocksize")) {
1957 e = Jim_GetOpt_String(goi, &arg, NULL);
1958 if (e != JIM_OK)
1959 return e;
1960
1961 if (goi->argc == 0) {
1962 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1963 "-blocksize ?bytes? ...");
1964 return JIM_ERR;
1965 }
1966
1967 e = Jim_GetOpt_Wide(goi, &w);
1968 if (e != JIM_OK)
1969 return e;
1970
1971 stm8->blocksize = w;
1972 LOG_DEBUG("blocksize=%8.8x", stm8->blocksize);
1973 return JIM_OK;
1974 }
1975 if (!strcmp(arg, "-flashstart")) {
1976 e = Jim_GetOpt_String(goi, &arg, NULL);
1977 if (e != JIM_OK)
1978 return e;
1979
1980 if (goi->argc == 0) {
1981 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1982 "-flashstart ?address? ...");
1983 return JIM_ERR;
1984 }
1985
1986 e = Jim_GetOpt_Wide(goi, &w);
1987 if (e != JIM_OK)
1988 return e;
1989
1990 stm8->flashstart = w;
1991 LOG_DEBUG("flashstart=%8.8x", stm8->flashstart);
1992 return JIM_OK;
1993 }
1994 if (!strcmp(arg, "-flashend")) {
1995 e = Jim_GetOpt_String(goi, &arg, NULL);
1996 if (e != JIM_OK)
1997 return e;
1998
1999 if (goi->argc == 0) {
2000 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2001 "-flashend ?address? ...");
2002 return JIM_ERR;
2003 }
2004
2005 e = Jim_GetOpt_Wide(goi, &w);
2006 if (e != JIM_OK)
2007 return e;
2008
2009 stm8->flashend = w;
2010 LOG_DEBUG("flashend=%8.8x", stm8->flashend);
2011 return JIM_OK;
2012 }
2013 if (!strcmp(arg, "-eepromstart")) {
2014 e = Jim_GetOpt_String(goi, &arg, NULL);
2015 if (e != JIM_OK)
2016 return e;
2017
2018 if (goi->argc == 0) {
2019 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2020 "-eepromstart ?address? ...");
2021 return JIM_ERR;
2022 }
2023
2024 e = Jim_GetOpt_Wide(goi, &w);
2025 if (e != JIM_OK)
2026 return e;
2027
2028 stm8->eepromstart = w;
2029 LOG_DEBUG("eepromstart=%8.8x", stm8->eepromstart);
2030 return JIM_OK;
2031 }
2032 if (!strcmp(arg, "-eepromend")) {
2033 e = Jim_GetOpt_String(goi, &arg, NULL);
2034 if (e != JIM_OK)
2035 return e;
2036
2037 if (goi->argc == 0) {
2038 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2039 "-eepromend ?address? ...");
2040 return JIM_ERR;
2041 }
2042
2043 e = Jim_GetOpt_Wide(goi, &w);
2044 if (e != JIM_OK)
2045 return e;
2046
2047 stm8->eepromend = w;
2048 LOG_DEBUG("eepromend=%8.8x", stm8->eepromend);
2049 return JIM_OK;
2050 }
2051 if (!strcmp(arg, "-optionstart")) {
2052 e = Jim_GetOpt_String(goi, &arg, NULL);
2053 if (e != JIM_OK)
2054 return e;
2055
2056 if (goi->argc == 0) {
2057 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2058 "-optionstart ?address? ...");
2059 return JIM_ERR;
2060 }
2061
2062 e = Jim_GetOpt_Wide(goi, &w);
2063 if (e != JIM_OK)
2064 return e;
2065
2066 stm8->optionstart = w;
2067 LOG_DEBUG("optionstart=%8.8x", stm8->optionstart);
2068 return JIM_OK;
2069 }
2070 if (!strcmp(arg, "-optionend")) {
2071 e = Jim_GetOpt_String(goi, &arg, NULL);
2072 if (e != JIM_OK)
2073 return e;
2074
2075 if (goi->argc == 0) {
2076 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2077 "-optionend ?address? ...");
2078 return JIM_ERR;
2079 }
2080
2081 e = Jim_GetOpt_Wide(goi, &w);
2082 if (e != JIM_OK)
2083 return e;
2084
2085 stm8->optionend = w;
2086 LOG_DEBUG("optionend=%8.8x", stm8->optionend);
2087 return JIM_OK;
2088 }
2089 if (!strcmp(arg, "-enable_step_irq")) {
2090 e = Jim_GetOpt_String(goi, &arg, NULL);
2091 if (e != JIM_OK)
2092 return e;
2093
2094 stm8->enable_step_irq = true;
2095 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2096 return JIM_OK;
2097 }
2098 if (!strcmp(arg, "-enable_stm8l")) {
2099 e = Jim_GetOpt_String(goi, &arg, NULL);
2100 if (e != JIM_OK)
2101 return e;
2102
2103 stm8->enable_stm8l = true;
2104 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2105 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2106 return JIM_OK;
2107 }
2108 return JIM_CONTINUE;
2109 }
2110
2111 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2112 {
2113 const char *msg;
2114 struct target *target = get_current_target(CMD_CTX);
2115 struct stm8_common *stm8 = target_to_stm8(target);
2116 bool enable = stm8->enable_step_irq;
2117
2118 if (CMD_ARGC > 0) {
2119 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2120 stm8->enable_step_irq = enable;
2121 }
2122 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2123 command_print(CMD, "enable_step_irq = %s", msg);
2124 return ERROR_OK;
2125 }
2126
2127 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2128 {
2129 const char *msg;
2130 struct target *target = get_current_target(CMD_CTX);
2131 struct stm8_common *stm8 = target_to_stm8(target);
2132 bool enable = stm8->enable_stm8l;
2133
2134 if (CMD_ARGC > 0) {
2135 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2136 stm8->enable_stm8l = enable;
2137 }
2138 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2139 command_print(CMD, "enable_stm8l = %s", msg);
2140 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2141 return ERROR_OK;
2142 }
2143
2144 static const struct command_registration stm8_exec_command_handlers[] = {
2145 {
2146 .name = "enable_step_irq",
2147 .handler = stm8_handle_enable_step_irq_command,
2148 .mode = COMMAND_ANY,
2149 .help = "Enable/disable irq handling during step",
2150 .usage = "[1/0]",
2151 },
2152 {
2153 .name = "enable_stm8l",
2154 .handler = stm8_handle_enable_stm8l_command,
2155 .mode = COMMAND_ANY,
2156 .help = "Enable/disable STM8L flash programming",
2157 .usage = "[1/0]",
2158 },
2159 COMMAND_REGISTRATION_DONE
2160 };
2161
2162 const struct command_registration stm8_command_handlers[] = {
2163 {
2164 .name = "stm8",
2165 .mode = COMMAND_ANY,
2166 .help = "stm8 command group",
2167 .usage = "",
2168 .chain = stm8_exec_command_handlers,
2169 },
2170 COMMAND_REGISTRATION_DONE
2171 };
2172
2173 struct target_type stm8_target = {
2174 .name = "stm8",
2175
2176 .poll = stm8_poll,
2177 .arch_state = stm8_arch_state,
2178
2179 .halt = stm8_halt,
2180 .resume = stm8_resume,
2181 .step = stm8_step,
2182
2183 .assert_reset = stm8_reset_assert,
2184 .deassert_reset = stm8_reset_deassert,
2185
2186 .get_gdb_arch = stm8_get_gdb_arch,
2187 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2188
2189 .read_memory = stm8_read_memory,
2190 .write_memory = stm8_write_memory,
2191 .checksum_memory = stm8_checksum_memory,
2192 .blank_check_memory = stm8_blank_check_memory,
2193
2194 .run_algorithm = stm8_run_algorithm,
2195
2196 .add_breakpoint = stm8_add_breakpoint,
2197 .remove_breakpoint = stm8_remove_breakpoint,
2198 .add_watchpoint = stm8_add_watchpoint,
2199 .remove_watchpoint = stm8_remove_watchpoint,
2200
2201 .commands = stm8_command_handlers,
2202 .target_create = stm8_target_create,
2203 .init_target = stm8_init,
2204 .examine = stm8_examine,
2205
2206 .deinit_target = stm8_deinit,
2207 .target_jim_configure = stm8_jim_configure,
2208 };

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)