stm8: fix compilation warning
[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 target_addr_t address, uint32_t count, uint32_t *blank, 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, address);
1782
1783 init_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);
1784 buf_set_u32(mem_params[1].value, 0, 24, count);
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 *blank = (*(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 return retval;
1807 }
1808
1809 static int stm8_checksum_memory(struct target *target, target_addr_t address,
1810 uint32_t count, uint32_t *checksum)
1811 {
1812 /* let image_calculate_checksum() take care of business */
1813 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1814 }
1815
1816 /* run to exit point. return error if exit point was not reached. */
1817 static int stm8_run_and_wait(struct target *target, uint32_t entry_point,
1818 int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
1819 {
1820 uint32_t pc;
1821 int retval;
1822 /* This code relies on the target specific resume() and
1823 poll()->debug_entry() sequence to write register values to the
1824 processor and the read them back */
1825 retval = target_resume(target, 0, entry_point, 0, 1);
1826 if (retval != ERROR_OK)
1827 return retval;
1828
1829 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1830 /* If the target fails to halt due to the breakpoint, force a halt */
1831 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
1832 retval = target_halt(target);
1833 if (retval != ERROR_OK)
1834 return retval;
1835 retval = target_wait_state(target, TARGET_HALTED, 500);
1836 if (retval != ERROR_OK)
1837 return retval;
1838 return ERROR_TARGET_TIMEOUT;
1839 }
1840
1841 pc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);
1842 if (exit_point && (pc != exit_point)) {
1843 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
1844 return ERROR_TARGET_TIMEOUT;
1845 }
1846
1847 return ERROR_OK;
1848 }
1849
1850 static int stm8_run_algorithm(struct target *target, int num_mem_params,
1851 struct mem_param *mem_params, int num_reg_params,
1852 struct reg_param *reg_params, target_addr_t entry_point,
1853 target_addr_t exit_point, int timeout_ms, void *arch_info)
1854 {
1855 struct stm8_common *stm8 = target_to_stm8(target);
1856
1857 uint32_t context[STM8_NUM_REGS];
1858 int retval = ERROR_OK;
1859
1860 LOG_DEBUG("Running algorithm");
1861
1862 /* NOTE: stm8_run_algorithm requires that each
1863 algorithm uses a software breakpoint
1864 at the exit point */
1865
1866 if (stm8->common_magic != STM8_COMMON_MAGIC) {
1867 LOG_ERROR("current target isn't a STM8 target");
1868 return ERROR_TARGET_INVALID;
1869 }
1870
1871 if (target->state != TARGET_HALTED) {
1872 LOG_WARNING("target not halted");
1873 return ERROR_TARGET_NOT_HALTED;
1874 }
1875
1876 /* refresh core register cache */
1877 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1878 if (!stm8->core_cache->reg_list[i].valid)
1879 stm8->read_core_reg(target, i);
1880 context[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1881 }
1882
1883 for (int i = 0; i < num_mem_params; i++) {
1884 retval = target_write_buffer(target, mem_params[i].address,
1885 mem_params[i].size, mem_params[i].value);
1886 if (retval != ERROR_OK)
1887 return retval;
1888 }
1889
1890 for (int i = 0; i < num_reg_params; i++) {
1891 struct reg *reg = register_get_by_name(stm8->core_cache,
1892 reg_params[i].reg_name, 0);
1893
1894 if (!reg) {
1895 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1896 return ERROR_COMMAND_SYNTAX_ERROR;
1897 }
1898
1899 if (reg_params[i].size != 32) {
1900 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1901 reg_params[i].reg_name);
1902 return ERROR_COMMAND_SYNTAX_ERROR;
1903 }
1904
1905 stm8_set_core_reg(reg, reg_params[i].value);
1906 }
1907
1908 retval = stm8_run_and_wait(target, entry_point,
1909 timeout_ms, exit_point, stm8);
1910
1911 if (retval != ERROR_OK)
1912 return retval;
1913
1914 for (int i = 0; i < num_mem_params; i++) {
1915 if (mem_params[i].direction != PARAM_OUT) {
1916 retval = target_read_buffer(target, mem_params[i].address,
1917 mem_params[i].size, mem_params[i].value);
1918 if (retval != ERROR_OK)
1919 return retval;
1920 }
1921 }
1922
1923 for (int i = 0; i < num_reg_params; i++) {
1924 if (reg_params[i].direction != PARAM_OUT) {
1925 struct reg *reg = register_get_by_name(stm8->core_cache,
1926 reg_params[i].reg_name, 0);
1927 if (!reg) {
1928 LOG_ERROR("BUG: register '%s' not found",
1929 reg_params[i].reg_name);
1930 return ERROR_COMMAND_SYNTAX_ERROR;
1931 }
1932
1933 if (reg_params[i].size != 32) {
1934 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1935 reg_params[i].reg_name);
1936 return ERROR_COMMAND_SYNTAX_ERROR;
1937 }
1938
1939 buf_set_u32(reg_params[i].value,
1940 0, 32, buf_get_u32(reg->value, 0, 32));
1941 }
1942 }
1943
1944 /* restore everything we saved before */
1945 for (unsigned int i = 0; i < STM8_NUM_REGS; i++) {
1946 uint32_t regvalue;
1947 regvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);
1948 if (regvalue != context[i]) {
1949 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
1950 stm8->core_cache->reg_list[i].name, context[i]);
1951 buf_set_u32(stm8->core_cache->reg_list[i].value,
1952 0, 32, context[i]);
1953 stm8->core_cache->reg_list[i].valid = true;
1954 stm8->core_cache->reg_list[i].dirty = true;
1955 }
1956 }
1957
1958 return ERROR_OK;
1959 }
1960
1961 int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi)
1962 {
1963 struct stm8_common *stm8 = target_to_stm8(target);
1964 jim_wide w;
1965 int e;
1966 const char *arg;
1967
1968 arg = Jim_GetString(goi->argv[0], NULL);
1969 if (!strcmp(arg, "-blocksize")) {
1970 e = Jim_GetOpt_String(goi, &arg, NULL);
1971 if (e != JIM_OK)
1972 return e;
1973
1974 if (goi->argc == 0) {
1975 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1976 "-blocksize ?bytes? ...");
1977 return JIM_ERR;
1978 }
1979
1980 e = Jim_GetOpt_Wide(goi, &w);
1981 if (e != JIM_OK)
1982 return e;
1983
1984 stm8->blocksize = w;
1985 LOG_DEBUG("blocksize=%8.8x", stm8->blocksize);
1986 return JIM_OK;
1987 }
1988 if (!strcmp(arg, "-flashstart")) {
1989 e = Jim_GetOpt_String(goi, &arg, NULL);
1990 if (e != JIM_OK)
1991 return e;
1992
1993 if (goi->argc == 0) {
1994 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
1995 "-flashstart ?address? ...");
1996 return JIM_ERR;
1997 }
1998
1999 e = Jim_GetOpt_Wide(goi, &w);
2000 if (e != JIM_OK)
2001 return e;
2002
2003 stm8->flashstart = w;
2004 LOG_DEBUG("flashstart=%8.8x", stm8->flashstart);
2005 return JIM_OK;
2006 }
2007 if (!strcmp(arg, "-flashend")) {
2008 e = Jim_GetOpt_String(goi, &arg, NULL);
2009 if (e != JIM_OK)
2010 return e;
2011
2012 if (goi->argc == 0) {
2013 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2014 "-flashend ?address? ...");
2015 return JIM_ERR;
2016 }
2017
2018 e = Jim_GetOpt_Wide(goi, &w);
2019 if (e != JIM_OK)
2020 return e;
2021
2022 stm8->flashend = w;
2023 LOG_DEBUG("flashend=%8.8x", stm8->flashend);
2024 return JIM_OK;
2025 }
2026 if (!strcmp(arg, "-eepromstart")) {
2027 e = Jim_GetOpt_String(goi, &arg, NULL);
2028 if (e != JIM_OK)
2029 return e;
2030
2031 if (goi->argc == 0) {
2032 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2033 "-eepromstart ?address? ...");
2034 return JIM_ERR;
2035 }
2036
2037 e = Jim_GetOpt_Wide(goi, &w);
2038 if (e != JIM_OK)
2039 return e;
2040
2041 stm8->eepromstart = w;
2042 LOG_DEBUG("eepromstart=%8.8x", stm8->eepromstart);
2043 return JIM_OK;
2044 }
2045 if (!strcmp(arg, "-eepromend")) {
2046 e = Jim_GetOpt_String(goi, &arg, NULL);
2047 if (e != JIM_OK)
2048 return e;
2049
2050 if (goi->argc == 0) {
2051 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2052 "-eepromend ?address? ...");
2053 return JIM_ERR;
2054 }
2055
2056 e = Jim_GetOpt_Wide(goi, &w);
2057 if (e != JIM_OK)
2058 return e;
2059
2060 stm8->eepromend = w;
2061 LOG_DEBUG("eepromend=%8.8x", stm8->eepromend);
2062 return JIM_OK;
2063 }
2064 if (!strcmp(arg, "-optionstart")) {
2065 e = Jim_GetOpt_String(goi, &arg, NULL);
2066 if (e != JIM_OK)
2067 return e;
2068
2069 if (goi->argc == 0) {
2070 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2071 "-optionstart ?address? ...");
2072 return JIM_ERR;
2073 }
2074
2075 e = Jim_GetOpt_Wide(goi, &w);
2076 if (e != JIM_OK)
2077 return e;
2078
2079 stm8->optionstart = w;
2080 LOG_DEBUG("optionstart=%8.8x", stm8->optionstart);
2081 return JIM_OK;
2082 }
2083 if (!strcmp(arg, "-optionend")) {
2084 e = Jim_GetOpt_String(goi, &arg, NULL);
2085 if (e != JIM_OK)
2086 return e;
2087
2088 if (goi->argc == 0) {
2089 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv,
2090 "-optionend ?address? ...");
2091 return JIM_ERR;
2092 }
2093
2094 e = Jim_GetOpt_Wide(goi, &w);
2095 if (e != JIM_OK)
2096 return e;
2097
2098 stm8->optionend = w;
2099 LOG_DEBUG("optionend=%8.8x", stm8->optionend);
2100 return JIM_OK;
2101 }
2102 if (!strcmp(arg, "-enable_step_irq")) {
2103 e = Jim_GetOpt_String(goi, &arg, NULL);
2104 if (e != JIM_OK)
2105 return e;
2106
2107 stm8->enable_step_irq = true;
2108 LOG_DEBUG("enable_step_irq=%8.8x", stm8->enable_step_irq);
2109 return JIM_OK;
2110 }
2111 if (!strcmp(arg, "-enable_stm8l")) {
2112 e = Jim_GetOpt_String(goi, &arg, NULL);
2113 if (e != JIM_OK)
2114 return e;
2115
2116 stm8->enable_stm8l = true;
2117 LOG_DEBUG("enable_stm8l=%8.8x", stm8->enable_stm8l);
2118 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2119 return JIM_OK;
2120 }
2121 return JIM_CONTINUE;
2122 }
2123
2124 COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
2125 {
2126 const char *msg;
2127 struct target *target = get_current_target(CMD_CTX);
2128 struct stm8_common *stm8 = target_to_stm8(target);
2129 bool enable = stm8->enable_step_irq;
2130
2131 if (CMD_ARGC > 0) {
2132 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2133 stm8->enable_step_irq = enable;
2134 }
2135 msg = stm8->enable_step_irq ? "enabled" : "disabled";
2136 command_print(CMD_CTX, "enable_step_irq = %s", msg);
2137 return ERROR_OK;
2138 }
2139
2140 COMMAND_HANDLER(stm8_handle_enable_stm8l_command)
2141 {
2142 const char *msg;
2143 struct target *target = get_current_target(CMD_CTX);
2144 struct stm8_common *stm8 = target_to_stm8(target);
2145 bool enable = stm8->enable_stm8l;
2146
2147 if (CMD_ARGC > 0) {
2148 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
2149 stm8->enable_stm8l = enable;
2150 }
2151 msg = stm8->enable_stm8l ? "enabled" : "disabled";
2152 command_print(CMD_CTX, "enable_stm8l = %s", msg);
2153 stm8_init_flash_regs(stm8->enable_stm8l, stm8);
2154 return ERROR_OK;
2155 }
2156
2157 static const struct command_registration stm8_exec_command_handlers[] = {
2158 {
2159 .name = "enable_step_irq",
2160 .handler = stm8_handle_enable_step_irq_command,
2161 .mode = COMMAND_ANY,
2162 .help = "Enable/disable irq handling during step",
2163 .usage = "[1/0]",
2164 },
2165 {
2166 .name = "enable_stm8l",
2167 .handler = stm8_handle_enable_stm8l_command,
2168 .mode = COMMAND_ANY,
2169 .help = "Enable/disable STM8L flash programming",
2170 .usage = "[1/0]",
2171 },
2172 COMMAND_REGISTRATION_DONE
2173 };
2174
2175 const struct command_registration stm8_command_handlers[] = {
2176 {
2177 .name = "stm8",
2178 .mode = COMMAND_ANY,
2179 .help = "stm8 command group",
2180 .usage = "",
2181 .chain = stm8_exec_command_handlers,
2182 },
2183 COMMAND_REGISTRATION_DONE
2184 };
2185
2186 struct target_type stm8_target = {
2187 .name = "stm8",
2188
2189 .poll = stm8_poll,
2190 .arch_state = stm8_arch_state,
2191
2192 .halt = stm8_halt,
2193 .resume = stm8_resume,
2194 .step = stm8_step,
2195
2196 .assert_reset = stm8_reset_assert,
2197 .deassert_reset = stm8_reset_deassert,
2198
2199 .get_gdb_reg_list = stm8_get_gdb_reg_list,
2200
2201 .read_memory = stm8_read_memory,
2202 .write_memory = stm8_write_memory,
2203 .checksum_memory = stm8_checksum_memory,
2204 .blank_check_memory = stm8_blank_check_memory,
2205
2206 .run_algorithm = stm8_run_algorithm,
2207
2208 .add_breakpoint = stm8_add_breakpoint,
2209 .remove_breakpoint = stm8_remove_breakpoint,
2210 .add_watchpoint = stm8_add_watchpoint,
2211 .remove_watchpoint = stm8_remove_watchpoint,
2212
2213 .commands = stm8_command_handlers,
2214 .target_create = stm8_target_create,
2215 .init_target = stm8_init,
2216 .examine = stm8_examine,
2217
2218 .deinit_target = stm8_deinit,
2219 .target_jim_configure = stm8_jim_configure,
2220 };