commit deab0abef44cb4d541aa33789445a703c7ff8ddc
parent 75d7471794d036f2a4408d2517cb6be600e9bb98
Author: Brian Swetland <swetland@frotz.net>
Date: Mon, 15 Jun 2015 02:28:12 -0700
stm32f4xx: first cut at a flash agent for this family
Diffstat:
7 files changed, 169 insertions(+), 1 deletion(-)
diff --git a/agents/module.mk b/agents/module.mk
@@ -11,3 +11,8 @@ M_START := agents/lpc-header.o
M_OBJS := agents/lpc-main.o
$(call build-target-executable)
+M_NAME := agent-stm32f4xx
+M_CHIP := stm32f4xx-agt
+M_START := agents/stm-header.o
+M_OBJS := agents/stm-main.o
+$(call build-target-executable)
diff --git a/agents/stm-header.S b/agents/stm-header.S
@@ -0,0 +1,22 @@
+
+.section .vectors
+.syntax unified
+.globl _start
+
+_start:
+ .long 0x42776166 // magic
+ .long 0x00010000 // version
+ .long 0x00000000 // flags
+ .long _start
+ .long _start + 0x400 // data addr
+ .long 0x00008000 // data size
+ .long CONFIG_FLASHADDR // flash addr
+ .long CONFIG_FLASHSIZE // flash size
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+ .long flash_agent_setup + 1
+ .long flash_agent_erase + 1
+ .long flash_agent_write + 1
+ .long flash_agent_ioctl + 1
diff --git a/agents/stm-main.c b/agents/stm-main.c
@@ -0,0 +1,128 @@
+// agents/stm-main.c
+//
+// Copyright 2015 Brian Swetland <swetland@frotz.net>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <agent/flash.h>
+#include <fw/io.h>
+
+#define FLASH_BASE 0x40023C00
+#define FLASH_ACR (FLASH_BASE + 0x00)
+
+#define FLASH_KEYR (FLASH_BASE + 0x04)
+#define FLASH_KEYR_KEY1 0x45670123
+#define FLASH_KEYR_KEY2 0xCDEF89AB
+
+#define FLASH_SR (FLASH_BASE + 0x0C)
+#define FLASH_SR_BSY (1 << 16)
+#define FLASH_SR_PGSERR (1 << 7) // sequence error
+#define FLASH_SR_PGPERR (1 << 6) // parallelism error
+#define FLASH_SR_PGAERR (1 << 5) // alignment error
+#define FLASH_SR_WRPERR (1 << 4) // write-protect error
+#define FLASH_SR_OPERR (1 << 1) // operation error
+#define FLASH_SR_ERRMASK 0xF2
+#define FLASH_SR_EOP (1 << 0) // end of operation
+
+#define FLASH_CR (FLASH_BASE + 0x10)
+#define FLASH_CR_LOCK (1 << 31)
+#define FLASH_CR_ERRIE (1 << 25) // error irq en
+#define FLASH_CR_EOPIE (1 << 24) // end of op irq en
+#define FLASH_CR_STRT (1 << 16) // start
+#define FLASH_CR_PSIZE_8 (0 << 8)
+#define FLASH_CR_PSIZE_16 (1 << 8)
+#define FLASH_CR_PSIZE_32 (2 << 8)
+#define FLASH_CR_PSIZE_64 (3 << 8)
+#define FLASH_CR_SNB(n) (((n) & 15) << 3) // sector number
+#define FLASH_CR_MER (1 << 2) // mass erase
+#define FLASH_CR_SER (1 << 1) // sector erase
+#define FLASH_CR_PG (1 << 0) // programming
+
+
+#define SECTORS 12
+
+static u32 sectors[SECTORS + 1] = {
+ 0x00000000,
+ 0x00004000,
+ 0x00008000,
+ 0x0000C000,
+ 0x00010000,
+ 0x00020000,
+ 0x00040000,
+ 0x00060000,
+ 0x00080000,
+ 0x000A0000,
+ 0x000C0000,
+ 0x000E0000,
+ 0x00100000,
+};
+
+int flash_agent_setup(flash_agent *agent) {
+ writel(FLASH_KEYR_KEY1, FLASH_KEYR);
+ writel(FLASH_KEYR_KEY2, FLASH_KEYR);
+ if (readl(FLASH_CR) & FLASH_CR_LOCK) {
+ return ERR_FAIL;
+ } else {
+ return ERR_NONE;
+ }
+}
+
+int flash_agent_erase(u32 flash_addr, u32 length) {
+ u32 v;
+ int n;
+ for (n = 0; n < SECTORS; n++) {
+ if (flash_addr == sectors[n]) goto ok;
+ }
+ return ERR_ALIGNMENT;
+ok:
+ for (;;) {
+ writel(FLASH_CR_SER | FLASH_CR_SNB(n), FLASH_CR);
+ writel(FLASH_CR_STRT | FLASH_CR_SER | FLASH_CR_SNB(n), FLASH_CR);
+ while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ;
+ if (v & FLASH_SR_ERRMASK) {
+ return ERR_FAIL;
+ }
+ n++;
+ if (n == SECTORS) break;
+ if ((sectors[n] - flash_addr) >= length) break;
+ }
+ return ERR_NONE;
+}
+
+int flash_agent_write(u32 flash_addr, const void *_data, u32 length) {
+ const u32 *data = _data;
+ u32 v;
+ if ((flash_addr & 3) || (length & 3)) {
+ return ERR_ALIGNMENT;
+ }
+ writel(FLASH_CR_PG | FLASH_CR_PSIZE_32, FLASH_CR);
+ while (length > 0) {
+ writel(*data, flash_addr);
+ data++;
+ length -= 4;
+ flash_addr += 4;
+ while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ;
+ if (v & FLASH_SR_ERRMASK) {
+ writel(0, FLASH_CR);
+ return ERR_FAIL;
+ }
+ }
+ writel(0, FLASH_CR);
+ return ERR_NONE;
+}
+
+int flash_agent_ioctl(u32 op, void *ptr, u32 arg0, u32 arg1) {
+ return ERR_INVALID;
+}
+
+
diff --git a/arch/stm32f4xx/config.mk b/arch/stm32f4xx/config.mk
@@ -0,0 +1,13 @@
+
+# name arch rambase ramsize flashbase flashsize linkscript
+$(call chip,stm32f4xx-rom,stm32f1xx,0x20000000,0x00020000,0x00000000,0x00100000,rom)
+$(call chip,stm32f4xx-ram,stm32f1xx,0x20000000,0x00020000,0x00000000,0x00000000,ram)
+$(call chip,stm32f4xx-agt,stm32f1xx,0x20000400,0x0001fc00,0x00000000,0x00100000,ram)
+
+
+ARCH_stm32f4xx_CFLAGS := -Iarch/stm32f4xx/include
+ARCH_stm32f4xx_CFLAGS += -Iarch/arm-cm3/include
+ARCH_stm32f4xx_CFLAGS += -DCONFIG_STACKTOP=0x20005000
+ARCH_stm32f4xx_START := arch/arm-cm3/start.o
+
+ARCH_stm32f4xx_OBJS :=
diff --git a/arch/stm32f4xx/include/arch/hardware.h b/arch/stm32f4xx/include/arch/hardware.h
diff --git a/arch/stm32f4xx/include/arch/irqs.h b/arch/stm32f4xx/include/arch/irqs.h
diff --git a/tools/module.mk b/tools/module.mk
@@ -10,7 +10,7 @@ M_OBJS += tools/usb.o
M_OBJS += out/debugger-builtins.o
$(call build-host-executable)
-AGENTS := out/agent-lpc13xx.bin out/agent-lpc15xx.bin
+AGENTS := out/agent-lpc13xx.bin out/agent-lpc15xx.bin out/agent-stm32f4xx.bin
out/debugger-builtins.c: $(AGENTS) bin/mkbuiltins
@mkdir -p out
./bin/mkbuiltins $(AGENTS) > $@