aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Smith2011-12-26 02:54:44 -0800
committerMike Smith2011-12-26 02:54:44 -0800
commitaf451397672ef3bb99a1292e0e7591267b41348f (patch)
tree0f518daa1c008bb82e163f4c81161c1dbf5dd5a7
parent00651032ad089711926c175bb252f0c76567c82b (diff)
Use a single static program buffer rather than allocating several on the stack.
-rw-r--r--src/nxp_tgt.c64
1 files changed, 31 insertions, 33 deletions
diff --git a/src/nxp_tgt.c b/src/nxp_tgt.c
index 9e97622..d5957f9 100644
--- a/src/nxp_tgt.c
+++ b/src/nxp_tgt.c
@@ -8,19 +8,21 @@
#include "target.h"
#include "nxp_tgt.h"
+#define IAP_PGM_CHUNKSIZE 256 /* should fit in RAM on any device */
+
struct flash_param {
uint16_t opcodes[2]; /* two opcodes to return to after calling the ROM */
uint32_t command[5]; /* command operands */
uint32_t result[4]; /* result data */
};
-#define IAP_PGM_CHUNKSIZE 256 /* should fit in RAM on any device */
-
struct flash_program {
struct flash_param p;
uint8_t data[IAP_PGM_CHUNKSIZE];
};
+static struct flash_program flash_pgm;
+
#define IAP_ENTRYPOINT 0x1fff1ff1
#define IAP_RAM_BASE 0x10000000
@@ -139,17 +141,15 @@ lpc11x_iap_call(struct target_s *target, struct flash_param *param, unsigned par
static int
lpc11xx_flash_prepare(struct target_s *target, uint32_t addr, int len)
-{
- struct flash_param p;
-
+{
/* prepare the sector(s) to be erased */
- memset(&p, 0, sizeof(p));
- p.command[0] = IAP_CMD_PREPARE;
- p.command[1] = addr / 4096;
- p.command[2] = p.command[1] + ((len + 4095) / 4096) - 1;
+ memset(&flash_pgm.p, 0, sizeof(flash_pgm.p));
+ flash_pgm.p.command[0] = IAP_CMD_PREPARE;
+ flash_pgm.p.command[1] = addr / 4096;
+ flash_pgm.p.command[2] = flash_pgm.p.command[1] + ((len + 4095) / 4096) - 1;
- lpc11x_iap_call(target, &p, sizeof(p));
- if (p.result[0] != IAP_STATUS_CMD_SUCCESS) {
+ lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
+ if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
return -1;
}
@@ -159,7 +159,6 @@ lpc11xx_flash_prepare(struct target_s *target, uint32_t addr, int len)
static int
lpc11xx_flash_erase(struct target_s *target, uint32_t addr, int len)
{
- struct flash_param p;
if (addr % 4096)
return -1;
@@ -169,17 +168,17 @@ lpc11xx_flash_erase(struct target_s *target, uint32_t addr, int len)
return -1;
/* and now erase them */
- p.command[0] = IAP_CMD_ERASE;
- p.command[1] = addr / 4096;
- p.command[2] = p.command[1] + ((len + 4095) / 4096) - 1;
- p.command[3] = 12000; /* XXX safe to assume this? */
- lpc11x_iap_call(target, &p, sizeof(p));
- if (p.result[0] != IAP_STATUS_CMD_SUCCESS) {
+ flash_pgm.p.command[0] = IAP_CMD_ERASE;
+ flash_pgm.p.command[1] = addr / 4096;
+ flash_pgm.p.command[2] = flash_pgm.p.command[1] + ((len + 4095) / 4096) - 1;
+ flash_pgm.p.command[3] = 12000; /* XXX safe to assume this? */
+ lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
+ if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
return -1;
}
- p.command[0] = IAP_CMD_BLANKCHECK;
- lpc11x_iap_call(target, &p, sizeof(p));
- if (p.result[0] != IAP_STATUS_CMD_SUCCESS) {
+ flash_pgm.p.command[0] = IAP_CMD_BLANKCHECK;
+ lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
+ if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
return -1;
}
@@ -189,7 +188,6 @@ lpc11xx_flash_erase(struct target_s *target, uint32_t addr, int len)
static int
lpc11xx_flash_write_words(struct target_s *target, uint32_t dest, const uint32_t *src, int len)
{
- struct flash_program pgm;
const uint8_t *s = (const uint8_t *)src;
unsigned first_chunk = dest / IAP_PGM_CHUNKSIZE;
unsigned last_chunk = (dest + len - 1) / IAP_PGM_CHUNKSIZE;
@@ -203,13 +201,13 @@ lpc11xx_flash_write_words(struct target_s *target, uint32_t dest, const uint32_t
if ((chunk == first_chunk) || (chunk == last_chunk)) {
/* fill with all ff to avoid sector rewrite corrupting other writes */
- memset(pgm.data, 0xff, sizeof(pgm.data));
+ memset(flash_pgm.data, 0xff, sizeof(flash_pgm.data));
/* copy as much as fits */
int copylen = IAP_PGM_CHUNKSIZE - chunk_offset;
if (copylen > len)
copylen = len;
- memcpy(&pgm.data[chunk_offset], s, copylen);
+ memcpy(&flash_pgm.data[chunk_offset], s, copylen);
/* update to suit */
len -= copylen;
@@ -218,7 +216,7 @@ lpc11xx_flash_write_words(struct target_s *target, uint32_t dest, const uint32_t
/* if we are programming the vectors, calculate the magic number */
if (chunk == 0) {
- uint32_t *w = (uint32_t *)(&pgm.data[0]);
+ uint32_t *w = (uint32_t *)(&flash_pgm.data[0]);
uint32_t sum = 0;
for (unsigned i = 0; i < 7; i++)
@@ -229,7 +227,7 @@ lpc11xx_flash_write_words(struct target_s *target, uint32_t dest, const uint32_t
} else {
/* interior chunk, must be aligned and full-sized */
- memcpy(pgm.data, s, IAP_PGM_CHUNKSIZE);
+ memcpy(flash_pgm.data, s, IAP_PGM_CHUNKSIZE);
len -= IAP_PGM_CHUNKSIZE;
s += IAP_PGM_CHUNKSIZE;
}
@@ -239,13 +237,13 @@ lpc11xx_flash_write_words(struct target_s *target, uint32_t dest, const uint32_t
return -1;
/* set the destination address and program */
- pgm.p.command[0] = IAP_CMD_PROGRAM;
- pgm.p.command[1] = chunk * IAP_PGM_CHUNKSIZE;
- pgm.p.command[2] = IAP_RAM_BASE + offsetof(struct flash_program, data);
- pgm.p.command[3] = IAP_PGM_CHUNKSIZE;
- pgm.p.command[4] = 12000; /* XXX safe to presume this? */
- lpc11x_iap_call(target, &pgm.p, sizeof(pgm));
- if (pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
+ flash_pgm.p.command[0] = IAP_CMD_PROGRAM;
+ flash_pgm.p.command[1] = chunk * IAP_PGM_CHUNKSIZE;
+ flash_pgm.p.command[2] = IAP_RAM_BASE + offsetof(struct flash_program, data);
+ flash_pgm.p.command[3] = IAP_PGM_CHUNKSIZE;
+ flash_pgm.p.command[4] = 12000; /* XXX safe to presume this? */
+ lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm));
+ if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
return -1;
}