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

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)