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/hla/hla_transport.h"
31 #include "jtag/hla/hla_interface.h"
32 #include "jtag/hla/hla_layout.h"
34 #include "breakpoints.h"
35 #include "algorithm.h"
38 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
);
39 static int stm8_read_core_reg(struct target
*target
, unsigned int num
);
40 static int stm8_write_core_reg(struct target
*target
, unsigned int num
);
41 static int stm8_save_context(struct target
*target
);
42 static void stm8_enable_breakpoints(struct target
*target
);
43 static int stm8_unset_breakpoint(struct target
*target
,
44 struct breakpoint
*breakpoint
);
45 static int stm8_set_breakpoint(struct target
*target
,
46 struct breakpoint
*breakpoint
);
47 static void stm8_enable_watchpoints(struct target
*target
);
48 static int stm8_unset_watchpoint(struct target
*target
,
49 struct watchpoint
*watchpoint
);
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 inline struct hl_interface_s
*target_to_adapter(struct target
*target
)
185 return target
->tap
->priv
;
188 static int stm8_adapter_read_memory(struct target
*target
,
189 uint32_t addr
, int size
, int count
, void *buf
)
192 struct hl_interface_s
*adapter
= target_to_adapter(target
);
194 ret
= adapter
->layout
->api
->read_mem(adapter
->handle
,
195 addr
, size
, count
, buf
);
201 static int stm8_adapter_write_memory(struct target
*target
,
202 uint32_t addr
, int size
, int count
, const void *buf
)
205 struct hl_interface_s
*adapter
= target_to_adapter(target
);
207 ret
= adapter
->layout
->api
->write_mem(adapter
->handle
,
208 addr
, size
, count
, buf
);
214 static int stm8_write_u8(struct target
*target
,
215 uint32_t addr
, uint8_t val
)
219 struct hl_interface_s
*adapter
= target_to_adapter(target
);
222 ret
= adapter
->layout
->api
->write_mem(adapter
->handle
, addr
, 1, 1, buf
);
228 static int stm8_read_u8(struct target
*target
,
229 uint32_t addr
, uint8_t *val
)
232 struct hl_interface_s
*adapter
= target_to_adapter(target
);
234 ret
= adapter
->layout
->api
->read_mem(adapter
->handle
, addr
, 1, 1, val
);
240 static int stm8_set_speed(struct target
*target
, int speed
)
242 struct hl_interface_s
*adapter
= target_to_adapter(target
);
243 adapter
->layout
->api
->speed(adapter
->handle
, speed
, 0);
248 <enable == 0> Disables interrupts.
249 If interrupts are enabled they are masked and the cc register
252 <enable == 1> Enables interrupts.
253 Enable interrupts is actually restoring I1 I0 state from previous
254 call with enable == 0. Note that if stepping and breaking on a sim
255 instruction will NOT work since the interrupt flags are restored on
256 debug_entry. We don't have any way for the debugger to exclusively
257 disable the interrupts
259 static int stm8_enable_interrupts(struct target
*target
, int enable
)
261 struct stm8_common
*stm8
= target_to_stm8(target
);
266 return ERROR_OK
; /* cc was not stashed */
267 /* fetch current cc */
268 stm8_read_u8(target
, DM_REG_CC
, &cc
);
270 cc
&= ~(CC_I0
+ CC_I1
);
271 /* restore I1 & I0 from stash*/
272 cc
|= (stm8
->cc
& (CC_I0
+CC_I1
));
273 /* update current cc */
274 stm8_write_u8(target
, DM_REG_CC
, cc
);
275 stm8
->cc_valid
= false;
277 stm8_read_u8(target
, DM_REG_CC
, &cc
);
278 if ((cc
& CC_I0
) && (cc
& CC_I1
))
279 return ERROR_OK
; /* interrupts already masked */
282 stm8
->cc_valid
= true;
283 /* mask interrupts (disable) */
284 cc
|= (CC_I0
+ CC_I1
);
285 stm8_write_u8(target
, DM_REG_CC
, cc
);
291 static int stm8_set_hwbreak(struct target
*target
,
292 struct stm8_comparator comparator_list
[])
297 /* Refer to Table 4 in UM0470 */
305 if (!comparator_list
[0].used
) {
306 comparator_list
[0].type
= HWBRK_EXEC
;
307 comparator_list
[0].bp_value
= -1;
310 if (!comparator_list
[1].used
) {
311 comparator_list
[1].type
= HWBRK_EXEC
;
312 comparator_list
[1].bp_value
= -1;
315 if ((comparator_list
[0].type
== HWBRK_EXEC
)
316 && (comparator_list
[1].type
== HWBRK_EXEC
)) {
317 comparator_list
[0].reg_address
= 0;
318 comparator_list
[1].reg_address
= 1;
321 if ((comparator_list
[0].type
== HWBRK_EXEC
)
322 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
323 comparator_list
[0].reg_address
= 0;
324 comparator_list
[1].reg_address
= 1;
325 switch (comparator_list
[1].type
) {
339 if ((comparator_list
[1].type
== HWBRK_EXEC
)
340 && (comparator_list
[0].type
!= HWBRK_EXEC
)) {
341 comparator_list
[0].reg_address
= 1;
342 comparator_list
[1].reg_address
= 0;
343 switch (comparator_list
[0].type
) {
357 if ((comparator_list
[0].type
!= HWBRK_EXEC
)
358 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
359 if (comparator_list
[0].type
!= comparator_list
[1].type
) {
360 LOG_ERROR("data hw breakpoints must be of same type");
361 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
365 for (i
= 0; i
< 2; i
++) {
366 data
= comparator_list
[i
].bp_value
;
367 addr
= comparator_list
[i
].reg_address
;
374 ret
= stm8_adapter_write_memory(target
, DM_BKR1E
, 1, 3, buf
);
375 LOG_DEBUG("DM_BKR1E=%" PRIx32
, data
);
376 } else if (addr
== 1) {
377 ret
= stm8_adapter_write_memory(target
, DM_BKR2E
, 1, 3, buf
);
378 LOG_DEBUG("DM_BKR2E=%" PRIx32
, data
);
380 LOG_DEBUG("addr=%" PRIu32
, addr
);
387 ret
= stm8_write_u8(target
, DM_CR1
,
388 (bc
<< 3) + (bir
<< 2) + (biw
<< 1));
389 LOG_DEBUG("DM_CR1=%" PRIx8
, buf
[0]);
397 /* read DM control and status regs */
398 static int stm8_read_dm_csrx(struct target
*target
, uint8_t *csr1
,
404 ret
= stm8_adapter_read_memory(target
, DM_CSR1
, 1, sizeof(buf
), buf
);
414 /* set or clear the single step flag in DM */
415 static int stm8_config_step(struct target
*target
, int enable
)
420 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
428 ret
= stm8_write_u8(target
, DM_CSR1
, csr1
);
434 /* set the stall flag in DM */
435 static int stm8_debug_stall(struct target
*target
)
440 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
444 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
450 static int stm8_configure_break_unit(struct target
*target
)
452 /* get pointers to arch-specific information */
453 struct stm8_common
*stm8
= target_to_stm8(target
);
455 if (stm8
->bp_scanned
)
458 stm8
->num_hw_bpoints
= 2;
459 stm8
->num_hw_bpoints_avail
= stm8
->num_hw_bpoints
;
461 stm8
->hw_break_list
= calloc(stm8
->num_hw_bpoints
,
462 sizeof(struct stm8_comparator
));
464 stm8
->hw_break_list
[0].reg_address
= 0;
465 stm8
->hw_break_list
[1].reg_address
= 1;
467 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8
->num_hw_bpoints
,
468 stm8
->num_hw_bpoints
);
470 stm8
->bp_scanned
= true;
475 static int stm8_examine_debug_reason(struct target
*target
)
480 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
481 if (retval
== ERROR_OK
)
482 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
484 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
485 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
487 if (retval
!= ERROR_OK
)
491 /* halted on reset */
492 target
->debug_reason
= DBG_REASON_UNDEFINED
;
494 if (csr1
& (BK1F
+BK2F
))
495 /* we have halted on a breakpoint (or wp)*/
496 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
499 /* we have halted on a breakpoint */
500 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
507 static int stm8_debug_entry(struct target
*target
)
509 struct stm8_common
*stm8
= target_to_stm8(target
);
511 /* restore interrupts */
512 stm8_enable_interrupts(target
, 1);
514 stm8_save_context(target
);
516 /* make sure stepping disabled STE bit in CSR1 cleared */
517 stm8_config_step(target
, 0);
519 /* attempt to find halt reason */
520 stm8_examine_debug_reason(target
);
522 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
523 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32),
524 target_state_name(target
));
529 /* clear stall flag in DM and flush instruction pipe */
530 static int stm8_exit_debug(struct target
*target
)
535 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
539 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
545 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
551 static int stm8_read_regs(struct target
*target
, uint32_t regs
[])
556 ret
= stm8_adapter_read_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
560 regs
[0] = be_to_h_u24(buf
+DM_REG_PC
-DM_REGS
);
561 regs
[1] = buf
[DM_REG_A
-DM_REGS
];
562 regs
[2] = be_to_h_u16(buf
+DM_REG_X
-DM_REGS
);
563 regs
[3] = be_to_h_u16(buf
+DM_REG_Y
-DM_REGS
);
564 regs
[4] = be_to_h_u16(buf
+DM_REG_SP
-DM_REGS
);
565 regs
[5] = buf
[DM_REG_CC
-DM_REGS
];
570 static int stm8_write_regs(struct target
*target
, uint32_t regs
[])
575 h_u24_to_be(buf
+DM_REG_PC
-DM_REGS
, regs
[0]);
576 buf
[DM_REG_A
-DM_REGS
] = regs
[1];
577 h_u16_to_be(buf
+DM_REG_X
-DM_REGS
, regs
[2]);
578 h_u16_to_be(buf
+DM_REG_Y
-DM_REGS
, regs
[3]);
579 h_u16_to_be(buf
+DM_REG_SP
-DM_REGS
, regs
[4]);
580 buf
[DM_REG_CC
-DM_REGS
] = regs
[5];
582 ret
= stm8_adapter_write_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
589 static int stm8_get_core_reg(struct reg
*reg
)
592 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
593 struct target
*target
= stm8_reg
->target
;
594 struct stm8_common
*stm8_target
= target_to_stm8(target
);
596 if (target
->state
!= TARGET_HALTED
)
597 return ERROR_TARGET_NOT_HALTED
;
599 retval
= stm8_target
->read_core_reg(target
, stm8_reg
->num
);
604 static int stm8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
606 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
607 struct target
*target
= stm8_reg
->target
;
608 uint32_t value
= buf_get_u32(buf
, 0, reg
->size
);
610 if (target
->state
!= TARGET_HALTED
)
611 return ERROR_TARGET_NOT_HALTED
;
613 buf_set_u32(reg
->value
, 0, 32, value
);
620 static int stm8_save_context(struct target
*target
)
624 /* get pointers to arch-specific information */
625 struct stm8_common
*stm8
= target_to_stm8(target
);
627 /* read core registers */
628 stm8_read_regs(target
, stm8
->core_regs
);
630 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
631 if (!stm8
->core_cache
->reg_list
[i
].valid
)
632 stm8
->read_core_reg(target
, i
);
638 static int stm8_restore_context(struct target
*target
)
642 /* get pointers to arch-specific information */
643 struct stm8_common
*stm8
= target_to_stm8(target
);
645 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
646 if (stm8
->core_cache
->reg_list
[i
].dirty
)
647 stm8
->write_core_reg(target
, i
);
650 /* write core regs */
651 stm8_write_regs(target
, stm8
->core_regs
);
656 static int stm8_unlock_flash(struct target
*target
)
660 struct stm8_common
*stm8
= target_to_stm8(target
);
662 /* check if flash is unlocked */
663 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
664 if (~data
[0] & PUL
) {
666 stm8_write_u8(target
, stm8
->flash_pukr
, 0x56);
667 stm8_write_u8(target
, stm8
->flash_pukr
, 0xae);
670 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
676 static int stm8_unlock_eeprom(struct target
*target
)
680 struct stm8_common
*stm8
= target_to_stm8(target
);
682 /* check if eeprom is unlocked */
683 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
684 if (~data
[0] & DUL
) {
686 stm8_write_u8(target
, stm8
->flash_dukr
, 0xae);
687 stm8_write_u8(target
, stm8
->flash_dukr
, 0x56);
690 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
696 static int stm8_write_flash(struct target
*target
, enum mem_type type
,
698 uint32_t size
, uint32_t count
, uint32_t blocksize_param
,
699 const uint8_t *buffer
)
701 struct stm8_common
*stm8
= target_to_stm8(target
);
706 uint32_t blocksize
= 0;
712 stm8_unlock_flash(target
);
715 stm8_unlock_eeprom(target
);
718 stm8_unlock_eeprom(target
);
722 LOG_ERROR("BUG: wrong mem_type %d", type
);
727 /* we don't support short writes */
732 bytecnt
= count
* size
;
735 if ((bytecnt
>= blocksize_param
) && ((address
& (blocksize_param
-1)) == 0)) {
737 stm8_write_u8(target
, stm8
->flash_cr2
, PRG
+ opt
);
738 if (stm8
->flash_ncr2
)
739 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(PRG
+ opt
));
740 blocksize
= blocksize_param
;
742 if ((bytecnt
>= 4) && ((address
& 0x3) == 0)) {
744 stm8_write_u8(target
, stm8
->flash_cr2
, WPRG
+ opt
);
745 if (stm8
->flash_ncr2
)
746 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(WPRG
+ opt
));
749 if (blocksize
!= 1) {
751 stm8_write_u8(target
, stm8
->flash_cr2
, opt
);
752 if (stm8
->flash_ncr2
)
753 stm8_write_u8(target
, stm8
->flash_ncr2
, ~opt
);
757 res
= stm8_adapter_write_memory(target
, address
, 1, blocksize
, buffer
);
760 address
+= blocksize
;
762 bytecnt
-= blocksize
;
764 /* lets hang here until end of program (EOP) */
765 for (i
= 0; i
< 16; i
++) {
766 stm8_read_u8(target
, stm8
->flash_iapsr
, &iapsr
);
776 /* disable write access */
777 res
= stm8_write_u8(target
, stm8
->flash_iapsr
, 0x0);
785 static int stm8_write_memory(struct target
*target
, target_addr_t address
,
786 uint32_t size
, uint32_t count
,
787 const uint8_t *buffer
)
789 struct stm8_common
*stm8
= target_to_stm8(target
);
791 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
792 ", size: 0x%8.8" PRIx32
793 ", count: 0x%8.8" PRIx32
,
794 address
, size
, count
);
796 if (target
->state
!= TARGET_HALTED
)
797 LOG_WARNING("target not halted");
801 if ((address
>= stm8
->flashstart
) && (address
<= stm8
->flashend
))
802 retval
= stm8_write_flash(target
, FLASH
, address
, size
, count
,
803 stm8
->blocksize
, buffer
);
804 else if ((address
>= stm8
->eepromstart
) && (address
<= stm8
->eepromend
))
805 retval
= stm8_write_flash(target
, EEPROM
, address
, size
, count
,
806 stm8
->blocksize
, buffer
);
807 else if ((address
>= stm8
->optionstart
) && (address
<= stm8
->optionend
))
808 retval
= stm8_write_flash(target
, OPTION
, address
, size
, count
, 0, buffer
);
810 retval
= stm8_adapter_write_memory(target
, address
, size
, count
,
813 if (retval
!= ERROR_OK
)
814 return ERROR_TARGET_FAILURE
;
819 static int stm8_read_memory(struct target
*target
, target_addr_t address
,
820 uint32_t size
, uint32_t count
, uint8_t *buffer
)
822 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
823 ", size: 0x%8.8" PRIx32
824 ", count: 0x%8.8" PRIx32
,
825 address
, size
, count
);
827 if (target
->state
!= TARGET_HALTED
)
828 LOG_WARNING("target not halted");
831 retval
= stm8_adapter_read_memory(target
, address
, size
, count
, buffer
);
833 if (retval
!= ERROR_OK
)
834 return ERROR_TARGET_FAILURE
;
839 static int stm8_init(struct command_context
*cmd_ctx
, struct target
*target
)
841 stm8_build_reg_cache(target
);
846 static int stm8_poll(struct target
*target
)
848 int retval
= ERROR_OK
;
852 LOG_DEBUG("target->state=%d", target
->state
);
855 /* read dm_csrx control regs */
856 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
857 if (retval
!= ERROR_OK
) {
858 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval
);
860 We return ERROR_OK here even if we didn't get an answer.
861 openocd will call target_wait_state until we get target state TARGET_HALTED
866 /* check for processor halted */
868 if (target
->state
!= TARGET_HALTED
) {
869 if (target
->state
== TARGET_UNKNOWN
)
870 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
872 retval
= stm8_debug_entry(target
);
873 if (retval
!= ERROR_OK
) {
874 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval
);
875 return ERROR_TARGET_FAILURE
;
878 if (target
->state
== TARGET_DEBUG_RUNNING
) {
879 target
->state
= TARGET_HALTED
;
880 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
882 target
->state
= TARGET_HALTED
;
883 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
887 target
->state
= TARGET_RUNNING
;
889 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
894 static int stm8_halt(struct target
*target
)
896 LOG_DEBUG("target->state: %s", target_state_name(target
));
898 if (target
->state
== TARGET_HALTED
) {
899 LOG_DEBUG("target was already halted");
903 if (target
->state
== TARGET_UNKNOWN
)
904 LOG_WARNING("target was in unknown state when halt was requested");
906 if (target
->state
== TARGET_RESET
) {
907 /* we came here in a reset_halt or reset_init sequence
908 * debug entry was already prepared in stm8_assert_reset()
910 target
->debug_reason
= DBG_REASON_DBGRQ
;
916 /* break processor */
917 stm8_debug_stall(target
);
919 target
->debug_reason
= DBG_REASON_DBGRQ
;
924 static int stm8_reset_assert(struct target
*target
)
927 struct hl_interface_s
*adapter
= target_to_adapter(target
);
928 struct stm8_common
*stm8
= target_to_stm8(target
);
929 bool use_srst_fallback
= true;
931 enum reset_types jtag_reset_config
= jtag_get_reset_config();
933 if (jtag_reset_config
& RESET_HAS_SRST
) {
934 res
= adapter_assert_reset();
936 /* hardware srst supported */
937 use_srst_fallback
= false;
938 else if (res
!= ERROR_COMMAND_NOTFOUND
)
939 /* some other failure */
943 if (use_srst_fallback
) {
944 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
945 res
= adapter
->layout
->api
->reset(adapter
->handle
);
950 /* registers are now invalid */
951 register_cache_invalidate(stm8
->core_cache
);
953 target
->state
= TARGET_RESET
;
954 target
->debug_reason
= DBG_REASON_NOTHALTED
;
956 if (target
->reset_halt
) {
957 res
= target_halt(target
);
965 static int stm8_reset_deassert(struct target
*target
)
968 enum reset_types jtag_reset_config
= jtag_get_reset_config();
970 if (jtag_reset_config
& RESET_HAS_SRST
) {
971 res
= adapter_deassert_reset();
972 if ((res
!= ERROR_OK
) && (res
!= ERROR_COMMAND_NOTFOUND
))
976 /* The cpu should now be stalled. If halt was requested
977 let poll detect the stall */
978 if (target
->reset_halt
)
981 /* Instead of going thrugh saving context, polling and
982 then resuming target again just clear stall and proceed. */
983 target
->state
= TARGET_RUNNING
;
984 return stm8_exit_debug(target
);
987 /* stm8_single_step_core() is only used for stepping over breakpoints
988 from stm8_resume() */
989 static int stm8_single_step_core(struct target
*target
)
991 struct stm8_common
*stm8
= target_to_stm8(target
);
993 /* configure single step mode */
994 stm8_config_step(target
, 1);
996 /* disable interrupts while stepping */
997 if (!stm8
->enable_step_irq
)
998 stm8_enable_interrupts(target
, 0);
1000 /* exit debug mode */
1001 stm8_exit_debug(target
);
1003 stm8_debug_entry(target
);
1008 static int stm8_resume(struct target
*target
, int current
,
1009 target_addr_t address
, int handle_breakpoints
,
1010 int debug_execution
)
1012 struct stm8_common
*stm8
= target_to_stm8(target
);
1013 struct breakpoint
*breakpoint
= NULL
;
1016 LOG_DEBUG("%d " TARGET_ADDR_FMT
" %d %d", current
, address
,
1017 handle_breakpoints
, debug_execution
);
1019 if (target
->state
!= TARGET_HALTED
) {
1020 LOG_WARNING("target not halted");
1021 return ERROR_TARGET_NOT_HALTED
;
1024 if (!debug_execution
) {
1025 target_free_all_working_areas(target
);
1026 stm8_enable_breakpoints(target
);
1027 stm8_enable_watchpoints(target
);
1028 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1029 stm8_set_hwbreak(target
, comparator_list
);
1032 /* current = 1: continue on current pc,
1033 otherwise continue at <address> */
1035 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1037 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1038 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1042 resume_pc
= address
;
1044 resume_pc
= buf_get_u32(
1045 stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1048 stm8_restore_context(target
);
1050 /* the front-end may request us not to handle breakpoints */
1051 if (handle_breakpoints
) {
1052 /* Single step past breakpoint at current address */
1053 breakpoint
= breakpoint_find(target
, resume_pc
);
1055 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
,
1056 breakpoint
->address
);
1057 stm8_unset_breakpoint(target
, breakpoint
);
1058 stm8_single_step_core(target
);
1059 stm8_set_breakpoint(target
, breakpoint
);
1063 /* disable interrupts if we are debugging */
1064 if (debug_execution
)
1065 stm8_enable_interrupts(target
, 0);
1067 /* exit debug mode */
1068 stm8_exit_debug(target
);
1069 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1071 /* registers are now invalid */
1072 register_cache_invalidate(stm8
->core_cache
);
1074 if (!debug_execution
) {
1075 target
->state
= TARGET_RUNNING
;
1076 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1077 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
1079 target
->state
= TARGET_DEBUG_RUNNING
;
1080 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1081 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
1087 static int stm8_init_flash_regs(bool enable_stm8l
, struct stm8_common
*stm8
)
1089 stm8
->enable_stm8l
= enable_stm8l
;
1091 if (stm8
->enable_stm8l
) {
1092 stm8
->flash_cr2
= FLASH_CR2_STM8L
;
1093 stm8
->flash_ncr2
= FLASH_NCR2_STM8L
;
1094 stm8
->flash_iapsr
= FLASH_IAPSR_STM8L
;
1095 stm8
->flash_dukr
= FLASH_DUKR_STM8L
;
1096 stm8
->flash_pukr
= FLASH_PUKR_STM8L
;
1098 stm8
->flash_cr2
= FLASH_CR2_STM8S
;
1099 stm8
->flash_ncr2
= FLASH_NCR2_STM8S
;
1100 stm8
->flash_iapsr
= FLASH_IAPSR_STM8S
;
1101 stm8
->flash_dukr
= FLASH_DUKR_STM8S
;
1102 stm8
->flash_pukr
= FLASH_PUKR_STM8S
;
1107 static int stm8_init_arch_info(struct target
*target
,
1108 struct stm8_common
*stm8
, struct jtag_tap
*tap
)
1110 target
->endianness
= TARGET_BIG_ENDIAN
;
1111 target
->arch_info
= stm8
;
1112 stm8
->common_magic
= STM8_COMMON_MAGIC
;
1113 stm8
->fast_data_area
= NULL
;
1114 stm8
->blocksize
= 0x80;
1115 stm8
->flashstart
= 0x8000;
1116 stm8
->flashend
= 0xffff;
1117 stm8
->eepromstart
= 0x4000;
1118 stm8
->eepromend
= 0x43ff;
1119 stm8
->optionstart
= 0x4800;
1120 stm8
->optionend
= 0x487F;
1122 /* has breakpoint/watchpoint unit been scanned */
1123 stm8
->bp_scanned
= false;
1124 stm8
->hw_break_list
= NULL
;
1126 stm8
->read_core_reg
= stm8_read_core_reg
;
1127 stm8
->write_core_reg
= stm8_write_core_reg
;
1129 stm8_init_flash_regs(0, stm8
);
1134 static int stm8_target_create(struct target
*target
,
1138 struct stm8_common
*stm8
= calloc(1, sizeof(struct stm8_common
));
1140 stm8_init_arch_info(target
, stm8
, target
->tap
);
1141 stm8_configure_break_unit(target
);
1146 static int stm8_read_core_reg(struct target
*target
, unsigned int num
)
1150 /* get pointers to arch-specific information */
1151 struct stm8_common
*stm8
= target_to_stm8(target
);
1153 if (num
>= STM8_NUM_REGS
)
1154 return ERROR_COMMAND_SYNTAX_ERROR
;
1156 reg_value
= stm8
->core_regs
[num
];
1157 LOG_DEBUG("read core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1158 buf_set_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
1159 stm8
->core_cache
->reg_list
[num
].valid
= true;
1160 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1165 static int stm8_write_core_reg(struct target
*target
, unsigned int num
)
1169 /* get pointers to arch-specific information */
1170 struct stm8_common
*stm8
= target_to_stm8(target
);
1172 if (num
>= STM8_NUM_REGS
)
1173 return ERROR_COMMAND_SYNTAX_ERROR
;
1175 reg_value
= buf_get_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32);
1176 stm8
->core_regs
[num
] = reg_value
;
1177 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1178 stm8
->core_cache
->reg_list
[num
].valid
= true;
1179 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1184 static const char *stm8_get_gdb_arch(struct target
*target
)
1189 static int stm8_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1190 int *reg_list_size
, enum target_register_class reg_class
)
1192 /* get pointers to arch-specific information */
1193 struct stm8_common
*stm8
= target_to_stm8(target
);
1196 *reg_list_size
= STM8_NUM_REGS
;
1197 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1199 for (i
= 0; i
< STM8_NUM_REGS
; i
++)
1200 (*reg_list
)[i
] = &stm8
->core_cache
->reg_list
[i
];
1205 static const struct reg_arch_type stm8_reg_type
= {
1206 .get
= stm8_get_core_reg
,
1207 .set
= stm8_set_core_reg
,
1210 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
)
1212 /* get pointers to arch-specific information */
1213 struct stm8_common
*stm8
= target_to_stm8(target
);
1215 int num_regs
= STM8_NUM_REGS
;
1216 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1217 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1218 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1219 struct stm8_core_reg
*arch_info
= malloc(
1220 sizeof(struct stm8_core_reg
) * num_regs
);
1221 struct reg_feature
*feature
;
1224 /* Build the process context cache */
1225 cache
->name
= "stm8 registers";
1227 cache
->reg_list
= reg_list
;
1228 cache
->num_regs
= num_regs
;
1230 stm8
->core_cache
= cache
;
1232 for (i
= 0; i
< num_regs
; i
++) {
1233 arch_info
[i
].num
= stm8_regs
[i
].id
;
1234 arch_info
[i
].target
= target
;
1235 arch_info
[i
].stm8_common
= stm8
;
1237 reg_list
[i
].name
= stm8_regs
[i
].name
;
1238 reg_list
[i
].size
= stm8_regs
[i
].bits
;
1240 reg_list
[i
].value
= calloc(1, 4);
1241 reg_list
[i
].valid
= false;
1242 reg_list
[i
].type
= &stm8_reg_type
;
1243 reg_list
[i
].arch_info
= &arch_info
[i
];
1245 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1246 if (reg_list
[i
].reg_data_type
)
1247 reg_list
[i
].reg_data_type
->type
= stm8_regs
[i
].type
;
1249 LOG_ERROR("unable to allocate reg type list");
1253 reg_list
[i
].dirty
= false;
1254 reg_list
[i
].group
= stm8_regs
[i
].group
;
1255 reg_list
[i
].number
= stm8_regs
[i
].id
;
1256 reg_list
[i
].exist
= true;
1257 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1259 feature
= calloc(1, sizeof(struct reg_feature
));
1261 feature
->name
= stm8_regs
[i
].feature
;
1262 reg_list
[i
].feature
= feature
;
1264 LOG_ERROR("unable to allocate feature list");
1270 static void stm8_free_reg_cache(struct target
*target
)
1272 struct stm8_common
*stm8
= target_to_stm8(target
);
1273 struct reg_cache
*cache
;
1277 cache
= stm8
->core_cache
;
1282 for (i
= 0; i
< cache
->num_regs
; i
++) {
1283 reg
= &cache
->reg_list
[i
];
1286 free(reg
->reg_data_type
);
1290 free(cache
->reg_list
[0].arch_info
);
1291 free(cache
->reg_list
);
1294 stm8
->core_cache
= NULL
;
1297 static void stm8_deinit(struct target
*target
)
1299 struct stm8_common
*stm8
= target_to_stm8(target
);
1301 free(stm8
->hw_break_list
);
1303 stm8_free_reg_cache(target
);
1308 static int stm8_arch_state(struct target
*target
)
1310 struct stm8_common
*stm8
= target_to_stm8(target
);
1312 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
1313 debug_reason_name(target
),
1314 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1319 static int stm8_step(struct target
*target
, int current
,
1320 target_addr_t address
, int handle_breakpoints
)
1322 LOG_DEBUG("%" PRIx32
" " TARGET_ADDR_FMT
" %" PRIx32
,
1323 current
, address
, handle_breakpoints
);
1325 /* get pointers to arch-specific information */
1326 struct stm8_common
*stm8
= target_to_stm8(target
);
1327 struct breakpoint
*breakpoint
= NULL
;
1329 if (target
->state
!= TARGET_HALTED
) {
1330 LOG_WARNING("target not halted");
1331 return ERROR_TARGET_NOT_HALTED
;
1334 /* current = 1: continue on current pc, otherwise continue at <address> */
1336 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32, address
);
1337 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1338 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1341 /* the front-end may request us not to handle breakpoints */
1342 if (handle_breakpoints
) {
1343 breakpoint
= breakpoint_find(target
,
1344 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1346 stm8_unset_breakpoint(target
, breakpoint
);
1349 /* restore context */
1350 stm8_restore_context(target
);
1352 /* configure single step mode */
1353 stm8_config_step(target
, 1);
1355 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1357 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1359 /* disable interrupts while stepping */
1360 if (!stm8
->enable_step_irq
)
1361 stm8_enable_interrupts(target
, 0);
1363 /* exit debug mode */
1364 stm8_exit_debug(target
);
1366 /* registers are now invalid */
1367 register_cache_invalidate(stm8
->core_cache
);
1369 LOG_DEBUG("target stepped ");
1370 stm8_debug_entry(target
);
1373 stm8_set_breakpoint(target
, breakpoint
);
1375 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1380 static void stm8_enable_breakpoints(struct target
*target
)
1382 struct breakpoint
*breakpoint
= target
->breakpoints
;
1384 /* set any pending breakpoints */
1385 while (breakpoint
) {
1386 if (breakpoint
->set
== 0)
1387 stm8_set_breakpoint(target
, breakpoint
);
1388 breakpoint
= breakpoint
->next
;
1392 static int stm8_set_breakpoint(struct target
*target
,
1393 struct breakpoint
*breakpoint
)
1395 struct stm8_common
*stm8
= target_to_stm8(target
);
1396 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1399 if (breakpoint
->set
) {
1400 LOG_WARNING("breakpoint already set");
1404 if (breakpoint
->type
== BKPT_HARD
) {
1407 while (comparator_list
[bp_num
].used
&& (bp_num
< stm8
->num_hw_bpoints
))
1409 if (bp_num
>= stm8
->num_hw_bpoints
) {
1410 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32
")",
1411 breakpoint
->unique_id
);
1412 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1414 breakpoint
->set
= bp_num
+ 1;
1415 comparator_list
[bp_num
].used
= true;
1416 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
1417 comparator_list
[bp_num
].type
= HWBRK_EXEC
;
1419 retval
= stm8_set_hwbreak(target
, comparator_list
);
1420 if (retval
!= ERROR_OK
)
1423 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1424 breakpoint
->unique_id
,
1425 bp_num
, comparator_list
[bp_num
].bp_value
);
1426 } else if (breakpoint
->type
== BKPT_SOFT
) {
1427 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1428 if (breakpoint
->length
== 1) {
1429 uint8_t verify
= 0x55;
1431 retval
= target_read_u8(target
, breakpoint
->address
,
1432 breakpoint
->orig_instr
);
1433 if (retval
!= ERROR_OK
)
1435 retval
= target_write_u8(target
, breakpoint
->address
, STM8_BREAK
);
1436 if (retval
!= ERROR_OK
)
1439 retval
= target_read_u8(target
, breakpoint
->address
, &verify
);
1440 if (retval
!= ERROR_OK
)
1442 if (verify
!= STM8_BREAK
) {
1443 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1444 " - check that memory is read/writable",
1445 breakpoint
->address
);
1446 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1449 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1451 breakpoint
->set
= 1; /* Any nice value but 0 */
1457 static int stm8_add_breakpoint(struct target
*target
,
1458 struct breakpoint
*breakpoint
)
1460 struct stm8_common
*stm8
= target_to_stm8(target
);
1463 if (breakpoint
->type
== BKPT_HARD
) {
1464 if (stm8
->num_hw_bpoints_avail
< 1) {
1465 LOG_INFO("no hardware breakpoint available");
1466 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1469 ret
= stm8_set_breakpoint(target
, breakpoint
);
1470 if (ret
!= ERROR_OK
)
1473 stm8
->num_hw_bpoints_avail
--;
1477 ret
= stm8_set_breakpoint(target
, breakpoint
);
1478 if (ret
!= ERROR_OK
)
1484 static int stm8_unset_breakpoint(struct target
*target
,
1485 struct breakpoint
*breakpoint
)
1487 /* get pointers to arch-specific information */
1488 struct stm8_common
*stm8
= target_to_stm8(target
);
1489 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1492 if (!breakpoint
->set
) {
1493 LOG_WARNING("breakpoint not set");
1497 if (breakpoint
->type
== BKPT_HARD
) {
1498 int bp_num
= breakpoint
->set
- 1;
1499 if ((bp_num
< 0) || (bp_num
>= stm8
->num_hw_bpoints
)) {
1500 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1501 breakpoint
->unique_id
);
1504 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d",
1505 breakpoint
->unique_id
,
1507 comparator_list
[bp_num
].used
= false;
1508 retval
= stm8_set_hwbreak(target
, comparator_list
);
1509 if (retval
!= ERROR_OK
)
1512 /* restore original instruction (kept in target endianness) */
1513 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1514 if (breakpoint
->length
== 1) {
1515 uint8_t current_instr
;
1517 /* check that user program has not
1518 modified breakpoint instruction */
1519 retval
= target_read_memory(target
, breakpoint
->address
, 1, 1,
1520 (uint8_t *)¤t_instr
);
1521 if (retval
!= ERROR_OK
)
1524 if (current_instr
== STM8_BREAK
) {
1525 retval
= target_write_memory(target
, breakpoint
->address
, 1, 1,
1526 breakpoint
->orig_instr
);
1527 if (retval
!= ERROR_OK
)
1533 breakpoint
->set
= 0;
1538 static int stm8_remove_breakpoint(struct target
*target
,
1539 struct breakpoint
*breakpoint
)
1541 /* get pointers to arch-specific information */
1542 struct stm8_common
*stm8
= target_to_stm8(target
);
1544 if (target
->state
!= TARGET_HALTED
) {
1545 LOG_WARNING("target not halted");
1546 return ERROR_TARGET_NOT_HALTED
;
1549 if (breakpoint
->set
)
1550 stm8_unset_breakpoint(target
, breakpoint
);
1552 if (breakpoint
->type
== BKPT_HARD
)
1553 stm8
->num_hw_bpoints_avail
++;
1558 static int stm8_set_watchpoint(struct target
*target
,
1559 struct watchpoint
*watchpoint
)
1561 struct stm8_common
*stm8
= target_to_stm8(target
);
1562 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1566 if (watchpoint
->set
) {
1567 LOG_WARNING("watchpoint already set");
1571 while (comparator_list
[wp_num
].used
&& (wp_num
< stm8
->num_hw_bpoints
))
1573 if (wp_num
>= stm8
->num_hw_bpoints
) {
1574 LOG_ERROR("Can not find free hw breakpoint");
1575 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1578 if (watchpoint
->length
!= 1) {
1579 LOG_ERROR("Only watchpoints of length 1 are supported");
1580 return ERROR_TARGET_UNALIGNED_ACCESS
;
1583 enum hw_break_type enable
= 0;
1585 switch (watchpoint
->rw
) {
1596 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1599 comparator_list
[wp_num
].used
= true;
1600 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
1601 comparator_list
[wp_num
].type
= enable
;
1603 ret
= stm8_set_hwbreak(target
, comparator_list
);
1604 if (ret
!= ERROR_OK
) {
1605 comparator_list
[wp_num
].used
= false;
1609 watchpoint
->set
= wp_num
+ 1;
1611 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"",
1613 comparator_list
[wp_num
].bp_value
);
1618 static int stm8_add_watchpoint(struct target
*target
,
1619 struct watchpoint
*watchpoint
)
1622 struct stm8_common
*stm8
= target_to_stm8(target
);
1624 if (stm8
->num_hw_bpoints_avail
< 1) {
1625 LOG_INFO("no hardware watchpoints available");
1626 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1629 ret
= stm8_set_watchpoint(target
, watchpoint
);
1630 if (ret
!= ERROR_OK
)
1633 stm8
->num_hw_bpoints_avail
--;
1637 static void stm8_enable_watchpoints(struct target
*target
)
1639 struct watchpoint
*watchpoint
= target
->watchpoints
;
1641 /* set any pending watchpoints */
1642 while (watchpoint
) {
1643 if (watchpoint
->set
== 0)
1644 stm8_set_watchpoint(target
, watchpoint
);
1645 watchpoint
= watchpoint
->next
;
1649 static int stm8_unset_watchpoint(struct target
*target
,
1650 struct watchpoint
*watchpoint
)
1652 /* get pointers to arch-specific information */
1653 struct stm8_common
*stm8
= target_to_stm8(target
);
1654 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1656 if (!watchpoint
->set
) {
1657 LOG_WARNING("watchpoint not set");
1661 int wp_num
= watchpoint
->set
- 1;
1662 if ((wp_num
< 0) || (wp_num
>= stm8
->num_hw_bpoints
)) {
1663 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1666 comparator_list
[wp_num
].used
= false;
1667 watchpoint
->set
= 0;
1669 stm8_set_hwbreak(target
, comparator_list
);
1674 static int stm8_remove_watchpoint(struct target
*target
,
1675 struct watchpoint
*watchpoint
)
1677 /* get pointers to arch-specific information */
1678 struct stm8_common
*stm8
= target_to_stm8(target
);
1680 if (target
->state
!= TARGET_HALTED
) {
1681 LOG_WARNING("target not halted");
1682 return ERROR_TARGET_NOT_HALTED
;
1685 if (watchpoint
->set
)
1686 stm8_unset_watchpoint(target
, watchpoint
);
1688 stm8
->num_hw_bpoints_avail
++;
1693 static int stm8_examine(struct target
*target
)
1697 /* get pointers to arch-specific information */
1698 struct stm8_common
*stm8
= target_to_stm8(target
);
1699 struct hl_interface_s
*adapter
= target_to_adapter(target
);
1701 if (!target_was_examined(target
)) {
1702 if (!stm8
->swim_configured
) {
1703 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1704 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1705 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
);
1706 if (retval
!= ERROR_OK
)
1708 /* set high speed */
1709 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1710 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
+ HS
);
1711 if (retval
!= ERROR_OK
)
1713 retval
= stm8_set_speed(target
, 1);
1714 if (retval
== ERROR_OK
)
1715 stm8
->swim_configured
= true;
1717 Now is the time to deassert reset if connect_under_reset.
1718 Releasing reset line will cause the option bytes to load.
1719 The core will still be stalled.
1721 if (adapter
->param
.connect_under_reset
)
1722 stm8_reset_deassert(target
);
1724 LOG_INFO("trying to reconnect");
1726 retval
= adapter
->layout
->api
->state(adapter
->handle
);
1727 if (retval
!= ERROR_OK
) {
1728 LOG_ERROR("reconnect failed");
1732 /* read dm_csrx control regs */
1733 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
1734 if (retval
!= ERROR_OK
) {
1735 LOG_ERROR("state query failed");
1740 target_set_examined(target
);
1748 /** Checks whether a memory region is erased. */
1749 static int stm8_blank_check_memory(struct target
*target
,
1750 struct target_memory_check_block
*blocks
, int num_blocks
, uint8_t erased_value
)
1752 struct working_area
*erase_check_algorithm
;
1753 struct reg_param reg_params
[2];
1754 struct mem_param mem_params
[2];
1755 struct stm8_algorithm stm8_info
;
1757 static const uint8_t stm8_erase_check_code
[] = {
1758 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1761 if (erased_value
!= 0xff) {
1762 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for STM8",
1767 /* make sure we have a working area */
1768 if (target_alloc_working_area(target
, sizeof(stm8_erase_check_code
),
1769 &erase_check_algorithm
) != ERROR_OK
)
1770 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1772 target_write_buffer(target
, erase_check_algorithm
->address
,
1773 sizeof(stm8_erase_check_code
), stm8_erase_check_code
);
1775 stm8_info
.common_magic
= STM8_COMMON_MAGIC
;
1777 init_mem_param(&mem_params
[0], 0x0, 3, PARAM_OUT
);
1778 buf_set_u32(mem_params
[0].value
, 0, 24, blocks
[0].address
);
1780 init_mem_param(&mem_params
[1], 0x3, 3, PARAM_OUT
);
1781 buf_set_u32(mem_params
[1].value
, 0, 24, blocks
[0].size
);
1783 init_reg_param(®_params
[0], "a", 32, PARAM_IN_OUT
);
1784 buf_set_u32(reg_params
[0].value
, 0, 32, erased_value
);
1786 init_reg_param(®_params
[1], "sp", 32, PARAM_OUT
);
1787 buf_set_u32(reg_params
[1].value
, 0, 32, erase_check_algorithm
->address
);
1789 int retval
= target_run_algorithm(target
, 2, mem_params
, 2, reg_params
,
1790 erase_check_algorithm
->address
+ 6,
1791 erase_check_algorithm
->address
+ (sizeof(stm8_erase_check_code
) - 1),
1794 if (retval
== ERROR_OK
)
1795 blocks
[0].result
= (*(reg_params
[0].value
) == 0xff);
1797 destroy_mem_param(&mem_params
[0]);
1798 destroy_mem_param(&mem_params
[1]);
1799 destroy_reg_param(®_params
[0]);
1800 destroy_reg_param(®_params
[1]);
1802 target_free_working_area(target
, erase_check_algorithm
);
1804 if (retval
!= ERROR_OK
)
1807 return 1; /* only one block has been checked */
1810 static int stm8_checksum_memory(struct target
*target
, target_addr_t address
,
1811 uint32_t count
, uint32_t *checksum
)
1813 /* let image_calculate_checksum() take care of business */
1814 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1817 /* run to exit point. return error if exit point was not reached. */
1818 static int stm8_run_and_wait(struct target
*target
, uint32_t entry_point
,
1819 int timeout_ms
, uint32_t exit_point
, struct stm8_common
*stm8
)
1823 /* This code relies on the target specific resume() and
1824 poll()->debug_entry() sequence to write register values to the
1825 processor and the read them back */
1826 retval
= target_resume(target
, 0, entry_point
, 0, 1);
1827 if (retval
!= ERROR_OK
)
1830 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1831 /* If the target fails to halt due to the breakpoint, force a halt */
1832 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
1833 retval
= target_halt(target
);
1834 if (retval
!= ERROR_OK
)
1836 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
1837 if (retval
!= ERROR_OK
)
1839 return ERROR_TARGET_TIMEOUT
;
1842 pc
= buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32);
1843 if (exit_point
&& (pc
!= exit_point
)) {
1844 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
1845 return ERROR_TARGET_TIMEOUT
;
1851 static int stm8_run_algorithm(struct target
*target
, int num_mem_params
,
1852 struct mem_param
*mem_params
, int num_reg_params
,
1853 struct reg_param
*reg_params
, target_addr_t entry_point
,
1854 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
1856 struct stm8_common
*stm8
= target_to_stm8(target
);
1858 uint32_t context
[STM8_NUM_REGS
];
1859 int retval
= ERROR_OK
;
1861 LOG_DEBUG("Running algorithm");
1863 /* NOTE: stm8_run_algorithm requires that each
1864 algorithm uses a software breakpoint
1865 at the exit point */
1867 if (stm8
->common_magic
!= STM8_COMMON_MAGIC
) {
1868 LOG_ERROR("current target isn't a STM8 target");
1869 return ERROR_TARGET_INVALID
;
1872 if (target
->state
!= TARGET_HALTED
) {
1873 LOG_WARNING("target not halted");
1874 return ERROR_TARGET_NOT_HALTED
;
1877 /* refresh core register cache */
1878 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1879 if (!stm8
->core_cache
->reg_list
[i
].valid
)
1880 stm8
->read_core_reg(target
, i
);
1881 context
[i
] = buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1884 for (int i
= 0; i
< num_mem_params
; i
++) {
1885 if (mem_params
[i
].direction
== PARAM_IN
)
1887 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1888 mem_params
[i
].size
, mem_params
[i
].value
);
1889 if (retval
!= ERROR_OK
)
1893 for (int i
= 0; i
< num_reg_params
; i
++) {
1894 if (reg_params
[i
].direction
== PARAM_IN
)
1897 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1898 reg_params
[i
].reg_name
, 0);
1901 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1902 return ERROR_COMMAND_SYNTAX_ERROR
;
1905 if (reg_params
[i
].size
!= 32) {
1906 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1907 reg_params
[i
].reg_name
);
1908 return ERROR_COMMAND_SYNTAX_ERROR
;
1911 stm8_set_core_reg(reg
, reg_params
[i
].value
);
1914 retval
= stm8_run_and_wait(target
, entry_point
,
1915 timeout_ms
, exit_point
, stm8
);
1917 if (retval
!= ERROR_OK
)
1920 for (int i
= 0; i
< num_mem_params
; i
++) {
1921 if (mem_params
[i
].direction
!= PARAM_OUT
) {
1922 retval
= target_read_buffer(target
, mem_params
[i
].address
,
1923 mem_params
[i
].size
, mem_params
[i
].value
);
1924 if (retval
!= ERROR_OK
)
1929 for (int i
= 0; i
< num_reg_params
; i
++) {
1930 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1931 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1932 reg_params
[i
].reg_name
, 0);
1934 LOG_ERROR("BUG: register '%s' not found",
1935 reg_params
[i
].reg_name
);
1936 return ERROR_COMMAND_SYNTAX_ERROR
;
1939 if (reg_params
[i
].size
!= 32) {
1940 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1941 reg_params
[i
].reg_name
);
1942 return ERROR_COMMAND_SYNTAX_ERROR
;
1945 buf_set_u32(reg_params
[i
].value
,
1946 0, 32, buf_get_u32(reg
->value
, 0, 32));
1950 /* restore everything we saved before */
1951 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1953 regvalue
= buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1954 if (regvalue
!= context
[i
]) {
1955 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
1956 stm8
->core_cache
->reg_list
[i
].name
, context
[i
]);
1957 buf_set_u32(stm8
->core_cache
->reg_list
[i
].value
,
1959 stm8
->core_cache
->reg_list
[i
].valid
= true;
1960 stm8
->core_cache
->reg_list
[i
].dirty
= true;
1967 int stm8_jim_configure(struct target
*target
, Jim_GetOptInfo
*goi
)
1969 struct stm8_common
*stm8
= target_to_stm8(target
);
1974 arg
= Jim_GetString(goi
->argv
[0], NULL
);
1975 if (!strcmp(arg
, "-blocksize")) {
1976 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1980 if (goi
->argc
== 0) {
1981 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1982 "-blocksize ?bytes? ...");
1986 e
= Jim_GetOpt_Wide(goi
, &w
);
1990 stm8
->blocksize
= w
;
1991 LOG_DEBUG("blocksize=%8.8x", stm8
->blocksize
);
1994 if (!strcmp(arg
, "-flashstart")) {
1995 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1999 if (goi
->argc
== 0) {
2000 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2001 "-flashstart ?address? ...");
2005 e
= Jim_GetOpt_Wide(goi
, &w
);
2009 stm8
->flashstart
= w
;
2010 LOG_DEBUG("flashstart=%8.8x", stm8
->flashstart
);
2013 if (!strcmp(arg
, "-flashend")) {
2014 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2018 if (goi
->argc
== 0) {
2019 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2020 "-flashend ?address? ...");
2024 e
= Jim_GetOpt_Wide(goi
, &w
);
2029 LOG_DEBUG("flashend=%8.8x", stm8
->flashend
);
2032 if (!strcmp(arg
, "-eepromstart")) {
2033 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2037 if (goi
->argc
== 0) {
2038 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2039 "-eepromstart ?address? ...");
2043 e
= Jim_GetOpt_Wide(goi
, &w
);
2047 stm8
->eepromstart
= w
;
2048 LOG_DEBUG("eepromstart=%8.8x", stm8
->eepromstart
);
2051 if (!strcmp(arg
, "-eepromend")) {
2052 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2056 if (goi
->argc
== 0) {
2057 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2058 "-eepromend ?address? ...");
2062 e
= Jim_GetOpt_Wide(goi
, &w
);
2066 stm8
->eepromend
= w
;
2067 LOG_DEBUG("eepromend=%8.8x", stm8
->eepromend
);
2070 if (!strcmp(arg
, "-optionstart")) {
2071 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2075 if (goi
->argc
== 0) {
2076 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2077 "-optionstart ?address? ...");
2081 e
= Jim_GetOpt_Wide(goi
, &w
);
2085 stm8
->optionstart
= w
;
2086 LOG_DEBUG("optionstart=%8.8x", stm8
->optionstart
);
2089 if (!strcmp(arg
, "-optionend")) {
2090 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2094 if (goi
->argc
== 0) {
2095 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2096 "-optionend ?address? ...");
2100 e
= Jim_GetOpt_Wide(goi
, &w
);
2104 stm8
->optionend
= w
;
2105 LOG_DEBUG("optionend=%8.8x", stm8
->optionend
);
2108 if (!strcmp(arg
, "-enable_step_irq")) {
2109 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2113 stm8
->enable_step_irq
= true;
2114 LOG_DEBUG("enable_step_irq=%8.8x", stm8
->enable_step_irq
);
2117 if (!strcmp(arg
, "-enable_stm8l")) {
2118 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2122 stm8
->enable_stm8l
= true;
2123 LOG_DEBUG("enable_stm8l=%8.8x", stm8
->enable_stm8l
);
2124 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2127 return JIM_CONTINUE
;
2130 COMMAND_HANDLER(stm8_handle_enable_step_irq_command
)
2133 struct target
*target
= get_current_target(CMD_CTX
);
2134 struct stm8_common
*stm8
= target_to_stm8(target
);
2135 bool enable
= stm8
->enable_step_irq
;
2138 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2139 stm8
->enable_step_irq
= enable
;
2141 msg
= stm8
->enable_step_irq
? "enabled" : "disabled";
2142 command_print(CMD
, "enable_step_irq = %s", msg
);
2146 COMMAND_HANDLER(stm8_handle_enable_stm8l_command
)
2149 struct target
*target
= get_current_target(CMD_CTX
);
2150 struct stm8_common
*stm8
= target_to_stm8(target
);
2151 bool enable
= stm8
->enable_stm8l
;
2154 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2155 stm8
->enable_stm8l
= enable
;
2157 msg
= stm8
->enable_stm8l
? "enabled" : "disabled";
2158 command_print(CMD
, "enable_stm8l = %s", msg
);
2159 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2163 static const struct command_registration stm8_exec_command_handlers
[] = {
2165 .name
= "enable_step_irq",
2166 .handler
= stm8_handle_enable_step_irq_command
,
2167 .mode
= COMMAND_ANY
,
2168 .help
= "Enable/disable irq handling during step",
2172 .name
= "enable_stm8l",
2173 .handler
= stm8_handle_enable_stm8l_command
,
2174 .mode
= COMMAND_ANY
,
2175 .help
= "Enable/disable STM8L flash programming",
2178 COMMAND_REGISTRATION_DONE
2181 const struct command_registration stm8_command_handlers
[] = {
2184 .mode
= COMMAND_ANY
,
2185 .help
= "stm8 command group",
2187 .chain
= stm8_exec_command_handlers
,
2189 COMMAND_REGISTRATION_DONE
2192 struct target_type stm8_target
= {
2196 .arch_state
= stm8_arch_state
,
2199 .resume
= stm8_resume
,
2202 .assert_reset
= stm8_reset_assert
,
2203 .deassert_reset
= stm8_reset_deassert
,
2205 .get_gdb_arch
= stm8_get_gdb_arch
,
2206 .get_gdb_reg_list
= stm8_get_gdb_reg_list
,
2208 .read_memory
= stm8_read_memory
,
2209 .write_memory
= stm8_write_memory
,
2210 .checksum_memory
= stm8_checksum_memory
,
2211 .blank_check_memory
= stm8_blank_check_memory
,
2213 .run_algorithm
= stm8_run_algorithm
,
2215 .add_breakpoint
= stm8_add_breakpoint
,
2216 .remove_breakpoint
= stm8_remove_breakpoint
,
2217 .add_watchpoint
= stm8_add_watchpoint
,
2218 .remove_watchpoint
= stm8_remove_watchpoint
,
2220 .commands
= stm8_command_handlers
,
2221 .target_create
= stm8_target_create
,
2222 .init_target
= stm8_init
,
2223 .examine
= stm8_examine
,
2225 .deinit_target
= stm8_deinit
,
2226 .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)