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