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

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)