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