2 * OpenOCD STM8 target driver
3 * Copyright (C) 2017 Ake Rehnman
4 * ake.rehnman(at)gmail.com
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.
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.
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/>.
24 #include <helper/log.h>
26 #include "target_type.h"
28 #include "jtag/interface.h"
29 #include "jtag/jtag.h"
30 #include "jtag/swim.h"
32 #include "breakpoints.h"
33 #include "algorithm.h"
36 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
);
37 static int stm8_read_core_reg(struct target
*target
, unsigned int num
);
38 static int stm8_write_core_reg(struct target
*target
, unsigned int num
);
39 static int stm8_save_context(struct target
*target
);
40 static void stm8_enable_breakpoints(struct target
*target
);
41 static int stm8_unset_breakpoint(struct target
*target
,
42 struct breakpoint
*breakpoint
);
43 static int stm8_set_breakpoint(struct target
*target
,
44 struct breakpoint
*breakpoint
);
45 static void stm8_enable_watchpoints(struct target
*target
);
46 static int stm8_unset_watchpoint(struct target
*target
,
47 struct watchpoint
*watchpoint
);
48 static int (*adapter_speed
)(int speed
);
49 extern struct adapter_driver
*adapter_driver
;
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 },
68 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
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
87 #define DM_BKR1E 0x7f90
88 #define DM_BKR2E 0x7f93
91 #define DM_CSR1 0x7f98
92 #define DM_CSR2 0x7f99
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
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
125 #define WR_PG_DIS 0x01
135 #define SAFE_MASK 0x80
136 #define NO_ACCESS 0x40
140 #define SWIM_RST 0x04
144 #define SWIM_CSR 0x7f80
146 #define STM8_BREAK 0x8B
155 struct stm8_algorithm
{
159 struct stm8_core_reg
{
161 struct target
*target
;
162 struct stm8_common
*stm8_common
;
166 /* break on execute */
172 /* break on read, write and execute */
176 struct stm8_comparator
{
179 uint32_t reg_address
;
180 enum hw_break_type type
;
183 static int stm8_adapter_read_memory(struct target
*target
,
184 uint32_t addr
, int size
, int count
, void *buf
)
186 return swim_read_mem(addr
, size
, count
, buf
);
189 static int stm8_adapter_write_memory(struct target
*target
,
190 uint32_t addr
, int size
, int count
, const void *buf
)
192 return swim_write_mem(addr
, size
, count
, buf
);
195 static int stm8_write_u8(struct target
*target
,
196 uint32_t addr
, uint8_t val
)
201 return swim_write_mem(addr
, 1, 1, buf
);
204 static int stm8_read_u8(struct target
*target
,
205 uint32_t addr
, uint8_t *val
)
207 return swim_read_mem(addr
, 1, 1, val
);
211 <enable == 0> Disables interrupts.
212 If interrupts are enabled they are masked and the cc register
215 <enable == 1> Enables interrupts.
216 Enable interrupts is actually restoring I1 I0 state from previous
217 call with enable == 0. Note that if stepping and breaking on a sim
218 instruction will NOT work since the interrupt flags are restored on
219 debug_entry. We don't have any way for the debugger to exclusively
220 disable the interrupts
222 static int stm8_enable_interrupts(struct target
*target
, int enable
)
224 struct stm8_common
*stm8
= target_to_stm8(target
);
229 return ERROR_OK
; /* cc was not stashed */
230 /* fetch current cc */
231 stm8_read_u8(target
, DM_REG_CC
, &cc
);
233 cc
&= ~(CC_I0
+ CC_I1
);
234 /* restore I1 & I0 from stash*/
235 cc
|= (stm8
->cc
& (CC_I0
+CC_I1
));
236 /* update current cc */
237 stm8_write_u8(target
, DM_REG_CC
, cc
);
238 stm8
->cc_valid
= false;
240 stm8_read_u8(target
, DM_REG_CC
, &cc
);
241 if ((cc
& CC_I0
) && (cc
& CC_I1
))
242 return ERROR_OK
; /* interrupts already masked */
245 stm8
->cc_valid
= true;
246 /* mask interrupts (disable) */
247 cc
|= (CC_I0
+ CC_I1
);
248 stm8_write_u8(target
, DM_REG_CC
, cc
);
254 static int stm8_set_hwbreak(struct target
*target
,
255 struct stm8_comparator comparator_list
[])
260 /* Refer to Table 4 in UM0470 */
268 if (!comparator_list
[0].used
) {
269 comparator_list
[0].type
= HWBRK_EXEC
;
270 comparator_list
[0].bp_value
= -1;
273 if (!comparator_list
[1].used
) {
274 comparator_list
[1].type
= HWBRK_EXEC
;
275 comparator_list
[1].bp_value
= -1;
278 if ((comparator_list
[0].type
== HWBRK_EXEC
)
279 && (comparator_list
[1].type
== HWBRK_EXEC
)) {
280 comparator_list
[0].reg_address
= 0;
281 comparator_list
[1].reg_address
= 1;
284 if ((comparator_list
[0].type
== HWBRK_EXEC
)
285 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
286 comparator_list
[0].reg_address
= 0;
287 comparator_list
[1].reg_address
= 1;
288 switch (comparator_list
[1].type
) {
302 if ((comparator_list
[1].type
== HWBRK_EXEC
)
303 && (comparator_list
[0].type
!= HWBRK_EXEC
)) {
304 comparator_list
[0].reg_address
= 1;
305 comparator_list
[1].reg_address
= 0;
306 switch (comparator_list
[0].type
) {
320 if ((comparator_list
[0].type
!= HWBRK_EXEC
)
321 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
322 if (comparator_list
[0].type
!= comparator_list
[1].type
) {
323 LOG_ERROR("data hw breakpoints must be of same type");
324 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
328 for (i
= 0; i
< 2; i
++) {
329 data
= comparator_list
[i
].bp_value
;
330 addr
= comparator_list
[i
].reg_address
;
337 ret
= stm8_adapter_write_memory(target
, DM_BKR1E
, 1, 3, buf
);
338 LOG_DEBUG("DM_BKR1E=%" PRIx32
, data
);
339 } else if (addr
== 1) {
340 ret
= stm8_adapter_write_memory(target
, DM_BKR2E
, 1, 3, buf
);
341 LOG_DEBUG("DM_BKR2E=%" PRIx32
, data
);
343 LOG_DEBUG("addr=%" PRIu32
, addr
);
350 ret
= stm8_write_u8(target
, DM_CR1
,
351 (bc
<< 3) + (bir
<< 2) + (biw
<< 1));
352 LOG_DEBUG("DM_CR1=%" PRIx8
, buf
[0]);
360 /* read DM control and status regs */
361 static int stm8_read_dm_csrx(struct target
*target
, uint8_t *csr1
,
367 ret
= stm8_adapter_read_memory(target
, DM_CSR1
, 1, sizeof(buf
), buf
);
377 /* set or clear the single step flag in DM */
378 static int stm8_config_step(struct target
*target
, int enable
)
383 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
391 ret
= stm8_write_u8(target
, DM_CSR1
, csr1
);
397 /* set the stall flag in DM */
398 static int stm8_debug_stall(struct target
*target
)
403 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
407 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
413 static int stm8_configure_break_unit(struct target
*target
)
415 /* get pointers to arch-specific information */
416 struct stm8_common
*stm8
= target_to_stm8(target
);
418 if (stm8
->bp_scanned
)
421 stm8
->num_hw_bpoints
= 2;
422 stm8
->num_hw_bpoints_avail
= stm8
->num_hw_bpoints
;
424 stm8
->hw_break_list
= calloc(stm8
->num_hw_bpoints
,
425 sizeof(struct stm8_comparator
));
427 stm8
->hw_break_list
[0].reg_address
= 0;
428 stm8
->hw_break_list
[1].reg_address
= 1;
430 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8
->num_hw_bpoints
,
431 stm8
->num_hw_bpoints
);
433 stm8
->bp_scanned
= true;
438 static int stm8_examine_debug_reason(struct target
*target
)
443 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
444 if (retval
== ERROR_OK
)
445 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
447 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
448 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
450 if (retval
!= ERROR_OK
)
454 /* halted on reset */
455 target
->debug_reason
= DBG_REASON_UNDEFINED
;
457 if (csr1
& (BK1F
+BK2F
))
458 /* we have halted on a breakpoint (or wp)*/
459 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
462 /* we have halted on a breakpoint */
463 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
470 static int stm8_debug_entry(struct target
*target
)
472 struct stm8_common
*stm8
= target_to_stm8(target
);
474 /* restore interrupts */
475 stm8_enable_interrupts(target
, 1);
477 stm8_save_context(target
);
479 /* make sure stepping disabled STE bit in CSR1 cleared */
480 stm8_config_step(target
, 0);
482 /* attempt to find halt reason */
483 stm8_examine_debug_reason(target
);
485 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
486 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32),
487 target_state_name(target
));
492 /* clear stall flag in DM and flush instruction pipe */
493 static int stm8_exit_debug(struct target
*target
)
498 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
502 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
508 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
514 static int stm8_read_regs(struct target
*target
, uint32_t regs
[])
519 ret
= stm8_adapter_read_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
523 regs
[0] = be_to_h_u24(buf
+DM_REG_PC
-DM_REGS
);
524 regs
[1] = buf
[DM_REG_A
-DM_REGS
];
525 regs
[2] = be_to_h_u16(buf
+DM_REG_X
-DM_REGS
);
526 regs
[3] = be_to_h_u16(buf
+DM_REG_Y
-DM_REGS
);
527 regs
[4] = be_to_h_u16(buf
+DM_REG_SP
-DM_REGS
);
528 regs
[5] = buf
[DM_REG_CC
-DM_REGS
];
533 static int stm8_write_regs(struct target
*target
, uint32_t regs
[])
538 h_u24_to_be(buf
+DM_REG_PC
-DM_REGS
, regs
[0]);
539 buf
[DM_REG_A
-DM_REGS
] = regs
[1];
540 h_u16_to_be(buf
+DM_REG_X
-DM_REGS
, regs
[2]);
541 h_u16_to_be(buf
+DM_REG_Y
-DM_REGS
, regs
[3]);
542 h_u16_to_be(buf
+DM_REG_SP
-DM_REGS
, regs
[4]);
543 buf
[DM_REG_CC
-DM_REGS
] = regs
[5];
545 ret
= stm8_adapter_write_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
552 static int stm8_get_core_reg(struct reg
*reg
)
555 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
556 struct target
*target
= stm8_reg
->target
;
557 struct stm8_common
*stm8_target
= target_to_stm8(target
);
559 if (target
->state
!= TARGET_HALTED
)
560 return ERROR_TARGET_NOT_HALTED
;
562 retval
= stm8_target
->read_core_reg(target
, stm8_reg
->num
);
567 static int stm8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
569 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
570 struct target
*target
= stm8_reg
->target
;
571 uint32_t value
= buf_get_u32(buf
, 0, reg
->size
);
573 if (target
->state
!= TARGET_HALTED
)
574 return ERROR_TARGET_NOT_HALTED
;
576 buf_set_u32(reg
->value
, 0, 32, value
);
583 static int stm8_save_context(struct target
*target
)
587 /* get pointers to arch-specific information */
588 struct stm8_common
*stm8
= target_to_stm8(target
);
590 /* read core registers */
591 stm8_read_regs(target
, stm8
->core_regs
);
593 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
594 if (!stm8
->core_cache
->reg_list
[i
].valid
)
595 stm8
->read_core_reg(target
, i
);
601 static int stm8_restore_context(struct target
*target
)
605 /* get pointers to arch-specific information */
606 struct stm8_common
*stm8
= target_to_stm8(target
);
608 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
609 if (stm8
->core_cache
->reg_list
[i
].dirty
)
610 stm8
->write_core_reg(target
, i
);
613 /* write core regs */
614 stm8_write_regs(target
, stm8
->core_regs
);
619 static int stm8_unlock_flash(struct target
*target
)
623 struct stm8_common
*stm8
= target_to_stm8(target
);
625 /* check if flash is unlocked */
626 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
627 if (~data
[0] & PUL
) {
629 stm8_write_u8(target
, stm8
->flash_pukr
, 0x56);
630 stm8_write_u8(target
, stm8
->flash_pukr
, 0xae);
633 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
639 static int stm8_unlock_eeprom(struct target
*target
)
643 struct stm8_common
*stm8
= target_to_stm8(target
);
645 /* check if eeprom is unlocked */
646 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
647 if (~data
[0] & DUL
) {
649 stm8_write_u8(target
, stm8
->flash_dukr
, 0xae);
650 stm8_write_u8(target
, stm8
->flash_dukr
, 0x56);
653 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
659 static int stm8_write_flash(struct target
*target
, enum mem_type type
,
661 uint32_t size
, uint32_t count
, uint32_t blocksize_param
,
662 const uint8_t *buffer
)
664 struct stm8_common
*stm8
= target_to_stm8(target
);
669 uint32_t blocksize
= 0;
675 stm8_unlock_flash(target
);
678 stm8_unlock_eeprom(target
);
681 stm8_unlock_eeprom(target
);
685 LOG_ERROR("BUG: wrong mem_type %d", type
);
690 /* we don't support short writes */
695 bytecnt
= count
* size
;
698 if ((bytecnt
>= blocksize_param
) && ((address
& (blocksize_param
-1)) == 0)) {
700 stm8_write_u8(target
, stm8
->flash_cr2
, PRG
+ opt
);
701 if (stm8
->flash_ncr2
)
702 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(PRG
+ opt
));
703 blocksize
= blocksize_param
;
705 if ((bytecnt
>= 4) && ((address
& 0x3) == 0)) {
707 stm8_write_u8(target
, stm8
->flash_cr2
, WPRG
+ opt
);
708 if (stm8
->flash_ncr2
)
709 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(WPRG
+ opt
));
712 if (blocksize
!= 1) {
714 stm8_write_u8(target
, stm8
->flash_cr2
, opt
);
715 if (stm8
->flash_ncr2
)
716 stm8_write_u8(target
, stm8
->flash_ncr2
, ~opt
);
720 res
= stm8_adapter_write_memory(target
, address
, 1, blocksize
, buffer
);
723 address
+= blocksize
;
725 bytecnt
-= blocksize
;
727 /* lets hang here until end of program (EOP) */
728 for (i
= 0; i
< 16; i
++) {
729 stm8_read_u8(target
, stm8
->flash_iapsr
, &iapsr
);
739 /* disable write access */
740 res
= stm8_write_u8(target
, stm8
->flash_iapsr
, 0x0);
748 static int stm8_write_memory(struct target
*target
, target_addr_t address
,
749 uint32_t size
, uint32_t count
,
750 const uint8_t *buffer
)
752 struct stm8_common
*stm8
= target_to_stm8(target
);
754 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
755 ", size: 0x%8.8" PRIx32
756 ", count: 0x%8.8" PRIx32
,
757 address
, size
, count
);
759 if (target
->state
!= TARGET_HALTED
)
760 LOG_WARNING("target not halted");
764 if ((address
>= stm8
->flashstart
) && (address
<= stm8
->flashend
))
765 retval
= stm8_write_flash(target
, FLASH
, address
, size
, count
,
766 stm8
->blocksize
, buffer
);
767 else if ((address
>= stm8
->eepromstart
) && (address
<= stm8
->eepromend
))
768 retval
= stm8_write_flash(target
, EEPROM
, address
, size
, count
,
769 stm8
->blocksize
, buffer
);
770 else if ((address
>= stm8
->optionstart
) && (address
<= stm8
->optionend
))
771 retval
= stm8_write_flash(target
, OPTION
, address
, size
, count
, 0, buffer
);
773 retval
= stm8_adapter_write_memory(target
, address
, size
, count
,
776 if (retval
!= ERROR_OK
)
777 return ERROR_TARGET_FAILURE
;
782 static int stm8_read_memory(struct target
*target
, target_addr_t address
,
783 uint32_t size
, uint32_t count
, uint8_t *buffer
)
785 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
786 ", size: 0x%8.8" PRIx32
787 ", count: 0x%8.8" PRIx32
,
788 address
, size
, count
);
790 if (target
->state
!= TARGET_HALTED
)
791 LOG_WARNING("target not halted");
794 retval
= stm8_adapter_read_memory(target
, address
, size
, count
, buffer
);
796 if (retval
!= ERROR_OK
)
797 return ERROR_TARGET_FAILURE
;
802 static int stm8_speed(int speed
)
807 LOG_DEBUG("stm8_speed: %d", speed
);
809 csr
= SAFE_MASK
| SWIM_DM
;
810 if (speed
>= SWIM_FREQ_HIGH
)
813 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)", csr
& HS
? 1 : 0);
814 retval
= stm8_write_u8(NULL
, SWIM_CSR
, csr
);
815 if (retval
!= ERROR_OK
)
817 return adapter_speed(speed
);
820 static int stm8_init(struct command_context
*cmd_ctx
, struct target
*target
)
823 * FIXME: this is a temporarily hack that needs better implementation.
824 * Being the only overwrite of adapter_driver, it prevents declaring const
825 * the struct adapter_driver.
826 * intercept adapter_driver->speed() calls
828 adapter_speed
= adapter_driver
->speed
;
829 adapter_driver
->speed
= stm8_speed
;
831 stm8_build_reg_cache(target
);
836 static int stm8_poll(struct target
*target
)
838 int retval
= ERROR_OK
;
842 LOG_DEBUG("target->state=%d", target
->state
);
845 /* read dm_csrx control regs */
846 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
847 if (retval
!= ERROR_OK
) {
848 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval
);
850 We return ERROR_OK here even if we didn't get an answer.
851 openocd will call target_wait_state until we get target state TARGET_HALTED
856 /* check for processor halted */
858 if (target
->state
!= TARGET_HALTED
) {
859 if (target
->state
== TARGET_UNKNOWN
)
860 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
862 retval
= stm8_debug_entry(target
);
863 if (retval
!= ERROR_OK
) {
864 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval
);
865 return ERROR_TARGET_FAILURE
;
868 if (target
->state
== TARGET_DEBUG_RUNNING
) {
869 target
->state
= TARGET_HALTED
;
870 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
872 target
->state
= TARGET_HALTED
;
873 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
877 target
->state
= TARGET_RUNNING
;
879 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
884 static int stm8_halt(struct target
*target
)
886 LOG_DEBUG("target->state: %s", target_state_name(target
));
888 if (target
->state
== TARGET_HALTED
) {
889 LOG_DEBUG("target was already halted");
893 if (target
->state
== TARGET_UNKNOWN
)
894 LOG_WARNING("target was in unknown state when halt was requested");
896 if (target
->state
== TARGET_RESET
) {
897 /* we came here in a reset_halt or reset_init sequence
898 * debug entry was already prepared in stm8_assert_reset()
900 target
->debug_reason
= DBG_REASON_DBGRQ
;
906 /* break processor */
907 stm8_debug_stall(target
);
909 target
->debug_reason
= DBG_REASON_DBGRQ
;
914 static int stm8_reset_assert(struct target
*target
)
917 struct stm8_common
*stm8
= target_to_stm8(target
);
918 bool use_srst_fallback
= true;
920 enum reset_types jtag_reset_config
= jtag_get_reset_config();
922 if (jtag_reset_config
& RESET_HAS_SRST
) {
923 res
= adapter_assert_reset();
925 /* hardware srst supported */
926 use_srst_fallback
= false;
927 else if (res
!= ERROR_COMMAND_NOTFOUND
)
928 /* some other failure */
932 if (use_srst_fallback
) {
933 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
934 res
= swim_system_reset();
939 /* registers are now invalid */
940 register_cache_invalidate(stm8
->core_cache
);
942 target
->state
= TARGET_RESET
;
943 target
->debug_reason
= DBG_REASON_NOTHALTED
;
945 if (target
->reset_halt
) {
946 res
= target_halt(target
);
954 static int stm8_reset_deassert(struct target
*target
)
957 enum reset_types jtag_reset_config
= jtag_get_reset_config();
959 if (jtag_reset_config
& RESET_HAS_SRST
) {
960 res
= adapter_deassert_reset();
961 if ((res
!= ERROR_OK
) && (res
!= ERROR_COMMAND_NOTFOUND
))
965 /* The cpu should now be stalled. If halt was requested
966 let poll detect the stall */
967 if (target
->reset_halt
)
970 /* Instead of going through saving context, polling and
971 then resuming target again just clear stall and proceed. */
972 target
->state
= TARGET_RUNNING
;
973 return stm8_exit_debug(target
);
976 /* stm8_single_step_core() is only used for stepping over breakpoints
977 from stm8_resume() */
978 static int stm8_single_step_core(struct target
*target
)
980 struct stm8_common
*stm8
= target_to_stm8(target
);
982 /* configure single step mode */
983 stm8_config_step(target
, 1);
985 /* disable interrupts while stepping */
986 if (!stm8
->enable_step_irq
)
987 stm8_enable_interrupts(target
, 0);
989 /* exit debug mode */
990 stm8_exit_debug(target
);
992 stm8_debug_entry(target
);
997 static int stm8_resume(struct target
*target
, int current
,
998 target_addr_t address
, int handle_breakpoints
,
1001 struct stm8_common
*stm8
= target_to_stm8(target
);
1002 struct breakpoint
*breakpoint
= NULL
;
1005 LOG_DEBUG("%d " TARGET_ADDR_FMT
" %d %d", current
, address
,
1006 handle_breakpoints
, debug_execution
);
1008 if (target
->state
!= TARGET_HALTED
) {
1009 LOG_WARNING("target not halted");
1010 return ERROR_TARGET_NOT_HALTED
;
1013 if (!debug_execution
) {
1014 target_free_all_working_areas(target
);
1015 stm8_enable_breakpoints(target
);
1016 stm8_enable_watchpoints(target
);
1017 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1018 stm8_set_hwbreak(target
, comparator_list
);
1021 /* current = 1: continue on current pc,
1022 otherwise continue at <address> */
1024 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1026 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1027 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1031 resume_pc
= address
;
1033 resume_pc
= buf_get_u32(
1034 stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1037 stm8_restore_context(target
);
1039 /* the front-end may request us not to handle breakpoints */
1040 if (handle_breakpoints
) {
1041 /* Single step past breakpoint at current address */
1042 breakpoint
= breakpoint_find(target
, resume_pc
);
1044 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
,
1045 breakpoint
->address
);
1046 stm8_unset_breakpoint(target
, breakpoint
);
1047 stm8_single_step_core(target
);
1048 stm8_set_breakpoint(target
, breakpoint
);
1052 /* disable interrupts if we are debugging */
1053 if (debug_execution
)
1054 stm8_enable_interrupts(target
, 0);
1056 /* exit debug mode */
1057 stm8_exit_debug(target
);
1058 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1060 /* registers are now invalid */
1061 register_cache_invalidate(stm8
->core_cache
);
1063 if (!debug_execution
) {
1064 target
->state
= TARGET_RUNNING
;
1065 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1066 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
1068 target
->state
= TARGET_DEBUG_RUNNING
;
1069 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1070 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
1076 static int stm8_init_flash_regs(bool enable_stm8l
, struct stm8_common
*stm8
)
1078 stm8
->enable_stm8l
= enable_stm8l
;
1080 if (stm8
->enable_stm8l
) {
1081 stm8
->flash_cr2
= FLASH_CR2_STM8L
;
1082 stm8
->flash_ncr2
= FLASH_NCR2_STM8L
;
1083 stm8
->flash_iapsr
= FLASH_IAPSR_STM8L
;
1084 stm8
->flash_dukr
= FLASH_DUKR_STM8L
;
1085 stm8
->flash_pukr
= FLASH_PUKR_STM8L
;
1087 stm8
->flash_cr2
= FLASH_CR2_STM8S
;
1088 stm8
->flash_ncr2
= FLASH_NCR2_STM8S
;
1089 stm8
->flash_iapsr
= FLASH_IAPSR_STM8S
;
1090 stm8
->flash_dukr
= FLASH_DUKR_STM8S
;
1091 stm8
->flash_pukr
= FLASH_PUKR_STM8S
;
1096 static int stm8_init_arch_info(struct target
*target
,
1097 struct stm8_common
*stm8
, struct jtag_tap
*tap
)
1099 target
->endianness
= TARGET_BIG_ENDIAN
;
1100 target
->arch_info
= stm8
;
1101 stm8
->common_magic
= STM8_COMMON_MAGIC
;
1102 stm8
->fast_data_area
= NULL
;
1103 stm8
->blocksize
= 0x80;
1104 stm8
->flashstart
= 0x8000;
1105 stm8
->flashend
= 0xffff;
1106 stm8
->eepromstart
= 0x4000;
1107 stm8
->eepromend
= 0x43ff;
1108 stm8
->optionstart
= 0x4800;
1109 stm8
->optionend
= 0x487F;
1111 /* has breakpoint/watchpoint unit been scanned */
1112 stm8
->bp_scanned
= false;
1113 stm8
->hw_break_list
= NULL
;
1115 stm8
->read_core_reg
= stm8_read_core_reg
;
1116 stm8
->write_core_reg
= stm8_write_core_reg
;
1118 stm8_init_flash_regs(0, stm8
);
1123 static int stm8_target_create(struct target
*target
,
1127 struct stm8_common
*stm8
= calloc(1, sizeof(struct stm8_common
));
1129 stm8_init_arch_info(target
, stm8
, target
->tap
);
1130 stm8_configure_break_unit(target
);
1135 static int stm8_read_core_reg(struct target
*target
, unsigned int num
)
1139 /* get pointers to arch-specific information */
1140 struct stm8_common
*stm8
= target_to_stm8(target
);
1142 if (num
>= STM8_NUM_REGS
)
1143 return ERROR_COMMAND_SYNTAX_ERROR
;
1145 reg_value
= stm8
->core_regs
[num
];
1146 LOG_DEBUG("read core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1147 buf_set_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
1148 stm8
->core_cache
->reg_list
[num
].valid
= true;
1149 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1154 static int stm8_write_core_reg(struct target
*target
, unsigned int num
)
1158 /* get pointers to arch-specific information */
1159 struct stm8_common
*stm8
= target_to_stm8(target
);
1161 if (num
>= STM8_NUM_REGS
)
1162 return ERROR_COMMAND_SYNTAX_ERROR
;
1164 reg_value
= buf_get_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32);
1165 stm8
->core_regs
[num
] = reg_value
;
1166 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1167 stm8
->core_cache
->reg_list
[num
].valid
= true;
1168 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1173 static const char *stm8_get_gdb_arch(struct target
*target
)
1178 static int stm8_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1179 int *reg_list_size
, enum target_register_class reg_class
)
1181 /* get pointers to arch-specific information */
1182 struct stm8_common
*stm8
= target_to_stm8(target
);
1185 *reg_list_size
= STM8_NUM_REGS
;
1186 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1188 for (i
= 0; i
< STM8_NUM_REGS
; i
++)
1189 (*reg_list
)[i
] = &stm8
->core_cache
->reg_list
[i
];
1194 static const struct reg_arch_type stm8_reg_type
= {
1195 .get
= stm8_get_core_reg
,
1196 .set
= stm8_set_core_reg
,
1199 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
)
1201 /* get pointers to arch-specific information */
1202 struct stm8_common
*stm8
= target_to_stm8(target
);
1204 int num_regs
= STM8_NUM_REGS
;
1205 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1206 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1207 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1208 struct stm8_core_reg
*arch_info
= malloc(
1209 sizeof(struct stm8_core_reg
) * num_regs
);
1210 struct reg_feature
*feature
;
1213 /* Build the process context cache */
1214 cache
->name
= "stm8 registers";
1216 cache
->reg_list
= reg_list
;
1217 cache
->num_regs
= num_regs
;
1219 stm8
->core_cache
= cache
;
1221 for (i
= 0; i
< num_regs
; i
++) {
1222 arch_info
[i
].num
= stm8_regs
[i
].id
;
1223 arch_info
[i
].target
= target
;
1224 arch_info
[i
].stm8_common
= stm8
;
1226 reg_list
[i
].name
= stm8_regs
[i
].name
;
1227 reg_list
[i
].size
= stm8_regs
[i
].bits
;
1229 reg_list
[i
].value
= calloc(1, 4);
1230 reg_list
[i
].valid
= false;
1231 reg_list
[i
].type
= &stm8_reg_type
;
1232 reg_list
[i
].arch_info
= &arch_info
[i
];
1234 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1235 if (reg_list
[i
].reg_data_type
)
1236 reg_list
[i
].reg_data_type
->type
= stm8_regs
[i
].type
;
1238 LOG_ERROR("unable to allocate reg type list");
1242 reg_list
[i
].dirty
= false;
1243 reg_list
[i
].group
= stm8_regs
[i
].group
;
1244 reg_list
[i
].number
= stm8_regs
[i
].id
;
1245 reg_list
[i
].exist
= true;
1246 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1248 feature
= calloc(1, sizeof(struct reg_feature
));
1250 feature
->name
= stm8_regs
[i
].feature
;
1251 reg_list
[i
].feature
= feature
;
1253 LOG_ERROR("unable to allocate feature list");
1259 static void stm8_free_reg_cache(struct target
*target
)
1261 struct stm8_common
*stm8
= target_to_stm8(target
);
1262 struct reg_cache
*cache
;
1266 cache
= stm8
->core_cache
;
1271 for (i
= 0; i
< cache
->num_regs
; i
++) {
1272 reg
= &cache
->reg_list
[i
];
1275 free(reg
->reg_data_type
);
1279 free(cache
->reg_list
[0].arch_info
);
1280 free(cache
->reg_list
);
1283 stm8
->core_cache
= NULL
;
1286 static void stm8_deinit(struct target
*target
)
1288 struct stm8_common
*stm8
= target_to_stm8(target
);
1290 free(stm8
->hw_break_list
);
1292 stm8_free_reg_cache(target
);
1297 static int stm8_arch_state(struct target
*target
)
1299 struct stm8_common
*stm8
= target_to_stm8(target
);
1301 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
1302 debug_reason_name(target
),
1303 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1308 static int stm8_step(struct target
*target
, int current
,
1309 target_addr_t address
, int handle_breakpoints
)
1311 LOG_DEBUG("%x " TARGET_ADDR_FMT
" %x",
1312 current
, address
, handle_breakpoints
);
1314 /* get pointers to arch-specific information */
1315 struct stm8_common
*stm8
= target_to_stm8(target
);
1316 struct breakpoint
*breakpoint
= NULL
;
1318 if (target
->state
!= TARGET_HALTED
) {
1319 LOG_WARNING("target not halted");
1320 return ERROR_TARGET_NOT_HALTED
;
1323 /* current = 1: continue on current pc, otherwise continue at <address> */
1325 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32, address
);
1326 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1327 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1330 /* the front-end may request us not to handle breakpoints */
1331 if (handle_breakpoints
) {
1332 breakpoint
= breakpoint_find(target
,
1333 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1335 stm8_unset_breakpoint(target
, breakpoint
);
1338 /* restore context */
1339 stm8_restore_context(target
);
1341 /* configure single step mode */
1342 stm8_config_step(target
, 1);
1344 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1346 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1348 /* disable interrupts while stepping */
1349 if (!stm8
->enable_step_irq
)
1350 stm8_enable_interrupts(target
, 0);
1352 /* exit debug mode */
1353 stm8_exit_debug(target
);
1355 /* registers are now invalid */
1356 register_cache_invalidate(stm8
->core_cache
);
1358 LOG_DEBUG("target stepped ");
1359 stm8_debug_entry(target
);
1362 stm8_set_breakpoint(target
, breakpoint
);
1364 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1369 static void stm8_enable_breakpoints(struct target
*target
)
1371 struct breakpoint
*breakpoint
= target
->breakpoints
;
1373 /* set any pending breakpoints */
1374 while (breakpoint
) {
1375 if (breakpoint
->set
== 0)
1376 stm8_set_breakpoint(target
, breakpoint
);
1377 breakpoint
= breakpoint
->next
;
1381 static int stm8_set_breakpoint(struct target
*target
,
1382 struct breakpoint
*breakpoint
)
1384 struct stm8_common
*stm8
= target_to_stm8(target
);
1385 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1388 if (breakpoint
->set
) {
1389 LOG_WARNING("breakpoint already set");
1393 if (breakpoint
->type
== BKPT_HARD
) {
1396 while (comparator_list
[bp_num
].used
&& (bp_num
< stm8
->num_hw_bpoints
))
1398 if (bp_num
>= stm8
->num_hw_bpoints
) {
1399 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32
")",
1400 breakpoint
->unique_id
);
1401 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1403 breakpoint
->set
= bp_num
+ 1;
1404 comparator_list
[bp_num
].used
= true;
1405 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
1406 comparator_list
[bp_num
].type
= HWBRK_EXEC
;
1408 retval
= stm8_set_hwbreak(target
, comparator_list
);
1409 if (retval
!= ERROR_OK
)
1412 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1413 breakpoint
->unique_id
,
1414 bp_num
, comparator_list
[bp_num
].bp_value
);
1415 } else if (breakpoint
->type
== BKPT_SOFT
) {
1416 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1417 if (breakpoint
->length
== 1) {
1418 uint8_t verify
= 0x55;
1420 retval
= target_read_u8(target
, breakpoint
->address
,
1421 breakpoint
->orig_instr
);
1422 if (retval
!= ERROR_OK
)
1424 retval
= target_write_u8(target
, breakpoint
->address
, STM8_BREAK
);
1425 if (retval
!= ERROR_OK
)
1428 retval
= target_read_u8(target
, breakpoint
->address
, &verify
);
1429 if (retval
!= ERROR_OK
)
1431 if (verify
!= STM8_BREAK
) {
1432 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1433 " - check that memory is read/writable",
1434 breakpoint
->address
);
1435 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1438 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1440 breakpoint
->set
= 1; /* Any nice value but 0 */
1446 static int stm8_add_breakpoint(struct target
*target
,
1447 struct breakpoint
*breakpoint
)
1449 struct stm8_common
*stm8
= target_to_stm8(target
);
1452 if (breakpoint
->type
== BKPT_HARD
) {
1453 if (stm8
->num_hw_bpoints_avail
< 1) {
1454 LOG_INFO("no hardware breakpoint available");
1455 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1458 ret
= stm8_set_breakpoint(target
, breakpoint
);
1459 if (ret
!= ERROR_OK
)
1462 stm8
->num_hw_bpoints_avail
--;
1466 ret
= stm8_set_breakpoint(target
, breakpoint
);
1467 if (ret
!= ERROR_OK
)
1473 static int stm8_unset_breakpoint(struct target
*target
,
1474 struct breakpoint
*breakpoint
)
1476 /* get pointers to arch-specific information */
1477 struct stm8_common
*stm8
= target_to_stm8(target
);
1478 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1481 if (!breakpoint
->set
) {
1482 LOG_WARNING("breakpoint not set");
1486 if (breakpoint
->type
== BKPT_HARD
) {
1487 int bp_num
= breakpoint
->set
- 1;
1488 if ((bp_num
< 0) || (bp_num
>= stm8
->num_hw_bpoints
)) {
1489 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1490 breakpoint
->unique_id
);
1493 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d",
1494 breakpoint
->unique_id
,
1496 comparator_list
[bp_num
].used
= false;
1497 retval
= stm8_set_hwbreak(target
, comparator_list
);
1498 if (retval
!= ERROR_OK
)
1501 /* restore original instruction (kept in target endianness) */
1502 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1503 if (breakpoint
->length
== 1) {
1504 uint8_t current_instr
;
1506 /* check that user program has not
1507 modified breakpoint instruction */
1508 retval
= target_read_memory(target
, breakpoint
->address
, 1, 1,
1509 (uint8_t *)¤t_instr
);
1510 if (retval
!= ERROR_OK
)
1513 if (current_instr
== STM8_BREAK
) {
1514 retval
= target_write_memory(target
, breakpoint
->address
, 1, 1,
1515 breakpoint
->orig_instr
);
1516 if (retval
!= ERROR_OK
)
1522 breakpoint
->set
= 0;
1527 static int stm8_remove_breakpoint(struct target
*target
,
1528 struct breakpoint
*breakpoint
)
1530 /* get pointers to arch-specific information */
1531 struct stm8_common
*stm8
= target_to_stm8(target
);
1533 if (target
->state
!= TARGET_HALTED
) {
1534 LOG_WARNING("target not halted");
1535 return ERROR_TARGET_NOT_HALTED
;
1538 if (breakpoint
->set
)
1539 stm8_unset_breakpoint(target
, breakpoint
);
1541 if (breakpoint
->type
== BKPT_HARD
)
1542 stm8
->num_hw_bpoints_avail
++;
1547 static int stm8_set_watchpoint(struct target
*target
,
1548 struct watchpoint
*watchpoint
)
1550 struct stm8_common
*stm8
= target_to_stm8(target
);
1551 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1555 if (watchpoint
->set
) {
1556 LOG_WARNING("watchpoint already set");
1560 while (comparator_list
[wp_num
].used
&& (wp_num
< stm8
->num_hw_bpoints
))
1562 if (wp_num
>= stm8
->num_hw_bpoints
) {
1563 LOG_ERROR("Can not find free hw breakpoint");
1564 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1567 if (watchpoint
->length
!= 1) {
1568 LOG_ERROR("Only watchpoints of length 1 are supported");
1569 return ERROR_TARGET_UNALIGNED_ACCESS
;
1572 enum hw_break_type enable
= 0;
1574 switch (watchpoint
->rw
) {
1585 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1588 comparator_list
[wp_num
].used
= true;
1589 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
1590 comparator_list
[wp_num
].type
= enable
;
1592 ret
= stm8_set_hwbreak(target
, comparator_list
);
1593 if (ret
!= ERROR_OK
) {
1594 comparator_list
[wp_num
].used
= false;
1598 watchpoint
->set
= wp_num
+ 1;
1600 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"",
1602 comparator_list
[wp_num
].bp_value
);
1607 static int stm8_add_watchpoint(struct target
*target
,
1608 struct watchpoint
*watchpoint
)
1611 struct stm8_common
*stm8
= target_to_stm8(target
);
1613 if (stm8
->num_hw_bpoints_avail
< 1) {
1614 LOG_INFO("no hardware watchpoints available");
1615 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1618 ret
= stm8_set_watchpoint(target
, watchpoint
);
1619 if (ret
!= ERROR_OK
)
1622 stm8
->num_hw_bpoints_avail
--;
1626 static void stm8_enable_watchpoints(struct target
*target
)
1628 struct watchpoint
*watchpoint
= target
->watchpoints
;
1630 /* set any pending watchpoints */
1631 while (watchpoint
) {
1632 if (watchpoint
->set
== 0)
1633 stm8_set_watchpoint(target
, watchpoint
);
1634 watchpoint
= watchpoint
->next
;
1638 static int stm8_unset_watchpoint(struct target
*target
,
1639 struct watchpoint
*watchpoint
)
1641 /* get pointers to arch-specific information */
1642 struct stm8_common
*stm8
= target_to_stm8(target
);
1643 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1645 if (!watchpoint
->set
) {
1646 LOG_WARNING("watchpoint not set");
1650 int wp_num
= watchpoint
->set
- 1;
1651 if ((wp_num
< 0) || (wp_num
>= stm8
->num_hw_bpoints
)) {
1652 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1655 comparator_list
[wp_num
].used
= false;
1656 watchpoint
->set
= 0;
1658 stm8_set_hwbreak(target
, comparator_list
);
1663 static int stm8_remove_watchpoint(struct target
*target
,
1664 struct watchpoint
*watchpoint
)
1666 /* get pointers to arch-specific information */
1667 struct stm8_common
*stm8
= target_to_stm8(target
);
1669 if (target
->state
!= TARGET_HALTED
) {
1670 LOG_WARNING("target not halted");
1671 return ERROR_TARGET_NOT_HALTED
;
1674 if (watchpoint
->set
)
1675 stm8_unset_watchpoint(target
, watchpoint
);
1677 stm8
->num_hw_bpoints_avail
++;
1682 static int stm8_examine(struct target
*target
)
1686 /* get pointers to arch-specific information */
1687 struct stm8_common
*stm8
= target_to_stm8(target
);
1688 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1690 if (!target_was_examined(target
)) {
1691 if (!stm8
->swim_configured
) {
1692 stm8
->swim_configured
= true;
1694 Now is the time to deassert reset if connect_under_reset.
1695 Releasing reset line will cause the option bytes to load.
1696 The core will still be stalled.
1698 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
1699 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
1700 stm8_reset_deassert(target
);
1702 LOG_WARNING("\'srst_nogate\' reset_config option is required");
1705 LOG_INFO("trying to reconnect");
1707 retval
= swim_reconnect();
1708 if (retval
!= ERROR_OK
) {
1709 LOG_ERROR("reconnect failed");
1713 /* read dm_csrx control regs */
1714 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
1715 if (retval
!= ERROR_OK
) {
1716 LOG_ERROR("state query failed");
1721 target_set_examined(target
);
1729 /** Checks whether a memory region is erased. */
1730 static int stm8_blank_check_memory(struct target
*target
,
1731 struct target_memory_check_block
*blocks
, int num_blocks
, uint8_t erased_value
)
1733 struct working_area
*erase_check_algorithm
;
1734 struct reg_param reg_params
[2];
1735 struct mem_param mem_params
[2];
1736 struct stm8_algorithm stm8_info
;
1738 static const uint8_t stm8_erase_check_code
[] = {
1739 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1742 if (erased_value
!= 0xff) {
1743 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for STM8",
1748 /* make sure we have a working area */
1749 if (target_alloc_working_area(target
, sizeof(stm8_erase_check_code
),
1750 &erase_check_algorithm
) != ERROR_OK
)
1751 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1753 target_write_buffer(target
, erase_check_algorithm
->address
,
1754 sizeof(stm8_erase_check_code
), stm8_erase_check_code
);
1756 stm8_info
.common_magic
= STM8_COMMON_MAGIC
;
1758 init_mem_param(&mem_params
[0], 0x0, 3, PARAM_OUT
);
1759 buf_set_u32(mem_params
[0].value
, 0, 24, blocks
[0].address
);
1761 init_mem_param(&mem_params
[1], 0x3, 3, PARAM_OUT
);
1762 buf_set_u32(mem_params
[1].value
, 0, 24, blocks
[0].size
);
1764 init_reg_param(®_params
[0], "a", 32, PARAM_IN_OUT
);
1765 buf_set_u32(reg_params
[0].value
, 0, 32, erased_value
);
1767 init_reg_param(®_params
[1], "sp", 32, PARAM_OUT
);
1768 buf_set_u32(reg_params
[1].value
, 0, 32, erase_check_algorithm
->address
);
1770 int retval
= target_run_algorithm(target
, 2, mem_params
, 2, reg_params
,
1771 erase_check_algorithm
->address
+ 6,
1772 erase_check_algorithm
->address
+ (sizeof(stm8_erase_check_code
) - 1),
1775 if (retval
== ERROR_OK
)
1776 blocks
[0].result
= (*(reg_params
[0].value
) == 0xff);
1778 destroy_mem_param(&mem_params
[0]);
1779 destroy_mem_param(&mem_params
[1]);
1780 destroy_reg_param(®_params
[0]);
1781 destroy_reg_param(®_params
[1]);
1783 target_free_working_area(target
, erase_check_algorithm
);
1785 if (retval
!= ERROR_OK
)
1788 return 1; /* only one block has been checked */
1791 static int stm8_checksum_memory(struct target
*target
, target_addr_t address
,
1792 uint32_t count
, uint32_t *checksum
)
1794 /* let image_calculate_checksum() take care of business */
1795 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1798 /* run to exit point. return error if exit point was not reached. */
1799 static int stm8_run_and_wait(struct target
*target
, uint32_t entry_point
,
1800 int timeout_ms
, uint32_t exit_point
, struct stm8_common
*stm8
)
1804 /* This code relies on the target specific resume() and
1805 poll()->debug_entry() sequence to write register values to the
1806 processor and the read them back */
1807 retval
= target_resume(target
, 0, entry_point
, 0, 1);
1808 if (retval
!= ERROR_OK
)
1811 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1812 /* If the target fails to halt due to the breakpoint, force a halt */
1813 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
1814 retval
= target_halt(target
);
1815 if (retval
!= ERROR_OK
)
1817 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
1818 if (retval
!= ERROR_OK
)
1820 return ERROR_TARGET_TIMEOUT
;
1823 pc
= buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32);
1824 if (exit_point
&& (pc
!= exit_point
)) {
1825 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
1826 return ERROR_TARGET_TIMEOUT
;
1832 static int stm8_run_algorithm(struct target
*target
, int num_mem_params
,
1833 struct mem_param
*mem_params
, int num_reg_params
,
1834 struct reg_param
*reg_params
, target_addr_t entry_point
,
1835 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
1837 struct stm8_common
*stm8
= target_to_stm8(target
);
1839 uint32_t context
[STM8_NUM_REGS
];
1840 int retval
= ERROR_OK
;
1842 LOG_DEBUG("Running algorithm");
1844 /* NOTE: stm8_run_algorithm requires that each
1845 algorithm uses a software breakpoint
1846 at the exit point */
1848 if (stm8
->common_magic
!= STM8_COMMON_MAGIC
) {
1849 LOG_ERROR("current target isn't a STM8 target");
1850 return ERROR_TARGET_INVALID
;
1853 if (target
->state
!= TARGET_HALTED
) {
1854 LOG_WARNING("target not halted");
1855 return ERROR_TARGET_NOT_HALTED
;
1858 /* refresh core register cache */
1859 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1860 if (!stm8
->core_cache
->reg_list
[i
].valid
)
1861 stm8
->read_core_reg(target
, i
);
1862 context
[i
] = buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1865 for (int i
= 0; i
< num_mem_params
; i
++) {
1866 if (mem_params
[i
].direction
== PARAM_IN
)
1868 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1869 mem_params
[i
].size
, mem_params
[i
].value
);
1870 if (retval
!= ERROR_OK
)
1874 for (int i
= 0; i
< num_reg_params
; i
++) {
1875 if (reg_params
[i
].direction
== PARAM_IN
)
1878 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1879 reg_params
[i
].reg_name
, 0);
1882 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1883 return ERROR_COMMAND_SYNTAX_ERROR
;
1886 if (reg_params
[i
].size
!= 32) {
1887 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1888 reg_params
[i
].reg_name
);
1889 return ERROR_COMMAND_SYNTAX_ERROR
;
1892 stm8_set_core_reg(reg
, reg_params
[i
].value
);
1895 retval
= stm8_run_and_wait(target
, entry_point
,
1896 timeout_ms
, exit_point
, stm8
);
1898 if (retval
!= ERROR_OK
)
1901 for (int i
= 0; i
< num_mem_params
; i
++) {
1902 if (mem_params
[i
].direction
!= PARAM_OUT
) {
1903 retval
= target_read_buffer(target
, mem_params
[i
].address
,
1904 mem_params
[i
].size
, mem_params
[i
].value
);
1905 if (retval
!= ERROR_OK
)
1910 for (int i
= 0; i
< num_reg_params
; i
++) {
1911 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1912 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1913 reg_params
[i
].reg_name
, 0);
1915 LOG_ERROR("BUG: register '%s' not found",
1916 reg_params
[i
].reg_name
);
1917 return ERROR_COMMAND_SYNTAX_ERROR
;
1920 if (reg_params
[i
].size
!= 32) {
1921 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1922 reg_params
[i
].reg_name
);
1923 return ERROR_COMMAND_SYNTAX_ERROR
;
1926 buf_set_u32(reg_params
[i
].value
,
1927 0, 32, buf_get_u32(reg
->value
, 0, 32));
1931 /* restore everything we saved before */
1932 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1934 regvalue
= buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1935 if (regvalue
!= context
[i
]) {
1936 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
1937 stm8
->core_cache
->reg_list
[i
].name
, context
[i
]);
1938 buf_set_u32(stm8
->core_cache
->reg_list
[i
].value
,
1940 stm8
->core_cache
->reg_list
[i
].valid
= true;
1941 stm8
->core_cache
->reg_list
[i
].dirty
= true;
1948 int stm8_jim_configure(struct target
*target
, Jim_GetOptInfo
*goi
)
1950 struct stm8_common
*stm8
= target_to_stm8(target
);
1955 arg
= Jim_GetString(goi
->argv
[0], NULL
);
1956 if (!strcmp(arg
, "-blocksize")) {
1957 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1961 if (goi
->argc
== 0) {
1962 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1963 "-blocksize ?bytes? ...");
1967 e
= Jim_GetOpt_Wide(goi
, &w
);
1971 stm8
->blocksize
= w
;
1972 LOG_DEBUG("blocksize=%8.8" PRIx32
, stm8
->blocksize
);
1975 if (!strcmp(arg
, "-flashstart")) {
1976 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1980 if (goi
->argc
== 0) {
1981 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1982 "-flashstart ?address? ...");
1986 e
= Jim_GetOpt_Wide(goi
, &w
);
1990 stm8
->flashstart
= w
;
1991 LOG_DEBUG("flashstart=%8.8" PRIx32
, stm8
->flashstart
);
1994 if (!strcmp(arg
, "-flashend")) {
1995 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1999 if (goi
->argc
== 0) {
2000 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2001 "-flashend ?address? ...");
2005 e
= Jim_GetOpt_Wide(goi
, &w
);
2010 LOG_DEBUG("flashend=%8.8" PRIx32
, stm8
->flashend
);
2013 if (!strcmp(arg
, "-eepromstart")) {
2014 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2018 if (goi
->argc
== 0) {
2019 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2020 "-eepromstart ?address? ...");
2024 e
= Jim_GetOpt_Wide(goi
, &w
);
2028 stm8
->eepromstart
= w
;
2029 LOG_DEBUG("eepromstart=%8.8" PRIx32
, stm8
->eepromstart
);
2032 if (!strcmp(arg
, "-eepromend")) {
2033 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2037 if (goi
->argc
== 0) {
2038 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2039 "-eepromend ?address? ...");
2043 e
= Jim_GetOpt_Wide(goi
, &w
);
2047 stm8
->eepromend
= w
;
2048 LOG_DEBUG("eepromend=%8.8" PRIx32
, stm8
->eepromend
);
2051 if (!strcmp(arg
, "-optionstart")) {
2052 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2056 if (goi
->argc
== 0) {
2057 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2058 "-optionstart ?address? ...");
2062 e
= Jim_GetOpt_Wide(goi
, &w
);
2066 stm8
->optionstart
= w
;
2067 LOG_DEBUG("optionstart=%8.8" PRIx32
, stm8
->optionstart
);
2070 if (!strcmp(arg
, "-optionend")) {
2071 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2075 if (goi
->argc
== 0) {
2076 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2077 "-optionend ?address? ...");
2081 e
= Jim_GetOpt_Wide(goi
, &w
);
2085 stm8
->optionend
= w
;
2086 LOG_DEBUG("optionend=%8.8" PRIx32
, stm8
->optionend
);
2089 if (!strcmp(arg
, "-enable_step_irq")) {
2090 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2094 stm8
->enable_step_irq
= true;
2095 LOG_DEBUG("enable_step_irq=%8.8x", stm8
->enable_step_irq
);
2098 if (!strcmp(arg
, "-enable_stm8l")) {
2099 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2103 stm8
->enable_stm8l
= true;
2104 LOG_DEBUG("enable_stm8l=%8.8x", stm8
->enable_stm8l
);
2105 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2108 return JIM_CONTINUE
;
2111 COMMAND_HANDLER(stm8_handle_enable_step_irq_command
)
2114 struct target
*target
= get_current_target(CMD_CTX
);
2115 struct stm8_common
*stm8
= target_to_stm8(target
);
2116 bool enable
= stm8
->enable_step_irq
;
2119 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2120 stm8
->enable_step_irq
= enable
;
2122 msg
= stm8
->enable_step_irq
? "enabled" : "disabled";
2123 command_print(CMD
, "enable_step_irq = %s", msg
);
2127 COMMAND_HANDLER(stm8_handle_enable_stm8l_command
)
2130 struct target
*target
= get_current_target(CMD_CTX
);
2131 struct stm8_common
*stm8
= target_to_stm8(target
);
2132 bool enable
= stm8
->enable_stm8l
;
2135 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2136 stm8
->enable_stm8l
= enable
;
2138 msg
= stm8
->enable_stm8l
? "enabled" : "disabled";
2139 command_print(CMD
, "enable_stm8l = %s", msg
);
2140 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2144 static const struct command_registration stm8_exec_command_handlers
[] = {
2146 .name
= "enable_step_irq",
2147 .handler
= stm8_handle_enable_step_irq_command
,
2148 .mode
= COMMAND_ANY
,
2149 .help
= "Enable/disable irq handling during step",
2153 .name
= "enable_stm8l",
2154 .handler
= stm8_handle_enable_stm8l_command
,
2155 .mode
= COMMAND_ANY
,
2156 .help
= "Enable/disable STM8L flash programming",
2159 COMMAND_REGISTRATION_DONE
2162 const struct command_registration stm8_command_handlers
[] = {
2165 .mode
= COMMAND_ANY
,
2166 .help
= "stm8 command group",
2168 .chain
= stm8_exec_command_handlers
,
2170 COMMAND_REGISTRATION_DONE
2173 struct target_type stm8_target
= {
2177 .arch_state
= stm8_arch_state
,
2180 .resume
= stm8_resume
,
2183 .assert_reset
= stm8_reset_assert
,
2184 .deassert_reset
= stm8_reset_deassert
,
2186 .get_gdb_arch
= stm8_get_gdb_arch
,
2187 .get_gdb_reg_list
= stm8_get_gdb_reg_list
,
2189 .read_memory
= stm8_read_memory
,
2190 .write_memory
= stm8_write_memory
,
2191 .checksum_memory
= stm8_checksum_memory
,
2192 .blank_check_memory
= stm8_blank_check_memory
,
2194 .run_algorithm
= stm8_run_algorithm
,
2196 .add_breakpoint
= stm8_add_breakpoint
,
2197 .remove_breakpoint
= stm8_remove_breakpoint
,
2198 .add_watchpoint
= stm8_add_watchpoint
,
2199 .remove_watchpoint
= stm8_remove_watchpoint
,
2201 .commands
= stm8_command_handlers
,
2202 .target_create
= stm8_target_create
,
2203 .init_target
= stm8_init
,
2204 .examine
= stm8_examine
,
2206 .deinit_target
= stm8_deinit
,
2207 .target_jim_configure
= stm8_jim_configure
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)