5a3438a6407b927e6e9e1a4164a8ba11f03004a2
[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 int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
1193 int *reg_list_size, enum target_register_class reg_class)
1194 {
1195 /* get pointers to arch-specific information */
1196 struct stm8_common *stm8 = target_to_stm8(target);
1197 unsigned int i;
1198
1199 *reg_list_size = STM8_NUM_REGS;
1200 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1201
1202 for (i = 0; i < STM8_NUM_REGS; i++)
1203 (*reg_list)[i] = &stm8->core_cache->reg_list[i];
1204
1205 return ERROR_OK;
1206 }
1207
1208 static const struct reg_arch_type stm8_reg_type = {
1209 .get = stm8_get_core_reg,
1210 .set = stm8_set_core_reg,
1211 };
1212
1213 static struct reg_cache *stm8_build_reg_cache(struct target *target)
1214 {
1215 /* get pointers to arch-specific information */
1216 struct stm8_common *stm8 = target_to_stm8(target);
1217
1218 int num_regs = STM8_NUM_REGS;
1219 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1220 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1221 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1222 struct stm8_core_reg *arch_info = malloc(
1223 sizeof(struct stm8_core_reg) * num_regs);
1224 struct reg_feature *feature;
1225 int i;
1226
1227 /* Build the process context cache */
1228 cache->name = "stm8 registers";
1229 cache->next = NULL;
1230 cache->reg_list = reg_list;
1231 cache->num_regs = num_regs;
1232 (*cache_p) = cache;
1233 stm8->core_cache = cache;
1234
1235 for (i = 0; i < num_regs; i++) {
1236 arch_info[i].num = stm8_regs[i].id;
1237 arch_info[i].target = target;
1238 arch_info[i].stm8_common = stm8;
1239
1240 reg_list[i].name = stm8_regs[i].name;
1241 reg_list[i].size = stm8_regs[i].bits;
1242
1243 reg_list[i].value = calloc(1, 4);
1244 reg_list[i].valid = false;
1245 reg_list[i].type = &stm8_reg_type;
1246 reg_list[i].arch_info = &arch_info[i];
1247
1248 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1249 if (reg_list[i].reg_data_type)
1250 reg_list[i].reg_data_type->type = stm8_regs[i].type;
1251 else {
1252 LOG_ERROR("unable to allocate reg type list");
1253 return NULL;
1254 }
1255
1256 reg_list[i].dirty = false;
1257 reg_list[i].group = stm8_regs[i].group;
1258 reg_list[i].number = stm8_regs[i].id;
1259 reg_list[i].exist = true;
1260 reg_list[i].caller_save = true; /* gdb defaults to true */
1261
1262 feature = calloc(1, sizeof(struct reg_feature));
1263 if (feature) {
1264 feature->name = stm8_regs[i].feature;
1265 reg_list[i].feature = feature;
1266 } else
1267 LOG_ERROR("unable to allocate feature list");
1268 }
1269
1270 return cache;
1271 }
1272
1273 static void stm8_free_reg_cache(struct target *target)
1274 {
1275 struct stm8_common *stm8 = target_to_stm8(target);
1276 struct reg_cache *cache;
1277 struct reg *reg;
1278 unsigned int i;
1279
1280 cache = stm8->core_cache;
1281
1282 if (!cache)
1283 return;
1284
1285 for (i = 0; i < cache->num_regs; i++) {
1286 reg = &cache->reg_list[i];
1287
1288 free(reg->feature);
1289 free(reg->reg_data_type);
1290 free(reg->value);
1291 }
1292
1293 free(cache->reg_list[0].arch_info);
1294 free(cache->reg_list);
1295 free(cache);
1296
1297 stm8->core_cache = NULL;
1298 }
1299
1300 static void stm8_deinit(struct target *target)
1301 {
1302 struct stm8_common *stm8 = target_to_stm8(target);
1303
1304 free(stm8->hw_break_list);
1305
1306 stm8_free_reg_cache(target);
1307
1308 free(stm8);
1309 }
1310
1311 static int stm8_arch_state(struct target *target)
1312 {
1313 struct stm8_common *stm8 = target_to_stm8(target);
1314
1315 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
1316 debug_reason_name(target),
1317 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1318
1319 return ERROR_OK;
1320 }
1321
1322 static int stm8_step(struct target *target, int current,
1323 target_addr_t address, int handle_breakpoints)
1324 {
1325 LOG_DEBUG("%" PRIx32 " " TARGET_ADDR_FMT " %" PRIx32,
1326 current, address, handle_breakpoints);
1327
1328 /* get pointers to arch-specific information */
1329 struct stm8_common *stm8 = target_to_stm8(target);
1330 struct breakpoint *breakpoint = NULL;
1331
1332 if (target->state != TARGET_HALTED) {
1333 LOG_WARNING("target not halted");
1334 return ERROR_TARGET_NOT_HALTED;
1335 }
1336
1337 /* current = 1: continue on current pc, otherwise continue at <address> */
1338 if (!current) {
1339 buf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);
1340 stm8->core_cache->reg_list[STM8_PC].dirty = true;
1341 stm8->core_cache->reg_list[STM8_PC].valid = true;
1342 }
1343
1344 /* the front-end may request us not to handle breakpoints */
1345 if (handle_breakpoints) {
1346 breakpoint = breakpoint_find(target,
1347 buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));
1348 if (breakpoint)
1349 stm8_unset_breakpoint(target, breakpoint);
1350 }
1351
1352 /* restore context */
1353 stm8_restore_context(target);
1354
1355 /* configure single step mode */
1356 stm8_config_step(target, 1);
1357
1358 target->debug_reason = DBG_REASON_SINGLESTEP;
1359
1360 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1361
1362 /* disable interrupts while stepping */
1363 if (!stm8->enable_step_irq)
1364 stm8_enable_interrupts(target, 0);
1365
1366 /* exit debug mode */
1367 stm8_exit_debug(target);
1368
1369 /* registers are now invalid */
1370 register_cache_invalidate(stm8->core_cache);
1371
1372 LOG_DEBUG("target stepped ");
1373 stm8_debug_entry(target);
1374
1375 if (breakpoint)
1376 stm8_set_breakpoint(target, breakpoint);
1377
1378 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1379
1380 return ERROR_OK;
1381 }
1382
1383 static void stm8_enable_breakpoints(struct target *target)
1384 {
1385 struct breakpoint *breakpoint = target->breakpoints;
1386
1387 /* set any pending breakpoints */
1388 while (breakpoint) {
1389 if (breakpoint->set == 0)
1390 stm8_set_breakpoint(target, breakpoint);
1391 breakpoint = breakpoint->next;
1392 }
1393 }
1394
1395 static int stm8_set_breakpoint(struct target *target,
1396 struct breakpoint *breakpoint)
1397 {
1398 struct stm8_common *stm8 = target_to_stm8(target);
1399 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1400 int retval;
1401
1402 if (breakpoint->set) {
1403 LOG_WARNING("breakpoint already set");
1404 return ERROR_OK;
1405 }
1406
1407 if (breakpoint->type == BKPT_HARD) {
1408 int bp_num = 0;
1409
1410 while (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))
1411 bp_num++;
1412 if (bp_num >= stm8->num_hw_bpoints) {
1413 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32 ")",
1414 breakpoint->unique_id);
1415 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1416 }
1417 breakpoint->set = bp_num + 1;
1418 comparator_list[bp_num].used = true;
1419 comparator_list[bp_num].bp_value = breakpoint->address;
1420 comparator_list[bp_num].type = HWBRK_EXEC;
1421
1422 retval = stm8_set_hwbreak(target, comparator_list);
1423 if (retval != ERROR_OK)
1424 return retval;
1425
1426 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
1427 breakpoint->unique_id,
1428 bp_num, comparator_list[bp_num].bp_value);
1429 } else if (breakpoint->type == BKPT_SOFT) {
1430 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1431 if (breakpoint->length == 1) {
1432 uint8_t verify = 0x55;
1433
1434 retval = target_read_u8(target, breakpoint->address,
1435 breakpoint->orig_instr);
1436 if (retval != ERROR_OK)
1437 return retval;
1438 retval = target_write_u8(target, breakpoint->address, STM8_BREAK);
1439 if (retval != ERROR_OK)
1440 return retval;
1441
1442 retval = target_read_u8(target, breakpoint->address, &verify);
1443 if (retval != ERROR_OK)
1444 return retval;
1445 if (verify != STM8_BREAK) {
1446 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1447 " - check that memory is read/writable",
1448 breakpoint->address);
1449 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1450 }
1451 } else {
1452 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1453 }
1454 breakpoint->set = 1; /* Any nice value but 0 */
1455 }
1456
1457 return ERROR_OK;
1458 }
1459
1460 static int stm8_add_breakpoint(struct target *target,
1461 struct breakpoint *breakpoint)
1462 {
1463 struct stm8_common *stm8 = target_to_stm8(target);
1464 int ret;
1465
1466 if (breakpoint->type == BKPT_HARD) {
1467 if (stm8->num_hw_bpoints_avail < 1) {
1468 LOG_INFO("no hardware breakpoint available");
1469 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1470 }
1471
1472 ret = stm8_set_breakpoint(target, breakpoint);
1473 if (ret != ERROR_OK)
1474 return ret;
1475
1476 stm8->num_hw_bpoints_avail--;
1477 return ERROR_OK;
1478 }
1479
1480 ret = stm8_set_breakpoint(target, breakpoint);
1481 if (ret != ERROR_OK)
1482 return ret;
1483
1484 return ERROR_OK;
1485 }
1486
1487 static int stm8_unset_breakpoint(struct target *target,
1488 struct breakpoint *breakpoint)
1489 {
1490 /* get pointers to arch-specific information */
1491 struct stm8_common *stm8 = target_to_stm8(target);
1492 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1493 int retval;
1494
1495 if (!breakpoint->set) {
1496 LOG_WARNING("breakpoint not set");
1497 return ERROR_OK;
1498 }
1499
1500 if (breakpoint->type == BKPT_HARD) {
1501 int bp_num = breakpoint->set - 1;
1502 if ((bp_num < 0) || (bp_num >= stm8->num_hw_bpoints)) {
1503 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
1504 breakpoint->unique_id);
1505 return ERROR_OK;
1506 }
1507 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
1508 breakpoint->unique_id,
1509 bp_num);
1510 comparator_list[bp_num].used = false;
1511 retval = stm8_set_hwbreak(target, comparator_list);
1512 if (retval != ERROR_OK)
1513 return retval;
1514 } else {
1515 /* restore original instruction (kept in target endianness) */
1516 LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
1517 if (breakpoint->length == 1) {
1518 uint8_t current_instr;
1519
1520 /* check that user program has not
1521 modified breakpoint instruction */
1522 retval = target_read_memory(target, breakpoint->address, 1, 1,
1523 (uint8_t *)&current_instr);
1524 if (retval != ERROR_OK)
1525 return retval;
1526
1527 if (current_instr == STM8_BREAK) {
1528 retval = target_write_memory(target, breakpoint->address, 1, 1,
1529 breakpoint->orig_instr);
1530 if (retval != ERROR_OK)
1531 return retval;
1532 }
1533 } else
1534 return ERROR_FAIL;
1535 }
1536 breakpoint->set = 0;
1537
1538 return ERROR_OK;
1539 }
1540
1541 static int stm8_remove_breakpoint(struct target *target,
1542 struct breakpoint *breakpoint)
1543 {
1544 /* get pointers to arch-specific information */
1545 struct stm8_common *stm8 = target_to_stm8(target);
1546
1547 if (target->state != TARGET_HALTED) {
1548 LOG_WARNING("target not halted");
1549 return ERROR_TARGET_NOT_HALTED;
1550 }
1551
1552 if (breakpoint->set)
1553 stm8_unset_breakpoint(target, breakpoint);
1554
1555 if (breakpoint->type == BKPT_HARD)
1556 stm8->num_hw_bpoints_avail++;
1557
1558 return ERROR_OK;
1559 }
1560
1561 static int stm8_set_watchpoint(struct target *target,
1562 struct watchpoint *watchpoint)
1563 {
1564 struct stm8_common *stm8 = target_to_stm8(target);
1565 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1566 int wp_num = 0;
1567 int ret;
1568
1569 if (watchpoint->set) {
1570 LOG_WARNING("watchpoint already set");
1571 return ERROR_OK;
1572 }
1573
1574 while (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))
1575 wp_num++;
1576 if (wp_num >= stm8->num_hw_bpoints) {
1577 LOG_ERROR("Can not find free hw breakpoint");
1578 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1579 }
1580
1581 if (watchpoint->length != 1) {
1582 LOG_ERROR("Only watchpoints of length 1 are supported");
1583 return ERROR_TARGET_UNALIGNED_ACCESS;
1584 }
1585
1586 enum hw_break_type enable = 0;
1587
1588 switch (watchpoint->rw) {
1589 case WPT_READ:
1590 enable = HWBRK_RD;
1591 break;
1592 case WPT_WRITE:
1593 enable = HWBRK_WR;
1594 break;
1595 case WPT_ACCESS:
1596 enable = HWBRK_ACC;
1597 break;
1598 default:
1599 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1600 }
1601
1602 comparator_list[wp_num].used = true;
1603 comparator_list[wp_num].bp_value = watchpoint->address;
1604 comparator_list[wp_num].type = enable;
1605
1606 ret = stm8_set_hwbreak(target, comparator_list);
1607 if (ret != ERROR_OK) {
1608 comparator_list[wp_num].used = false;
1609 return ret;
1610 }
1611
1612 watchpoint->set = wp_num + 1;
1613
1614 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
1615 wp_num,
1616 comparator_list[wp_num].bp_value);
1617
1618 return ERROR_OK;
1619 }
1620
1621 static int stm8_add_watchpoint(struct target *target,
1622 struct watchpoint *watchpoint)
1623 {
1624 int ret;
1625 struct stm8_common *stm8 = target_to_stm8(target);
1626
1627 if (stm8->num_hw_bpoints_avail < 1) {
1628 LOG_INFO("no hardware watchpoints available");
1629 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1630 }
1631
1632 ret = stm8_set_watchpoint(target, watchpoint);
1633 if (ret != ERROR_OK)
1634 return ret;
1635
1636 stm8->num_hw_bpoints_avail--;
1637 return ERROR_OK;
1638 }
1639
1640 static void stm8_enable_watchpoints(struct target *target)
1641 {
1642 struct watchpoint *watchpoint = target->watchpoints;
1643
1644 /* set any pending watchpoints */
1645 while (watchpoint) {
1646 if (watchpoint->set == 0)
1647 stm8_set_watchpoint(target, watchpoint);
1648 watchpoint = watchpoint->next;
1649 }
1650 }
1651
1652 static int stm8_unset_watchpoint(struct target *target,
1653 struct watchpoint *watchpoint)
1654 {
1655 /* get pointers to arch-specific information */
1656 struct stm8_common *stm8 = target_to_stm8(target);
1657 struct stm8_comparator *comparator_list = stm8->hw_break_list;
1658
1659 if (!watchpoint->set) {
1660 LOG_WARNING("watchpoint not set");
1661 return ERROR_OK;
1662 }
1663
1664 int wp_num = watchpoint->set - 1;
1665 if ((wp_num < 0) || (wp_num >= stm8->num_hw_bpoints)) {
1666 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1667 return ERROR_OK;
1668 }
1669 comparator_list[wp_num].used = false;
1670 watchpoint->set = 0;
1671
1672 stm8_set_hwbreak(target, comparator_list);
1673
1674 return ERROR_OK;
1675 }
1676
1677 static int stm8_remove_watchpoint(struct target *target,
1678 struct watchpoint *watchpoint)
1679 {
1680 /* get pointers to arch-specific information */
1681 struct stm8_common *stm8 = target_to_stm8(target);
1682
1683 if (target->state != TARGET_HALTED) {
1684 LOG_WARNING("target not halted");
1685 return ERROR_TARGET_NOT_HALTED;
1686 }
1687
1688 if (watchpoint->set)
1689 stm8_unset_watchpoint(target, watchpoint);
1690
1691 stm8->num_hw_bpoints_avail++;
1692
1693 return ERROR_OK;
1694 }
1695
1696 static int stm8_examine(struct target *target)
1697 {
1698 int retval;
1699 uint8_t csr1, csr2;
1700 /* get pointers to arch-specific information */
1701 struct stm8_common *stm8 = target_to_stm8(target);
1702 struct hl_interface_s *adapter = target_to_adapter(target);
1703
1704 if (!target_was_examined(target)) {
1705 if (!stm8->swim_configured) {
1706 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1707 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1708 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM);
1709 if (retval != ERROR_OK)
1710 return retval;
1711 /* set high speed */
1712 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1713 retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS);
1714 if (retval != ERROR_OK)
1715 return retval;
1716 retval = stm8_set_speed(target, 1);
1717 if (retval == ERROR_OK)
1718 stm8->swim_configured = true;
1719 /*
1720 Now is the time to deassert reset if connect_under_reset.
1721 Releasing reset line will cause the option bytes to load.
1722 The core will still be stalled.
1723 */
1724 if (adapter->param.connect_under_reset)
1725 stm8_reset_deassert(target);
1726 } else {
1727 LOG_INFO("trying to reconnect");
1728
1729 retval = adapter->layout->api->state(adapter->handle);
1730 if (retval != ERROR_OK) {
1731 LOG_ERROR("reconnect failed");
1732 return ERROR_FAIL;
1733 }
1734
1735 /* read dm_csrx control regs */
1736 retval = stm8_read_dm_csrx(target, &csr1, &csr2);
1737 if (retval != ERROR_OK) {
1738 LOG_ERROR("state query failed");
1739 return ERROR_FAIL;
1740 }
1741 }
1742
1743 target_set_examined(target);
1744
1745 return ERROR_OK;
1746 }
1747
1748 return ERROR_OK;
1749 }
1750
1751 /** Checks whether a memory region is erased. */
1752 static int stm8_blank_check_memory(struct target *target,
1753 struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
1754 {
1755 struct working_area *erase_check_algorithm;
1756 struct reg_param reg_params[2];
1757 struct mem_param mem_params[2];
1758 struct stm8_algorithm stm8_info;
1759
1760 static const uint8_t stm8_erase_check_code[] = {
1761 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1762 };
1763
1764 if (erased_value != 0xff) {
1765 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for STM8",
1766 erased_value);
1767 return ERROR_FAIL;
1768 }
1769
1770 /* make sure we have a working area */
1771 if (target_alloc_working_area(target, sizeof(stm8_erase_check_code),
1772 &erase_check_algorithm) != ERROR_OK)
1773 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1774
1775 target_write_buffer(target, erase_check_algorithm->address,
1776 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1777
1778 stm8_info.common_magic = STM8_COMMON_MAGIC;
1779
1780 init_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);
1781 buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
1782
1783 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1784 buf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);
1785
1786 init_reg_param(&reg_params[0], "a", 32, PARAM_IN_OUT);
1787 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1788
1789 init_reg_param(&reg_params[1], "sp", 32, PARAM_OUT);
1790 buf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);
1791
1792 int retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,
1793 erase_check_algorithm->address + 6,
1794 erase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),
1795 10000, &stm8_info);
1796
1797 if (retval == ERROR_OK)
1798 blocks[0].result = (*(reg_params[0].value) == 0xff);
1799
1800 destroy_mem_param(&mem_params[0]);
1801 destroy_mem_param(&mem_params[1]);
1802 destroy_reg_param(&reg_params[0]);
1803
1804 target_free_working_area(target, erase_check_algorithm);
1805
1806 if (retval != ERROR_OK)
1807 return retval;
1808
1809 return 1; /* only one block has been checked */
1810 }
1811
1812 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1813 uint32_t count, uint32_t *checksum)
1814 {
1815 /* let image_calculate_checksum() take care of business */
1816 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1817 }
1818
1819 /* run to exit point. return error if exit point was not reached. */
1820 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1821 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1822 {
1823 uint32_t pc;
1824 int retval;
1825 /* This code relies on the target specific resume() and
1826 poll()->debug_entry() sequence to write register values to the
1827 processor and the read them back */
1828 retval = target_resume(target, 0, entry_point, 0, 1);
1829 if (retval != ERROR_OK)
1830 return retval;
1831
1832 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1833 /* If the target fails to halt due to the breakpoint, force a halt */
1834 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1835 retval = target_halt(target);
1836 if (retval != ERROR_OK)
1837 return retval;
1838 retval = target_wait_state(target, TARGET_HALTED, 500);
1839 if (retval != ERROR_OK)
1840 return retval;
1841 return ERROR_TARGET_TIMEOUT;
1842 }
1843
1844 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1845 if (exit_point && (pc != exit_point)) {
1846 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1847 return ERROR_TARGET_TIMEOUT;
1848 }
1849
1850 return ERROR_OK;
1851 }
1852
1853 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1854 struct mem_param *mem_params, int num_reg_params,
1855 struct reg_param *reg_params, target_addr_t entry_point,
1856 target_addr_t exit_point, int timeout_ms, void *arch_info)
1857 {
1858 struct stm8_common *stm8 = target_to_stm8(target);
1859
1860 uint32_t context[STM8_NUM_REGS];
1861 int retval = ERROR_OK;
1862
1863 LOG_DEBUG("Running algorithm");
1864
1865 /* NOTE: stm8_run_algorithm requires that each
1866 algorithm uses a software breakpoint
1867 at the exit point */
1868
1869 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1870 LOG_ERROR("current target isn't a STM8 target");
1871 return ERROR_TARGET_INVALID;
1872 }
1873
1874 if (target->state != TARGET_HALTED) {
1875 LOG_WARNING("target not halted");
1876 return ERROR_TARGET_NOT_HALTED;
1877 }
1878
1879 /* refresh core register cache */
1880 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1881 if (!stm8->core_cache->reg_list[i].valid)
1882 stm8->read_core_reg(target, i);
1883 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1884 }
1885
1886 for (int i = 0; i < num_mem_params; i++) {
1887 retval = target_write_buffer(target, mem_params[i].address,
1888 mem_params[i].size, mem_params[i].value);
1889 if (retval != ERROR_OK)
1890 return retval;
1891 }
1892
1893 for (int i = 0; i < num_reg_params; i++) {
1894 struct reg *reg = register_get_by_name(stm8->core_cache,
1895 reg_params[i].reg_name, 0);
1896
1897 if (!reg) {
1898 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1899 return ERROR_COMMAND_SYNTAX_ERROR;
1900 }
1901
1902 if (reg_params[i].size != 32) {
1903 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1904 reg_params[i].reg_name);
1905 return ERROR_COMMAND_SYNTAX_ERROR;
1906 }
1907
1908 stm8_set_core_reg(reg, reg_params[i].value);
1909 }
1910
1911 retval = stm8_run_and_wait(target, entry_point,
1912 timeout_ms, exit_point, stm8);
1913
1914 if (retval != ERROR_OK)
1915 return retval;
1916
1917 for (int i = 0; i < num_mem_params; i++) {
1918 if (mem_params[i].direction != PARAM_OUT) {
1919 retval = target_read_buffer(target, mem_params[i].address,
1920 mem_params[i].size, mem_params[i].value);
1921 if (retval != ERROR_OK)
1922 return retval;
1923 }
1924 }
1925
1926 for (int i = 0; i < num_reg_params; i++) {
1927 if (reg_params[i].direction != PARAM_OUT) {
1928 struct reg *reg = register_get_by_name(stm8->core_cache,
1929 reg_params[i].reg_name, 0);
1930 if (!reg) {
1931 LOG_ERROR("BUG: register '%s' not found",
1932 reg_params[i].reg_name);
1933 return ERROR_COMMAND_SYNTAX_ERROR;
1934 }
1935
1936 if (reg_params[i].size != 32) {
1937 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1938 reg_params[i].reg_name);
1939 return ERROR_COMMAND_SYNTAX_ERROR;
1940 }
1941
1942 buf_set_u32(reg_params[i].value,
1943 0, 32, buf_get_u32(reg->value, 0, 32));
1944 }
1945 }
1946
1947 /* restore everything we saved before */
1948 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1949 uint32_t regvalue;
1950 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1951 if (regvalue != context[i]) {
1952 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1953 stm8->core_cache->reg_list[i].name, context[i]);
1954 buf_set_u32(stm8->core_cache->reg_list[i].value,
1955 0, 32, context[i]);
1956 stm8->core_cache->reg_list[i].valid = true;
1957 stm8->core_cache->reg_list[i].dirty = true;
1958 }
1959 }
1960
1961 return ERROR_OK;
1962 }
1963
1964 int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi)
1965 {
1966 struct stm8_common *stm8 = target_to_stm8(target);
1967 jim_wide w;
1968 int e;
1969 const char *arg;
1970
1971 arg = Jim_GetString(goi->argv[0], NULL);
1972 if (!strcmp(arg, "-blocksize")) {
1973 e = Jim_GetOpt_String(goi, &arg, NULL);
1974 if (e != JIM_OK)
1975 return e;
1976
1977 if (goi->argc == 0) {
1978 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1979 "-blocksize ?bytes? ...");
1980 return JIM_ERR;
1981 }
1982
1983 e = Jim_GetOpt_Wide(goi, &w);
1984 if (e != JIM_OK)
1985 return e;
1986
1987 stm8->blocksize = w;
1988 LOG_DEBUG("blocksize=%8.8x", stm8->blocksize);
1989 return JIM_OK;
1990 }
1991 if (!strcmp(arg, "-flashstart")) {
1992 e = Jim_GetOpt_String(goi, &arg, NULL);
1993 if (e != JIM_OK)
1994 return e;
1995
1996 if (goi->argc == 0) {
1997 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1998 "-flashstart ?address? ...");
1999 return JIM_ERR;
2000 }
2001
2002 e = Jim_GetOpt_Wide(goi, &w);
2003 if (e != JIM_OK)
2004 return e;
2005
2006 stm8->flashstart = w;
2007 LOG_DEBUG("flashstart=%8.8x", stm8->flashstart);
2008 return JIM_OK;
2009 }
2010 if (!strcmp(arg, "-flashend")) {
2011 e = Jim_GetOpt_String(goi, &arg, NULL);
2012 if (e != JIM_OK)
2013 return e;
2014
2015 if (goi->argc == 0) {
2016 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2017 "-flashend ?address? ...");
2018 return JIM_ERR;
2019 }
2020
2021 e = Jim_GetOpt_Wide(goi, &w);
2022 if (e != JIM_OK)
2023 return e;
2024
2025 stm8->flashend = w;
2026 LOG_DEBUG("flashend=%8.8x", stm8->flashend);
2027 return JIM_OK;
2028 }
2029 if (!strcmp(arg, "-eepromstart")) {
2030 e = Jim_GetOpt_String(goi, &arg, NULL);
2031 if (e != JIM_OK)
2032 return e;
2033
2034 if (goi->argc == 0) {
2035 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2036 "-eepromstart ?address? ...");
2037 return JIM_ERR;
2038 }
2039
2040 e = Jim_GetOpt_Wide(goi, &w);
2041 if (e != JIM_OK)
2042 return e;
2043
2044 stm8->eepromstart = w;
2045 LOG_DEBUG("eepromstart=%8.8x", stm8->eepromstart);
2046 return JIM_OK;
2047 }
2048 if (!strcmp(arg, "-eepromend")) {
2049 e = Jim_GetOpt_String(goi, &arg, NULL);
2050 if (e != JIM_OK)
2051 return e;
2052
2053 if (goi->argc == 0) {
2054 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2055 "-eepromend ?address? ...");
2056 return JIM_ERR;
2057 }
2058
2059 e = Jim_GetOpt_Wide(goi, &w);
2060 if (e != JIM_OK)
2061 return e;
2062
2063 stm8->eepromend = w;
2064 LOG_DEBUG("eepromend=%8.8x", stm8->eepromend);
2065 return JIM_OK;
2066 }
2067 if (!strcmp(arg, "-optionstart")) {
2068 e = Jim_GetOpt_String(goi, &arg, NULL);
2069 if (e != JIM_OK)
2070 return e;
2071
2072 if (goi->argc == 0) {
2073 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2074 "-optionstart ?address? ...");
2075 return JIM_ERR;
2076 }
2077
2078 e = Jim_GetOpt_Wide(goi, &w);
2079 if (e != JIM_OK)
2080 return e;
2081
2082 stm8->optionstart = w;
2083 LOG_DEBUG("optionstart=%8.8x", stm8->optionstart);
2084 return JIM_OK;
2085 }
2086 if (!strcmp(arg, "-optionend")) {
2087 e = Jim_GetOpt_String(goi, &arg, NULL);
2088 if (e != JIM_OK)
2089 return e;
2090
2091 if (goi->argc == 0) {
2092 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2093 "-optionend ?address? ...");
2094 return JIM_ERR;
2095 }
2096
2097 e = Jim_GetOpt_Wide(goi, &w);
2098 if (e != JIM_OK)
2099 return e;
2100
2101 stm8->optionend = w;
2102 LOG_DEBUG("optionend=%8.8x", stm8->optionend);
2103 return JIM_OK;
2104 }
2105 if (!strcmp(arg, "-enable_step_irq")) {
2106 e = Jim_GetOpt_String(goi, &arg, NULL);
2107 if (e != JIM_OK)
2108 return e;
2109
2110 stm8->enable_step_irq = true;
2111 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2112 return JIM_OK;
2113 }
2114 if (!strcmp(arg, "-enable_stm8l")) {
2115 e = Jim_GetOpt_String(goi, &arg, NULL);
2116 if (e != JIM_OK)
2117 return e;
2118
2119 stm8->enable_stm8l = true;
2120 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2121 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2122 return JIM_OK;
2123 }
2124 return JIM_CONTINUE;
2125 }
2126
2127 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2128 {
2129 const char *msg;
2130 struct target *target = get_current_target(CMD_CTX);
2131 struct stm8_common *stm8 = target_to_stm8(target);
2132 bool enable = stm8->enable_step_irq;
2133
2134 if (CMD_ARGC > 0) {
2135 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2136 stm8->enable_step_irq = enable;
2137 }
2138 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2139 command_print(CMD_CTX, "enable_step_irq = %s", msg);
2140 return ERROR_OK;
2141 }
2142
2143 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2144 {
2145 const char *msg;
2146 struct target *target = get_current_target(CMD_CTX);
2147 struct stm8_common *stm8 = target_to_stm8(target);
2148 bool enable = stm8->enable_stm8l;
2149
2150 if (CMD_ARGC > 0) {
2151 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2152 stm8->enable_stm8l = enable;
2153 }
2154 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2155 command_print(CMD_CTX, "enable_stm8l = %s", msg);
2156 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2157 return ERROR_OK;
2158 }
2159
2160 static const struct command_registration stm8_exec_command_handlers[] = {
2161 {
2162 .name = "enable_step_irq",
2163 .handler = stm8_handle_enable_step_irq_command,
2164 .mode = COMMAND_ANY,
2165 .help = "Enable/disable irq handling during step",
2166 .usage = "[1/0]",
2167 },
2168 {
2169 .name = "enable_stm8l",
2170 .handler = stm8_handle_enable_stm8l_command,
2171 .mode = COMMAND_ANY,
2172 .help = "Enable/disable STM8L flash programming",
2173 .usage = "[1/0]",
2174 },
2175 COMMAND_REGISTRATION_DONE
2176 };
2177
2178 const struct command_registration stm8_command_handlers[] = {
2179 {
2180 .name = "stm8",
2181 .mode = COMMAND_ANY,
2182 .help = "stm8 command group",
2183 .usage = "",
2184 .chain = stm8_exec_command_handlers,
2185 },
2186 COMMAND_REGISTRATION_DONE
2187 };
2188
2189 struct target_type stm8_target = {
2190 .name = "stm8",
2191
2192 .poll = stm8_poll,
2193 .arch_state = stm8_arch_state,
2194
2195 .halt = stm8_halt,
2196 .resume = stm8_resume,
2197 .step = stm8_step,
2198
2199 .assert_reset = stm8_reset_assert,
2200 .deassert_reset = stm8_reset_deassert,
2201
2202 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2203
2204 .read_memory = stm8_read_memory,
2205 .write_memory = stm8_write_memory,
2206 .checksum_memory = stm8_checksum_memory,
2207 .blank_check_memory = stm8_blank_check_memory,
2208
2209 .run_algorithm = stm8_run_algorithm,
2210
2211 .add_breakpoint = stm8_add_breakpoint,
2212 .remove_breakpoint = stm8_remove_breakpoint,
2213 .add_watchpoint = stm8_add_watchpoint,
2214 .remove_watchpoint = stm8_remove_watchpoint,
2215
2216 .commands = stm8_command_handlers,
2217 .target_create = stm8_target_create,
2218 .init_target = stm8_init,
2219 .examine = stm8_examine,
2220
2221 .deinit_target = stm8_deinit,
2222 .target_jim_configure = stm8_jim_configure,
2223 };

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)