49 { 0,
"pc", 32,
REG_TYPE_UINT32,
"general",
"org.gnu.gdb.stm8.core", 0 },
50 { 1,
"a", 8,
REG_TYPE_UINT8,
"general",
"org.gnu.gdb.stm8.core", 0 },
53 { 4,
"sp", 16,
REG_TYPE_UINT16,
"general",
"org.gnu.gdb.stm8.core", 0 },
54 { 5,
"cc", 8,
REG_TYPE_UINT8,
"general",
"org.gnu.gdb.stm8.core", 0 },
57 #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)
68 #define DM_REGS 0x7f00
69 #define DM_REG_A 0x7f00
70 #define DM_REG_PC 0x7f01
71 #define DM_REG_X 0x7f04
72 #define DM_REG_Y 0x7f06
73 #define DM_REG_SP 0x7f08
74 #define DM_REG_CC 0x7f0a
76 #define DM_BKR1E 0x7f90
77 #define DM_BKR2E 0x7f93
80 #define DM_CSR1 0x7f98
81 #define DM_CSR2 0x7f99
95 #define FLASH_CR1_STM8S 0x505A
96 #define FLASH_CR2_STM8S 0x505B
97 #define FLASH_NCR2_STM8S 0x505C
98 #define FLASH_IAPSR_STM8S 0x505F
99 #define FLASH_PUKR_STM8S 0x5062
100 #define FLASH_DUKR_STM8S 0x5064
102 #define FLASH_CR1_STM8L 0x5050
103 #define FLASH_CR2_STM8L 0x5051
104 #define FLASH_NCR2_STM8L 0
105 #define FLASH_PUKR_STM8L 0x5052
106 #define FLASH_DUKR_STM8L 0x5053
107 #define FLASH_IAPSR_STM8L 0x5054
114 #define WR_PG_DIS 0x01
124 #define SAFE_MASK 0x80
125 #define NO_ACCESS 0x40
129 #define SWIM_RST 0x04
133 #define SWIM_CSR 0x7f80
135 #define STM8_BREAK 0x8B
184 uint32_t
addr, uint8_t val)
193 uint32_t
addr, uint8_t *val)
256 if (!comparator_list[0].used) {
261 if (!comparator_list[1].used) {
276 switch (comparator_list[1].
type) {
294 switch (comparator_list[0].
type) {
310 if (comparator_list[0].
type != comparator_list[1].
type) {
311 LOG_ERROR(
"data hw breakpoints must be of same type");
316 for (i = 0; i < 2; i++) {
327 }
else if (
addr == 1) {
339 (bc << 3) + (bir << 2) + (biw << 1));
433 LOG_DEBUG(
"csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
473 LOG_DEBUG(
"entered debug state at PC 0x%" PRIx32
", target->state: %s",
615 if (~data[0] &
PUL) {
635 if (~data[0] &
DUL) {
649 uint32_t
size, uint32_t
count, uint32_t blocksize_param,
686 if ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {
693 if ((bytecnt >= 4) && ((address & 0x3) == 0)) {
716 for (i = 0; i < 16; i++) {
743 ", size: 0x%8.8" PRIx32
744 ", count: 0x%8.8" PRIx32,
774 ", size: 0x%8.8" PRIx32
775 ", count: 0x%8.8" PRIx32,
801 LOG_DEBUG(
"writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)",
csr &
HS ? 1 : 0);
836 LOG_DEBUG(
"stm8_read_dm_csrx failed retval=%d", retval);
848 LOG_DEBUG(
"DM_CSR2_STALL already set during server startup.");
852 LOG_DEBUG(
"stm8_debug_entry failed retval=%d", retval);
867 LOG_DEBUG(
"csr1 = 0x%02X csr2 = 0x%02X", csr1, csr2);
882 LOG_WARNING(
"target was in unknown state when halt was requested");
906 bool use_srst_fallback =
true;
914 use_srst_fallback =
false;
920 if (use_srst_fallback) {
921 LOG_DEBUG(
"Hardware srst not supported, falling back to swim reset");
994 handle_breakpoints, debug_execution);
1001 if (!debug_execution) {
1019 resume_pc = address;
1028 if (handle_breakpoints) {
1041 if (debug_execution)
1051 if (!debug_execution) {
1054 LOG_DEBUG(
"target resumed at 0x%" PRIx32
"", resume_pc);
1058 LOG_DEBUG(
"target debug resumed at 0x%" PRIx32
"", resume_pc);
1134 LOG_DEBUG(
"read core reg %i value 0x%" PRIx32
"", num, reg_value);
1154 LOG_DEBUG(
"write core reg %i value 0x%" PRIx32
"", num, reg_value);
1174 *reg_list = malloc(
sizeof(
struct reg *) * (*reg_list_size));
1195 struct reg *reg_list = calloc(num_regs,
sizeof(
struct reg));
1202 cache->
name =
"stm8 registers";
1209 for (i = 0; i < num_regs; i++) {
1216 reg_list[i].
value = calloc(1, 4);
1217 reg_list[i].
valid =
false;
1225 LOG_ERROR(
"unable to allocate reg type list");
1229 reg_list[i].
dirty =
false;
1232 reg_list[i].
exist =
true;
1240 LOG_ERROR(
"unable to allocate feature list");
1258 for (i = 0; i < cache->
num_regs; i++) {
1288 LOG_USER(
"target halted due to %s, pc: 0x%8.8" PRIx32
"",
1299 current, address, handle_breakpoints);
1318 if (handle_breakpoints) {
1383 while (comparator_list[bp_num].
used && (bp_num < stm8->num_hw_bpoints))
1386 LOG_ERROR(
"Can not find free breakpoint register (bpid: %" PRIu32
")",
1391 comparator_list[bp_num].
used =
true;
1399 LOG_DEBUG(
"bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx32
"",
1401 bp_num, comparator_list[bp_num].
bp_value);
1405 uint8_t verify = 0x55;
1420 " - check that memory is read/writable",
1441 LOG_INFO(
"no hardware breakpoint available");
1476 LOG_DEBUG(
"Invalid comparator number in breakpoint (bpid: %" PRIu32
")",
1480 LOG_DEBUG(
"bpid: %" PRIu32
" - releasing hw: %d",
1483 comparator_list[bp_num].
used =
false;
1491 uint8_t current_instr;
1496 (uint8_t *)¤t_instr);
1547 while (comparator_list[wp_num].
used && (wp_num < stm8->num_hw_bpoints))
1550 LOG_ERROR(
"Can not find free hw breakpoint");
1555 LOG_ERROR(
"Only watchpoints of length 1 are supported");
1572 LOG_ERROR(
"BUG: watchpoint->rw neither read, write nor access");
1575 comparator_list[wp_num].
used =
true;
1577 comparator_list[wp_num].
type = enable;
1581 comparator_list[wp_num].
used =
false;
1587 LOG_DEBUG(
"wp_num %i bp_value 0x%" PRIx32
"",
1601 LOG_INFO(
"no hardware watchpoints available");
1639 LOG_DEBUG(
"Invalid hw comparator number in watchpoint");
1642 comparator_list[wp_num].
used =
false;
1689 LOG_WARNING(
"\'srst_nogate\' reset_config option is required");
1725 static const uint8_t stm8_erase_check_code[] = {
1726 #include "../../contrib/loaders/erase_check/stm8_erase_check.inc"
1729 if (erased_value != 0xff) {
1730 LOG_ERROR(
"Erase value 0x%02" PRIx8
" not yet supported for STM8",
1737 &erase_check_algorithm) !=
ERROR_OK)
1741 sizeof(stm8_erase_check_code), stm8_erase_check_code);
1746 buf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);
1752 buf_set_u32(reg_params[0].value, 0, 32, erased_value);
1758 erase_check_algorithm->
address + 6,
1759 erase_check_algorithm->
address + (
sizeof(stm8_erase_check_code) - 1),
1763 blocks[0].
result = (*(reg_params[0].
value) == 0xff);
1779 uint32_t
count, uint32_t *checksum)
1787 unsigned int timeout_ms, uint32_t exit_point,
struct stm8_common *stm8)
1811 if (exit_point && (pc != exit_point)) {
1812 LOG_DEBUG(
"failed algorithm halted at 0x%" PRIx32
" ", pc);
1820 struct mem_param *mem_params,
int num_reg_params,
1822 target_addr_t exit_point,
unsigned int timeout_ms,
void *arch_info)
1836 LOG_ERROR(
"current target isn't a STM8 target");
1852 for (
int i = 0; i < num_mem_params; i++) {
1856 mem_params[i].
size, mem_params[i].value);
1861 for (
int i = 0; i < num_reg_params; i++) {
1869 LOG_ERROR(
"BUG: register '%s' not found", reg_params[i].reg_name);
1873 if (reg_params[i].
size != 32) {
1874 LOG_ERROR(
"BUG: register '%s' size doesn't match reg_params[i].size",
1875 reg_params[i].reg_name);
1883 timeout_ms, exit_point, stm8);
1888 for (
int i = 0; i < num_mem_params; i++) {
1891 mem_params[i].
size, mem_params[i].
value);
1897 for (
int i = 0; i < num_reg_params; i++) {
1902 LOG_ERROR(
"BUG: register '%s' not found",
1903 reg_params[i].reg_name);
1907 if (reg_params[i].
size != 32) {
1908 LOG_ERROR(
"BUG: register '%s' size doesn't match reg_params[i].size",
1909 reg_params[i].reg_name);
1922 if (regvalue != context[i]) {
1923 LOG_DEBUG(
"restoring register %s with value 0x%8.8" PRIx32,
1942 arg = Jim_GetString(goi->
argv[0],
NULL);
1943 if (!strcmp(arg,
"-blocksize")) {
1948 if (goi->
argc == 0) {
1950 "-blocksize ?bytes? ...");
1962 if (!strcmp(arg,
"-flashstart")) {
1967 if (goi->
argc == 0) {
1969 "-flashstart ?address? ...");
1981 if (!strcmp(arg,
"-flashend")) {
1986 if (goi->
argc == 0) {
1988 "-flashend ?address? ...");
2000 if (!strcmp(arg,
"-eepromstart")) {
2005 if (goi->
argc == 0) {
2007 "-eepromstart ?address? ...");
2019 if (!strcmp(arg,
"-eepromend")) {
2024 if (goi->
argc == 0) {
2026 "-eepromend ?address? ...");
2038 if (!strcmp(arg,
"-optionstart")) {
2043 if (goi->
argc == 0) {
2045 "-optionstart ?address? ...");
2057 if (!strcmp(arg,
"-optionend")) {
2062 if (goi->
argc == 0) {
2064 "-optionend ?address? ...");
2076 if (!strcmp(arg,
"-enable_step_irq")) {
2085 if (!strcmp(arg,
"-enable_stm8l")) {
2095 return JIM_CONTINUE;
2133 .
name =
"enable_step_irq",
2134 .handler = stm8_handle_enable_step_irq_command,
2136 .help =
"Enable/disable irq handling during step",
2140 .name =
"enable_stm8l",
2141 .handler = stm8_handle_enable_stm8l_command,
2143 .help =
"Enable/disable STM8L flash programming",
2153 .help =
"stm8 command group",
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
void destroy_mem_param(struct mem_param *param)
void destroy_reg_param(struct reg_param *param)
void init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction)
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
struct breakpoint * breakpoint_find(struct target *target, target_addr_t address)
static void watchpoint_set(struct watchpoint *watchpoint, unsigned int number)
static void breakpoint_hw_set(struct breakpoint *breakpoint, unsigned int hw_number)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define ERROR_COMMAND_NOTFOUND
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_ENABLE(in, out)
parses an enable/disable command argument
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static uint16_t direction
int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere)
Remove argv[0] as wide.
int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len)
Remove argv[0] as string.
static enum reset_types jtag_reset_config
int adapter_deassert_reset(void)
enum reset_types jtag_get_reset_config(void)
int adapter_assert_reset(void)
The JTAG interface can be implemented with a software or hardware fifo.
static const struct @109 regs[]
#define LOG_USER(expr ...)
#define LOG_WARNING(expr ...)
#define LOG_TARGET_ERROR(target, fmt_str,...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
struct reg * register_get_by_name(struct reg_cache *first, const char *name, bool search_all)
struct reg_cache ** register_get_last_cache_p(struct reg_cache **first)
void register_cache_invalidate(struct reg_cache *cache)
Marks the contents of the register cache as invalid (and clean).
target_addr_t addr
Start address to search for the control block.
size_t size
Size of the control block search area.
#define FLASH_IAPSR_STM8L
static int stm8_init_arch_info(struct target *target, struct stm8_common *stm8, struct jtag_tap *tap)
static int stm8_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)
static int stm8_arch_state(struct target *target)
static int stm8_examine(struct target *target)
static const struct command_registration stm8_command_handlers[]
static const char * stm8_get_gdb_arch(const struct target *target)
static int stm8_set_hwbreak(struct target *target, struct stm8_comparator comparator_list[])
static void stm8_enable_breakpoints(struct target *target)
static int stm8_config_step(struct target *target, int enable)
static int stm8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
static int stm8_exit_debug(struct target *target)
static int stm8_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution)
static int(* adapter_speed)(int speed)
static int stm8_examine_debug_reason(struct target *target)
static int stm8_read_dm_csrx(struct target *target, uint8_t *csr1, uint8_t *csr2)
static int stm8_write_core_reg(struct target *target, unsigned int num)
static int stm8_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
static int stm8_enable_interrupts(struct target *target, int enable)
static int stm8_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
static int stm8_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
static int stm8_debug_entry(struct target *target)
COMMAND_HANDLER(stm8_handle_enable_step_irq_command)
static int stm8_read_core_reg(struct target *target, unsigned int num)
struct target_type stm8_target
static int stm8_blank_check_memory(struct target *target, struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
Checks whether a memory region is erased.
static int stm8_poll(struct target *target)
static int stm8_restore_context(struct target *target)
static int stm8_adapter_write_memory(struct target *target, uint32_t addr, int size, int count, const void *buf)
static int stm8_write_flash(struct target *target, enum mem_type type, uint32_t address, uint32_t size, uint32_t count, uint32_t blocksize_param, const uint8_t *buffer)
static int stm8_init(struct command_context *cmd_ctx, struct target *target)
static int stm8_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
static int stm8_jim_configure(struct target *target, struct jim_getopt_info *goi)
static int stm8_adapter_read_memory(struct target *target, uint32_t addr, int size, int count, void *buf)
static int stm8_write_u8(struct target *target, uint32_t addr, uint8_t val)
static int stm8_read_regs(struct target *target, uint32_t regs[])
static int stm8_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
static struct reg_cache * stm8_build_reg_cache(struct target *target)
static int stm8_get_core_reg(struct reg *reg)
static int stm8_speed(int speed)
static int stm8_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
static int stm8_read_u8(struct target *target, uint32_t addr, uint8_t *val)
static void stm8_free_reg_cache(struct target *target)
static int stm8_reset_assert(struct target *target)
static int stm8_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
static int stm8_halt(struct target *target)
static const struct command_registration stm8_exec_command_handlers[]
#define FLASH_IAPSR_STM8S
static int stm8_unlock_eeprom(struct target *target)
static int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
static int stm8_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
static void stm8_enable_watchpoints(struct target *target)
static void stm8_deinit(struct target *target)
static int stm8_unlock_flash(struct target *target)
static int stm8_set_core_reg(struct reg *reg, uint8_t *buf)
static int stm8_write_regs(struct target *target, uint32_t regs[])
static const struct reg_arch_type stm8_reg_type
static int stm8_save_context(struct target *target)
static int stm8_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
static int stm8_run_and_wait(struct target *target, uint32_t entry_point, unsigned int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)
static const struct @122 stm8_regs[]
static int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)
struct adapter_driver * adapter_driver
static int stm8_reset_deassert(struct target *target)
static int stm8_target_create(struct target *target, Jim_Interp *interp)
static int stm8_single_step_core(struct target *target)
static int stm8_debug_stall(struct target *target)
static int stm8_configure_break_unit(struct target *target)
static int stm8_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
static int stm8_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
#define STM8_COMMON_MAGIC
static struct stm8_common * target_to_stm8(struct target *target)
Represents a driver for a debugging interface.
int(* speed)(int speed)
Set the interface speed.
const char *const name
The name of the interface driver.
enum breakpoint_type type
A TCL -ish GetOpt like code.
int(* get)(struct reg *reg)
struct reg_feature * feature
struct reg_data_type * reg_data_type
const struct reg_arch_type * type
uint8_t num_hw_bpoints_avail
struct stm8_comparator * hw_break_list
uint32_t core_regs[STM8_NUM_CORE_REGS]
int(* write_core_reg)(struct target *target, unsigned int num)
int(* read_core_reg)(struct target *target, unsigned int num)
struct working_area * fast_data_area
unsigned int common_magic
struct reg_cache * core_cache
This holds methods shared between all instances of a given target type.
const char * name
Name of this type of target.
enum target_debug_reason debug_reason
enum target_endianness endianness
struct reg_cache * reg_cache
struct breakpoint * breakpoints
struct watchpoint * watchpoints
int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer)
int swim_system_reset(void)
int swim_write_mem(uint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer)
This file implements support for STMicroelectronics debug protocol SWIM (Single Wire Interface Module...
int target_call_event_callbacks(struct target *target, enum target_event event)
void target_free_all_working_areas(struct target *target)
int target_halt(struct target *target)
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_write_u8(struct target *target, target_addr_t address, uint8_t value)
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
int target_read_u8(struct target *target, target_addr_t address, uint8_t *value)
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
int target_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Write count items of size bytes to the memory of target at the address given.
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
const char * target_state_name(const struct target *t)
Return the name of this targets current state.
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
const char * debug_reason_name(const struct target *t)
int target_wait_state(struct target *target, enum target_state state, unsigned int ms)
struct target * get_current_target(struct command_context *cmd_ctx)
int target_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution)
Make the target (re)start executing using its saved execution context (possibly with some modificatio...
#define ERROR_TARGET_NOT_HALTED
static bool target_was_examined(const struct target *target)
#define ERROR_TARGET_UNALIGNED_ACCESS
#define ERROR_TARGET_INVALID
@ TARGET_EVENT_DEBUG_RESUMED
@ TARGET_EVENT_DEBUG_HALTED
#define ERROR_TARGET_TIMEOUT
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
static void target_set_examined(struct target *target)
Sets the examined flag for the given target.
#define ERROR_TARGET_FAILURE
static uint32_t be_to_h_u24(const uint8_t *buf)
static void h_u16_to_be(uint8_t *buf, uint16_t val)
static void h_u24_to_be(uint8_t *buf, unsigned int val)
static uint16_t be_to_h_u16(const uint8_t *buf)