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

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)