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

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)