diff options
Diffstat (limited to 'contrib/loaders')
21 files changed, 656 insertions, 167 deletions
diff --git a/contrib/loaders/debug/xscale/debug_handler.S b/contrib/loaders/debug/xscale/debug_handler.S index 66dfa88..0f62d9c 100644 --- a/contrib/loaders/debug/xscale/debug_handler.S +++ b/contrib/loaders/debug/xscale/debug_handler.S @@ -713,4 +713,3 @@ send_to_debugger: receive_from_debugger: m_receive_from_debugger r0 mov pc, lr - diff --git a/contrib/loaders/erase_check/stm8_erase_check.s b/contrib/loaders/erase_check/stm8_erase_check.s index 6269400..04cde5b 100644 --- a/contrib/loaders/erase_check/stm8_erase_check.s +++ b/contrib/loaders/erase_check/stm8_erase_check.s @@ -1,19 +1,19 @@ /* - 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/>. +* 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 2 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 diff --git a/contrib/loaders/flash/armv7m_io.s b/contrib/loaders/flash/armv7m_io.s index 797981c..f6dbbe9 100644 --- a/contrib/loaders/flash/armv7m_io.s +++ b/contrib/loaders/flash/armv7m_io.s @@ -57,4 +57,3 @@ done_write: bkpt #0 .end - diff --git a/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld b/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld index ea06931..8cb2118 100644 --- a/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld +++ b/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld @@ -129,4 +129,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/contrib/loaders/flash/at91sam7x/makefile b/contrib/loaders/flash/at91sam7x/makefile index c3eaf12..3948297 100644 --- a/contrib/loaders/flash/at91sam7x/makefile +++ b/contrib/loaders/flash/at91sam7x/makefile @@ -127,4 +127,4 @@ clean: # #-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF ***
\ No newline at end of file +# *** EOF *** diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c index 3dd17b2..f09f7f5 100644 --- a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c +++ b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c @@ -2,6 +2,7 @@ /* Then postprocess output of command "arm-none-eabi-objdump -d bluenrgx.o" to make a C array of bytes */ #include <stdint.h> +#include "../../../../src/flash/nor/bluenrg-x.h" /* Status Values ----------------------------------------------------------*/ #define SUCCESS 0 @@ -13,43 +14,22 @@ #define ERR_ERASE_REQUIRED 6 #define ERR_VERIFY_FAILED 7 -/* Flash Controller defines ---------------------------------------------------*/ -#define FLASH_REG_COMMAND ((volatile uint32_t *)0x40100000) -#define FLASH_REG_CONFIG ((volatile uint32_t *)0x40100004) -#define FLASH_REG_IRQSTAT ((volatile uint32_t *)0x40100008) -#define FLASH_REG_IRQMASK ((volatile uint32_t *)0x4010000C) -#define FLASH_REG_IRQRAW ((volatile uint32_t *)0x40100010) -#define FLASH_REG_ADDRESS ((volatile uint32_t *)0x40100018) -#define FLASH_REG_UNLOCKM ((volatile uint32_t *)0x4010001C) -#define FLASH_REG_UNLOCKL ((volatile uint32_t *)0x40100020) -#define FLASH_REG_DATA0 ((volatile uint32_t *)0x40100040) -#define FLASH_REG_DATA1 ((volatile uint32_t *)0x40100044) -#define FLASH_REG_DATA2 ((volatile uint32_t *)0x40100048) -#define FLASH_REG_DATA3 ((volatile uint32_t *)0x4010004C) -#define FLASH_SIZE_REG 0x40100014 - #define MFB_MASS_ERASE 0x01 #define MFB_PAGE_ERASE 0x02 #define DO_ERASE 0x0100 #define DO_VERIFY 0x0200 -#define FLASH_CMD_ERASE_PAGE 0x11 -#define FLASH_CMD_MASSERASE 0x22 -#define FLASH_CMD_WRITE 0x33 -#define FLASH_CMD_BURSTWRITE 0xCC -#define FLASH_INT_CMDDONE 0x01 -#define MFB_BOTTOM (0x10040000) -#define MFB_SIZE_B ((16 * (((*(uint32_t *) FLASH_SIZE_REG) + 1) >> 12)) * 1024) -#define MFB_SIZE_W (MFB_SIZE_B/4) -#define MFB_TOP (MFB_BOTTOM+MFB_SIZE_B-1) -#define MFB_PAGE_SIZE_B (2048) -#define MFB_PAGE_SIZE_W (MFB_PAGE_SIZE_B/4) + +#define MFB_BOTTOM (0x10040000) +#define MFB_SIZE_B(regs_base) ((16 * (((*(volatile uint32_t *)(regs_base + FLASH_SIZE_REG)) + 1) >> 12)) * 1024) +#define MFB_SIZE_W (MFB_SIZE_B/4) +#define MFB_TOP (MFB_BOTTOM+MFB_SIZE_B-1) +#define MFB_PAGE_SIZE_B (2048) +#define MFB_PAGE_SIZE_W (MFB_PAGE_SIZE_B/4) #define AREA_ERROR 0x01 #define AREA_MFB 0x04 -#define FLASH_WORD_LEN 4 - typedef struct { volatile uint8_t *wp; uint8_t *rp; @@ -57,29 +37,29 @@ typedef struct { /* Flash Commands --------------------------------------------------------*/ static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t address, uint8_t **data, - uint32_t writeLength) + uint32_t writeLength, uint32_t flash_regs_base) { uint32_t index, flash_word[4]; uint8_t i; - *FLASH_REG_IRQMASK = 0; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQMASK)) = 0; for (index = 0; index < writeLength; index += (FLASH_WORD_LEN*4)) { for (i = 0; i < 4; i++) flash_word[i] = (*(uint32_t *) (*data + i*4)); /* Clear the IRQ flags */ - *FLASH_REG_IRQRAW = 0x0000003F; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) = 0x0000003F; /* Load the flash address to write */ - *FLASH_REG_ADDRESS = (uint16_t)((address + index) >> 2); + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_ADDRESS)) = (uint16_t)((address + index - MFB_BOTTOM) >> 2); /* Prepare and load the data to flash */ - *FLASH_REG_DATA0 = flash_word[0]; - *FLASH_REG_DATA1 = flash_word[1]; - *FLASH_REG_DATA2 = flash_word[2]; - *FLASH_REG_DATA3 = flash_word[3]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA0)) = flash_word[0]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA1)) = flash_word[1]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA2)) = flash_word[2]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA3)) = flash_word[3]; /* Flash write command */ - *FLASH_REG_COMMAND = FLASH_CMD_BURSTWRITE; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_COMMAND)) = FLASH_CMD_BURSTWRITE; /* Wait the end of the flash write command */ - while ((*FLASH_REG_IRQRAW & FLASH_INT_CMDDONE) == 0) + while ((*((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) & FLASH_INT_CMDDONE) == 0) ; *data += (FLASH_WORD_LEN * 4); } @@ -90,7 +70,8 @@ static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t addres __attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p, uint8_t *fifo_end, uint8_t *target_address, - uint32_t count) + uint32_t count, + uint32_t flash_regs_base) { uint32_t retval; volatile work_area_t *work_area = (work_area_t *) work_area_p; @@ -118,7 +99,7 @@ __attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p continue; } - retval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size); + retval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size, flash_regs_base); if (retval != SUCCESS) { work_area->rp = (uint8_t *)retval; break; diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc index 47f3312..ff05634 100644 --- a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc +++ b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc @@ -1,18 +1,17 @@ /* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x05,0x93,0x43,0x68,0x05,0x00,0x07,0x93,0x05,0x9b,0x06,0x91,0x03,0x92,0x35,0x4c, -0x00,0x2b,0x5c,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0xfb,0xd0,0x2b,0x68,0x00,0x2b, -0x55,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0x52,0xd9,0x6b,0x68,0x06,0x9a,0xd3,0x1a, -0x09,0x93,0x09,0x9b,0x0f,0x2b,0xed,0xdd,0x00,0x21,0x09,0x9b,0x04,0x93,0x1a,0x1e, -0x29,0x4b,0x19,0x60,0x32,0xd0,0x29,0x4b,0x00,0x20,0x98,0x46,0x28,0x4b,0x6a,0x68, -0x9c,0x46,0x28,0x4b,0x28,0x4e,0x9b,0x46,0x28,0x4b,0x9a,0x46,0x28,0x4b,0x99,0x46, -0x01,0x23,0x51,0x68,0x17,0x68,0x00,0x91,0x91,0x68,0x01,0x91,0xd1,0x68,0x02,0x91, -0x3f,0x21,0x21,0x60,0x03,0x99,0x09,0x18,0x89,0x03,0x09,0x0c,0x31,0x60,0x41,0x46, -0x0f,0x60,0x67,0x46,0x00,0x99,0x39,0x60,0x5f,0x46,0x01,0x99,0x39,0x60,0x57,0x46, -0x02,0x99,0x39,0x60,0x49,0x46,0xcc,0x27,0x0f,0x60,0x21,0x68,0x0b,0x42,0xfc,0xd0, -0x04,0x99,0x10,0x32,0x10,0x30,0x6a,0x60,0x81,0x42,0xda,0xd8,0x03,0x9a,0x09,0x9b, -0x94,0x46,0x9c,0x44,0x63,0x46,0x06,0x9a,0x03,0x93,0x6b,0x68,0x9a,0x42,0x01,0xd8, -0x07,0x9b,0x6b,0x60,0x05,0x9a,0x09,0x9b,0xd3,0x1a,0x05,0x93,0xa2,0xd1,0x00,0xbe, -0x2b,0x68,0x6a,0x68,0x9b,0x1a,0x09,0x93,0x09,0x9b,0x00,0x2b,0xa9,0xda,0x00,0x23, -0x09,0x93,0xa6,0xe7,0x10,0x00,0x10,0x40,0x0c,0x00,0x10,0x40,0x40,0x00,0x10,0x40, -0x44,0x00,0x10,0x40,0x48,0x00,0x10,0x40,0x18,0x00,0x10,0x40,0x4c,0x00,0x10,0x40, -0x00,0x00,0x10,0x40, +0x05,0x93,0x43,0x68,0x14,0x9e,0x09,0x93,0x05,0x9b,0x05,0x00,0x07,0x91,0x06,0x92, +0x01,0x24,0xb1,0x46,0x00,0x2b,0x68,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0xfb,0xd0, +0x2b,0x68,0x00,0x2b,0x61,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0x5e,0xd9,0x6b,0x68, +0x07,0x9a,0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x4a,0x46,0x00,0x21,0x03,0x93,0xd1,0x60, +0x00,0x2b,0x42,0xd0,0x40,0x22,0x4a,0x44,0x90,0x46,0x44,0x22,0x4a,0x44,0x00,0x92, +0x48,0x22,0x4a,0x44,0x93,0x46,0x4c,0x22,0x27,0x4f,0x4a,0x44,0xbc,0x46,0x4e,0x46, +0x92,0x46,0x06,0x99,0x4b,0x46,0x61,0x44,0x08,0x00,0x00,0x99,0x18,0x36,0x6a,0x68, +0x08,0x95,0x8c,0x46,0x55,0x46,0xda,0x46,0xb3,0x46,0x10,0x33,0x04,0x92,0x11,0x68, +0x5e,0x46,0x00,0x91,0x51,0x68,0x97,0x68,0x01,0x91,0xd1,0x68,0x02,0x91,0x3f,0x21, +0x19,0x60,0x81,0x03,0x09,0x0c,0x31,0x60,0x46,0x46,0x00,0x99,0x31,0x60,0x66,0x46, +0x01,0x99,0x31,0x60,0x56,0x46,0x02,0x99,0x37,0x60,0x29,0x60,0xcc,0x26,0x49,0x46, +0x0e,0x60,0x19,0x68,0x0c,0x42,0xfc,0xd0,0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30, +0x51,0x1a,0x8e,0x42,0xdb,0xd8,0x08,0x9d,0x6a,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46, +0x63,0x44,0x06,0x93,0x07,0x9a,0x6b,0x68,0x9a,0x42,0x01,0xd8,0x09,0x9b,0x6b,0x60, +0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93,0x96,0xd1,0x00,0xbe,0x2b,0x68,0x6a,0x68, +0x9b,0x1a,0x9f,0xd5,0x90,0xe7,0xc0,0x46,0x00,0x00,0xfc,0xef, diff --git a/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds b/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds index 7798b30..0e7aa2d 100644 --- a/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds +++ b/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds @@ -148,4 +148,3 @@ SECTIONS { __stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK); PROVIDE(__stack = __stack_top); } - diff --git a/contrib/loaders/flash/nrf5/Makefile b/contrib/loaders/flash/nrf5/Makefile new file mode 100644 index 0000000..67390b9 --- /dev/null +++ b/contrib/loaders/flash/nrf5/Makefile @@ -0,0 +1,28 @@ +BIN2C = ../../../../src/helper/bin2char.sh + +CROSS_COMPILE ?= arm-none-eabi- + +CC=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy +OBJDUMP=$(CROSS_COMPILE)objdump + +CFLAGS = -static -nostartfiles -mlittle-endian -Wa,-EL + +all: nrf5.inc + +.PHONY: clean + +%.elf: %.S + $(CC) $(CFLAGS) $< -o $@ + +%.lst: %.elf + $(OBJDUMP) -S $< > $@ + +%.bin: %.elf + $(OBJCOPY) -Obinary $< $@ + +%.inc: %.bin + $(BIN2C) < $< > $@ + +clean: + -rm -f *.elf *.lst *.bin *.inc diff --git a/contrib/loaders/flash/nrf5/nrf5.S b/contrib/loaders/flash/nrf5/nrf5.S new file mode 100644 index 0000000..12b1d92 --- /dev/null +++ b/contrib/loaders/flash/nrf5/nrf5.S @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2014 Angus Gratton * + * gus@projectgus.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 2 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, write to the * + * Free Software Foundation, Inc. * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m0 + .thumb + +/* + * Params : + * r0 = byte count + * r1 = buffer start + * r2 = buffer end + * r3 = target address + * r6 = watchdog refresh value + * r7 = watchdog refresh register address + */ + + .thumb_func + .global _start +_start: +wait_fifo: + // Kick the watchdog + str r6, [r7, #0] + // Load write pointer + ldr r5, [r1, #0] + // Abort if it is NULL + cmp r5, #0 + beq.n exit + // Load read pointer + ldr r4, [r1, #4] + // Continue waiting if it equals the write pointer + cmp r4, r5 + beq.n wait_fifo + // Copy one word from buffer to target, and increment pointers + ldmia r4!, {r5} + stmia r3!, {r5} + // If at end of buffer, wrap back to buffer start + cmp r4, r2 + bcc.n no_wrap + mov r4, r1 + adds r4, #8 +no_wrap: + // Update read pointer inside the buffer + str r4, [r1, #4] + // Deduce the word transferred from the byte count + subs r0, #4 + // Start again + bne.n wait_fifo +exit: + // Wait for OpenOCD + bkpt #0x00 + + .pool diff --git a/contrib/loaders/flash/nrf5/nrf5.inc b/contrib/loaders/flash/nrf5/nrf5.inc new file mode 100644 index 0000000..2b35b5d --- /dev/null +++ b/contrib/loaders/flash/nrf5/nrf5.inc @@ -0,0 +1,4 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0x3e,0x60,0x0d,0x68,0x00,0x2d,0x0b,0xd0,0x4c,0x68,0xac,0x42,0xf8,0xd0,0x20,0xcc, +0x20,0xc3,0x94,0x42,0x01,0xd3,0x0c,0x46,0x08,0x34,0x4c,0x60,0x04,0x38,0xef,0xd1, +0x00,0xbe, diff --git a/contrib/loaders/flash/sh_qspi/Makefile b/contrib/loaders/flash/sh_qspi/Makefile new file mode 100644 index 0000000..2bfbad1 --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/Makefile @@ -0,0 +1,37 @@ +CROSS_COMPILE=arm-linux-gnueabihf- +BIN2C = ../../../../src/helper/bin2char.sh + +TGT = sh_qspi +ASRC += sh_qspi.S +LDS = sh_qspi.ld + +OBJS += $(ASRC:.S=.o) + +CC=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy +OBJDUMP=$(CROSS_COMPILE)objdump +LD=$(CROSS_COMPILE)ld +NM=$(CROSS_COMPILE)nm +SIZE=$(CROSS_COMPILE)size + +CFLAGS=-Os -Wall -nostartfiles -marm -nostdinc -ffreestanding -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -msoft-float -pipe -march=armv7-a -mtune=generic-armv7-a +LDFLAGS=-T$(LDS) -nostdlib -Map=$(TGT).map + +all: $(TGT).inc + +%.o: %.S + $(CC) $(CFLAGS) -c $^ -o $@ + +$(TGT).elf: $(OBJS) + $(LD) $(LDFLAGS) $^ -o $@ + +$(TGT).bin: $(TGT).elf + $(OBJCOPY) $< -O binary $@ + $(NM) -n $(TGT).elf > $(TGT).sym + $(SIZE) $(TGT).elf + +$(TGT).inc: $(TGT).bin + $(BIN2C) < $< > $@ + +clean: + rm -rf *.elf *.hex *.map *.o *.disasm *.sym diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.S b/contrib/loaders/flash/sh_qspi/sh_qspi.S new file mode 100644 index 0000000..78eb1e8 --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/sh_qspi.S @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * SH QSPI (Quad SPI) driver + * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com> + */ + +#define BIT(n) (1UL << (n)) +/* SH QSPI register bit masks <REG>_<BIT> */ +#define SPCR_MSTR 0x08 +#define SPCR_SPE 0x40 +#define SPSR_SPRFF 0x80 +#define SPSR_SPTEF 0x20 +#define SPPCR_IO3FV 0x04 +#define SPPCR_IO2FV 0x02 +#define SPPCR_IO1FV 0x01 +#define SPBDCR_RXBC0 BIT(0) +#define SPCMD_SCKDEN BIT(15) +#define SPCMD_SLNDEN BIT(14) +#define SPCMD_SPNDEN BIT(13) +#define SPCMD_SSLKP BIT(7) +#define SPCMD_BRDV0 BIT(2) +#define SPCMD_INIT1 SPCMD_SCKDEN | SPCMD_SLNDEN | \ + SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0 +#define SPCMD_INIT2 SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0 +#define SPBFCR_TXRST BIT(7) +#define SPBFCR_RXRST BIT(6) +#define SPBFCR_TXTRG 0x30 +#define SPBFCR_RXTRG 0x07 + +/* SH QSPI register set */ +#define SH_QSPI_SPCR 0x00 +#define SH_QSPI_SSLP 0x01 +#define SH_QSPI_SPPCR 0x02 +#define SH_QSPI_SPSR 0x03 +#define SH_QSPI_SPDR 0x04 +#define SH_QSPI_SPSCR 0x08 +#define SH_QSPI_SPSSR 0x09 +#define SH_QSPI_SPBR 0x0a +#define SH_QSPI_SPDCR 0x0b +#define SH_QSPI_SPCKD 0x0c +#define SH_QSPI_SSLND 0x0d +#define SH_QSPI_SPND 0x0e +#define SH_QSPI_DUMMY0 0x0f +#define SH_QSPI_SPCMD0 0x10 +#define SH_QSPI_SPCMD1 0x12 +#define SH_QSPI_SPCMD2 0x14 +#define SH_QSPI_SPCMD3 0x16 +#define SH_QSPI_SPBFCR 0x18 +#define SH_QSPI_DUMMY1 0x19 +#define SH_QSPI_SPBDCR 0x1a +#define SH_QSPI_SPBMUL0 0x1c +#define SH_QSPI_SPBMUL1 0x20 +#define SH_QSPI_SPBMUL2 0x24 +#define SH_QSPI_SPBMUL3 0x28 + +.syntax unified +.arm +.text + +.macro wait_for_spsr, spsrbit + 1: ldrb r12, [r0, #SH_QSPI_SPSR] + tst r12, \spsrbit + beq 1b +.endm + +.macro sh_qspi_xfer + bl sh_qspi_cs_activate + str r6, [r0, SH_QSPI_SPBMUL0] + bl sh_qspi_xfer_common + bl sh_qspi_cs_deactivate +.endm + +.macro sh_qspi_write_enable + ldr r4, =SPIFLASH_WRITE_ENABLE + adr r5, _start + add r4, r5 + mov r5, #0x0 + mov r6, #0x1 + sh_qspi_xfer +.endm + +.macro sh_qspi_wait_till_ready + 1: ldr r4, =SPIFLASH_READ_STATUS + adr r5, _start + add r4, r5 + mov r5, #0x0 + mov r6, #0x2 + sh_qspi_xfer + and r13, #0x1 + cmp r13, #0x1 + beq 1b +.endm + +/* + * r0: controller base address + * r1: data buffer base address + * r2: BIT(31) -- page program (not read) + * BIT(30) -- 4-byte address (not 3-byte) + * BIT(29) -- 512-byte page (not 256-byte) + * BIT(27:20) -- SF command + * BIT(19:0) -- amount of data to read/write + * r3: SF target address + * + * r7: data size + * r8: page size + * + * r14: lr, link register + * r15: pc, program counter + * + * Clobber: r4, r5, r6, r7, r8 + */ + +.global _start +_start: + bic r7, r2, #0xff000000 + bic r7, r7, #0x00f00000 + + and r8, r2, #(1 << 31) + cmp r8, #(1 << 31) + beq do_page_program + +/* fast read */ + + bl sh_qspi_cs_activate + + bl sh_qspi_setup_command + add r8, r6, r7 + str r8, [r0, SH_QSPI_SPBMUL0] + bl sh_qspi_xfer_common + + mov r4, #0x0 + mov r5, r1 + mov r6, r7 + bl sh_qspi_xfer_common + + bl sh_qspi_cs_deactivate + + b end + +do_page_program: + + mov r8, #0x100 + tst r2, (1 << 29) + movne r8, #0x200 + +do_pp_next_page: + /* Check if less then page bytes left. */ + cmp r7, r8 + movlt r8, r7 + + sh_qspi_write_enable + + bl sh_qspi_cs_activate + + bl sh_qspi_setup_command + str r6, [r0, SH_QSPI_SPBMUL0] + bl sh_qspi_xfer_common + + mov r4, r1 + mov r5, #0x0 + mov r6, r8 + + bl sh_qspi_xfer_common + + bl sh_qspi_cs_deactivate + + sh_qspi_wait_till_ready + + add r1, r8 + add r3, r8 + sub r7, r8 + cmp r7, #0 + + bne do_pp_next_page + +end: + bkpt #0 + +sh_qspi_cs_activate: + /* Set master mode only */ + mov r12, #SPCR_MSTR + strb r12, [r0, SH_QSPI_SPCR] + + /* Set command */ + mov r12, #SPCMD_INIT1 + strh r12, [r0, SH_QSPI_SPCMD0] + + /* Reset transfer and receive Buffer */ + ldrb r12, [r0, SH_QSPI_SPSCR] + orr r12, #(SPBFCR_TXRST | SPBFCR_RXRST) + strb r12, [r0, SH_QSPI_SPBFCR] + + /* Clear transfer and receive Buffer control bit */ + ldrb r12, [r0, SH_QSPI_SPBFCR] + bic r12, #(SPBFCR_TXRST | SPBFCR_RXRST) + strb r12, [r0, SH_QSPI_SPBFCR] + + /* Set sequence control method. Use sequence0 only */ + mov r12, #0x00 + strb r12, [r0, SH_QSPI_SPSCR] + + /* Enable SPI function */ + ldrb r12, [r0, SH_QSPI_SPCR] + orr r12, #SPCR_SPE + strb r12, [r0, SH_QSPI_SPCR] + + mov pc, lr + +sh_qspi_cs_deactivate: + /* Disable SPI function */ + ldrb r12, [r0, SH_QSPI_SPCR] + bic r12, #SPCR_SPE + strb r12, [r0, SH_QSPI_SPCR] + + mov pc, lr + +/* + * r0, controller base address + * r4, tx buffer + * r5, rx buffer + * r6, xfer len, non-zero + * + * Upon exit, r13 contains the last byte in SPDR + * + * Clobber: r11, r12, r13 + */ +sh_qspi_xfer_common: +prepcopy: + ldr r13, [r0, #SH_QSPI_SPBFCR] + orr r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG) + mov r11, #32 + cmp r6, #32 + + biclt r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG) + movlt r11, #1 + +copy: + str r13, [r0, #SH_QSPI_SPBFCR] + + wait_for_spsr SPSR_SPTEF + + mov r12, r11 + mov r13, #0 + cmp r4, #0 + beq 3f + +2: ldrb r13, [r4], #1 + strb r13, [r0, #SH_QSPI_SPDR] + subs r12, #1 + bne 2b + b 4f + +3: strb r13, [r0, #SH_QSPI_SPDR] + subs r12, #1 + bne 3b + +4: wait_for_spsr SPSR_SPRFF + + mov r12, r11 + cmp r5, #0 + beq 6f + +5: ldrb r13, [r0, #SH_QSPI_SPDR] + strb r13, [r5], #1 + subs r12, #1 + bne 5b + b 7f + +6: ldrb r13, [r0, #SH_QSPI_SPDR] + subs r12, #1 + bne 6b + +7: subs r6, r11 + bne prepcopy + + mov pc, lr + +sh_qspi_setup_command: + ldr r4, =SPIFLASH_SCRATCH_DATA + adr r5, _start + add r4, r5 + and r12, r2, #0x0ff00000 + lsr r12, #20 + strb r12, [r4] + mov r12, r3 + strb r12, [r4, #4] + lsr r12, #8 + strb r12, [r4, #3] + lsr r12, #8 + strb r12, [r4, #2] + lsr r12, #8 + strb r12, [r4, #1] + lsr r12, #8 + mov r5, #0x0 + mov r6, #0x4 + tst r2, (1 << 30) + movne r6, #0x5 + + mov pc, lr + +SPIFLASH_READ_STATUS: .byte 0x05 /* Read Status Register */ +SPIFLASH_WRITE_ENABLE: .byte 0x06 /* Write Enable */ +SPIFLASH_NOOP: .byte 0x00 +SPIFLASH_SCRATCH_DATA: .byte 0x00, 0x0, 0x0, 0x0, 0x0 diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.inc b/contrib/loaders/flash/sh_qspi/sh_qspi.inc new file mode 100644 index 0000000..ca91392 --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/sh_qspi.inc @@ -0,0 +1,37 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0xff,0x74,0xc2,0xe3,0x0f,0x76,0xc7,0xe3,0x02,0x81,0x02,0xe2,0x02,0x01,0x58,0xe3, +0x0a,0x00,0x00,0x0a,0x32,0x00,0x00,0xeb,0x6c,0x00,0x00,0xeb,0x07,0x80,0x86,0xe0, +0x1c,0x80,0x80,0xe5,0x42,0x00,0x00,0xeb,0x00,0x40,0xa0,0xe3,0x01,0x50,0xa0,0xe1, +0x07,0x60,0xa0,0xe1,0x3e,0x00,0x00,0xeb,0x39,0x00,0x00,0xeb,0x27,0x00,0x00,0xea, +0x01,0x8c,0xa0,0xe3,0x02,0x02,0x12,0xe3,0x02,0x8c,0xa0,0x13,0x08,0x00,0x57,0xe1, +0x07,0x80,0xa0,0xb1,0xcc,0x41,0x9f,0xe5,0x60,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0, +0x00,0x50,0xa0,0xe3,0x01,0x60,0xa0,0xe3,0x1d,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5, +0x2f,0x00,0x00,0xeb,0x2a,0x00,0x00,0xeb,0x19,0x00,0x00,0xeb,0x53,0x00,0x00,0xeb, +0x1c,0x60,0x80,0xe5,0x2a,0x00,0x00,0xeb,0x01,0x40,0xa0,0xe1,0x00,0x50,0xa0,0xe3, +0x08,0x60,0xa0,0xe1,0x26,0x00,0x00,0xeb,0x21,0x00,0x00,0xeb,0x88,0x41,0x9f,0xe5, +0xa8,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0,0x00,0x50,0xa0,0xe3,0x02,0x60,0xa0,0xe3, +0x0b,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5,0x1d,0x00,0x00,0xeb,0x18,0x00,0x00,0xeb, +0x01,0xd0,0x0d,0xe2,0x01,0x00,0x5d,0xe3,0xf3,0xff,0xff,0x0a,0x08,0x10,0x81,0xe0, +0x08,0x30,0x83,0xe0,0x08,0x70,0x47,0xe0,0x00,0x00,0x57,0xe3,0xda,0xff,0xff,0x1a, +0x70,0x00,0x20,0xe1,0x08,0xc0,0xa0,0xe3,0x00,0xc0,0xc0,0xe5,0x84,0xc0,0x0e,0xe3, +0xb0,0xc1,0xc0,0xe1,0x08,0xc0,0xd0,0xe5,0xc0,0xc0,0x8c,0xe3,0x18,0xc0,0xc0,0xe5, +0x18,0xc0,0xd0,0xe5,0xc0,0xc0,0xcc,0xe3,0x18,0xc0,0xc0,0xe5,0x00,0xc0,0xa0,0xe3, +0x08,0xc0,0xc0,0xe5,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0x8c,0xe3,0x00,0xc0,0xc0,0xe5, +0x0e,0xf0,0xa0,0xe1,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0xcc,0xe3,0x00,0xc0,0xc0,0xe5, +0x0e,0xf0,0xa0,0xe1,0x18,0xd0,0x90,0xe5,0x37,0xd0,0x8d,0xe3,0x20,0xb0,0xa0,0xe3, +0x20,0x00,0x56,0xe3,0x37,0xd0,0xcd,0xb3,0x01,0xb0,0xa0,0xb3,0x18,0xd0,0x80,0xe5, +0x03,0xc0,0xd0,0xe5,0x20,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1, +0x00,0xd0,0xa0,0xe3,0x00,0x00,0x54,0xe3,0x04,0x00,0x00,0x0a,0x01,0xd0,0xd4,0xe4, +0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea, +0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfc,0xff,0xff,0x1a,0x03,0xc0,0xd0,0xe5, +0x80,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1,0x00,0x00,0x55,0xe3, +0x04,0x00,0x00,0x0a,0x04,0xd0,0xd0,0xe5,0x01,0xd0,0xc5,0xe4,0x01,0xc0,0x5c,0xe2, +0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea,0x04,0xd0,0xd0,0xe5,0x01,0xc0,0x5c,0xe2, +0xfc,0xff,0xff,0x1a,0x0b,0x60,0x56,0xe0,0xd9,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1, +0x58,0x40,0x9f,0xe5,0x77,0x5f,0x4f,0xe2,0x05,0x40,0x84,0xe0,0xff,0xc6,0x02,0xe2, +0x2c,0xca,0xa0,0xe1,0x00,0xc0,0xc4,0xe5,0x03,0xc0,0xa0,0xe1,0x04,0xc0,0xc4,0xe5, +0x2c,0xc4,0xa0,0xe1,0x03,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x02,0xc0,0xc4,0xe5, +0x2c,0xc4,0xa0,0xe1,0x01,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x00,0x50,0xa0,0xe3, +0x04,0x60,0xa0,0xe3,0x01,0x01,0x12,0xe3,0x05,0x60,0xa0,0x13,0x0e,0xf0,0xa0,0xe1, +0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x02,0x00,0x00,0x20,0x02,0x00,0x00, +0x23,0x02,0x00,0x00, diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.ld b/contrib/loaders/flash/sh_qspi/sh_qspi.ld new file mode 100644 index 0000000..2683c52 --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/sh_qspi.ld @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x0; + . = ALIGN(4); + .text : { + sh_qspi.o (.text*) + *(.text*) + } +} diff --git a/contrib/loaders/flash/stm32/stm32h7x.S b/contrib/loaders/flash/stm32/stm32h7x.S index f0d3295..99e4167 100644 --- a/contrib/loaders/flash/stm32/stm32h7x.S +++ b/contrib/loaders/flash/stm32/stm32h7x.S @@ -18,36 +18,42 @@ .text .syntax unified - .cpu cortex-m7 + .cpu cortex-m4 .thumb /* * Code limitations: * The workarea must have size multiple of 4 bytes, since R/W * operations are all at 32 bits. - * The workarea must be big enough to contain 32 bytes of data, - * thus the minimum size is (rp, wp, data) = 4 + 4 + 32 = 40 bytes. + * The workarea must be big enough to contain rp, wp and data, thus the minumum + * workarea size is: min_wa_size = sizeof(rp, wp, data) = 4 + 4 + sizeof(data). + * - for 0x450 devices: sizeof(data) = 32 bytes, thus min_wa_size = 40 bytes. + * - for 0x480 devices: sizeof(data) = 16 bytes, thus min_wa_size = 24 bytes. * To benefit from concurrent host write-to-buffer and target * write-to-flash, the workarea must be way bigger than the minimum. - */ + * + * To avoid confusions the write word size is got from .block_size member of + * struct stm32h7x_part_info defined in stm32h7x.c +*/ /* * Params : * r0 = workarea start, status (out) * r1 = workarea end * r2 = target address - * r3 = count (256 bit words) - * r4 = flash reg base + * r3 = count (of write words) + * r4 = size of write word + * r5 = flash reg base * * Clobbered: - * r5 - rp - * r6 - wp, status, tmp - * r7 - loop index, tmp + * r6 - rp + * r7 - wp, status, tmp + * r8 - loop index, tmp */ #define STM32_FLASH_CR_OFFSET 0x0C /* offset of CR register in FLASH struct */ #define STM32_FLASH_SR_OFFSET 0x10 /* offset of SR register in FLASH struct */ -#define STM32_CR_PROG 0x00000032 /* PSIZE64 | PG */ +#define STM32_CR_PROG 0x00000002 /* PG */ #define STM32_SR_QW_MASK 0x00000004 /* QW */ #define STM32_SR_ERROR_MASK 0x07ee0000 /* DBECCERR | SNECCERR | RDSERR | RDPERR | OPERR | INCERR | STRBERR | PGSERR | WRPERR */ @@ -55,55 +61,55 @@ .thumb_func .global _start _start: - ldr r5, [r0, #4] /* read rp */ + ldr r6, [r0, #4] /* read rp */ wait_fifo: - ldr r6, [r0, #0] /* read wp */ - cbz r6, exit /* abort if wp == 0, status = 0 */ - subs r6, r6, r5 /* number of bytes available for read in r6 */ + ldr r7, [r0, #0] /* read wp */ + cbz r7, exit /* abort if wp == 0, status = 0 */ + subs r7, r7, r6 /* number of bytes available for read in r7 */ ittt mi /* if wrapped around */ - addmi r6, r1 /* add size of buffer */ - submi r6, r0 - submi r6, #8 - cmp r6, #32 /* wait until 32 bytes are available */ + addmi r7, r1 /* add size of buffer */ + submi r7, r0 + submi r7, #8 + cmp r7, r4 /* wait until data buffer is full */ bcc wait_fifo - mov r6, #STM32_CR_PROG - str r6, [r4, #STM32_FLASH_CR_OFFSET] + mov r7, #STM32_CR_PROG + str r7, [r5, #STM32_FLASH_CR_OFFSET] - mov r7, #8 /* program by 8 words = 32 bytes */ + mov r8, #4 + udiv r8, r4, r8 /* number of words is size of write word devided by 4*/ write_flash: dsb - ldr r6, [r5], #0x04 /* read one word from src, increment ptr */ - str r6, [r2], #0x04 /* write one word to dst, increment ptr */ + ldr r7, [r6], #0x04 /* read one word from src, increment ptr */ + str r7, [r2], #0x04 /* write one word to dst, increment ptr */ dsb - cmp r5, r1 /* if rp >= end of buffer ... */ + cmp r6, r1 /* if rp >= end of buffer ... */ it cs - addcs r5, r0, #8 /* ... then wrap at buffer start */ - subs r7, r7, #1 /* decrement loop index */ + addcs r6, r0, #8 /* ... then wrap at buffer start */ + subs r8, r8, #1 /* decrement loop index */ bne write_flash /* loop if not done */ busy: - ldr r6, [r4, #STM32_FLASH_SR_OFFSET] - tst r6, #STM32_SR_QW_MASK + ldr r7, [r5, #STM32_FLASH_SR_OFFSET] + tst r7, #STM32_SR_QW_MASK bne busy /* operation in progress, wait ... */ - ldr r7, =STM32_SR_ERROR_MASK - tst r6, r7 + ldr r8, =STM32_SR_ERROR_MASK + tst r7, r8 bne error /* fail... */ - str r5, [r0, #4] /* store rp */ + str r6, [r0, #4] /* store rp */ subs r3, r3, #1 /* decrement count */ bne wait_fifo /* loop if not done */ b exit error: - movs r7, #0 - str r7, [r0, #4] /* set rp = 0 on error */ + movs r8, #0 + str r8, [r0, #4] /* set rp = 0 on error */ exit: - mov r0, r6 /* return status in r0 */ + mov r0, r7 /* return status in r0 */ bkpt #0x00 .pool - diff --git a/contrib/loaders/flash/stm32/stm32h7x.inc b/contrib/loaders/flash/stm32/stm32h7x.inc index ec14de0..015644f 100644 --- a/contrib/loaders/flash/stm32/stm32h7x.inc +++ b/contrib/loaders/flash/stm32/stm32h7x.inc @@ -1,7 +1,8 @@ /* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x45,0x68,0x06,0x68,0x36,0xb3,0x76,0x1b,0x42,0xbf,0x76,0x18,0x36,0x1a,0x08,0x3e, -0x20,0x2e,0xf6,0xd3,0x4f,0xf0,0x32,0x06,0xe6,0x60,0x4f,0xf0,0x08,0x07,0xbf,0xf3, -0x4f,0x8f,0x55,0xf8,0x04,0x6b,0x42,0xf8,0x04,0x6b,0xbf,0xf3,0x4f,0x8f,0x8d,0x42, -0x28,0xbf,0x00,0xf1,0x08,0x05,0x01,0x3f,0xf1,0xd1,0x26,0x69,0x16,0xf0,0x04,0x0f, -0xfb,0xd1,0x05,0x4f,0x3e,0x42,0x03,0xd1,0x45,0x60,0x01,0x3b,0xd9,0xd1,0x01,0xe0, -0x00,0x27,0x47,0x60,0x30,0x46,0x00,0xbe,0x00,0x00,0xee,0x07, +0x46,0x68,0x07,0x68,0x6f,0xb3,0xbf,0x1b,0x42,0xbf,0x7f,0x18,0x3f,0x1a,0x08,0x3f, +0xa7,0x42,0xf6,0xd3,0x4f,0xf0,0x02,0x07,0xef,0x60,0x4f,0xf0,0x04,0x08,0xb4,0xfb, +0xf8,0xf8,0xbf,0xf3,0x4f,0x8f,0x56,0xf8,0x04,0x7b,0x42,0xf8,0x04,0x7b,0xbf,0xf3, +0x4f,0x8f,0x8e,0x42,0x28,0xbf,0x00,0xf1,0x08,0x06,0xb8,0xf1,0x01,0x08,0xf0,0xd1, +0x2f,0x69,0x17,0xf0,0x04,0x0f,0xfb,0xd1,0xdf,0xf8,0x1c,0x80,0x17,0xea,0x08,0x0f, +0x03,0xd1,0x46,0x60,0x01,0x3b,0xd4,0xd1,0x03,0xe0,0x5f,0xf0,0x00,0x08,0xc0,0xf8, +0x04,0x80,0x38,0x46,0x00,0xbe,0x00,0x00,0x00,0x00,0xee,0x07, diff --git a/contrib/loaders/flash/stm32/stm32l4x.S b/contrib/loaders/flash/stm32/stm32l4x.S index 9c49016..9923ce7 100644 --- a/contrib/loaders/flash/stm32/stm32l4x.S +++ b/contrib/loaders/flash/stm32/stm32l4x.S @@ -8,6 +8,9 @@ * Copyright (C) 2015 Uwe Bonnes * * bon@elektron.ikp.physik.tu-darmstadt.de * * * + * Copyright (C) 2018 Andreas Bolsch * + * andreas.bolsch@mni.thm.de * + * * * 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 2 of the License, or * @@ -25,68 +28,78 @@ .text .syntax unified - .cpu cortex-m4 + .cpu cortex-m0 .thumb /* * Params : * r0 = workarea start, status (out) - * r1 = workarea end + * r1 = workarea end + 1 * r2 = target address * r3 = count (64bit words) - * r4 = flash base + * r4 = flash status register + * r5 = flash control register * * Clobbered: - * r5 - rp * r6/7 - temp (64-bit) - * r8 - wp, tmp */ -#define STM32_FLASH_CR_OFFSET 0x14 /* offset of CR register in FLASH struct */ -#define STM32_FLASH_SR_OFFSET 0x10 /* offset of SR register in FLASH struct */ - -#define STM32_PROG 0x1 /* PG */ +#include "../../../../src/flash/nor/stm32l4x.h" .thumb_func .global _start + _start: + mov r8, r3 /* copy dword count */ wait_fifo: - ldr r8, [r0, #0] /* read wp */ - cmp r8, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r0, #4] /* read rp */ - subs r6, r8, r5 /* number of bytes available for read in r6*/ - itt mi /* if wrapped around*/ - addmi r6, r1 /* add size of buffer */ - submi r6, r0 - cmp r6, #8 /* wait until 8 bytes are available */ - bcc wait_fifo + ldr r6, [r0, #0] /* read wp */ + cmp r6, #0 /* if wp == 0, */ + beq exit /* then abort */ + ldr r3, [r0, #4] /* read rp */ + subs r6, r6, r3 /* number of bytes available for read in r6 */ + bpl fifo_stat /* if not wrapped around, skip */ + adds r6, r6, r1 /* add end of buffer */ + subs r6, r6, r0 /* sub start of buffer */ +fifo_stat: + cmp r6, #8 /* wait until at least one dword available */ + bcc wait_fifo - ldr r6, =STM32_PROG - str r6, [r4, #STM32_FLASH_CR_OFFSET] - ldrd r6, [r5], #0x08 /* read one word from src, increment ptr */ - strd r6, [r2], #0x08 /* write one word to dst, increment ptr */ + movs r6, #FLASH_PG /* flash program enable */ + str r6, [r5] /* write to FLASH_CR, start operation */ + ldmia r3!, {r6, r7} /* read one dword from src, increment ptr */ + stmia r2!, {r6, r7} /* write one dword to dst, increment ptr */ dsb + ldr r7, =FLASH_BSY /* FLASH_BSY mask */ busy: - ldr r6, [r4, #STM32_FLASH_SR_OFFSET] - tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */ - bne busy /* wait more... */ - tst r6, #0xfa /* PGSERR | PGPERR | PGAERR | WRPERR | PROGERR*/ - bne error /* fail... */ + ldr r6, [r4] /* get FLASH_SR register */ + tst r6, r7 /* BSY == 1 => operation in progress */ + bne busy /* if still set, wait more ... */ + movs r7, #FLASH_ERROR /* all error bits */ + tst r6, r7 /* check for any error bit */ + bne error /* fail ... */ - cmp r5, r1 /* wrap rp at end of buffer */ - it cs - addcs r5, r0, #8 /* skip loader args */ - str r5, [r0, #4] /* store rp */ - subs r3, r3, #1 /* decrement dword count */ - cbz r3, exit /* loop if not done */ - b wait_fifo -error: - movs r1, #0 - str r1, [r0, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0x00 + cmp r3, r1 /* rp at end of buffer? */ + bcc upd_rp /* if no, then skip */ + subs r3, r3, r1 /* sub end of buffer */ + adds r3, r3, r0 /* add start of buffer */ + adds r3, r3, #8 /* skip wp and rp */ +upd_rp: + str r3, [r0, #4] /* store rp */ + mov r7, r8 /* get dword count */ + subs r7, r7, #1 /* decrement dword count */ + mov r8, r7 /* save dword count */ + beq exit /* exit if done */ + b wait_fifo .pool +error: + movs r3, #0 + str r3, [r0, #4] /* set rp = 0 on error */ +exit: + mov r0, r6 /* return status in r0 */ + movs r6, #0 /* flash program disable */ + str r6, [r5] /* write to FLASH_CR */ + movs r6, #FLASH_ERROR /* all error bits */ + str r6, [r4] /* write to FLASH_CR to clear errors */ + bkpt #0x00 diff --git a/contrib/loaders/flash/stm32/stm32l4x.inc b/contrib/loaders/flash/stm32/stm32l4x.inc index 4065d14..df5c7ed 100644 --- a/contrib/loaders/flash/stm32/stm32l4x.inc +++ b/contrib/loaders/flash/stm32/stm32l4x.inc @@ -1,7 +1,7 @@ /* Autogenerated with ../../../../src/helper/bin2char.sh */ -0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x20,0xd0,0x45,0x68,0xb8,0xeb,0x05,0x06, -0x44,0xbf,0x76,0x18,0x36,0x1a,0x08,0x2e,0xf2,0xd3,0x0d,0x4e,0x66,0x61,0xf5,0xe8, -0x02,0x67,0xe2,0xe8,0x02,0x67,0xbf,0xf3,0x4f,0x8f,0x26,0x69,0x16,0xf4,0x80,0x3f, -0xfb,0xd1,0x16,0xf0,0xfa,0x0f,0x07,0xd1,0x8d,0x42,0x28,0xbf,0x00,0xf1,0x08,0x05, -0x45,0x60,0x01,0x3b,0x13,0xb1,0xdb,0xe7,0x00,0x21,0x41,0x60,0x30,0x46,0x00,0xbe, -0x01,0x00,0x00,0x00, +0x98,0x46,0x06,0x68,0x00,0x2e,0x23,0xd0,0x43,0x68,0xf6,0x1a,0x01,0xd5,0x76,0x18, +0x36,0x1a,0x08,0x2e,0xf5,0xd3,0x01,0x26,0x2e,0x60,0xc0,0xcb,0xc0,0xc2,0xbf,0xf3, +0x4f,0x8f,0x09,0x4f,0x26,0x68,0x3e,0x42,0xfc,0xd1,0xfa,0x27,0x3e,0x42,0x0d,0xd1, +0x8b,0x42,0x02,0xd3,0x5b,0x1a,0x1b,0x18,0x08,0x33,0x43,0x60,0x47,0x46,0x01,0x3f, +0xb8,0x46,0x05,0xd0,0xdd,0xe7,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x23,0x43,0x60, +0x30,0x46,0x00,0x26,0x2e,0x60,0xfa,0x26,0x26,0x60,0x00,0xbe, diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s index d724192..2a7eb89 100644 --- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s +++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s @@ -61,4 +61,3 @@ done: bkpt #0 .end - diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s index bf58327..1284ab0 100644 --- a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s +++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s @@ -78,4 +78,3 @@ done: bkpt #0 .end - |