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