commit 2b0ab579ae6da0a3ae144bd364874ea967279eb8
parent 0ac79702203fef35f9b7f91eec72d3e418570a7e
Author: Brian Swetland <swetland@frotz.net>
Date: Sun, 12 Jul 2015 04:48:41 -0700
agents: simplify things, decouple from the arch/chip system
Diffstat:
11 files changed, 397 insertions(+), 291 deletions(-)
diff --git a/Makefile b/Makefile
@@ -61,6 +61,7 @@ OUT_TARGET_OBJ := $(OUT)/_obj/target
ALL :=
DEPS :=
+AGENTS :=
# build system internals
include build/build.mk
diff --git a/agents/lpc-header.S b/agents/lpc-header.S
@@ -1,22 +0,0 @@
-
-.section .vectors
-.syntax unified
-.globl _start
-
-_start:
- .long 0x42776166 // magic
- .long 0x00010000 // version
- .long 0x00000001 // flags
- .long _start
- .long _start + 0x400 // data addr
- .long 0x00001000 // 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/lpc-main.c b/agents/lpc-main.c
@@ -1,106 +0,0 @@
-// agent-lpc15xx/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>
-
-#ifdef CONFIG_ARCH_LPC15XX
-#define LPC_IAP_FUNC 0x03000205
-#else
-#define LPC_IAP_FUNC 0x1fff1ff1
-#endif
-
-#define LPC_IAP_PREPARE 50
-#define LPC_IAP_WRITE 51
-#define LPC_IAP_ERASE 52
-
-// Note that while the databook claims you can reuse the same array
-// for both parameters and results, this is a lie. Attempting to
-// do so causes an invalid command failure.
-
-
-int flash_agent_setup(flash_agent *agent) {
- return ERR_NONE;
-}
-
-int flash_agent_erase(u32 flash_addr, u32 length) {
- void (*romcall)(u32 *, u32 *) = (void*) LPC_IAP_FUNC;
- u32 p[5],r[4];
- u32 page = flash_addr >> 12;
- u32 last = page + ((length - 1) >> 12);
- if (flash_addr & 0xFFF) {
- return ERR_ALIGNMENT;
- }
-
- p[0] = LPC_IAP_PREPARE;
- p[1] = page;
- p[2] = last;
- romcall(p,r);
- if (r[0]) {
- return ERR_FAIL;
- }
-
- p[0] = LPC_IAP_ERASE;
- p[1] = page;
- p[2] = last;
- p[3] = 0x2ee0;
- romcall(p,r);
- if (r[0]) {
- return ERR_FAIL;
- }
- return ERR_NONE;
-}
-
-int flash_agent_write(u32 flash_addr, const void *data, u32 length) {
- void (*romcall)(u32 *,u32 *) = (void*) LPC_IAP_FUNC;
- u32 p[5],r[4];
- u32 page = flash_addr >> 12;
- if (flash_addr & 0xFFF) {
- return ERR_ALIGNMENT;
- }
-
- p[0] = LPC_IAP_PREPARE;
- p[1] = page;
- p[2] = page;
- romcall(p,r);
- if (r[0]) {
- return ERR_FAIL;
- }
-
- // todo: smaller writes, etc
- if (length != 4096) {
- int n;
- for (n = length; n < 4096; n++) {
- ((char*) data)[n] = 0;
- }
- }
- p[0] = LPC_IAP_WRITE;
- p[1] = flash_addr;
- p[2] = (u32) data;
- p[3] = 0x1000;
- p[4] = 0x2ee0;
- romcall(p,r);
- if (r[0]) {
- return ERR_FAIL;
- }
-
- return ERR_NONE;
-}
-
-int flash_agent_ioctl(u32 op, void *ptr, u32 arg0, u32 arg1) {
- return ERR_INVALID;
-}
-
-
diff --git a/agents/lpc13xx_lpc15xx.c b/agents/lpc13xx_lpc15xx.c
@@ -0,0 +1,119 @@
+// agent-lpc15xx/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>
+
+#ifdef CONFIG_ARCH_LPC15XX
+#define LPC_IAP_FUNC 0x03000205
+#else
+#define LPC_IAP_FUNC 0x1fff1ff1
+#endif
+
+#define LPC_IAP_PREPARE 50
+#define LPC_IAP_WRITE 51
+#define LPC_IAP_ERASE 52
+
+// Note that while the databook claims you can reuse the same array
+// for both parameters and results, this is a lie. Attempting to
+// do so causes an invalid command failure.
+
+
+int flash_agent_setup(flash_agent *agent) {
+ return ERR_NONE;
+}
+
+int flash_agent_erase(u32 flash_addr, u32 length) {
+ void (*romcall)(u32 *, u32 *) = (void*) LPC_IAP_FUNC;
+ u32 p[5],r[4];
+ u32 page = flash_addr >> 12;
+ u32 last = page + ((length - 1) >> 12);
+ if (flash_addr & 0xFFF) {
+ return ERR_ALIGNMENT;
+ }
+
+ p[0] = LPC_IAP_PREPARE;
+ p[1] = page;
+ p[2] = last;
+ romcall(p,r);
+ if (r[0]) {
+ return ERR_FAIL;
+ }
+
+ p[0] = LPC_IAP_ERASE;
+ p[1] = page;
+ p[2] = last;
+ p[3] = 0x2ee0;
+ romcall(p,r);
+ if (r[0]) {
+ return ERR_FAIL;
+ }
+ return ERR_NONE;
+}
+
+int flash_agent_write(u32 flash_addr, const void *data, u32 length) {
+ void (*romcall)(u32 *,u32 *) = (void*) LPC_IAP_FUNC;
+ u32 p[5],r[4];
+ u32 page = flash_addr >> 12;
+ if (flash_addr & 0xFFF) {
+ return ERR_ALIGNMENT;
+ }
+
+ p[0] = LPC_IAP_PREPARE;
+ p[1] = page;
+ p[2] = page;
+ romcall(p,r);
+ if (r[0]) {
+ return ERR_FAIL;
+ }
+
+ // todo: smaller writes, etc
+ if (length != 4096) {
+ int n;
+ for (n = length; n < 4096; n++) {
+ ((char*) data)[n] = 0;
+ }
+ }
+ p[0] = LPC_IAP_WRITE;
+ p[1] = flash_addr;
+ p[2] = (u32) data;
+ p[3] = 0x1000;
+ p[4] = 0x2ee0;
+ romcall(p,r);
+ if (r[0]) {
+ return ERR_FAIL;
+ }
+
+ return ERR_NONE;
+}
+
+int flash_agent_ioctl(u32 op, void *ptr, u32 arg0, u32 arg1) {
+ return ERR_INVALID;
+}
+
+const flash_agent __attribute((section(".vectors"))) FlashAgent = {
+ .magic = AGENT_MAGIC,
+ .version = AGENT_VERSION,
+ .flags = FLAG_BOOT_ROM_HACK,
+ .load_addr = CONFIG_LOADADDR,
+ .data_addr = CONFIG_LOADADDR + 0x400,
+ .data_size = 0x1000,
+ .flash_addr = CONFIG_FLASHADDR,
+ .flash_size = CONFIG_FLASHSIZE,
+ .setup = flash_agent_setup,
+ .erase = flash_agent_erase,
+ .write = flash_agent_write,
+ .ioctl = flash_agent_ioctl,
+};
diff --git a/agents/module.mk b/agents/module.mk
@@ -1,18 +1,26 @@
M_NAME := agent-lpc15xx
-M_CHIP := lpc1547-agt
-M_START := agents/lpc-header.o
-M_OBJS := agents/lpc-main.o
-$(call build-target-executable)
+M_CONFIG := ARCH_LPC15xx=1
+M_ROMBASE := 0x00000000
+M_ROMSIZE := 0x00010000
+M_RAMBASE := 0x02000400
+M_RAMSIZE := 0x00000400
+M_OBJS := agents/lpc13xx_lpc15xx.o
+$(call build-target-agent)
M_NAME := agent-lpc13xx
-M_CHIP := lpc1343-agt
-M_START := agents/lpc-header.o
-M_OBJS := agents/lpc-main.o
-$(call build-target-executable)
+M_ROMBASE := 0x00000000
+M_ROMSIZE := 0x00008000
+M_RAMBASE := 0x10000400
+M_RAMSIZE := 0x00000400
+M_OBJS := agents/lpc13xx_lpc15xx.o
+$(call build-target-agent)
M_NAME := agent-stm32f4xx
-M_CHIP := stm32f4xx-agt
-M_START := agents/stm-header.o
-M_OBJS := agents/stm-main.o
-$(call build-target-executable)
+M_ROMBASE := 0x00000000
+M_ROMSIZE := 0x00100000
+M_RAMBASE := 0x20000400
+M_RAMSIZE := 0x00000400
+M_OBJS := agents/stm32fxxx.o
+$(call build-target-agent)
+
diff --git a/agents/stm-header.S b/agents/stm-header.S
@@ -1,22 +0,0 @@
-
-.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
@@ -1,128 +0,0 @@
-// 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/agents/stm32fxxx.c b/agents/stm32fxxx.c
@@ -0,0 +1,141 @@
+// 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;
+}
+
+const flash_agent __attribute((section(".vectors"))) FlashAgent = {
+ .magic = AGENT_MAGIC,
+ .version = AGENT_VERSION,
+ .flags = 0,
+ .load_addr = CONFIG_LOADADDR,
+ .data_addr = CONFIG_LOADADDR + 0x400,
+ .data_size = 0x8000,
+ .flash_addr = CONFIG_FLASHADDR,
+ .flash_size = CONFIG_FLASHSIZE,
+ .setup = flash_agent_setup,
+ .erase = flash_agent_erase,
+ .write = flash_agent_write,
+ .ioctl = flash_agent_ioctl,
+};
diff --git a/build/build.mk b/build/build.mk
@@ -52,6 +52,7 @@ mv $1.tmp $1
endef
start-module-mk = $(eval M_MAKEFILE := $(lastword $(MAKEFILE_LIST)))
+build-target-agent = $(eval include build/target-agent.mk)
build-target-executable = $(eval include build/target-executable.mk)
build-host-executable = $(eval include build/host-executable.mk)
diff --git a/build/target-agent.mk b/build/target-agent.mk
@@ -0,0 +1,115 @@
+## Copyright 2011 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.
+
+M_NAME := $(strip $(M_NAME))
+M_CHIP := $(strip $(M_CHIP))
+
+ifeq ($(strip $(M_START)),)
+M_START := $(ARCH_$(M_ARCH)_START)
+endif
+
+M_ARCH := $(CHIP_$(M_CHIP)_ARCH)
+M_ARCH_CFLAGS := $(ARCH_$(M_ARCH)_CFLAGS)
+M_ARCH_OBJS := $(ARCH_$(M_ARCH)_OBJS)
+
+# sanity check
+ifeq "$(M_NAME)" ""
+$(error $(M_MAKEFILE): No module name specified)
+endif
+
+# architecture start glue goes first
+M_OBJS := $(addprefix $(OUT_TARGET_OBJ)/$(M_NAME)/,$(M_OBJS))
+
+DEPS += $(M_OBJS:%o=%d)
+
+M_OUT_BIN := $(OUT)/$(M_NAME).bin
+M_OUT_LST := $(OUT)/$(M_NAME).lst
+M_OUT_ELF := $(OUT)/$(M_NAME).elf
+
+ALL += $(M_OUT_BIN) $(M_OUT_LST) $(M_OUT_ELF)
+
+M_INCLUDE := $(OUT_TARGET_OBJ)/$(M_NAME)/include
+M_CONFIG_H := $(M_INCLUDE)/config.h
+M_LINK_SCRIPT := $(OUT_TARGET_OBJ)/$(M_NAME)/script.ld
+
+# generate link script
+$(M_LINK_SCRIPT): _RADDR := $(M_RAMBASE)
+$(M_LINK_SCRIPT): _RSIZE := $(M_RAMSIZE)
+$(M_LINK_SCRIPT): $(CHIP_$(M_CHIP)_DEPS)
+ @echo linkscript $@
+ @echo "MEMORY {" > $@
+ @echo " RAM (xrw) : ORIGIN = $(_RADDR), LENGTH = $(_RSIZE)" >> $@
+ @echo "}" >> $@
+ @echo " INCLUDE \"build/generic-ram.ld\"" >> $@
+
+$(OUT_TARGET_OBJ)/$(M_NAME)/%.o: %.c
+ @$(MKDIR)
+ @echo compile $<
+ $(QUIET)$(TARGET_CC) $(TARGET_CFLAGS) $(_CFLAGS) -c $< -o $@ -MD -MT $@ -MF $(@:%o=%d)
+
+$(OUT_TARGET_OBJ)/$(M_NAME)/%.o: %.S
+ @$(MKDIR)
+ @echo assemble $<
+ $(QUIET)$(TARGET_CC) $(TARGET_CFLAGS) $(_CFLAGS) -c $< -o $@ -MD -MT $@ -MF $(@:%o=%d)
+
+# apply our flags to our objects
+$(M_OBJS): _CFLAGS := --include $(M_CONFIG_H) $(M_CFLAGS)
+$(M_ARCH_OBJS): _CFLAGS := --include $(M_CONFIG_H) $(M_CFLAGS)
+
+# objects depend on generated config header
+$(M_OBJS): $(M_CONFIG_H)
+$(M_ARCH_OBJS): $(M_CONFIG_H)
+
+X_CONFIG := FLASHSIZE=$(M_ROMSIZE)
+X_CONFIG += FLASHADDR=$(M_ROMBASE)
+X_CONFIG += LOADADDR=$(M_RAMBASE)
+
+# generate config header from module, chip, and arch config lists
+# generated config header depends on toplevel, module, and chip/arch makefiles
+$(M_CONFIG_H): _CFG := $(M_CONFIG) $(X_CONFIG)
+$(M_CONFIG_H): Makefile $(M_MAKEFILE)
+ @$(MKDIR)
+ @echo generate $@
+ @$(call make-config-header,$@,$(_CFG))
+
+$(M_OUT_BIN): $(M_OUT_ELF)
+ @echo create $@
+ $(QUIET)$(TARGET_OBJCOPY) --gap-fill=0xee -O binary $< $@
+
+$(M_OUT_LST): $(M_OUT_ELF)
+ @echo create $@
+ $(QUIET)$(TARGET_OBJDUMP) --source -d $< > $@
+
+$(M_OUT_ELF): _OBJS := $(M_OBJS)
+$(M_OUT_ELF): _LINK := $(M_LINK_SCRIPT)
+$(M_OUT_ELF): $(M_OBJS) $(M_LINK_SCRIPT)
+ @echo link $@
+ $(QUIET)$(TARGET_LD) $(TARGET_LFLAGS) -Bstatic -T $(_LINK) $(_OBJS) $(_LIBS) -o $@
+
+AGENTS += $(M_OUT_BIN)
+
+$(info module $(M_NAME))
+
+M_START :=
+M_OBJS :=
+M_NAME :=
+M_BASE :=
+M_LIBS :=
+M_CFLAGS :=
+M_CONFIG :=
+M_SIGN :=
+M_RAMBASE :=
+M_RAMSIZE :=
+M_ROMBASE :=
+M_ROMSIZE :=
diff --git a/tools/module.mk b/tools/module.mk
@@ -13,7 +13,6 @@ M_OBJS += tools/lkdebug.o
M_OBJS += out/debugger-builtins.o
$(call build-host-executable)
-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) > $@