New STM8 target based mostly on mips4k. Target communication through STLINK/SWIM. No flash driver yet but it is still possible to program flash through load_image command. The usual target debug methods are implemented. Change-Id: I7216f231d3ac7c70cae20f1cd8463c2ed864a329 Signed-off-by: Ake Rehnman <ake.rehnman@gmail.com> Reviewed-on: http://openocd.zylin.com/3953 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-by: Paul Fertser <fercerpav@gmail.com>jim-nrf5-free
@@ -1,6 +1,6 @@ | |||
.PHONY: arm clean-arm | |||
all: arm | |||
all: arm stm8 | |||
common_dirs = \ | |||
checksum \ | |||
@@ -32,3 +32,6 @@ clean: clean-arm | |||
for d in $(common_dirs); do \ | |||
$(MAKE) -C $$d clean; \ | |||
done | |||
stm8: | |||
$(MAKE) -C erase_check stm8 |
@@ -6,6 +6,12 @@ ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy | |||
ARM_AFLAGS = -EL | |||
STM8_CROSS_COMPILE ?= stm8- | |||
STM8_AS ?= $(STM8_CROSS_COMPILE)as | |||
STM8_OBJCOPY ?= $(STM8_CROSS_COMPILE)objcopy | |||
STM8_AFLAGS = | |||
arm: armv4_5_erase_check.inc armv7m_erase_check.inc armv7m_0_erase_check.inc | |||
armv4_5_%.elf: armv4_5_%.s | |||
@@ -26,5 +32,16 @@ armv7m_%.bin: armv7m_%.elf | |||
armv7m_%.inc: armv7m_%.bin | |||
$(BIN2C) < $< > $@ | |||
stm8: stm8_erase_check.inc | |||
stm8_%.elf: stm8_%.s | |||
$(STM8_AS) $(STM8_AFLAGS) $< -o $@ | |||
stm8_%.bin: stm8_%.elf | |||
$(STM8_OBJCOPY) -Obinary $< $@ | |||
stm8_%.inc: stm8_%.bin | |||
$(BIN2C) < $< > $@ | |||
clean: | |||
-rm -f *.elf *.bin *.inc |
@@ -0,0 +1,5 @@ | |||
/* Autogenerated with ../../../src/helper/bin2char.sh */ | |||
0x00,0x80,0x00,0x00,0x80,0x00,0x96,0xcf,0x00,0x22,0x1e,0x01,0x16,0x04,0xa6,0xff, | |||
0x90,0x5d,0x26,0x04,0x0d,0x03,0x27,0x17,0x90,0x5d,0x26,0x02,0x0a,0x03,0x90,0x5a, | |||
0x92,0xbc,0x00,0x00,0xa1,0xff,0x26,0x07,0x5c,0x26,0xe5,0x0c,0x00,0x20,0xe1,0x1f, | |||
0x01,0x17,0x04,0x8b, |
@@ -0,0 +1,69 @@ | |||
/* | |||
Copyright (C) 2017 Ake Rehnman | |||
ake.rehnman(at)gmail.com | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 3 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
;; | |||
;; erase check memory code | |||
;; | |||
.org 0x0 | |||
;; start address | |||
start_addr: .byte 0x00 | |||
.word 0x8000 | |||
;; byte count | |||
byte_cnt: .byte 0x00 | |||
.word 0x8000 | |||
; | |||
; SP must point to start_addr on entry | |||
; first relocate start_addr to the location | |||
; we are running at | |||
start: | |||
ldw X,SP | |||
ldw .cont+2,X | |||
ldw X,(start_addr+1,SP) ;start addr | |||
ldw Y,(byte_cnt+1,SP) ;count | |||
ld A,#0xff | |||
; | |||
; if count == 0 return | |||
.L1: | |||
tnzw Y | |||
jrne .decrcnt ;continue if low word != 0 | |||
tnz (byte_cnt,SP) ;high byte | |||
jreq .exit ;goto exit | |||
; | |||
; decrement count (byte_cnt) | |||
.decrcnt: | |||
tnzw Y ;low word count | |||
jrne .decr1 | |||
dec (byte_cnt,SP) ;high byte | |||
.decr1: | |||
decw Y; decr low word | |||
; | |||
; first check if [start_addr] is 0xff | |||
.cont: | |||
ldf A, [start_addr.e] | |||
cp A,#0xff | |||
jrne .exit ;exit if not 0xff | |||
; | |||
; increment start_addr (addr) | |||
incw X | |||
jrne .L1 | |||
inc (start_addr,SP) ;increment high byte | |||
jra .L1 | |||
; | |||
.exit: | |||
ldw (start_addr+1,SP),X ;start addr | |||
ldw (byte_cnt+1,SP),Y ;count | |||
break |
@@ -19,6 +19,7 @@ noinst_LTLIBRARIES += %D%/libtarget.la | |||
$(AVR32_SRC) \ | |||
$(MIPS32_SRC) \ | |||
$(NDS32_SRC) \ | |||
$(STM8_SRC) \ | |||
$(INTEL_IA32_SRC) \ | |||
%D%/avrt.c \ | |||
%D%/dsp563xx.c \ | |||
@@ -124,6 +125,9 @@ NDS32_SRC = \ | |||
%D%/nds32_v3m.c \ | |||
%D%/nds32_aice.c | |||
STM8_SRC = \ | |||
%D%/stm8.c | |||
INTEL_IA32_SRC = \ | |||
%D%/quark_x10xx.c \ | |||
%D%/quark_d20xx.c \ | |||
@@ -205,6 +209,7 @@ INTEL_IA32_SRC = \ | |||
%D%/nds32_v3.h \ | |||
%D%/nds32_v3m.h \ | |||
%D%/nds32_aice.h \ | |||
%D%/stm8.h \ | |||
%D%/lakemont.h \ | |||
%D%/x86_32_common.h \ | |||
%D%/arm_cti.h | |||
@@ -0,0 +1,75 @@ | |||
/* | |||
OpenOCD STM8 target driver | |||
Copyright (C) 2017 Ake Rehnman | |||
ake.rehnman(at)gmail.com | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 3 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef OPENOCD_TARGET_STM8_H | |||
#define OPENOCD_TARGET_STM8_H | |||
struct target; | |||
#define STM8_COMMON_MAGIC 0x53544D38 | |||
#define STM8_NUM_CORE_REGS 6 | |||
struct stm8_common { | |||
uint32_t common_magic; | |||
void *arch_info; | |||
struct reg_cache *core_cache; | |||
uint32_t core_regs[STM8_NUM_CORE_REGS]; | |||
/* working area for fastdata access */ | |||
struct working_area *fast_data_area; | |||
bool swim_configured; | |||
bool bp_scanned; | |||
uint8_t num_hw_bpoints; | |||
uint8_t num_hw_bpoints_avail; | |||
struct stm8_comparator *hw_break_list; | |||
uint32_t blocksize; | |||
uint32_t flashstart; | |||
uint32_t flashend; | |||
uint32_t eepromstart; | |||
uint32_t eepromend; | |||
uint32_t optionstart; | |||
uint32_t optionend; | |||
bool enable_step_irq; | |||
bool enable_stm8l; | |||
uint32_t flash_cr2; | |||
uint32_t flash_ncr2; | |||
uint32_t flash_iapsr; | |||
uint32_t flash_dukr; | |||
uint32_t flash_pukr; | |||
/* cc value used for interrupt flags restore */ | |||
uint32_t cc; | |||
bool cc_valid; | |||
/* register cache to processor synchronization */ | |||
int (*read_core_reg)(struct target *target, unsigned int num); | |||
int (*write_core_reg)(struct target *target, unsigned int num); | |||
}; | |||
static inline struct stm8_common * | |||
target_to_stm8(struct target *target) | |||
{ | |||
return target->arch_info; | |||
} | |||
const struct command_registration stm8_command_handlers[]; | |||
#endif /* OPENOCD_TARGET_STM8_H */ |
@@ -105,6 +105,7 @@ extern struct target_type nds32_v3m_target; | |||
extern struct target_type or1k_target; | |||
extern struct target_type quark_x10xx_target; | |||
extern struct target_type quark_d20xx_target; | |||
extern struct target_type stm8_target; | |||
static struct target_type *target_types[] = { | |||
&arm7tdmi_target, | |||
@@ -136,6 +137,7 @@ static struct target_type *target_types[] = { | |||
&or1k_target, | |||
&quark_x10xx_target, | |||
&quark_d20xx_target, | |||
&stm8_target, | |||
#if BUILD_TARGET64 | |||
&aarch64_target, | |||
#endif | |||
@@ -0,0 +1,87 @@ | |||
# script for stm8l family | |||
# | |||
# stm8 devices support SWIM transports only. | |||
# | |||
transport select stlink_swim | |||
if { [info exists CHIPNAME] } { | |||
set _CHIPNAME $CHIPNAME | |||
} else { | |||
set _CHIPNAME stm8l | |||
} | |||
# Work-area is a space in RAM used for flash programming | |||
# By default use 1kB | |||
if { [info exists WORKAREASIZE] } { | |||
set _WORKAREASIZE $WORKAREASIZE | |||
} else { | |||
set _WORKAREASIZE 0x400 | |||
} | |||
if { [info exists FLASHSTART] } { | |||
set _FLASHSTART $FLASHSTART | |||
} else { | |||
set _FLASHSTART 0x8000 | |||
} | |||
if { [info exists FLASHEND] } { | |||
set _FLASHEND $FLASHEND | |||
} else { | |||
set _FLASHEND 0xffff | |||
} | |||
if { [info exists EEPROMSTART] } { | |||
set _EEPROMSTART $EEPROMSTART | |||
} else { | |||
set _EEPROMSTART 0x4000 | |||
} | |||
if { [info exists EEPROMEND] } { | |||
set _EEPROMEND $EEPROMEND | |||
} else { | |||
set _EEPROMEND 0x43ff | |||
} | |||
if { [info exists OPTIONSTART] } { | |||
set _OPTIONSTART $OPTIONSTART | |||
} else { | |||
set _OPTIONSTART 0x4800 | |||
} | |||
if { [info exists OPTIONEND] } { | |||
set _OPTIONEND $OPTIONEND | |||
} else { | |||
set _OPTIONEND 0x487f | |||
} | |||
if { [info exists BLOCKSIZE] } { | |||
set _BLOCKSIZE $BLOCKSIZE | |||
} else { | |||
set _BLOCKSIZE 0x80 | |||
} | |||
hla newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0 | |||
set _TARGETNAME $_CHIPNAME.cpu | |||
target create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu | |||
$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1 | |||
$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND | |||
$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE | |||
# Uncomment this line to enable interrupts while instruction step | |||
#$_TARGETNAME configure -enable_step_irq | |||
# Set stm8l type | |||
$_TARGETNAME configure -enable_stm8l | |||
# The khz rate does not apply here, only slow <0> and fast <1> | |||
adapter_khz 1 | |||
reset_config srst_only | |||
#uncomment this line to connect under reset | |||
#reset_config srst_nogate connect_assert_srst |
@@ -0,0 +1,84 @@ | |||
# script for stm8s family | |||
# | |||
# stm8 devices support SWIM transports only. | |||
# | |||
transport select stlink_swim | |||
if { [info exists CHIPNAME] } { | |||
set _CHIPNAME $CHIPNAME | |||
} else { | |||
set _CHIPNAME stm8s | |||
} | |||
# Work-area is a space in RAM used for flash programming | |||
# By default use 1kB | |||
if { [info exists WORKAREASIZE] } { | |||
set _WORKAREASIZE $WORKAREASIZE | |||
} else { | |||
set _WORKAREASIZE 0x400 | |||
} | |||
if { [info exists FLASHSTART] } { | |||
set _FLASHSTART $FLASHSTART | |||
} else { | |||
set _FLASHSTART 0x8000 | |||
} | |||
if { [info exists FLASHEND] } { | |||
set _FLASHEND $FLASHEND | |||
} else { | |||
set _FLASHEND 0xffff | |||
} | |||
if { [info exists EEPROMSTART] } { | |||
set _EEPROMSTART $EEPROMSTART | |||
} else { | |||
set _EEPROMSTART 0x4000 | |||
} | |||
if { [info exists EEPROMEND] } { | |||
set _EEPROMEND $EEPROMEND | |||
} else { | |||
set _EEPROMEND 0x43ff | |||
} | |||
if { [info exists OPTIONSTART] } { | |||
set _OPTIONSTART $OPTIONSTART | |||
} else { | |||
set _OPTIONSTART 0x4800 | |||
} | |||
if { [info exists OPTIONEND] } { | |||
set _OPTIONEND $OPTIONEND | |||
} else { | |||
set _OPTIONEND 0x487f | |||
} | |||
if { [info exists BLOCKSIZE] } { | |||
set _BLOCKSIZE $BLOCKSIZE | |||
} else { | |||
set _BLOCKSIZE 0x80 | |||
} | |||
hla newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0 | |||
set _TARGETNAME $_CHIPNAME.cpu | |||
target create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu | |||
$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1 | |||
$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND | |||
$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE | |||
# Uncomment this line to enable interrupts while instruction step | |||
#$_TARGETNAME configure -enable_step_irq | |||
# The khz rate does not apply here, only slow <0> and fast <1> | |||
adapter_khz 1 | |||
reset_config srst_only | |||
# uncomment this line to connect under reset | |||
#reset_config srst_nogate connect_assert_srst |