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 if (retval
== ERROR_OK
)
481 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
483 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
484 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
486 if (retval
!= ERROR_OK
)
490 /* halted on reset */
491 target
->debug_reason
= DBG_REASON_UNDEFINED
;
493 if (csr1
& (BK1F
+BK2F
))
494 /* we have halted on a breakpoint (or wp)*/
495 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
498 /* we have halted on a breakpoint */
499 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
506 static int stm8_debug_entry(struct target
*target
)
508 struct stm8_common
*stm8
= target_to_stm8(target
);
510 /* restore interrupts */
511 stm8_enable_interrupts(target
, 1);
513 stm8_save_context(target
);
515 /* make sure stepping disabled STE bit in CSR1 cleared */
516 stm8_config_step(target
, 0);
518 /* attempt to find halt reason */
519 stm8_examine_debug_reason(target
);
521 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
522 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32),
523 target_state_name(target
));
528 /* clear stall flag in DM and flush instruction pipe */
529 static int stm8_exit_debug(struct target
*target
)
534 ret
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
538 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
544 ret
= stm8_write_u8(target
, DM_CSR2
, csr2
);
550 static int stm8_read_regs(struct target
*target
, uint32_t regs
[])
555 ret
= stm8_adapter_read_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
559 regs
[0] = be_to_h_u24(buf
+DM_REG_PC
-DM_REGS
);
560 regs
[1] = buf
[DM_REG_A
-DM_REGS
];
561 regs
[2] = be_to_h_u16(buf
+DM_REG_X
-DM_REGS
);
562 regs
[3] = be_to_h_u16(buf
+DM_REG_Y
-DM_REGS
);
563 regs
[4] = be_to_h_u16(buf
+DM_REG_SP
-DM_REGS
);
564 regs
[5] = buf
[DM_REG_CC
-DM_REGS
];
569 static int stm8_write_regs(struct target
*target
, uint32_t regs
[])
574 h_u24_to_be(buf
+DM_REG_PC
-DM_REGS
, regs
[0]);
575 buf
[DM_REG_A
-DM_REGS
] = regs
[1];
576 h_u16_to_be(buf
+DM_REG_X
-DM_REGS
, regs
[2]);
577 h_u16_to_be(buf
+DM_REG_Y
-DM_REGS
, regs
[3]);
578 h_u16_to_be(buf
+DM_REG_SP
-DM_REGS
, regs
[4]);
579 buf
[DM_REG_CC
-DM_REGS
] = regs
[5];
581 ret
= stm8_adapter_write_memory(target
, DM_REGS
, 1, sizeof(buf
), buf
);
588 static int stm8_get_core_reg(struct reg
*reg
)
591 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
592 struct target
*target
= stm8_reg
->target
;
593 struct stm8_common
*stm8_target
= target_to_stm8(target
);
595 if (target
->state
!= TARGET_HALTED
)
596 return ERROR_TARGET_NOT_HALTED
;
598 retval
= stm8_target
->read_core_reg(target
, stm8_reg
->num
);
603 static int stm8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
605 struct stm8_core_reg
*stm8_reg
= reg
->arch_info
;
606 struct target
*target
= stm8_reg
->target
;
607 uint32_t value
= buf_get_u32(buf
, 0, reg
->size
);
609 if (target
->state
!= TARGET_HALTED
)
610 return ERROR_TARGET_NOT_HALTED
;
612 buf_set_u32(reg
->value
, 0, 32, value
);
619 static int stm8_save_context(struct target
*target
)
623 /* get pointers to arch-specific information */
624 struct stm8_common
*stm8
= target_to_stm8(target
);
626 /* read core registers */
627 stm8_read_regs(target
, stm8
->core_regs
);
629 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
630 if (!stm8
->core_cache
->reg_list
[i
].valid
)
631 stm8
->read_core_reg(target
, i
);
637 static int stm8_restore_context(struct target
*target
)
641 /* get pointers to arch-specific information */
642 struct stm8_common
*stm8
= target_to_stm8(target
);
644 for (i
= 0; i
< STM8_NUM_REGS
; i
++) {
645 if (stm8
->core_cache
->reg_list
[i
].dirty
)
646 stm8
->write_core_reg(target
, i
);
649 /* write core regs */
650 stm8_write_regs(target
, stm8
->core_regs
);
655 static int stm8_unlock_flash(struct target
*target
)
659 struct stm8_common
*stm8
= target_to_stm8(target
);
661 /* check if flash is unlocked */
662 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
663 if (~data
[0] & PUL
) {
665 stm8_write_u8(target
, stm8
->flash_pukr
, 0x56);
666 stm8_write_u8(target
, stm8
->flash_pukr
, 0xae);
669 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
675 static int stm8_unlock_eeprom(struct target
*target
)
679 struct stm8_common
*stm8
= target_to_stm8(target
);
681 /* check if eeprom is unlocked */
682 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
683 if (~data
[0] & DUL
) {
685 stm8_write_u8(target
, stm8
->flash_dukr
, 0xae);
686 stm8_write_u8(target
, stm8
->flash_dukr
, 0x56);
689 stm8_read_u8(target
, stm8
->flash_iapsr
, data
);
695 static int stm8_write_flash(struct target
*target
, enum mem_type type
,
697 uint32_t size
, uint32_t count
, uint32_t blocksize_param
,
698 const uint8_t *buffer
)
700 struct stm8_common
*stm8
= target_to_stm8(target
);
705 uint32_t blocksize
= 0;
711 stm8_unlock_flash(target
);
714 stm8_unlock_eeprom(target
);
717 stm8_unlock_eeprom(target
);
721 LOG_ERROR("BUG: wrong mem_type %d", type
);
726 /* we don't support short writes */
731 bytecnt
= count
* size
;
734 if ((bytecnt
>= blocksize_param
) && ((address
& (blocksize_param
-1)) == 0)) {
736 stm8_write_u8(target
, stm8
->flash_cr2
, PRG
+ opt
);
737 if (stm8
->flash_ncr2
)
738 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(PRG
+ opt
));
739 blocksize
= blocksize_param
;
741 if ((bytecnt
>= 4) && ((address
& 0x3) == 0)) {
743 stm8_write_u8(target
, stm8
->flash_cr2
, WPRG
+ opt
);
744 if (stm8
->flash_ncr2
)
745 stm8_write_u8(target
, stm8
->flash_ncr2
, ~(WPRG
+ opt
));
748 if (blocksize
!= 1) {
750 stm8_write_u8(target
, stm8
->flash_cr2
, opt
);
751 if (stm8
->flash_ncr2
)
752 stm8_write_u8(target
, stm8
->flash_ncr2
, ~opt
);
756 res
= stm8_adapter_write_memory(target
, address
, 1, blocksize
, buffer
);
759 address
+= blocksize
;
761 bytecnt
-= blocksize
;
763 /* lets hang here until end of program (EOP) */
764 for (i
= 0; i
< 16; i
++) {
765 stm8_read_u8(target
, stm8
->flash_iapsr
, &iapsr
);
775 /* disable write access */
776 res
= stm8_write_u8(target
, stm8
->flash_iapsr
, 0x0);
784 static int stm8_write_memory(struct target
*target
, target_addr_t address
,
785 uint32_t size
, uint32_t count
,
786 const uint8_t *buffer
)
788 struct stm8_common
*stm8
= target_to_stm8(target
);
790 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
791 ", size: 0x%8.8" PRIx32
792 ", count: 0x%8.8" PRIx32
,
793 address
, size
, count
);
795 if (target
->state
!= TARGET_HALTED
)
796 LOG_WARNING("target not halted");
800 if ((address
>= stm8
->flashstart
) && (address
<= stm8
->flashend
))
801 retval
= stm8_write_flash(target
, FLASH
, address
, size
, count
,
802 stm8
->blocksize
, buffer
);
803 else if ((address
>= stm8
->eepromstart
) && (address
<= stm8
->eepromend
))
804 retval
= stm8_write_flash(target
, EEPROM
, address
, size
, count
,
805 stm8
->blocksize
, buffer
);
806 else if ((address
>= stm8
->optionstart
) && (address
<= stm8
->optionend
))
807 retval
= stm8_write_flash(target
, OPTION
, address
, size
, count
, 0, buffer
);
809 retval
= stm8_adapter_write_memory(target
, address
, size
, count
,
812 if (retval
!= ERROR_OK
)
813 return ERROR_TARGET_FAILURE
;
818 static int stm8_read_memory(struct target
*target
, target_addr_t address
,
819 uint32_t size
, uint32_t count
, uint8_t *buffer
)
821 LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR
822 ", size: 0x%8.8" PRIx32
823 ", count: 0x%8.8" PRIx32
,
824 address
, size
, count
);
826 if (target
->state
!= TARGET_HALTED
)
827 LOG_WARNING("target not halted");
830 retval
= stm8_adapter_read_memory(target
, address
, size
, count
, buffer
);
832 if (retval
!= ERROR_OK
)
833 return ERROR_TARGET_FAILURE
;
838 static int stm8_init(struct command_context
*cmd_ctx
, struct target
*target
)
840 stm8_build_reg_cache(target
);
845 static int stm8_poll(struct target
*target
)
847 int retval
= ERROR_OK
;
851 LOG_DEBUG("target->state=%d", target
->state
);
854 /* read dm_csrx control regs */
855 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
856 if (retval
!= ERROR_OK
) {
857 LOG_DEBUG("stm8_read_dm_csrx failed retval=%d", retval
);
859 We return ERROR_OK here even if we didn't get an answer.
860 openocd will call target_wait_state until we get target state TARGET_HALTED
865 /* check for processor halted */
867 if (target
->state
!= TARGET_HALTED
) {
868 if (target
->state
== TARGET_UNKNOWN
)
869 LOG_DEBUG("DM_CSR2_STALL already set during server startup.");
871 retval
= stm8_debug_entry(target
);
872 if (retval
!= ERROR_OK
) {
873 LOG_DEBUG("stm8_debug_entry failed retval=%d", retval
);
874 return ERROR_TARGET_FAILURE
;
877 if (target
->state
== TARGET_DEBUG_RUNNING
) {
878 target
->state
= TARGET_HALTED
;
879 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
881 target
->state
= TARGET_HALTED
;
882 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
886 target
->state
= TARGET_RUNNING
;
888 LOG_DEBUG("csr1 = 0x%02X csr2 = 0x%02X", csr1
, csr2
);
893 static int stm8_halt(struct target
*target
)
895 LOG_DEBUG("target->state: %s", target_state_name(target
));
897 if (target
->state
== TARGET_HALTED
) {
898 LOG_DEBUG("target was already halted");
902 if (target
->state
== TARGET_UNKNOWN
)
903 LOG_WARNING("target was in unknown state when halt was requested");
905 if (target
->state
== TARGET_RESET
) {
906 /* we came here in a reset_halt or reset_init sequence
907 * debug entry was already prepared in stm8_assert_reset()
909 target
->debug_reason
= DBG_REASON_DBGRQ
;
915 /* break processor */
916 stm8_debug_stall(target
);
918 target
->debug_reason
= DBG_REASON_DBGRQ
;
923 static int stm8_reset_assert(struct target
*target
)
926 struct hl_interface_s
*adapter
= target_to_adapter(target
);
927 struct stm8_common
*stm8
= target_to_stm8(target
);
928 bool use_srst_fallback
= true;
930 enum reset_types jtag_reset_config
= jtag_get_reset_config();
932 if (jtag_reset_config
& RESET_HAS_SRST
) {
933 jtag_add_reset(0, 1);
934 res
= adapter
->layout
->api
->assert_srst(adapter
->handle
, 0);
937 /* hardware srst supported */
938 use_srst_fallback
= false;
939 else if (res
!= ERROR_COMMAND_NOTFOUND
)
940 /* some other failure */
944 if (use_srst_fallback
) {
945 LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
946 res
= adapter
->layout
->api
->reset(adapter
->handle
);
951 /* registers are now invalid */
952 register_cache_invalidate(stm8
->core_cache
);
954 target
->state
= TARGET_RESET
;
955 target
->debug_reason
= DBG_REASON_NOTHALTED
;
957 if (target
->reset_halt
) {
958 res
= target_halt(target
);
966 static int stm8_reset_deassert(struct target
*target
)
969 struct hl_interface_s
*adapter
= target_to_adapter(target
);
971 enum reset_types jtag_reset_config
= jtag_get_reset_config();
973 if (jtag_reset_config
& RESET_HAS_SRST
) {
974 res
= adapter
->layout
->api
->assert_srst(adapter
->handle
, 1);
975 if ((res
!= ERROR_OK
) && (res
!= ERROR_COMMAND_NOTFOUND
))
979 /* virtual deassert reset, we need it for the internal
982 jtag_add_reset(0, 0);
984 /* The cpu should now be stalled. If halt was requested
985 let poll detect the stall */
986 if (target
->reset_halt
)
989 /* Instead of going thrugh saving context, polling and
990 then resuming target again just clear stall and proceed. */
991 target
->state
= TARGET_RUNNING
;
992 return stm8_exit_debug(target
);
995 /* stm8_single_step_core() is only used for stepping over breakpoints
996 from stm8_resume() */
997 static int stm8_single_step_core(struct target
*target
)
999 struct stm8_common
*stm8
= target_to_stm8(target
);
1001 /* configure single step mode */
1002 stm8_config_step(target
, 1);
1004 /* disable interrupts while stepping */
1005 if (!stm8
->enable_step_irq
)
1006 stm8_enable_interrupts(target
, 0);
1008 /* exit debug mode */
1009 stm8_exit_debug(target
);
1011 stm8_debug_entry(target
);
1016 static int stm8_resume(struct target
*target
, int current
,
1017 target_addr_t address
, int handle_breakpoints
,
1018 int debug_execution
)
1020 struct stm8_common
*stm8
= target_to_stm8(target
);
1021 struct breakpoint
*breakpoint
= NULL
;
1024 LOG_DEBUG("%d " TARGET_ADDR_FMT
" %d %d", current
, address
,
1025 handle_breakpoints
, debug_execution
);
1027 if (target
->state
!= TARGET_HALTED
) {
1028 LOG_WARNING("target not halted");
1029 return ERROR_TARGET_NOT_HALTED
;
1032 if (!debug_execution
) {
1033 target_free_all_working_areas(target
);
1034 stm8_enable_breakpoints(target
);
1035 stm8_enable_watchpoints(target
);
1036 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1037 stm8_set_hwbreak(target
, comparator_list
);
1040 /* current = 1: continue on current pc,
1041 otherwise continue at <address> */
1043 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1045 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1046 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1050 resume_pc
= address
;
1052 resume_pc
= buf_get_u32(
1053 stm8
->core_cache
->reg_list
[STM8_PC
].value
,
1056 stm8_restore_context(target
);
1058 /* the front-end may request us not to handle breakpoints */
1059 if (handle_breakpoints
) {
1060 /* Single step past breakpoint at current address */
1061 breakpoint
= breakpoint_find(target
, resume_pc
);
1063 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
,
1064 breakpoint
->address
);
1065 stm8_unset_breakpoint(target
, breakpoint
);
1066 stm8_single_step_core(target
);
1067 stm8_set_breakpoint(target
, breakpoint
);
1071 /* disable interrupts if we are debugging */
1072 if (debug_execution
)
1073 stm8_enable_interrupts(target
, 0);
1075 /* exit debug mode */
1076 stm8_exit_debug(target
);
1077 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1079 /* registers are now invalid */
1080 register_cache_invalidate(stm8
->core_cache
);
1082 if (!debug_execution
) {
1083 target
->state
= TARGET_RUNNING
;
1084 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1085 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
1087 target
->state
= TARGET_DEBUG_RUNNING
;
1088 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1089 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
1095 static int stm8_init_flash_regs(bool enable_stm8l
, struct stm8_common
*stm8
)
1097 stm8
->enable_stm8l
= enable_stm8l
;
1099 if (stm8
->enable_stm8l
) {
1100 stm8
->flash_cr2
= FLASH_CR2_STM8L
;
1101 stm8
->flash_ncr2
= FLASH_NCR2_STM8L
;
1102 stm8
->flash_iapsr
= FLASH_IAPSR_STM8L
;
1103 stm8
->flash_dukr
= FLASH_DUKR_STM8L
;
1104 stm8
->flash_pukr
= FLASH_PUKR_STM8L
;
1106 stm8
->flash_cr2
= FLASH_CR2_STM8S
;
1107 stm8
->flash_ncr2
= FLASH_NCR2_STM8S
;
1108 stm8
->flash_iapsr
= FLASH_IAPSR_STM8S
;
1109 stm8
->flash_dukr
= FLASH_DUKR_STM8S
;
1110 stm8
->flash_pukr
= FLASH_PUKR_STM8S
;
1115 static int stm8_init_arch_info(struct target
*target
,
1116 struct stm8_common
*stm8
, struct jtag_tap
*tap
)
1118 target
->endianness
= TARGET_BIG_ENDIAN
;
1119 target
->arch_info
= stm8
;
1120 stm8
->common_magic
= STM8_COMMON_MAGIC
;
1121 stm8
->fast_data_area
= NULL
;
1122 stm8
->blocksize
= 0x80;
1123 stm8
->flashstart
= 0x8000;
1124 stm8
->flashend
= 0xffff;
1125 stm8
->eepromstart
= 0x4000;
1126 stm8
->eepromend
= 0x43ff;
1127 stm8
->optionstart
= 0x4800;
1128 stm8
->optionend
= 0x487F;
1130 /* has breakpoint/watchpoint unit been scanned */
1131 stm8
->bp_scanned
= false;
1132 stm8
->hw_break_list
= NULL
;
1134 stm8
->read_core_reg
= stm8_read_core_reg
;
1135 stm8
->write_core_reg
= stm8_write_core_reg
;
1137 stm8_init_flash_regs(0, stm8
);
1142 static int stm8_target_create(struct target
*target
,
1146 struct stm8_common
*stm8
= calloc(1, sizeof(struct stm8_common
));
1148 stm8_init_arch_info(target
, stm8
, target
->tap
);
1149 stm8_configure_break_unit(target
);
1154 static int stm8_read_core_reg(struct target
*target
, unsigned int num
)
1158 /* get pointers to arch-specific information */
1159 struct stm8_common
*stm8
= target_to_stm8(target
);
1161 if (num
>= STM8_NUM_REGS
)
1162 return ERROR_COMMAND_SYNTAX_ERROR
;
1164 reg_value
= stm8
->core_regs
[num
];
1165 LOG_DEBUG("read core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1166 buf_set_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
1167 stm8
->core_cache
->reg_list
[num
].valid
= true;
1168 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1173 static int stm8_write_core_reg(struct target
*target
, unsigned int num
)
1177 /* get pointers to arch-specific information */
1178 struct stm8_common
*stm8
= target_to_stm8(target
);
1180 if (num
>= STM8_NUM_REGS
)
1181 return ERROR_COMMAND_SYNTAX_ERROR
;
1183 reg_value
= buf_get_u32(stm8
->core_cache
->reg_list
[num
].value
, 0, 32);
1184 stm8
->core_regs
[num
] = reg_value
;
1185 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
1186 stm8
->core_cache
->reg_list
[num
].valid
= true;
1187 stm8
->core_cache
->reg_list
[num
].dirty
= false;
1192 static int stm8_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
1193 int *reg_list_size
, enum target_register_class reg_class
)
1195 /* get pointers to arch-specific information */
1196 struct stm8_common
*stm8
= target_to_stm8(target
);
1199 *reg_list_size
= STM8_NUM_REGS
;
1200 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1202 for (i
= 0; i
< STM8_NUM_REGS
; i
++)
1203 (*reg_list
)[i
] = &stm8
->core_cache
->reg_list
[i
];
1208 static const struct reg_arch_type stm8_reg_type
= {
1209 .get
= stm8_get_core_reg
,
1210 .set
= stm8_set_core_reg
,
1213 static struct reg_cache
*stm8_build_reg_cache(struct target
*target
)
1215 /* get pointers to arch-specific information */
1216 struct stm8_common
*stm8
= target_to_stm8(target
);
1218 int num_regs
= STM8_NUM_REGS
;
1219 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1220 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1221 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1222 struct stm8_core_reg
*arch_info
= malloc(
1223 sizeof(struct stm8_core_reg
) * num_regs
);
1224 struct reg_feature
*feature
;
1227 /* Build the process context cache */
1228 cache
->name
= "stm8 registers";
1230 cache
->reg_list
= reg_list
;
1231 cache
->num_regs
= num_regs
;
1233 stm8
->core_cache
= cache
;
1235 for (i
= 0; i
< num_regs
; i
++) {
1236 arch_info
[i
].num
= stm8_regs
[i
].id
;
1237 arch_info
[i
].target
= target
;
1238 arch_info
[i
].stm8_common
= stm8
;
1240 reg_list
[i
].name
= stm8_regs
[i
].name
;
1241 reg_list
[i
].size
= stm8_regs
[i
].bits
;
1243 reg_list
[i
].value
= calloc(1, 4);
1244 reg_list
[i
].valid
= false;
1245 reg_list
[i
].type
= &stm8_reg_type
;
1246 reg_list
[i
].arch_info
= &arch_info
[i
];
1248 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1249 if (reg_list
[i
].reg_data_type
)
1250 reg_list
[i
].reg_data_type
->type
= stm8_regs
[i
].type
;
1252 LOG_ERROR("unable to allocate reg type list");
1256 reg_list
[i
].dirty
= false;
1257 reg_list
[i
].group
= stm8_regs
[i
].group
;
1258 reg_list
[i
].number
= stm8_regs
[i
].id
;
1259 reg_list
[i
].exist
= true;
1260 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1262 feature
= calloc(1, sizeof(struct reg_feature
));
1264 feature
->name
= stm8_regs
[i
].feature
;
1265 reg_list
[i
].feature
= feature
;
1267 LOG_ERROR("unable to allocate feature list");
1273 static void stm8_free_reg_cache(struct target
*target
)
1275 struct stm8_common
*stm8
= target_to_stm8(target
);
1276 struct reg_cache
*cache
;
1280 cache
= stm8
->core_cache
;
1285 for (i
= 0; i
< cache
->num_regs
; i
++) {
1286 reg
= &cache
->reg_list
[i
];
1289 free(reg
->reg_data_type
);
1293 free(cache
->reg_list
[0].arch_info
);
1294 free(cache
->reg_list
);
1297 stm8
->core_cache
= NULL
;
1300 static void stm8_deinit(struct target
*target
)
1302 struct stm8_common
*stm8
= target_to_stm8(target
);
1304 free(stm8
->hw_break_list
);
1306 stm8_free_reg_cache(target
);
1311 static int stm8_arch_state(struct target
*target
)
1313 struct stm8_common
*stm8
= target_to_stm8(target
);
1315 LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32
"",
1316 debug_reason_name(target
),
1317 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1322 static int stm8_step(struct target
*target
, int current
,
1323 target_addr_t address
, int handle_breakpoints
)
1325 LOG_DEBUG("%" PRIx32
" " TARGET_ADDR_FMT
" %" PRIx32
,
1326 current
, address
, handle_breakpoints
);
1328 /* get pointers to arch-specific information */
1329 struct stm8_common
*stm8
= target_to_stm8(target
);
1330 struct breakpoint
*breakpoint
= NULL
;
1332 if (target
->state
!= TARGET_HALTED
) {
1333 LOG_WARNING("target not halted");
1334 return ERROR_TARGET_NOT_HALTED
;
1337 /* current = 1: continue on current pc, otherwise continue at <address> */
1339 buf_set_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32, address
);
1340 stm8
->core_cache
->reg_list
[STM8_PC
].dirty
= true;
1341 stm8
->core_cache
->reg_list
[STM8_PC
].valid
= true;
1344 /* the front-end may request us not to handle breakpoints */
1345 if (handle_breakpoints
) {
1346 breakpoint
= breakpoint_find(target
,
1347 buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32));
1349 stm8_unset_breakpoint(target
, breakpoint
);
1352 /* restore context */
1353 stm8_restore_context(target
);
1355 /* configure single step mode */
1356 stm8_config_step(target
, 1);
1358 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1360 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1362 /* disable interrupts while stepping */
1363 if (!stm8
->enable_step_irq
)
1364 stm8_enable_interrupts(target
, 0);
1366 /* exit debug mode */
1367 stm8_exit_debug(target
);
1369 /* registers are now invalid */
1370 register_cache_invalidate(stm8
->core_cache
);
1372 LOG_DEBUG("target stepped ");
1373 stm8_debug_entry(target
);
1376 stm8_set_breakpoint(target
, breakpoint
);
1378 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1383 static void stm8_enable_breakpoints(struct target
*target
)
1385 struct breakpoint
*breakpoint
= target
->breakpoints
;
1387 /* set any pending breakpoints */
1388 while (breakpoint
) {
1389 if (breakpoint
->set
== 0)
1390 stm8_set_breakpoint(target
, breakpoint
);
1391 breakpoint
= breakpoint
->next
;
1395 static int stm8_set_breakpoint(struct target
*target
,
1396 struct breakpoint
*breakpoint
)
1398 struct stm8_common
*stm8
= target_to_stm8(target
);
1399 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1402 if (breakpoint
->set
) {
1403 LOG_WARNING("breakpoint already set");
1407 if (breakpoint
->type
== BKPT_HARD
) {
1410 while (comparator_list
[bp_num
].used
&& (bp_num
< stm8
->num_hw_bpoints
))
1412 if (bp_num
>= stm8
->num_hw_bpoints
) {
1413 LOG_ERROR("Can not find free breakpoint register (bpid: %" PRIu32
")",
1414 breakpoint
->unique_id
);
1415 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1417 breakpoint
->set
= bp_num
+ 1;
1418 comparator_list
[bp_num
].used
= true;
1419 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
1420 comparator_list
[bp_num
].type
= HWBRK_EXEC
;
1422 retval
= stm8_set_hwbreak(target
, comparator_list
);
1423 if (retval
!= ERROR_OK
)
1426 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1427 breakpoint
->unique_id
,
1428 bp_num
, comparator_list
[bp_num
].bp_value
);
1429 } else if (breakpoint
->type
== BKPT_SOFT
) {
1430 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1431 if (breakpoint
->length
== 1) {
1432 uint8_t verify
= 0x55;
1434 retval
= target_read_u8(target
, breakpoint
->address
,
1435 breakpoint
->orig_instr
);
1436 if (retval
!= ERROR_OK
)
1438 retval
= target_write_u8(target
, breakpoint
->address
, STM8_BREAK
);
1439 if (retval
!= ERROR_OK
)
1442 retval
= target_read_u8(target
, breakpoint
->address
, &verify
);
1443 if (retval
!= ERROR_OK
)
1445 if (verify
!= STM8_BREAK
) {
1446 LOG_ERROR("Unable to set breakpoint at address " TARGET_ADDR_FMT
1447 " - check that memory is read/writable",
1448 breakpoint
->address
);
1449 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1452 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1454 breakpoint
->set
= 1; /* Any nice value but 0 */
1460 static int stm8_add_breakpoint(struct target
*target
,
1461 struct breakpoint
*breakpoint
)
1463 struct stm8_common
*stm8
= target_to_stm8(target
);
1466 if (breakpoint
->type
== BKPT_HARD
) {
1467 if (stm8
->num_hw_bpoints_avail
< 1) {
1468 LOG_INFO("no hardware breakpoint available");
1469 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1472 ret
= stm8_set_breakpoint(target
, breakpoint
);
1473 if (ret
!= ERROR_OK
)
1476 stm8
->num_hw_bpoints_avail
--;
1480 ret
= stm8_set_breakpoint(target
, breakpoint
);
1481 if (ret
!= ERROR_OK
)
1487 static int stm8_unset_breakpoint(struct target
*target
,
1488 struct breakpoint
*breakpoint
)
1490 /* get pointers to arch-specific information */
1491 struct stm8_common
*stm8
= target_to_stm8(target
);
1492 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1495 if (!breakpoint
->set
) {
1496 LOG_WARNING("breakpoint not set");
1500 if (breakpoint
->type
== BKPT_HARD
) {
1501 int bp_num
= breakpoint
->set
- 1;
1502 if ((bp_num
< 0) || (bp_num
>= stm8
->num_hw_bpoints
)) {
1503 LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1504 breakpoint
->unique_id
);
1507 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d",
1508 breakpoint
->unique_id
,
1510 comparator_list
[bp_num
].used
= false;
1511 retval
= stm8_set_hwbreak(target
, comparator_list
);
1512 if (retval
!= ERROR_OK
)
1515 /* restore original instruction (kept in target endianness) */
1516 LOG_DEBUG("bpid: %" PRIu32
, breakpoint
->unique_id
);
1517 if (breakpoint
->length
== 1) {
1518 uint8_t current_instr
;
1520 /* check that user program has not
1521 modified breakpoint instruction */
1522 retval
= target_read_memory(target
, breakpoint
->address
, 1, 1,
1523 (uint8_t *)¤t_instr
);
1524 if (retval
!= ERROR_OK
)
1527 if (current_instr
== STM8_BREAK
) {
1528 retval
= target_write_memory(target
, breakpoint
->address
, 1, 1,
1529 breakpoint
->orig_instr
);
1530 if (retval
!= ERROR_OK
)
1536 breakpoint
->set
= 0;
1541 static int stm8_remove_breakpoint(struct target
*target
,
1542 struct breakpoint
*breakpoint
)
1544 /* get pointers to arch-specific information */
1545 struct stm8_common
*stm8
= target_to_stm8(target
);
1547 if (target
->state
!= TARGET_HALTED
) {
1548 LOG_WARNING("target not halted");
1549 return ERROR_TARGET_NOT_HALTED
;
1552 if (breakpoint
->set
)
1553 stm8_unset_breakpoint(target
, breakpoint
);
1555 if (breakpoint
->type
== BKPT_HARD
)
1556 stm8
->num_hw_bpoints_avail
++;
1561 static int stm8_set_watchpoint(struct target
*target
,
1562 struct watchpoint
*watchpoint
)
1564 struct stm8_common
*stm8
= target_to_stm8(target
);
1565 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1569 if (watchpoint
->set
) {
1570 LOG_WARNING("watchpoint already set");
1574 while (comparator_list
[wp_num
].used
&& (wp_num
< stm8
->num_hw_bpoints
))
1576 if (wp_num
>= stm8
->num_hw_bpoints
) {
1577 LOG_ERROR("Can not find free hw breakpoint");
1578 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1581 if (watchpoint
->length
!= 1) {
1582 LOG_ERROR("Only watchpoints of length 1 are supported");
1583 return ERROR_TARGET_UNALIGNED_ACCESS
;
1586 enum hw_break_type enable
= 0;
1588 switch (watchpoint
->rw
) {
1599 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
1602 comparator_list
[wp_num
].used
= true;
1603 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
1604 comparator_list
[wp_num
].type
= enable
;
1606 ret
= stm8_set_hwbreak(target
, comparator_list
);
1607 if (ret
!= ERROR_OK
) {
1608 comparator_list
[wp_num
].used
= false;
1612 watchpoint
->set
= wp_num
+ 1;
1614 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"",
1616 comparator_list
[wp_num
].bp_value
);
1621 static int stm8_add_watchpoint(struct target
*target
,
1622 struct watchpoint
*watchpoint
)
1625 struct stm8_common
*stm8
= target_to_stm8(target
);
1627 if (stm8
->num_hw_bpoints_avail
< 1) {
1628 LOG_INFO("no hardware watchpoints available");
1629 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1632 ret
= stm8_set_watchpoint(target
, watchpoint
);
1633 if (ret
!= ERROR_OK
)
1636 stm8
->num_hw_bpoints_avail
--;
1640 static void stm8_enable_watchpoints(struct target
*target
)
1642 struct watchpoint
*watchpoint
= target
->watchpoints
;
1644 /* set any pending watchpoints */
1645 while (watchpoint
) {
1646 if (watchpoint
->set
== 0)
1647 stm8_set_watchpoint(target
, watchpoint
);
1648 watchpoint
= watchpoint
->next
;
1652 static int stm8_unset_watchpoint(struct target
*target
,
1653 struct watchpoint
*watchpoint
)
1655 /* get pointers to arch-specific information */
1656 struct stm8_common
*stm8
= target_to_stm8(target
);
1657 struct stm8_comparator
*comparator_list
= stm8
->hw_break_list
;
1659 if (!watchpoint
->set
) {
1660 LOG_WARNING("watchpoint not set");
1664 int wp_num
= watchpoint
->set
- 1;
1665 if ((wp_num
< 0) || (wp_num
>= stm8
->num_hw_bpoints
)) {
1666 LOG_DEBUG("Invalid hw comparator number in watchpoint");
1669 comparator_list
[wp_num
].used
= false;
1670 watchpoint
->set
= 0;
1672 stm8_set_hwbreak(target
, comparator_list
);
1677 static int stm8_remove_watchpoint(struct target
*target
,
1678 struct watchpoint
*watchpoint
)
1680 /* get pointers to arch-specific information */
1681 struct stm8_common
*stm8
= target_to_stm8(target
);
1683 if (target
->state
!= TARGET_HALTED
) {
1684 LOG_WARNING("target not halted");
1685 return ERROR_TARGET_NOT_HALTED
;
1688 if (watchpoint
->set
)
1689 stm8_unset_watchpoint(target
, watchpoint
);
1691 stm8
->num_hw_bpoints_avail
++;
1696 static int stm8_examine(struct target
*target
)
1700 /* get pointers to arch-specific information */
1701 struct stm8_common
*stm8
= target_to_stm8(target
);
1702 struct hl_interface_s
*adapter
= target_to_adapter(target
);
1704 if (!target_was_examined(target
)) {
1705 if (!stm8
->swim_configured
) {
1706 /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */
1707 LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)");
1708 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
);
1709 if (retval
!= ERROR_OK
)
1711 /* set high speed */
1712 LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)");
1713 retval
= stm8_write_u8(target
, SWIM_CSR
, SAFE_MASK
+ SWIM_DM
+ HS
);
1714 if (retval
!= ERROR_OK
)
1716 retval
= stm8_set_speed(target
, 1);
1717 if (retval
== ERROR_OK
)
1718 stm8
->swim_configured
= true;
1720 Now is the time to deassert reset if connect_under_reset.
1721 Releasing reset line will cause the option bytes to load.
1722 The core will still be stalled.
1724 if (adapter
->param
.connect_under_reset
)
1725 stm8_reset_deassert(target
);
1727 LOG_INFO("trying to reconnect");
1729 retval
= adapter
->layout
->api
->state(adapter
->handle
);
1730 if (retval
!= ERROR_OK
) {
1731 LOG_ERROR("reconnect failed");
1735 /* read dm_csrx control regs */
1736 retval
= stm8_read_dm_csrx(target
, &csr1
, &csr2
);
1737 if (retval
!= ERROR_OK
) {
1738 LOG_ERROR("state query failed");
1743 target_set_examined(target
);
1751 /** Checks whether a memory region is erased. */
1752 static int stm8_blank_check_memory(struct target
*target
,
1753 target_addr_t address
, uint32_t count
, uint32_t *blank
, uint8_t erased_value
)
1755 struct working_area
*erase_check_algorithm
;
1756 struct reg_param reg_params
[2];
1757 struct mem_param mem_params
[2];
1758 struct stm8_algorithm stm8_info
;
1760 static const uint8_t stm8_erase_check_code
[] = {
1761 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1764 if (erased_value
!= 0xff) {
1765 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for STM8",
1770 /* make sure we have a working area */
1771 if (target_alloc_working_area(target
, sizeof(stm8_erase_check_code
),
1772 &erase_check_algorithm
) != ERROR_OK
)
1773 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1775 target_write_buffer(target
, erase_check_algorithm
->address
,
1776 sizeof(stm8_erase_check_code
), stm8_erase_check_code
);
1778 stm8_info
.common_magic
= STM8_COMMON_MAGIC
;
1780 init_mem_param(&mem_params
[0], 0x0, 3, PARAM_OUT
);
1781 buf_set_u32(mem_params
[0].value
, 0, 24, address
);
1783 init_mem_param(&mem_params
[1], 0x3, 3, PARAM_OUT
);
1784 buf_set_u32(mem_params
[1].value
, 0, 24, count
);
1786 init_reg_param(®_params
[0], "a", 32, PARAM_IN_OUT
);
1787 buf_set_u32(reg_params
[0].value
, 0, 32, erased_value
);
1789 init_reg_param(®_params
[1], "sp", 32, PARAM_OUT
);
1790 buf_set_u32(reg_params
[1].value
, 0, 32, erase_check_algorithm
->address
);
1792 int retval
= target_run_algorithm(target
, 2, mem_params
, 2, reg_params
,
1793 erase_check_algorithm
->address
+ 6,
1794 erase_check_algorithm
->address
+ (sizeof(stm8_erase_check_code
) - 1),
1797 if (retval
== ERROR_OK
)
1798 *blank
= (*(reg_params
[0].value
) == 0xff);
1800 destroy_mem_param(&mem_params
[0]);
1801 destroy_mem_param(&mem_params
[1]);
1802 destroy_reg_param(®_params
[0]);
1804 target_free_working_area(target
, erase_check_algorithm
);
1809 static int stm8_checksum_memory(struct target
*target
, target_addr_t address
,
1810 uint32_t count
, uint32_t *checksum
)
1812 /* let image_calculate_checksum() take care of business */
1813 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1816 /* run to exit point. return error if exit point was not reached. */
1817 static int stm8_run_and_wait(struct target
*target
, uint32_t entry_point
,
1818 int timeout_ms
, uint32_t exit_point
, struct stm8_common
*stm8
)
1822 /* This code relies on the target specific resume() and
1823 poll()->debug_entry() sequence to write register values to the
1824 processor and the read them back */
1825 retval
= target_resume(target
, 0, entry_point
, 0, 1);
1826 if (retval
!= ERROR_OK
)
1829 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1830 /* If the target fails to halt due to the breakpoint, force a halt */
1831 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
1832 retval
= target_halt(target
);
1833 if (retval
!= ERROR_OK
)
1835 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
1836 if (retval
!= ERROR_OK
)
1838 return ERROR_TARGET_TIMEOUT
;
1841 pc
= buf_get_u32(stm8
->core_cache
->reg_list
[STM8_PC
].value
, 0, 32);
1842 if (exit_point
&& (pc
!= exit_point
)) {
1843 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
1844 return ERROR_TARGET_TIMEOUT
;
1850 static int stm8_run_algorithm(struct target
*target
, int num_mem_params
,
1851 struct mem_param
*mem_params
, int num_reg_params
,
1852 struct reg_param
*reg_params
, target_addr_t entry_point
,
1853 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
1855 struct stm8_common
*stm8
= target_to_stm8(target
);
1857 uint32_t context
[STM8_NUM_REGS
];
1858 int retval
= ERROR_OK
;
1860 LOG_DEBUG("Running algorithm");
1862 /* NOTE: stm8_run_algorithm requires that each
1863 algorithm uses a software breakpoint
1864 at the exit point */
1866 if (stm8
->common_magic
!= STM8_COMMON_MAGIC
) {
1867 LOG_ERROR("current target isn't a STM8 target");
1868 return ERROR_TARGET_INVALID
;
1871 if (target
->state
!= TARGET_HALTED
) {
1872 LOG_WARNING("target not halted");
1873 return ERROR_TARGET_NOT_HALTED
;
1876 /* refresh core register cache */
1877 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1878 if (!stm8
->core_cache
->reg_list
[i
].valid
)
1879 stm8
->read_core_reg(target
, i
);
1880 context
[i
] = buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1883 for (int i
= 0; i
< num_mem_params
; i
++) {
1884 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1885 mem_params
[i
].size
, mem_params
[i
].value
);
1886 if (retval
!= ERROR_OK
)
1890 for (int i
= 0; i
< num_reg_params
; i
++) {
1891 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1892 reg_params
[i
].reg_name
, 0);
1895 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1896 return ERROR_COMMAND_SYNTAX_ERROR
;
1899 if (reg_params
[i
].size
!= 32) {
1900 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1901 reg_params
[i
].reg_name
);
1902 return ERROR_COMMAND_SYNTAX_ERROR
;
1905 stm8_set_core_reg(reg
, reg_params
[i
].value
);
1908 retval
= stm8_run_and_wait(target
, entry_point
,
1909 timeout_ms
, exit_point
, stm8
);
1911 if (retval
!= ERROR_OK
)
1914 for (int i
= 0; i
< num_mem_params
; i
++) {
1915 if (mem_params
[i
].direction
!= PARAM_OUT
) {
1916 retval
= target_read_buffer(target
, mem_params
[i
].address
,
1917 mem_params
[i
].size
, mem_params
[i
].value
);
1918 if (retval
!= ERROR_OK
)
1923 for (int i
= 0; i
< num_reg_params
; i
++) {
1924 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1925 struct reg
*reg
= register_get_by_name(stm8
->core_cache
,
1926 reg_params
[i
].reg_name
, 0);
1928 LOG_ERROR("BUG: register '%s' not found",
1929 reg_params
[i
].reg_name
);
1930 return ERROR_COMMAND_SYNTAX_ERROR
;
1933 if (reg_params
[i
].size
!= 32) {
1934 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1935 reg_params
[i
].reg_name
);
1936 return ERROR_COMMAND_SYNTAX_ERROR
;
1939 buf_set_u32(reg_params
[i
].value
,
1940 0, 32, buf_get_u32(reg
->value
, 0, 32));
1944 /* restore everything we saved before */
1945 for (unsigned int i
= 0; i
< STM8_NUM_REGS
; i
++) {
1947 regvalue
= buf_get_u32(stm8
->core_cache
->reg_list
[i
].value
, 0, 32);
1948 if (regvalue
!= context
[i
]) {
1949 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
1950 stm8
->core_cache
->reg_list
[i
].name
, context
[i
]);
1951 buf_set_u32(stm8
->core_cache
->reg_list
[i
].value
,
1953 stm8
->core_cache
->reg_list
[i
].valid
= true;
1954 stm8
->core_cache
->reg_list
[i
].dirty
= true;
1961 int stm8_jim_configure(struct target
*target
, Jim_GetOptInfo
*goi
)
1963 struct stm8_common
*stm8
= target_to_stm8(target
);
1968 arg
= Jim_GetString(goi
->argv
[0], NULL
);
1969 if (!strcmp(arg
, "-blocksize")) {
1970 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1974 if (goi
->argc
== 0) {
1975 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1976 "-blocksize ?bytes? ...");
1980 e
= Jim_GetOpt_Wide(goi
, &w
);
1984 stm8
->blocksize
= w
;
1985 LOG_DEBUG("blocksize=%8.8x", stm8
->blocksize
);
1988 if (!strcmp(arg
, "-flashstart")) {
1989 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
1993 if (goi
->argc
== 0) {
1994 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
1995 "-flashstart ?address? ...");
1999 e
= Jim_GetOpt_Wide(goi
, &w
);
2003 stm8
->flashstart
= w
;
2004 LOG_DEBUG("flashstart=%8.8x", stm8
->flashstart
);
2007 if (!strcmp(arg
, "-flashend")) {
2008 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2012 if (goi
->argc
== 0) {
2013 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2014 "-flashend ?address? ...");
2018 e
= Jim_GetOpt_Wide(goi
, &w
);
2023 LOG_DEBUG("flashend=%8.8x", stm8
->flashend
);
2026 if (!strcmp(arg
, "-eepromstart")) {
2027 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2031 if (goi
->argc
== 0) {
2032 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2033 "-eepromstart ?address? ...");
2037 e
= Jim_GetOpt_Wide(goi
, &w
);
2041 stm8
->eepromstart
= w
;
2042 LOG_DEBUG("eepromstart=%8.8x", stm8
->eepromstart
);
2045 if (!strcmp(arg
, "-eepromend")) {
2046 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2050 if (goi
->argc
== 0) {
2051 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2052 "-eepromend ?address? ...");
2056 e
= Jim_GetOpt_Wide(goi
, &w
);
2060 stm8
->eepromend
= w
;
2061 LOG_DEBUG("eepromend=%8.8x", stm8
->eepromend
);
2064 if (!strcmp(arg
, "-optionstart")) {
2065 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2069 if (goi
->argc
== 0) {
2070 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2071 "-optionstart ?address? ...");
2075 e
= Jim_GetOpt_Wide(goi
, &w
);
2079 stm8
->optionstart
= w
;
2080 LOG_DEBUG("optionstart=%8.8x", stm8
->optionstart
);
2083 if (!strcmp(arg
, "-optionend")) {
2084 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2088 if (goi
->argc
== 0) {
2089 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
,
2090 "-optionend ?address? ...");
2094 e
= Jim_GetOpt_Wide(goi
, &w
);
2098 stm8
->optionend
= w
;
2099 LOG_DEBUG("optionend=%8.8x", stm8
->optionend
);
2102 if (!strcmp(arg
, "-enable_step_irq")) {
2103 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2107 stm8
->enable_step_irq
= true;
2108 LOG_DEBUG("enable_step_irq=%8.8x", stm8
->enable_step_irq
);
2111 if (!strcmp(arg
, "-enable_stm8l")) {
2112 e
= Jim_GetOpt_String(goi
, &arg
, NULL
);
2116 stm8
->enable_stm8l
= true;
2117 LOG_DEBUG("enable_stm8l=%8.8x", stm8
->enable_stm8l
);
2118 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2121 return JIM_CONTINUE
;
2124 COMMAND_HANDLER(stm8_handle_enable_step_irq_command
)
2127 struct target
*target
= get_current_target(CMD_CTX
);
2128 struct stm8_common
*stm8
= target_to_stm8(target
);
2129 bool enable
= stm8
->enable_step_irq
;
2132 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2133 stm8
->enable_step_irq
= enable
;
2135 msg
= stm8
->enable_step_irq
? "enabled" : "disabled";
2136 command_print(CMD_CTX
, "enable_step_irq = %s", msg
);
2140 COMMAND_HANDLER(stm8_handle_enable_stm8l_command
)
2143 struct target
*target
= get_current_target(CMD_CTX
);
2144 struct stm8_common
*stm8
= target_to_stm8(target
);
2145 bool enable
= stm8
->enable_stm8l
;
2148 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
2149 stm8
->enable_stm8l
= enable
;
2151 msg
= stm8
->enable_stm8l
? "enabled" : "disabled";
2152 command_print(CMD_CTX
, "enable_stm8l = %s", msg
);
2153 stm8_init_flash_regs(stm8
->enable_stm8l
, stm8
);
2157 static const struct command_registration stm8_exec_command_handlers
[] = {
2159 .name
= "enable_step_irq",
2160 .handler
= stm8_handle_enable_step_irq_command
,
2161 .mode
= COMMAND_ANY
,
2162 .help
= "Enable/disable irq handling during step",
2166 .name
= "enable_stm8l",
2167 .handler
= stm8_handle_enable_stm8l_command
,
2168 .mode
= COMMAND_ANY
,
2169 .help
= "Enable/disable STM8L flash programming",
2172 COMMAND_REGISTRATION_DONE
2175 const struct command_registration stm8_command_handlers
[] = {
2178 .mode
= COMMAND_ANY
,
2179 .help
= "stm8 command group",
2181 .chain
= stm8_exec_command_handlers
,
2183 COMMAND_REGISTRATION_DONE
2186 struct target_type stm8_target
= {
2190 .arch_state
= stm8_arch_state
,
2193 .resume
= stm8_resume
,
2196 .assert_reset
= stm8_reset_assert
,
2197 .deassert_reset
= stm8_reset_deassert
,
2199 .get_gdb_reg_list
= stm8_get_gdb_reg_list
,
2201 .read_memory
= stm8_read_memory
,
2202 .write_memory
= stm8_write_memory
,
2203 .checksum_memory
= stm8_checksum_memory
,
2204 .blank_check_memory
= stm8_blank_check_memory
,
2206 .run_algorithm
= stm8_run_algorithm
,
2208 .add_breakpoint
= stm8_add_breakpoint
,
2209 .remove_breakpoint
= stm8_remove_breakpoint
,
2210 .add_watchpoint
= stm8_add_watchpoint
,
2211 .remove_watchpoint
= stm8_remove_watchpoint
,
2213 .commands
= stm8_command_handlers
,
2214 .target_create
= stm8_target_create
,
2215 .init_target
= stm8_init
,
2216 .examine
= stm8_examine
,
2218 .deinit_target
= stm8_deinit
,
2219 .target_jim_configure
= stm8_jim_configure
,