From 94c822cb62c5d9d6e1a0da50aa9a1b016a629afe Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Fri, 21 Apr 2017 13:33:12 +1200 Subject: [PATCH] nrf51: Replace stub with C version and pass params in registers --- src/target/flashstub/nrf51.c | 37 ++++++++++++++++++++++++++++++ src/target/flashstub/nrf51.s | 40 --------------------------------- src/target/flashstub/nrf51.stub | 2 +- src/target/nrf51.c | 19 +++++----------- 4 files changed, 43 insertions(+), 55 deletions(-) create mode 100644 src/target/flashstub/nrf51.c delete mode 100644 src/target/flashstub/nrf51.s diff --git a/src/target/flashstub/nrf51.c b/src/target/flashstub/nrf51.c new file mode 100644 index 0000000..d291592 --- /dev/null +++ b/src/target/flashstub/nrf51.c @@ -0,0 +1,37 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2017 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * 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 . + */ +#include +#include "stub.h" + +/* Non-Volatile Memory Controller (NVMC) Registers */ +#define NVMC ((volatile uint32_t *)0x4001E000) +#define NVMC_READY NVMC[0x100] + +void __attribute__((naked)) +nrf51_flash_write_stub(volatile uint32_t *dest, uint32_t *src, uint32_t size) +{ + for (int i; i < size; i += 4) { + *dest++ = *src++; + while (!(NVMC_READY & 1)) + ; + } + + stub_exit(0); +} diff --git a/src/target/flashstub/nrf51.s b/src/target/flashstub/nrf51.s deleted file mode 100644 index e23b613..0000000 --- a/src/target/flashstub/nrf51.s +++ /dev/null @@ -1,40 +0,0 @@ -.global _start - -_start: - ldr r0, _ready - ldr r1, _addr - mov r2, pc - add r2, #(_data - . - 2) - ldr r3, _size -_next: - cmp r3, #0 - beq _done - @ Write data to flash - ldr r4, [r2] - str r4, [r1] - -_wait: @ Wait for READY bit - ldr r4, [r0] - mov r6, #1 - tst r4, r6 - beq _wait - - sub r3, #4 - add r1, #4 - add r2, #4 - b _next -_done: - bkpt - -@.align 4 -.org 0x24 -_ready: - .word 0x4001E400 -_addr: - .word 0 -_size: - .word 12 -_data: - .word 0xAAAAAAAA - .word 0xBBBBBBBB - .word 0xCCCCCCCC diff --git a/src/target/flashstub/nrf51.stub b/src/target/flashstub/nrf51.stub index 78292cc..3378abb 100644 --- a/src/target/flashstub/nrf51.stub +++ b/src/target/flashstub/nrf51.stub @@ -1 +1 @@ -0x4808, 0x4909, 0x467A, 0x3228, 0x4B08, 0x2B00, 0xD009, 0x6814, 0x600C, 0x6804, 0x2601, 0x4234, 0xD0FB, 0x3B04, 0x3104, 0x3204, 0xE7F3, 0xBE00, 0xE400, 0x4001, 0x0000, 0x0000, 0x000C, 0x0000, 0xAAAA, 0xAAAA, 0xBBBB, 0xBBBB, 0xCCCC, 0xCCCC, \ No newline at end of file +0x2300, 0x2601, 0x4D06, 0x1AC9, 0x18C4, 0x429A, 0xD800, 0xBE00, 0x58CF, 0x6027, 0x682C, 0x4234, 0xD0FC, 0x3304, 0xE7F4, 0x46C0, 0xE400, 0x4001, \ No newline at end of file diff --git a/src/target/nrf51.c b/src/target/nrf51.c index d495507..2e361c6 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -82,7 +82,7 @@ const struct command_s nrf51_read_cmd_list[] = { #define NRF52_PAGE_SIZE 4096 #define SRAM_BASE 0x20000000 -#define STUB_BUFFER_BASE (SRAM_BASE + 0x28) +#define STUB_BUFFER_BASE ALIGN(SRAM_BASE + sizeof(nrf51_flash_write_stub), 4) static const uint16_t nrf51_flash_write_stub[] = { #include "flashstub/nrf51.stub" @@ -219,14 +219,6 @@ static int nrf51_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len) { target *t = f->t; - uint32_t data[2 + len/4]; - - /* FIXME rewrite stub to use register args */ - - /* Construct data buffer used by stub */ - data[0] = dest; - data[1] = len; /* length must always be a multiple of 4 */ - memcpy((uint8_t *)&data[2], src, len); /* Enable write */ target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_WEN); @@ -239,13 +231,13 @@ static int nrf51_flash_write(struct target_flash *f, /* Write stub and data to target ram and call stub */ target_mem_write(t, SRAM_BASE, nrf51_flash_write_stub, sizeof(nrf51_flash_write_stub)); - target_mem_write(t, STUB_BUFFER_BASE, data, len + 8); - cortexm_run_stub(t, SRAM_BASE, 0, 0, 0, 0); - + target_mem_write(t, STUB_BUFFER_BASE, src, len); + int ret = cortexm_run_stub(t, SRAM_BASE, dest, + STUB_BUFFER_BASE, len, 0); /* Return to read-only */ target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN); - return 0; + return ret; } static bool nrf51_cmd_erase_all(target *t) @@ -332,4 +324,3 @@ static bool nrf51_cmd_read(target *t, int argc, const char *argv[]) return nrf51_cmd_read_help(t); } -