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

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)