From 9ba59de212d33cd9245073fdfcb4c842d9eb6ea9 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 6 Jul 2015 15:52:04 +0900 Subject: [PATCH] stlinkv2.py: merge Cortex-M0 support for FSM-55 --- ChangeLog | 16 +++++ tool/asm-thumb/blank_check.S | 2 +- tool/asm-thumb/flash_write.S | 9 ++- tool/asm-thumb/opt_bytes_write.S | 13 ++-- tool/stlinkv2.py | 111 ++++++++++++++++++++++--------- 5 files changed, 109 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index bde1a3e..6dc8cb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2015-07-06 Niibe Yutaka + + Enhancement for FSM-55. + * tool/stlinkv2.py (stlinkv2.control_nrst): New. + (stlinkv2.get_rdp_key,has_spi_flash,has_protection): New. + (stlinkv2.get_core_id): Rename. + (stlinkv2.blank_check): Use self.flash_size. + (stlinkv2.start): Call control_nrst. Call get_core_id. + Distinguishing chip, and set rdp_key, flash_size and require_nrst. + (stlinkv2.flash_write): Use self.flash_block_size. + (main): Call control_nrst. + (prog_flash_write_body, prog_option_bytes_write_body) + (prog_blank_check_body): Support Cortex-M0. + (main): Call API V2 halt twice. + * tool/asm-thumb/*.S: Updated for Cortex-M0. + 2015-06-30 Niibe Yutaka * chopstx: Update. diff --git a/tool/asm-thumb/blank_check.S b/tool/asm-thumb/blank_check.S index 567ef23..53befbf 100644 --- a/tool/asm-thumb/blank_check.S +++ b/tool/asm-thumb/blank_check.S @@ -1,7 +1,7 @@ /* ARM Thumb Assembler code */ // arm-none-eabi-gcc -Wa,-amhls=blank_check.lst -c blank_check.S - .cpu cortex-m3 + .cpu cortex-m0 .thumb ldr r1, .START_ADDR ldr r2, .END_ADDR diff --git a/tool/asm-thumb/flash_write.S b/tool/asm-thumb/flash_write.S index 8f4b16c..66a577d 100644 --- a/tool/asm-thumb/flash_write.S +++ b/tool/asm-thumb/flash_write.S @@ -8,11 +8,9 @@ #define FLASH_SR_OFFSET 0x0c #define FLASH_CR_OFFSET 0x10 -#define COUNT 0x1000 - - .cpu cortex-m3 + .cpu cortex-m0 .thumb - movw r2, #COUNT + ldr r2, .SIZE ldr r0, .SRC_ADDR ldr r1, .TARGET_ADDR ldr r4, .FLASH_BASE_ADDR @@ -35,5 +33,6 @@ bkpt #0x00 .align 2 .FLASH_BASE_ADDR: .word 0x40022000 -.SRC_ADDR: .word 0x20000038 +.SRC_ADDR: .word 0x2000003C .TARGET_ADDR: .word 0x08000000 +.SIZE: .word 0x00000000 diff --git a/tool/asm-thumb/opt_bytes_write.S b/tool/asm-thumb/opt_bytes_write.S index dad89bb..aafcbf9 100644 --- a/tool/asm-thumb/opt_bytes_write.S +++ b/tool/asm-thumb/opt_bytes_write.S @@ -7,11 +7,9 @@ #define FLASH_SR_OFFSET 0x0c #define FLASH_CR_OFFSET 0x10 -#define OB_RDP_UNLOCK 0x00a5 - - .cpu cortex-m3 + .cpu cortex-m0 .thumb - movw r0, #OB_RDP_UNLOCK + ldr r0, .OPTION_BYTES ldr r1, .TARGET_ADDR ldr r2, .FLASH_BASE_ADDR mov r3, #FLASH_CR_OPTPG @@ -21,9 +19,16 @@ 1: ldr r0, [r2, #FLASH_SR_OFFSET] tst r0, r4 bne 1b + add r1, #2 + mov r0, #255 + strh r0, [r1] +2: ldr r0, [r2, #FLASH_SR_OFFSET] + tst r0, r4 + bne 2b mov r0, #0 str r0, [r2, #FLASH_CR_OFFSET] bkpt #0x00 .align 2 .FLASH_BASE_ADDR: .word 0x40022000 .TARGET_ADDR: .word 0x1FFFF800 +.OPTION_BYTES: .word 0x00000000 diff --git a/tool/stlinkv2.py b/tool/stlinkv2.py index 2a2e0d3..bbe188b 100755 --- a/tool/stlinkv2.py +++ b/tool/stlinkv2.py @@ -3,7 +3,7 @@ """ stlinkv2.py - a tool to control ST-Link/V2 -Copyright (C) 2012, 2013 Free Software Initiative of Japan +Copyright (C) 2012, 2013, 2015 Free Software Initiative of Japan Author: NIIBE Yutaka This file is a part of Gnuk, a GnuPG USB Token implementation. @@ -31,11 +31,17 @@ from colorama import init as colorama_init, Fore, Back, Style # Assumes only single ST-Link/V2 device is attached to computer. +CORE_ID_CORTEX_M3=0x1ba01477 +CORE_ID_CORTEX_M0=0x0bb11477 + +CHIP_ID_STM32F103=0x20036410 + GPIOA=0x40010800 GPIOB=0x40010C00 OPTION_BYTES_ADDR=0x1ffff800 -RDP_KEY=0x00a5 # Unlock readprotection +RDP_KEY_F1=0x00a5 # Unlock readprotection +RDP_KEY_F0=0x00aa # Unlock readprotection FLASH_BASE_ADDR=0x40022000 FLASH_KEYR= FLASH_BASE_ADDR+0x04 @@ -62,44 +68,45 @@ FLASH_CR_STRT= 0x0040 FLASH_CR_LOCK= 0x0080 FLASH_CR_OPTWRE= 0x0200 +FLASH_SIZE_F1=0x20000 # 128KiB +FLASH_SIZE_F0=0x4000 # 16KiB SPI1= 0x40013000 def uint32(v): return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24) -## HERE comes: "movw r2,#SIZE" instruction -prog_flash_write_body = "\x0A\x48" + "\x0B\x49" + \ - "\x08\x4C" + "\x01\x25" + "\x14\x26" + "\x00\x27" + "\x25\x61" + \ +prog_flash_write_body = "\x0D\x4A" + "\x0B\x48" + "\x0B\x49" + \ + "\x09\x4C" + "\x01\x25" + "\x14\x26" + "\x00\x27" + "\x25\x61" + \ "\xC3\x5B" + "\xCB\x53" + "\xE3\x68" + "\x2B\x42" + "\xFC\xD1" + \ "\x33\x42" + "\x02\xD1" + "\x02\x37" + "\x97\x42" + "\xF5\xD1" + \ - "\x00\x27" + "\x27\x61" + "\x00\xBE" + "\x00\x20\x02\x40" + \ - "\x38\x00\x00\x20" -# .SRC_ADDR: 0x20000038 + "\x00\x27" + "\x27\x61" + "\x00\xBE" + "\xC0\x46" + "\x00\x20\x02\x40" + \ + "\x3C\x00\x00\x20" +# .SRC_ADDR: 0x2000003C ## HERE comes: target_addr in 4-byte # .TARGET_ADDR +## HERE comes: size in 4-byte +# .SIZE def gen_prog_flash_write(addr,size): - return pack(">12), (0xf2 | (size&0x0800)>>9), - (size & 0x00ff), (0x02 | ((size&0x0700) >> 4))) + \ - prog_flash_write_body + pack(">12), (0xf2 | (val&0x0800)>>9), - (val & 0x00ff), (0x00 | ((val&0x0700) >> 4))) + \ - prog_option_bytes_write_body + pack(" BLOCK_SIZE: - size = BLOCK_SIZE + if len(data[off:]) > self.flash_block_size: + size = self.flash_block_size self.flash_write_internal(addr, data, off, size) off = off + size addr = addr + size @@ -467,6 +478,7 @@ class stlinkv2(object): self.exit_from_dfu() new_mode = self.stl_mode() print "Change ST-Link/V2 mode %04x -> %04x" % (mode, new_mode) + self.control_nrst(2) self.enter_swd() s = self.get_status() if s != 0x0080: @@ -483,6 +495,38 @@ class stlinkv2(object): if mode != 2: raise ValueError("Failed to switch debug mode.", mode) + self.core_id = self.get_core_id() + if self.core_id == CORE_ID_CORTEX_M3: + self.chip_id = self.read_memory_u32(0xE0042000) + elif self.core_id == CORE_ID_CORTEX_M0: + self.chip_id = 0 + else: + raise ValueError("Unknown core ID", self.core_id) + if self.chip_id == CHIP_ID_STM32F103: + self.rdp_key = RDP_KEY_F1 + self.flash_size = FLASH_SIZE_F1 + self.flash_block_size = FLASH_BLOCK_SIZE_F1 + self.require_nrst = False + self.external_spi_flash = True + self.protection_feature = True + else: + self.rdp_key = RDP_KEY_F0 + self.flash_size = FLASH_SIZE_F0 + self.flash_block_size = FLASH_BLOCK_SIZE_F0 + self.require_nrst = True + self.external_spi_flash = False + self.protection_feature = False + return (self.core_id, self.chip_id) + + def get_rdp_key(self): + return self.rdp_key + + def has_spi_flash(self): + return self.external_spi_flash + + def has_protection(self): + return self.protection_feature + USB_VENDOR_ST=0x0483 # 0x0483 SGS Thomson Microelectronics USB_VENDOR_STLINKV2=0x3748 # 0x3748 ST-LINK/V2 @@ -538,9 +582,7 @@ def main(show_help, erase_only, no_protect, spi_flash_check, raise ValueError("No ST-Link/V2 device found.", None) print "ST-Link/V2 version info: %d %d %d" % stl.version() - stl.start() - core_id = stl.core_id() - chip_id = stl.read_memory_u32(0xE0042000) + (core_id, chip_id) = stl.start() # FST-01 chip id: 0x20036410 print "CORE: %08x, CHIP_ID: %08x" % (core_id, chip_id) @@ -553,11 +595,13 @@ def main(show_help, erase_only, no_protect, spi_flash_check, option_bytes = stl.option_bytes_read() print "Option bytes: %08x" % option_bytes - if (option_bytes & 0xff) == RDP_KEY: + rdp_key = stl.get_rdp_key() + if (option_bytes & 0xff) == rdp_key: ob_protection_enable = False else: ob_protection_enable = True + stl.control_nrst(2) stl.enter_debug() status = stl.get_status() if status != 0x0081: @@ -565,6 +609,8 @@ def main(show_help, erase_only, no_protect, spi_flash_check, # DCB_DHCSR DBGKEY|C_HALT|C_DEBUGEN stl.write_debug_reg(0xE000EDF0, 0xA05F0003) status = stl.get_status() + stl.write_debug_reg(0xE000EDF0, 0xA05F0003) + status = stl.get_status() if status != 0x0081: raise ValueError("Status of core is not halt.", status) @@ -602,14 +648,14 @@ def main(show_help, erase_only, no_protect, spi_flash_check, stl.reset_sys() stl.option_bytes_erase() stl.reset_sys() - stl.option_bytes_write(OPTION_BYTES_ADDR,RDP_KEY) + stl.option_bytes_write(OPTION_BYTES_ADDR,rdp_key) stl.usb_disconnect() time.sleep(0.100) stl.finish_gpio() print "Flash ROM read protection disabled. Reset the board, now." return 0 - if spi_flash_check: + if spi_flash_check and stl.has_spi_flash(): stl.spi_flash_init() id = stl.spi_flash_read_id() print "SPI Flash ROM ID: %06x" % id @@ -646,12 +692,13 @@ def main(show_help, erase_only, no_protect, spi_flash_check, off = off + blk_size compare(data, data_received) - if not no_protect: + if not no_protect and stl.has_protection(): print "PROTECT" stl.option_bytes_erase() print "Flash ROM read protection enabled. Reset the board to enable protection." if reset_after_successful_write: + stl.control_nrst(2) stl.usb_disconnect() stl.reset_sys() stl.run()