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 3 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/jtag.h"
29 #include "jtag/hla/hla_transport.h"
30 #include "jtag/hla/hla_interface.h"
31 #include "jtag/hla/hla_layout.h"
33 #include "breakpoints.h"
34 #include "algorithm.h"
37 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
);
38 static int stm8_read_core_reg(struct target
*target
, unsigned int num
);
39 static int stm8_write_core_reg(struct target
*target
, unsigned int num
);
40 static int stm8_save_context(struct target
*target
);
41 static void stm8_enable_breakpoints(struct target
*target
);
42 static int stm8_unset_breakpoint(struct target
*target
,
43 struct breakpoint
*breakpoint
);
44 static int stm8_set_breakpoint(struct target
*target
,
45 struct breakpoint
*breakpoint
);
46 static void stm8_enable_watchpoints(struct target
*target
);
47 static int stm8_unset_watchpoint(struct target
*target
,
48 struct watchpoint
*watchpoint
);
59 { 0, "pc", 32, REG_TYPE_UINT32
, "general", "org.gnu.gdb.stm8.core", 0 },
60 { 1, "a", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
61 { 2, "x", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
62 { 3, "y", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
63 { 4, "sp", 16, REG_TYPE_UINT16
, "general", "org.gnu.gdb.stm8.core", 0 },
64 { 5, "cc", 8, REG_TYPE_UINT8
, "general", "org.gnu.gdb.stm8.core", 0 },
67 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
78 #define DM_REGS 0x7f00
79 #define DM_REG_A 0x7f00
80 #define DM_REG_PC 0x7f01
81 #define DM_REG_X 0x7f04
82 #define DM_REG_Y 0x7f06
83 #define DM_REG_SP 0x7f08
84 #define DM_REG_CC 0x7f0a
86 #define DM_BKR1E 0x7f90
87 #define DM_BKR2E 0x7f93
90 #define DM_CSR1 0x7f98
91 #define DM_CSR2 0x7f99
105 #define FLASH_CR1_STM8S 0x505A
106 #define FLASH_CR2_STM8S 0x505B
107 #define FLASH_NCR2_STM8S 0x505C
108 #define FLASH_IAPSR_STM8S 0x505F
109 #define FLASH_PUKR_STM8S 0x5062
110 #define FLASH_DUKR_STM8S 0x5064
112 #define FLASH_CR1_STM8L 0x5050
113 #define FLASH_CR2_STM8L 0x5051
114 #define FLASH_NCR2_STM8L 0
115 #define FLASH_PUKR_STM8L 0x5052
116 #define FLASH_DUKR_STM8L 0x5053
117 #define FLASH_IAPSR_STM8L 0x5054
124 #define WR_PG_DIS 0x01
134 #define SAFE_MASK 0x80
135 #define NO_ACCESS 0x40
139 #define SWIM_RST 0x04
143 #define SWIM_CSR 0x7f80
145 #define STM8_BREAK 0x8B
154 struct stm8_algorithm
{
158 struct stm8_core_reg
{
160 struct target
*target
;
161 struct stm8_common
*stm8_common
;
165 /* break on execute */
171 /* break on read, write and execute */
175 struct stm8_comparator
{
178 uint32_t reg_address
;
179 enum hw_break_type type
;
182 static inline struct hl_interface_s
*target_to_adapter(struct target
*target
)
184 return target
->tap
->priv
;
187 static int stm8_adapter_read_memory(struct target
*target
,
188 uint32_t addr
, int size
, int count
, void *buf
)
191 struct hl_interface_s
*adapter
= target_to_adapter(target
);
193 ret
= adapter
->layout
->api
->read_mem(adapter
->handle
,
194 addr
, size
, count
, buf
);
200 static int stm8_adapter_write_memory(struct target
*target
,
201 uint32_t addr
, int size
, int count
, const void *buf
)
204 struct hl_interface_s
*adapter
= target_to_adapter(target
);
206 ret
= adapter
->layout
->api
->write_mem(adapter
->handle
,
207 addr
, size
, count
, buf
);
213 static int stm8_write_u8(struct target
*target
,
214 uint32_t addr
, uint8_t val
)
218 struct hl_interface_s
*adapter
= target_to_adapter(target
);
221 ret
= adapter
->layout
->api
->write_mem(adapter
->handle
, addr
, 1, 1, buf
);
227 static int stm8_read_u8(struct target
*target
,
228 uint32_t addr
, uint8_t *val
)
231 struct hl_interface_s
*adapter
= target_to_adapter(target
);
233 ret
= adapter
->layout
->api
->read_mem(adapter
->handle
, addr
, 1, 1, val
);
239 static int stm8_set_speed(struct target
*target
, int speed
)
241 struct hl_interface_s
*adapter
= target_to_adapter(target
);
242 adapter
->layout
->api
->speed(adapter
->handle
, speed
, 0);
247 <enable == 0> Disables interrupts.
248 If interrupts are enabled they are masked and the cc register
251 <enable == 1> Enables interrupts.
252 Enable interrupts is actually restoring I1 I0 state from previous
253 call with enable == 0. Note that if stepping and breaking on a sim
254 instruction will NOT work since the interrupt flags are restored on
255 debug_entry. We don't have any way for the debugger to exclusively
256 disable the interrupts
258 static int stm8_enable_interrupts(struct target
*target
, int enable
)
260 struct stm8_common
*stm8
= target_to_stm8(target
);
265 return ERROR_OK
; /* cc was not stashed */
266 /* fetch current cc */
267 stm8_read_u8(target
, DM_REG_CC
, &cc
);
269 cc
&= ~(CC_I0
+ CC_I1
);
270 /* restore I1 & I0 from stash*/
271 cc
|= (stm8
->cc
& (CC_I0
+CC_I1
));
272 /* update current cc */
273 stm8_write_u8(target
, DM_REG_CC
, cc
);
274 stm8
->cc_valid
= false;
276 stm8_read_u8(target
, DM_REG_CC
, &cc
);
277 if ((cc
& CC_I0
) && (cc
& CC_I1
))
278 return ERROR_OK
; /* interrupts already masked */
281 stm8
->cc_valid
= true;
282 /* mask interrupts (disable) */
283 cc
|= (CC_I0
+ CC_I1
);
284 stm8_write_u8(target
, DM_REG_CC
, cc
);
290 static int stm8_set_hwbreak(struct target
*target
,
291 struct stm8_comparator comparator_list
[])
296 /* Refer to Table 4 in UM0470 */
304 if (!comparator_list
[0].used
) {
305 comparator_list
[0].type
= HWBRK_EXEC
;
306 comparator_list
[0].bp_value
= -1;
309 if (!comparator_list
[1].used
) {
310 comparator_list
[1].type
= HWBRK_EXEC
;
311 comparator_list
[1].bp_value
= -1;
314 if ((comparator_list
[0].type
== HWBRK_EXEC
)
315 && (comparator_list
[1].type
== HWBRK_EXEC
)) {
316 comparator_list
[0].reg_address
= 0;
317 comparator_list
[1].reg_address
= 1;
320 if ((comparator_list
[0].type
== HWBRK_EXEC
)
321 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
322 comparator_list
[0].reg_address
= 0;
323 comparator_list
[1].reg_address
= 1;
324 switch (comparator_list
[1].type
) {
338 if ((comparator_list
[1].type
== HWBRK_EXEC
)
339 && (comparator_list
[0].type
!= HWBRK_EXEC
)) {
340 comparator_list
[0].reg_address
= 1;
341 comparator_list
[1].reg_address
= 0;
342 switch (comparator_list
[0].type
) {
356 if ((comparator_list
[0].type
!= HWBRK_EXEC
)
357 && (comparator_list
[1].type
!= HWBRK_EXEC
)) {
358 if ((comparator_list
[0].type
!= comparator_list
[1].type
)) {
359 LOG_ERROR("data hw breakpoints must be of same type");
360 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
364 for (i
= 0; i
< 2; i
++) {
365 data
= comparator_list
[i
].bp_value
;
366 addr
= comparator_list
[i
].reg_address
;
373 ret
= stm8_adapter_write_memory(target
, DM_BKR1E
, 1, 3, buf
);
374 LOG_DEBUG("DM_BKR1E=%" PRIx32
, data
);
375 } else if (addr
== 1) {
376 ret
= stm8_adapter_write_memory(target
, DM_BKR2E
, 1, 3, buf
);
377 LOG_DEBUG("DM_BKR2E=%" PRIx32
, data
);
379 LOG_DEBUG("addr=%" PRIu32
, addr
);
386 ret
= stm8_write_u8(target
, DM_CR1
,
387 (bc
<< 3) + (bir
<< 2) + (biw
<< 1));
388 LOG_DEBUG("DM_CR1=%" PRIx8
, buf
[0]);
396 /* read DM control and status regs */
397 static int stm8_read_dm_csrx(struct target
*target
, uint8_t *csr1
,
403 ret
= stm8_adapter_read_memory(target
, DM_CSR1
, 1, sizeof(buf
), buf
);
413 /* set or clear the single step flag in DM */
414 static int stm8_config_step(struct target
*target
, int enable
)
419 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
427 ret
= stm8_write_u8(target
, DM_CSR1
, csr1
);
433 /* set the stall flag in DM */
434 static int stm8_debug_stall(struct target
*target
)
439 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
443 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
449 static int stm8_configure_break_unit(struct target
*target
)
451 /* get pointers to arch-specific information */
452 struct stm8_common
*stm8
= target_to_stm8(target
);
454 if (stm8
->bp_scanned
)
457 stm8
->num_hw_bpoints
= 2;
458 stm8
->num_hw_bpoints_avail
= stm8
->num_hw_bpoints
;
460 stm8
->hw_break_list
= calloc(stm8
->num_hw_bpoints
,
461 sizeof(struct stm8_comparator
));
463 stm8
->hw_break_list
[0].reg_address
= 0;
464 stm8
->hw_break_list
[1].reg_address
= 1;
466 LOG_DEBUG("hw breakpoints: numinst %i numdata %i", stm8
->num_hw_bpoints
,
467 stm8
->num_hw_bpoints
);
469 stm8
->bp_scanned
= true;
474 static int stm8_examine_debug_reason(struct target
*target
)
479 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
480 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
482 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
483 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
485 if (retval
!= ERROR_OK
)
489 /* halted on reset */
490 target
->debug_reason
= DBG_REASON_UNDEFINED
;
492 if (csr1
& (BK1F
+BK2F
))
493 /* we have halted on a breakpoint (or wp)*/
494 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
497 /* we have halted on a breakpoint */
498 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
505 static int stm8_debug_entry(struct target
*target
)
507 struct stm8_common
*stm8
= target_to_stm8(target
);
509 /* restore interrupts */
510 stm8_enable_interrupts(target
, 1);
512 stm8_save_context(target
);
514 /* make sure stepping disabled STE bit in CSR1 cleared */
515 stm8_config_step(target
, 0);
517 /* attempt to find halt reason */
518 stm8_examine_debug_reason(target
);
520 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
521 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32),
522 target_state_name(target
));
527 /* clear stall flag in DM and flush instruction pipe */
528 static int stm8_exit_debug(struct target
*target
)
533 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
537 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
543 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
549 static int stm8_read_regs(struct target
*target
, uint32_t regs
[])
554 ret
= stm8_adapter_read_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
558 regs
[0] = be_to_h_u24(buf
+DM_REG_PC
-DM_REGS
);
559 regs
[1] = buf
[DM_REG_A
-DM_REGS
];
560 regs
[2] = be_to_h_u16(buf
+DM_REG_X
-DM_REGS
);
561 regs
[3] = be_to_h_u16(buf
+DM_REG_Y
-DM_REGS
);
562 regs
[4] = be_to_h_u16(buf
+DM_REG_SP
-DM_REGS
);
563 regs
[5] = buf
[DM_REG_CC
-DM_REGS
];
568 static int stm8_write_regs(struct target
*target
, uint32_t regs
[])
573 h_u24_to_be(buf
+DM_REG_PC
-DM_REGS
, regs
[0]);
574 buf
[DM_REG_A
-DM_REGS
] = regs
[1];
575 h_u16_to_be(buf
+DM_REG_X
-DM_REGS
, regs
[2]);
576 h_u16_to_be(buf
+DM_REG_Y
-DM_REGS
, regs
[3]);
577 h_u16_to_be(buf
+DM_REG_SP
-DM_REGS
, regs
[4]);
578 buf
[DM_REG_CC
-DM_REGS
] = regs
[5];
580 ret
= stm8_adapter_write_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
587 static int stm8_get_core_reg(struct reg
*reg
)
590 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
591 struct target
*target
= stm8_reg
->target
;
592 struct stm8_common
*stm8_target
= target_to_stm8(target
);
594 if (target
->state
!= TARGET_HALTED
)
595 return ERROR_TARGET_NOT_HALTED
;
597 retval
= stm8_target
->read_core_reg(target
, stm8_reg
->num
);
602 static int stm8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
604 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
605 struct target
*target
= stm8_reg
->target
;
606 uint32_t value
= buf_get_u32(buf
, 0, reg
->size
);
608 if (target
->state
!= TARGET_HALTED
)
609 return ERROR_TARGET_NOT_HALTED
;
611 buf_set_u32(reg
->value
, 0, 32, value
);
618 static int stm8_save_context(struct target
*target
)
622 /* get pointers to arch-specific information */
623 struct stm8_common
*stm8
= target_to_stm8(target
);
625 /* read core registers */
626 stm8_read_regs(target
, stm8
->core_regs
);
628 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
629 if (!stm8
->core_cache
->reg_list
[i
].valid
)
630 stm8
->read_core_reg(target
, i
);
636 static int stm8_restore_context(struct target
*target
)
640 /* get pointers to arch-specific information */
641 struct stm8_common
*stm8
= target_to_stm8(target
);
643 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
644 if (stm8
->core_cache
->reg_list
[i
].dirty
)
645 stm8
->write_core_reg(target
, i
);
648 /* write core regs */
649 stm8_write_regs(target
, stm8
->core_regs
);
654 static int stm8_unlock_flash(struct target
*target
)
658 struct stm8_common
*stm8
= target_to_stm8(target
);
660 /* check if flash is unlocked */
661 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
662 if (~data
[0] & PUL
) {
664 stm8_write_u8(target
, stm8
->flash_pukr
, 0x56);
665 stm8_write_u8(target
, stm8
->flash_pukr
, 0xae);
668 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
674 static int stm8_unlock_eeprom(struct target
*target
)
678 struct stm8_common
*stm8
= target_to_stm8(target
);
680 /* check if eeprom is unlocked */
681 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
682 if (~data
[0] & DUL
) {
684 stm8_write_u8(target
, stm8
->flash_dukr
, 0xae);
685 stm8_write_u8(target
, stm8
->flash_dukr
, 0x56);
688 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
694 static int stm8_write_flash(struct target
*target
, enum mem_type type
,
696 uint32_t size
, uint32_t count
, uint32_t blocksize_param
,
697 const uint8_t *buffer
)
699 struct stm8_common
*stm8
= target_to_stm8(target
);
704 uint32_t blocksize
= 0;
710 stm8_unlock_flash(target
);
713 stm8_unlock_eeprom(target
);
716 stm8_unlock_eeprom(target
);
720 LOG_ERROR("BUG: wrong mem_type %d", type
);
725 /* we don't support short writes */
730 bytecnt
= count
* size
;
733 if ((bytecnt
>= blocksize_param
) && ((address
& (blocksize_param
-1)) == 0)) {
735 stm8_write_u8(target
, stm8
->flash_cr2
, PRG
+ opt
);
736 if (stm8
->flash_ncr2
)
737 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(PRG
+ opt
));
738 blocksize
= blocksize_param
;
740 if ((bytecnt
>= 4) && ((address
& 0x3) == 0)) {
742 stm8_write_u8(target
, stm8
->flash_cr2
, WPRG
+ opt
);
743 if (stm8
->flash_ncr2
)
744 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(WPRG
+ opt
));
747 if (blocksize
!= 1) {
749 stm8_write_u8(target
, stm8
->flash_cr2
, opt
);
750 if (stm8
->flash_ncr2
)
751 stm8_write_u8(target
, stm8
->flash_ncr2
, ~opt
);
755 res
= stm8_adapter_write_memory(target
, address
, 1, blocksize
, buffer
);
758 address
+= blocksize
;
760 bytecnt
-= blocksize
;
762 /* lets hang here until end of program (EOP) */
763 for (i
= 0; i
< 16; i
++) {
764 stm8_read_u8(target
, stm8
->flash_iapsr
, &iapsr
);
774 /* disable write access */
775 res
= stm8_write_u8(target
, stm8
->flash_iapsr
, 0x0);
783 static int stm8_write_memory(struct target
*target
, target_addr_t address
,
784 uint32_t size
, uint32_t count
,
785 const uint8_t *buffer
)
787 struct stm8_common
*stm8
= target_to_stm8(target
);
789 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
790 ", size: 0x%8.8" PRIx32
791 ", count: 0x%8.8" PRIx32
,
792 address
, size
, count
);
794 if (target
->state
!= TARGET_HALTED
)
795 LOG_WARNING("target not halted");
799 if ((address
>= stm8
->flashstart
) && (address
<= stm8
->flashend
))
800 retval
= stm8_write_flash(target
, FLASH
, address
, size
, count
,
801 stm8
->blocksize
, buffer
);
802 else if ((address
>= stm8
->eepromstart
) && (address
<= stm8
->eepromend
))
803 retval
= stm8_write_flash(target
, EEPROM
, address
, size
, count
,
804 stm8
->blocksize
, buffer
);
805 else if ((address
>= stm8
->optionstart
) && (address
<= stm8
->optionend
))
806 retval
= stm8_write_flash(target
, OPTION
, address
, size
, count
, 0, buffer
);
808 retval
= stm8_adapter_write_memory(target
, address
, size
, count
,
811 if (retval
!= ERROR_OK
)
812 return ERROR_TARGET_FAILURE
;
817 static int stm8_read_memory(struct target
*target
, target_addr_t address
,
818 uint32_t size
, uint32_t count
, uint8_t *buffer
)
820 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
821 ", size: 0x%8.8" PRIx32
822 ", count: 0x%8.8" PRIx32
,
823 address
, size
, count
);
825 if (target
->state
!= TARGET_HALTED
)
826 LOG_WARNING("target not halted");
829 retval
= stm8_adapter_read_memory(target
, address
, size
, count
, buffer
);
831 if (retval
!= ERROR_OK
)
832 return ERROR_TARGET_FAILURE
;
837 static int stm8_init(struct command_context
*cmd_ctx
, struct target
*target
)
839 stm8_build_reg_cache(target
);
844 static int stm8_poll(struct target
*target
)
846 int retval
= ERROR_OK
;
850 LOG_DEBUG("target->state=%d", target
->state
);
853 /* read dm_csrx control regs */
854 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
855 if (retval
!= ERROR_OK
) {
856 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval
);
858 We return ERROR_OK here even if we didn't get an answer.
859 openocd will call target_wait_state until we get target state TARGET_HALTED
864 /* check for processor halted */
866 if (target
->state
!= TARGET_HALTED
) {
867 if (target
->state
== TARGET_UNKNOWN
)
868 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
870 retval
= stm8_debug_entry(target
);
871 if (retval
!= ERROR_OK
) {
872 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval
);
873 return ERROR_TARGET_FAILURE
;
876 if (target
->state
== TARGET_DEBUG_RUNNING
) {
877 target
->state
= TARGET_HALTED
;
878 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
880 target
->state
= TARGET_HALTED
;
881 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
885 target
->state
= TARGET_RUNNING
;
887 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
892 static int stm8_halt(struct target
*target
)
894 LOG_DEBUG("target->state: %s", target_state_name(target
));
896 if (target
->state
== TARGET_HALTED
) {
897 LOG_DEBUG("target was already halted");
901 if (target
->state
== TARGET_UNKNOWN
)
902 LOG_WARNING("target was in unknown state when halt was requested");
904 if (target
->state
== TARGET_RESET
) {
905 /* we came here in a reset_halt or reset_init sequence
906 * debug entry was already prepared in stm8_assert_reset()
908 target
->debug_reason
= DBG_REASON_DBGRQ
;
914 /* break processor */
915 stm8_debug_stall(target
);
917 target
->debug_reason
= DBG_REASON_DBGRQ
;
922 static int stm8_reset_assert(struct target
*target
)
925 struct hl_interface_s
*adapter
= target_to_adapter(target
);
926 struct stm8_common
*stm8
= target_to_stm8(target
);
927 bool use_srst_fallback
= true;
929 enum reset_types jtag_reset_config
= jtag_get_reset_config();
931 if (jtag_reset_config
& RESET_HAS_SRST
) {
932 jtag_add_reset(0, 1);
933 res
= adapter
->layout
->api
->assert_srst(adapter
->handle
, 0);
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 struct hl_interface_s
*adapter
= target_to_adapter(target
);
970 enum reset_types jtag_reset_config
= jtag_get_reset_config();
972 if (jtag_reset_config
& RESET_HAS_SRST
) {
973 res
= adapter
->layout
->api
->assert_srst(adapter
->handle
, 1);
974 if ((res
!= ERROR_OK
) && (res
!= ERROR_COMMAND_NOTFOUND
))
978 /* virtual deassert reset, we need it for the internal
981 jtag_add_reset(0, 0);
983 /* The cpu should now be stalled. If halt was requested
984 let poll detect the stall */
985 if (target
->reset_halt
)
988 /* Instead of going thrugh saving context, polling and
989 then resuming target again just clear stall and proceed. */
990 target
->state
= TARGET_RUNNING
;
991 return stm8_exit_debug(target
);
994 /* stm8_single_step_core() is only used for stepping over breakpoints
995 from stm8_resume() */
996 static int stm8_single_step_core(struct target
*target
)
998 struct stm8_common
*stm8
= target_to_stm8(target
);
1000 /* configure single step mode */
1001 stm8_config_step(target
, 1);
1003 /* disable interrupts while stepping */
1004 if (!stm8
->enable_step_irq
)
1005 stm8_enable_interrupts(target
, 0);
1007 /* exit debug mode */
1008 stm8_exit_debug(target
);
1010 stm8_debug_entry(target
);
1015 static int stm8_resume(struct target
*target
, int current
,
1016 target_addr_t address
, int handle_breakpoints
,
1017 int debug_execution
)
1019 struct stm8_common
*stm8
= target_to_stm8(target
);
1020 struct breakpoint
*breakpoint
= NULL
;
1023 LOG_DEBUG("%d " TARGET_ADDR_FMT
" %d %d", current
, address
,
1024 handle_breakpoints
, debug_execution
);
1026 if (target
->state
!= TARGET_HALTED
) {
1027 LOG_WARNING("target not halted");
1028 return ERROR_TARGET_NOT_HALTED
;
1031 if (!debug_execution
) {
1032 target_free_all_working_areas(target
);
1033 stm8_enable_breakpoints(target
);
1034 stm8_enable_watchpoints(target
);
1035 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1036 stm8_set_hwbreak(target
, comparator_list
);
1039 /* current = 1: continue on current pc,
1040 otherwise continue at <address> */
1042 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1044 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1045 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1049 resume_pc
= address
;
1051 resume_pc
= buf_get_u32(
1052 stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1055 stm8_restore_context(target
);
1057 /* the front-end may request us not to handle breakpoints */
1058 if (handle_breakpoints
) {
1059 /* Single step past breakpoint at current address */
1060 breakpoint
= breakpoint_find(target
, resume_pc
);
1062 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
,
1063 breakpoint
->address
);
1064 stm8_unset_breakpoint(target
, breakpoint
);
1065 stm8_single_step_core(target
);
1066 stm8_set_breakpoint(target
, breakpoint
);
1070 /* disable interrupts if we are debugging */
1071 if (debug_execution
)
1072 stm8_enable_interrupts(target
, 0);
1074 /* exit debug mode */
1075 stm8_exit_debug(target
);
1076 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1078 /* registers are now invalid */
1079 register_cache_invalidate(stm8
->core_cache
);
1081 if (!debug_execution
) {
1082 target
->state
= TARGET_RUNNING
;
1083 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1084 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
1086 target
->state
= TARGET_DEBUG_RUNNING
;
1087 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1088 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
1094 static int stm8_init_flash_regs(bool enable_stm8l
, struct stm8_common
*stm8
)
1096 stm8
->enable_stm8l
= enable_stm8l
;
1098 if (stm8
->enable_stm8l
) {
1099 stm8
->flash_cr2
= FLASH_CR2_STM8L
;
1100 stm8
->flash_ncr2
= FLASH_NCR2_STM8L
;
1101 stm8
->flash_iapsr
= FLASH_IAPSR_STM8L
;
1102 stm8
->flash_dukr
= FLASH_DUKR_STM8L
;
1103 stm8
->flash_pukr
= FLASH_PUKR_STM8L
;
1105 stm8
->flash_cr2
= FLASH_CR2_STM8S
;
1106 stm8
->flash_ncr2
= FLASH_NCR2_STM8S
;
1107 stm8
->flash_iapsr
= FLASH_IAPSR_STM8S
;
1108 stm8
->flash_dukr
= FLASH_DUKR_STM8S
;
1109 stm8
->flash_pukr
= FLASH_PUKR_STM8S
;
1114 static int stm8_init_arch_info(struct target
*target
,
1115 struct stm8_common
*stm8
, struct jtag_tap
*tap
)
1117 target
->endianness
= TARGET_BIG_ENDIAN
;
1118 target
->arch_info
= stm8
;
1119 stm8
->common_magic
= STM8_COMMON_MAGIC
;
1120 stm8
->fast_data_area
= NULL
;
1121 stm8
->blocksize
= 0x80;
1122 stm8
->flashstart
= 0x8000;
1123 stm8
->flashend
= 0xffff;
1124 stm8
->eepromstart
= 0x4000;
1125 stm8
->eepromend
= 0x43ff;
1126 stm8
->optionstart
= 0x4800;
1127 stm8
->optionend
= 0x487F;
1129 /* has breakpoint/watchpoint unit been scanned */
1130 stm8
->bp_scanned
= false;
1131 stm8
->hw_break_list
= NULL
;
1133 stm8
->read_core_reg
= stm8_read_core_reg
;
1134 stm8
->write_core_reg
= stm8_write_core_reg
;
1136 stm8_init_flash_regs(0, stm8
);
1141 static int stm8_target_create(struct target
*target
,
1145 struct stm8_common
*stm8
= calloc(1, sizeof(struct stm8_common
));
1147 stm8_init_arch_info(target
, stm8
, target
->tap
);
1148 stm8_configure_break_unit(target
);
1153 static int stm8_read_core_reg(struct target
*target
, unsigned int num
)
1157 /* get pointers to arch-specific information */
1158 struct stm8_common
*stm8
= target_to_stm8(target
);
1160 if (num
>= STM8_NUM_REGS
)
1161 return ERROR_COMMAND_SYNTAX_ERROR
;
1163 reg_value
= stm8
->core_regs
[num
];
1164 LOG_DEBUG("read core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1165 buf_set_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
1166 stm8
->core_cache
->reg_list
[num
].valid
= true;
1167 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1172 static int stm8_write_core_reg(struct target
*target
, unsigned int num
)
1176 /* get pointers to arch-specific information */
1177 struct stm8_common
*stm8
= target_to_stm8(target
);
1179 if (num
>= STM8_NUM_REGS
)
1180 return ERROR_COMMAND_SYNTAX_ERROR
;
1182 reg_value
= buf_get_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32);
1183 stm8
->core_regs
[num
] = reg_value
;
1184 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1185 stm8
->core_cache
->reg_list
[num
].valid
= true;
1186 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1191 static int stm8_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1192 int *reg_list_size
, enum target_register_class reg_class
)
1194 /* get pointers to arch-specific information */
1195 struct stm8_common
*stm8
= target_to_stm8(target
);
1198 *reg_list_size
= STM8_NUM_REGS
;
1199 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1201 for (i
= 0; i
< STM8_NUM_REGS
; i
++)
1202 (*reg_list
)[i
] = &stm8
->core_cache
->reg_list
[i
];
1207 static const struct reg_arch_type stm8_reg_type
= {
1208 .get
= stm8_get_core_reg
,
1209 .set
= stm8_set_core_reg
,
1212 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
)
1214 /* get pointers to arch-specific information */
1215 struct stm8_common
*stm8
= target_to_stm8(target
);
1217 int num_regs
= STM8_NUM_REGS
;
1218 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1219 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1220 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1221 struct stm8_core_reg
*arch_info
= malloc(
1222 sizeof(struct stm8_core_reg
) * num_regs
);
1223 struct reg_feature
*feature
;
1226 /* Build the process context cache */
1227 cache
->name
= "stm8 registers";
1229 cache
->reg_list
= reg_list
;
1230 cache
->num_regs
= num_regs
;
1232 stm8
->core_cache
= cache
;
1234 for (i
= 0; i
< num_regs
; i
++) {
1235 arch_info
[i
].num
= stm8_regs
[i
].id
;
1236 arch_info
[i
].target
= target
;
1237 arch_info
[i
].stm8_common
= stm8
;
1239 reg_list
[i
].name
= stm8_regs
[i
].name
;
1240 reg_list
[i
].size
= stm8_regs
[i
].bits
;
1242 reg_list
[i
].value
= calloc(1, 4);
1243 reg_list
[i
].valid
= false;
1244 reg_list
[i
].type
= &stm8_reg_type
;
1245 reg_list
[i
].arch_info
= &arch_info
[i
];
1247 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1248 if (reg_list
[i
].reg_data_type
)
1249 reg_list
[i
].reg_data_type
->type
= stm8_regs
[i
].type
;
1251 LOG_ERROR("unable to allocate reg type list");
1255 reg_list
[i
].dirty
= false;
1256 reg_list
[i
].group
= stm8_regs
[i
].group
;
1257 reg_list
[i
].number
= stm8_regs
[i
].id
;
1258 reg_list
[i
].exist
= true;
1259 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1261 feature
= calloc(1, sizeof(struct reg_feature
));
1263 feature
->name
= stm8_regs
[i
].feature
;
1264 reg_list
[i
].feature
= feature
;
1266 LOG_ERROR("unable to allocate feature list");
1272 static void stm8_free_reg_cache(struct target
*target
)
1274 struct stm8_common
*stm8
= target_to_stm8(target
);
1275 struct reg_cache
*cache
;
1279 cache
= stm8
->core_cache
;
1284 for (i
= 0; i
< cache
->num_regs
; i
++) {
1285 reg
= &cache
->reg_list
[i
];
1288 free(reg
->reg_data_type
);
1292 free(cache
->reg_list
[0].arch_info
);
1293 free(cache
->reg_list
);
1296 stm8
->core_cache
= NULL
;
1299 static void stm8_deinit(struct target
*target
)
1301 struct stm8_common
*stm8
= target_to_stm8(target
);
1303 free(stm8
->hw_break_list
);
1305 stm8_free_reg_cache(target
);
1310 static int stm8_arch_state(struct target
*target
)
1312 struct stm8_common
*stm8
= target_to_stm8(target
);
1314 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
1315 debug_reason_name(target
),
1316 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1321 static int stm8_step(struct target
*target
, int current
,
1322 target_addr_t address
, int handle_breakpoints
)
1324 LOG_DEBUG("%" PRIx32
" " TARGET_ADDR_FMT
" %" PRIx32
,
1325 current
, address
, handle_breakpoints
);
1327 /* get pointers to arch-specific information */
1328 struct stm8_common
*stm8
= target_to_stm8(target
);
1329 struct breakpoint
*breakpoint
= NULL
;
1331 if (target
->state
!= TARGET_HALTED
) {
1332 LOG_WARNING("target not halted");
1333 return ERROR_TARGET_NOT_HALTED
;
1336 /* current = 1: continue on current pc, otherwise continue at <address> */
1338 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32, address
);
1339 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1340 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1343 /* the front-end may request us not to handle breakpoints */
1344 if (handle_breakpoints
) {
1345 breakpoint
= breakpoint_find(target
,
1346 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1348 stm8_unset_breakpoint(target
, breakpoint
);
1351 /* restore context */
1352 stm8_restore_context(target
);
1354 /* configure single step mode */
1355 stm8_config_step(target
, 1);
1357 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1359 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1361 /* disable interrupts while stepping */
1362 if (!stm8
->enable_step_irq
)
1363 stm8_enable_interrupts(target
, 0);
1365 /* exit debug mode */
1366 stm8_exit_debug(target
);
1368 /* registers are now invalid */
1369 register_cache_invalidate(stm8
->core_cache
);
1371 LOG_DEBUG("target stepped ");
1372 stm8_debug_entry(target
);
1375 stm8_set_breakpoint(target
, breakpoint
);
1377 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1382 static void stm8_enable_breakpoints(struct target
*target
)
1384 struct breakpoint
*breakpoint
= target
->breakpoints
;
1386 /* set any pending breakpoints */
1387 while (breakpoint
) {
1388 if (breakpoint
->set
== 0)
1389 stm8_set_breakpoint(target
, breakpoint
);
1390 breakpoint
= breakpoint
->next
;
1394 static int stm8_set_breakpoint(struct target
*target
,
1395 struct breakpoint
*breakpoint
)
1397 struct stm8_common
*stm8
= target_to_stm8(target
);
1398 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1401 if (breakpoint
->set
) {
1402 LOG_WARNING("breakpoint already set");
1406 if (breakpoint
->type
== BKPT_HARD
) {
1409 while (comparator_list
[bp_num
].used
&& (bp_num
< stm8
->num_hw_bpoints
))
1411 if (bp_num
>= stm8
->num_hw_bpoints
) {
1412 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32
")",
1413 breakpoint
->unique_id
);
1414 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1416 breakpoint
->set
= bp_num
+ 1;
1417 comparator_list
[bp_num
].used
= true;
1418 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
1419 comparator_list
[bp_num
].type
= HWBRK_EXEC
;
1421 retval
= stm8_set_hwbreak(target
, comparator_list
);
1422 if (retval
!= ERROR_OK
)
1425 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1426 breakpoint
->unique_id
,
1427 bp_num
, comparator_list
[bp_num
].bp_value
);
1428 } else if (breakpoint
->type
== BKPT_SOFT
) {
1429 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1430 if (breakpoint
->length
== 1) {
1431 uint8_t verify
= 0x55;
1433 retval
= target_read_u8(target
, breakpoint
->address
,
1434 breakpoint
->orig_instr
);
1435 if (retval
!= ERROR_OK
)
1437 retval
= target_write_u8(target
, breakpoint
->address
, STM8_BREAK
);
1438 if (retval
!= ERROR_OK
)
1441 retval
= target_read_u8(target
, breakpoint
->address
, &verify
);
1442 if (retval
!= ERROR_OK
)
1444 if (verify
!= STM8_BREAK
) {
1445 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1446 " - check that memory is read/writable",
1447 breakpoint
->address
);
1448 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1451 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1453 breakpoint
->set
= 1; /* Any nice value but 0 */
1459 static int stm8_add_breakpoint(struct target
*target
,
1460 struct breakpoint
*breakpoint
)
1462 struct stm8_common
*stm8
= target_to_stm8(target
);
1465 if (breakpoint
->type
== BKPT_HARD
) {
1466 if (stm8
->num_hw_bpoints_avail
< 1) {
1467 LOG_INFO("no hardware breakpoint available");
1468 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1471 ret
= stm8_set_breakpoint(target
, breakpoint
);
1472 if (ret
!= ERROR_OK
)
1475 stm8
->num_hw_bpoints_avail
--;
1479 ret
= stm8_set_breakpoint(target
, breakpoint
);
1480 if (ret
!= ERROR_OK
)
1486 static int stm8_unset_breakpoint(struct target
*target
,
1487 struct breakpoint
*breakpoint
)
1489 /* get pointers to arch-specific information */
1490 struct stm8_common
*stm8
= target_to_stm8(target
);
1491 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1494 if (!breakpoint
->set
) {
1495 LOG_WARNING("breakpoint not set");
1499 if (breakpoint
->type
== BKPT_HARD
) {
1500 int bp_num
= breakpoint
->set
- 1;
1501 if ((bp_num
< 0) || (bp_num
>= stm8
->num_hw_bpoints
)) {
1502 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1503 breakpoint
->unique_id
);
1506 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d",
1507 breakpoint
->unique_id
,
1509 comparator_list
[bp_num
].used
= false;
1510 retval
= stm8_set_hwbreak(target
, comparator_list
);
1511 if (retval
!= ERROR_OK
)
1514 /* restore original instruction (kept in target endianness) */
1515 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1516 if (breakpoint
->length
== 1) {
1517 uint8_t current_instr
;
1519 /* check that user program has not
1520 modified breakpoint instruction */
1521 retval
= target_read_memory(target
, breakpoint
->address
, 1, 1,
1522 (uint8_t *)¤t_instr
);
1523 if (retval
!= ERROR_OK
)
1526 if (current_instr
== STM8_BREAK
) {
1527 retval
= target_write_memory(target
, breakpoint
->address
, 1, 1,
1528 breakpoint
->orig_instr
);
1529 if (retval
!= ERROR_OK
)
1535 breakpoint
->set
= 0;
1540 static int stm8_remove_breakpoint(struct target
*target
,
1541 struct breakpoint
*breakpoint
)
1543 /* get pointers to arch-specific information */
1544 struct stm8_common
*stm8
= target_to_stm8(target
);
1546 if (target
->state
!= TARGET_HALTED
) {
1547 LOG_WARNING("target not halted");
1548 return ERROR_TARGET_NOT_HALTED
;
1551 if (breakpoint
->set
)
1552 stm8_unset_breakpoint(target
, breakpoint
);
1554 if (breakpoint
->type
== BKPT_HARD
)
1555 stm8
->num_hw_bpoints_avail
++;
1560 static int stm8_set_watchpoint(struct target
*target
,
1561 struct watchpoint
*watchpoint
)
1563 struct stm8_common
*stm8
= target_to_stm8(target
);
1564 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1568 if (watchpoint
->set
) {
1569 LOG_WARNING("watchpoint already set");
1573 while (comparator_list
[wp_num
].used
&& (wp_num
< stm8
->num_hw_bpoints
))
1575 if (wp_num
>= stm8
->num_hw_bpoints
) {
1576 LOG_ERROR("Can not find free hw breakpoint");
1577 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1580 if (watchpoint
->length
!= 1) {
1581 LOG_ERROR("Only watchpoints of length 1 are supported");
1582 return ERROR_TARGET_UNALIGNED_ACCESS
;
1585 enum hw_break_type enable
= 0;
1587 switch (watchpoint
->rw
) {
1598 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1601 comparator_list
[wp_num
].used
= true;
1602 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
1603 comparator_list
[wp_num
].type
= enable
;
1605 ret
= stm8_set_hwbreak(target
, comparator_list
);
1606 if (ret
!= ERROR_OK
) {
1607 comparator_list
[wp_num
].used
= false;
1611 watchpoint
->set
= wp_num
+ 1;
1613 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"",
1615 comparator_list
[wp_num
].bp_value
);
1620 static int stm8_add_watchpoint(struct target
*target
,
1621 struct watchpoint
*watchpoint
)
1624 struct stm8_common
*stm8
= target_to_stm8(target
);
1626 if (stm8
->num_hw_bpoints_avail
< 1) {
1627 LOG_INFO("no hardware watchpoints available");
1628 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1631 ret
= stm8_set_watchpoint(target
, watchpoint
);
1632 if (ret
!= ERROR_OK
)
1635 stm8
->num_hw_bpoints_avail
--;
1639 static void stm8_enable_watchpoints(struct target
*target
)
1641 struct watchpoint
*watchpoint
= target
->watchpoints
;
1643 /* set any pending watchpoints */
1644 while (watchpoint
) {
1645 if (watchpoint
->set
== 0)
1646 stm8_set_watchpoint(target
, watchpoint
);
1647 watchpoint
= watchpoint
->next
;
1651 static int stm8_unset_watchpoint(struct target
*target
,
1652 struct watchpoint
*watchpoint
)
1654 /* get pointers to arch-specific information */
1655 struct stm8_common
*stm8
= target_to_stm8(target
);
1656 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1658 if (!watchpoint
->set
) {
1659 LOG_WARNING("watchpoint not set");
1663 int wp_num
= watchpoint
->set
- 1;
1664 if ((wp_num
< 0) || (wp_num
>= stm8
->num_hw_bpoints
)) {
1665 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1668 comparator_list
[wp_num
].used
= false;
1669 watchpoint
->set
= 0;
1671 stm8_set_hwbreak(target
, comparator_list
);
1676 static int stm8_remove_watchpoint(struct target
*target
,
1677 struct watchpoint
*watchpoint
)
1679 /* get pointers to arch-specific information */
1680 struct stm8_common
*stm8
= target_to_stm8(target
);
1682 if (target
->state
!= TARGET_HALTED
) {
1683 LOG_WARNING("target not halted");
1684 return ERROR_TARGET_NOT_HALTED
;
1687 if (watchpoint
->set
)
1688 stm8_unset_watchpoint(target
, watchpoint
);
1690 stm8
->num_hw_bpoints_avail
++;
1695 static int stm8_examine(struct target
*target
)
1699 /* get pointers to arch-specific information */
1700 struct stm8_common
*stm8
= target_to_stm8(target
);
1701 struct hl_interface_s
*adapter
= target_to_adapter(target
);
1703 if (!target_was_examined(target
)) {
1704 if (!stm8
->swim_configured
) {
1705 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1706 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1707 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
);
1708 if (retval
!= ERROR_OK
)
1710 /* set high speed */
1711 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1712 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
+ HS
);
1713 if (retval
!= ERROR_OK
)
1715 retval
= stm8_set_speed(target
, 1);
1716 if (retval
== ERROR_OK
)
1717 stm8
->swim_configured
= true;
1719 Now is the time to deassert reset if connect_under_reset.
1720 Releasing reset line will cause the option bytes to load.
1721 The core will still be stalled.
1723 if (adapter
->param
.connect_under_reset
)
1724 stm8_reset_deassert(target
);
1726 LOG_INFO("trying to reconnect");
1728 retval
= adapter
->layout
->api
->state(adapter
->handle
);
1729 if (retval
!= ERROR_OK
) {
1730 LOG_ERROR("reconnect failed");
1734 /* read dm_csrx control regs */
1735 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
1736 if (retval
!= ERROR_OK
) {
1737 LOG_ERROR("state query failed");
1742 target_set_examined(target
);
1750 /** Checks whether a memory region is erased. */
1751 static int stm8_blank_check_memory(struct target
*target
,
1752 target_addr_t address
, uint32_t count
, uint32_t *blank
, uint8_t erased_value
)
1754 struct working_area
*erase_check_algorithm
;
1755 struct reg_param reg_params
[2];
1756 struct mem_param mem_params
[2];
1757 struct stm8_algorithm stm8_info
;
1759 static const uint8_t stm8_erase_check_code
[] = {
1760 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1763 if (erased_value
!= 0xff) {
1764 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for STM8",
1769 /* make sure we have a working area */
1770 if (target_alloc_working_area(target
, sizeof(stm8_erase_check_code
),
1771 &erase_check_algorithm
) != ERROR_OK
)
1772 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1774 target_write_buffer(target
, erase_check_algorithm
->address
,
1775 sizeof(stm8_erase_check_code
), stm8_erase_check_code
);
1777 stm8_info
.common_magic
= STM8_COMMON_MAGIC
;
1779 init_mem_param(&mem_params
[0], 0x0, 3, PARAM_OUT
);
1780 buf_set_u32(mem_params
[0].value
, 0, 24, address
);
1782 init_mem_param(&mem_params
[1], 0x3, 3, PARAM_OUT
);
1783 buf_set_u32(mem_params
[1].value
, 0, 24, count
);
1785 init_reg_param(®_params
[0], "a", 32, PARAM_IN_OUT
);
1786 buf_set_u32(reg_params
[0].value
, 0, 32, erased_value
);
1788 init_reg_param(®_params
[1], "sp", 32, PARAM_OUT
);
1789 buf_set_u32(reg_params
[1].value
, 0, 32, erase_check_algorithm
->address
);
1791 int retval
= target_run_algorithm(target
, 2, mem_params
, 2, reg_params
,
1792 erase_check_algorithm
->address
+ 6,
1793 erase_check_algorithm
->address
+ (sizeof(stm8_erase_check_code
) - 1),
1796 if (retval
== ERROR_OK
)
1797 *blank
= (*(reg_params
[0].value
) == 0xff);
1799 destroy_mem_param(&mem_params
[0]);
1800 destroy_mem_param(&mem_params
[1]);
1801 destroy_reg_param(®_params
[0]);
1803 target_free_working_area(target
, erase_check_algorithm
);
1808 static int stm8_checksum_memory(struct target
*target
, target_addr_t address
,
1809 uint32_t count
, uint32_t *checksum
)
1811 /* let image_calculate_checksum() take care of business */
1812 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1815 /* run to exit point. return error if exit point was not reached. */
1816 static int stm8_run_and_wait(struct target
*target
, uint32_t entry_point
,
1817 int timeout_ms
, uint32_t exit_point
, struct stm8_common
*stm8
)
1821 /* This code relies on the target specific resume() and
1822 poll()->debug_entry() sequence to write register values to the
1823 processor and the read them back */
1824 retval
= target_resume(target
, 0, entry_point
, 0, 1);
1825 if (retval
!= ERROR_OK
)
1828 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1829 /* If the target fails to halt due to the breakpoint, force a halt */
1830 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
1831 retval
= target_halt(target
);
1832 if (retval
!= ERROR_OK
)
1834 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
1835 if (retval
!= ERROR_OK
)
1837 return ERROR_TARGET_TIMEOUT
;
1840 pc
= buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32);
1841 if (exit_point
&& (pc
!= exit_point
)) {
1842 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
1843 return ERROR_TARGET_TIMEOUT
;
1849 static int stm8_run_algorithm(struct target
*target
, int num_mem_params
,
1850 struct mem_param
*mem_params
, int num_reg_params
,
1851 struct reg_param
*reg_params
, target_addr_t entry_point
,
1852 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
1854 struct stm8_common
*stm8
= target_to_stm8(target
);
1856 uint32_t context
[STM8_NUM_REGS
];
1857 int retval
= ERROR_OK
;
1859 LOG_DEBUG("Running algorithm");
1861 /* NOTE: stm8_run_algorithm requires that each
1862 algorithm uses a software breakpoint
1863 at the exit point */
1865 if (stm8
->common_magic
!= STM8_COMMON_MAGIC
) {
1866 LOG_ERROR("current target isn't a STM8 target");
1867 return ERROR_TARGET_INVALID
;
1870 if (target
->state
!= TARGET_HALTED
) {
1871 LOG_WARNING("target not halted");
1872 return ERROR_TARGET_NOT_HALTED
;
1875 /* refresh core register cache */
1876 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1877 if (!stm8
->core_cache
->reg_list
[i
].valid
)
1878 stm8
->read_core_reg(target
, i
);
1879 context
[i
] = buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1882 for (int i
= 0; i
< num_mem_params
; i
++) {
1883 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1884 mem_params
[i
].size
, mem_params
[i
].value
);
1885 if (retval
!= ERROR_OK
)
1889 for (int i
= 0; i
< num_reg_params
; i
++) {
1890 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1891 reg_params
[i
].reg_name
, 0);
1894 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1895 return ERROR_COMMAND_SYNTAX_ERROR
;
1898 if (reg_params
[i
].size
!= 32) {
1899 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1900 reg_params
[i
].reg_name
);
1901 return ERROR_COMMAND_SYNTAX_ERROR
;
1904 stm8_set_core_reg(reg
, reg_params
[i
].value
);
1907 retval
= stm8_run_and_wait(target
, entry_point
,
1908 timeout_ms
, exit_point
, stm8
);
1910 if (retval
!= ERROR_OK
)
1913 for (int i
= 0; i
< num_mem_params
; i
++) {
1914 if (mem_params
[i
].direction
!= PARAM_OUT
) {
1915 retval
= target_read_buffer(target
, mem_params
[i
].address
,
1916 mem_params
[i
].size
, mem_params
[i
].value
);
1917 if (retval
!= ERROR_OK
)
1922 for (int i
= 0; i
< num_reg_params
; i
++) {
1923 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1924 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1925 reg_params
[i
].reg_name
, 0);
1927 LOG_ERROR("BUG: register '%s' not found",
1928 reg_params
[i
].reg_name
);
1929 return ERROR_COMMAND_SYNTAX_ERROR
;
1932 if (reg_params
[i
].size
!= 32) {
1933 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1934 reg_params
[i
].reg_name
);
1935 return ERROR_COMMAND_SYNTAX_ERROR
;
1938 buf_set_u32(reg_params
[i
].value
,
1939 0, 32, buf_get_u32(reg
->value
, 0, 32));
1943 /* restore everything we saved before */
1944 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1946 regvalue
= buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1947 if (regvalue
!= context
[i
]) {
1948 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
1949 stm8
->core_cache
->reg_list
[i
].name
, context
[i
]);
1950 buf_set_u32(stm8
->core_cache
->reg_list
[i
].value
,
1952 stm8
->core_cache
->reg_list
[i
].valid
= true;
1953 stm8
->core_cache
->reg_list
[i
].dirty
= true;
1960 int stm8_jim_configure(struct target
*target
, Jim_GetOptInfo
*goi
)
1962 struct stm8_common
*stm8
= target_to_stm8(target
);
1967 arg
= Jim_GetString(goi
->argv
[0], NULL
);
1968 if (!strcmp(arg
, "-blocksize")) {
1969 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1973 if (goi
->argc
== 0) {
1974 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1975 "-blocksize ?bytes? ...");
1979 e
= Jim_GetOpt_Wide(goi
, &w
);
1983 stm8
->blocksize
= w
;
1984 LOG_DEBUG("blocksize=%8.8x", stm8
->blocksize
);
1987 if (!strcmp(arg
, "-flashstart")) {
1988 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1992 if (goi
->argc
== 0) {
1993 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1994 "-flashstart ?address? ...");
1998 e
= Jim_GetOpt_Wide(goi
, &w
);
2002 stm8
->flashstart
= w
;
2003 LOG_DEBUG("flashstart=%8.8x", stm8
->flashstart
);
2006 if (!strcmp(arg
, "-flashend")) {
2007 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2011 if (goi
->argc
== 0) {
2012 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2013 "-flashend ?address? ...");
2017 e
= Jim_GetOpt_Wide(goi
, &w
);
2022 LOG_DEBUG("flashend=%8.8x", stm8
->flashend
);
2025 if (!strcmp(arg
, "-eepromstart")) {
2026 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2030 if (goi
->argc
== 0) {
2031 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2032 "-eepromstart ?address? ...");
2036 e
= Jim_GetOpt_Wide(goi
, &w
);
2040 stm8
->eepromstart
= w
;
2041 LOG_DEBUG("eepromstart=%8.8x", stm8
->eepromstart
);
2044 if (!strcmp(arg
, "-eepromend")) {
2045 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2049 if (goi
->argc
== 0) {
2050 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2051 "-eepromend ?address? ...");
2055 e
= Jim_GetOpt_Wide(goi
, &w
);
2059 stm8
->eepromend
= w
;
2060 LOG_DEBUG("eepromend=%8.8x", stm8
->eepromend
);
2063 if (!strcmp(arg
, "-optionstart")) {
2064 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2068 if (goi
->argc
== 0) {
2069 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2070 "-optionstart ?address? ...");
2074 e
= Jim_GetOpt_Wide(goi
, &w
);
2078 stm8
->optionstart
= w
;
2079 LOG_DEBUG("optionstart=%8.8x", stm8
->optionstart
);
2082 if (!strcmp(arg
, "-optionend")) {
2083 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2087 if (goi
->argc
== 0) {
2088 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2089 "-optionend ?address? ...");
2093 e
= Jim_GetOpt_Wide(goi
, &w
);
2097 stm8
->optionend
= w
;
2098 LOG_DEBUG("optionend=%8.8x", stm8
->optionend
);
2101 if (!strcmp(arg
, "-enable_step_irq")) {
2102 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2106 stm8
->enable_step_irq
= true;
2107 LOG_DEBUG("enable_step_irq=%8.8x", stm8
->enable_step_irq
);
2110 if (!strcmp(arg
, "-enable_stm8l")) {
2111 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2115 stm8
->enable_stm8l
= true;
2116 LOG_DEBUG("enable_stm8l=%8.8x", stm8
->enable_stm8l
);
2117 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2120 return JIM_CONTINUE
;
2123 COMMAND_HANDLER(stm8_handle_enable_step_irq_command
)
2126 struct target
*target
= get_current_target(CMD_CTX
);
2127 struct stm8_common
*stm8
= target_to_stm8(target
);
2128 bool enable
= stm8
->enable_step_irq
;
2131 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2132 stm8
->enable_step_irq
= enable
;
2134 msg
= stm8
->enable_step_irq
? "enabled" : "disabled";
2135 command_print(CMD_CTX
, "enable_step_irq = %s", msg
);
2139 COMMAND_HANDLER(stm8_handle_enable_stm8l_command
)
2142 struct target
*target
= get_current_target(CMD_CTX
);
2143 struct stm8_common
*stm8
= target_to_stm8(target
);
2144 bool enable
= stm8
->enable_stm8l
;
2147 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2148 stm8
->enable_stm8l
= enable
;
2150 msg
= stm8
->enable_stm8l
? "enabled" : "disabled";
2151 command_print(CMD_CTX
, "enable_stm8l = %s", msg
);
2152 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2156 static const struct command_registration stm8_exec_command_handlers
[] = {
2158 .name
= "enable_step_irq",
2159 .handler
= stm8_handle_enable_step_irq_command
,
2160 .mode
= COMMAND_ANY
,
2161 .help
= "Enable/disable irq handling during step",
2165 .name
= "enable_stm8l",
2166 .handler
= stm8_handle_enable_stm8l_command
,
2167 .mode
= COMMAND_ANY
,
2168 .help
= "Enable/disable STM8L flash programming",
2171 COMMAND_REGISTRATION_DONE
2174 const struct command_registration stm8_command_handlers
[] = {
2177 .mode
= COMMAND_ANY
,
2178 .help
= "stm8 command group",
2180 .chain
= stm8_exec_command_handlers
,
2182 COMMAND_REGISTRATION_DONE
2185 struct target_type stm8_target
= {
2189 .arch_state
= stm8_arch_state
,
2192 .resume
= stm8_resume
,
2195 .assert_reset
= stm8_reset_assert
,
2196 .deassert_reset
= stm8_reset_deassert
,
2198 .get_gdb_reg_list
= stm8_get_gdb_reg_list
,
2200 .read_memory
= stm8_read_memory
,
2201 .write_memory
= stm8_write_memory
,
2202 .checksum_memory
= stm8_checksum_memory
,
2203 .blank_check_memory
= stm8_blank_check_memory
,
2205 .run_algorithm
= stm8_run_algorithm
,
2207 .add_breakpoint
= stm8_add_breakpoint
,
2208 .remove_breakpoint
= stm8_remove_breakpoint
,
2209 .add_watchpoint
= stm8_add_watchpoint
,
2210 .remove_watchpoint
= stm8_remove_watchpoint
,
2212 .commands
= stm8_command_handlers
,
2213 .target_create
= stm8_target_create
,
2214 .init_target
= stm8_init
,
2215 .examine
= stm8_examine
,
2217 .deinit_target
= stm8_deinit
,
2218 .target_jim_configure
= stm8_jim_configure
,