Message ID | 1424774311-23726-4-git-send-email-p.marczak@samsung.com |
---|---|
State | Superseded |
Headers | show |
Hi Przemyslaw, > For writing files, DFU implementation requires the file buffer > with the len at least of file size. For big files it requires > the same big buffer. > > Previously the file buffer was allocated as a static variable, > so it was a part of U-Boot .bss section. For 32MiB len of buffer > we have 32MiB of additional space, required for this section. > > The .bss needs to be cleared after the relocation. > This introduces an additional boot delay at every start, but usually > the dfu feature is not required at the standard boot, so the buffer > should be allocated only if required. > > This patch removes the static allocation of this buffer, > and alloc it with memalign after first call of function: > - dfu_fill_entity_mmc() > and the buffer is freed on dfu_free_entity() call. > > This was tested on Trats2. > A quick test with trace. Boot time from start to main_loop() entry: > - ~888ms - before this change (arch memset enabled for .bss clear) > - ~464ms - after this change > > Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com> > Reviewed-by: Simon Glass <sjg@chromium.org> > Cc: Lukasz Majewski <l.majewski@samsung.com> > Cc: Stephen Warren <swarren@nvidia.com> > Cc: Pantelis Antoniou <panto@antoniou-consulting.com> > Cc: Tom Rini <trini@ti.com> > Cc: Marek Vasut <marek.vasut@gmail.com> > > --- > Changes V3, V4, V5 > - none > --- > drivers/dfu/dfu_mmc.c | 25 ++++++++++++++++++++++--- > 1 file changed, 22 insertions(+), 3 deletions(-) > > diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c > index 62d72fe..fd865e1 100644 > --- a/drivers/dfu/dfu_mmc.c > +++ b/drivers/dfu/dfu_mmc.c > @@ -16,8 +16,7 @@ > #include <fat.h> > #include <mmc.h> > > -static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) > - > dfu_file_buf[CONFIG_SYS_DFU_MAX_FILE_SIZE]; +static unsigned char > *dfu_file_buf; static long dfu_file_buf_len; > > static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, > int part) @@ -211,7 +210,7 @@ int dfu_flush_medium_mmc(struct > dfu_entity *dfu) > if (dfu->layout != DFU_RAW_ADDR) { > /* Do stuff here. */ > - ret = mmc_file_op(DFU_OP_WRITE, dfu, &dfu_file_buf, > + ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf, > &dfu_file_buf_len); > > /* Now that we're done */ > @@ -263,6 +262,14 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, > u64 offset, void *buf, return ret; > } > > +void dfu_free_entity_mmc(struct dfu_entity *dfu) > +{ > + if (dfu_file_buf) { > + free(dfu_file_buf); > + dfu_file_buf = NULL; > + } > +} > + > /* > * @param s Parameter string containing space-separated arguments: > * 1st: > @@ -370,6 +377,18 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, > char *devstr, char *s) dfu->write_medium = dfu_write_medium_mmc; > dfu->flush_medium = dfu_flush_medium_mmc; > dfu->inited = 0; > + dfu->free_entity = dfu_free_entity_mmc; > + > + /* Check if file buffer is ready */ > + if (!dfu_file_buf) { > + dfu_file_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, > + > CONFIG_SYS_DFU_MAX_FILE_SIZE); > + if (!dfu_file_buf) { > + error("Could not memalign 0x%x bytes", > + CONFIG_SYS_DFU_MAX_FILE_SIZE); > + return -ENOMEM; > + } > + } > > return 0; > } Acked-by: Lukasz Majewski <l.majewski@samsung.com>
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index 62d72fe..fd865e1 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -16,8 +16,7 @@ #include <fat.h> #include <mmc.h> -static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) - dfu_file_buf[CONFIG_SYS_DFU_MAX_FILE_SIZE]; +static unsigned char *dfu_file_buf; static long dfu_file_buf_len; static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part) @@ -211,7 +210,7 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu) if (dfu->layout != DFU_RAW_ADDR) { /* Do stuff here. */ - ret = mmc_file_op(DFU_OP_WRITE, dfu, &dfu_file_buf, + ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf, &dfu_file_buf_len); /* Now that we're done */ @@ -263,6 +262,14 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, return ret; } +void dfu_free_entity_mmc(struct dfu_entity *dfu) +{ + if (dfu_file_buf) { + free(dfu_file_buf); + dfu_file_buf = NULL; + } +} + /* * @param s Parameter string containing space-separated arguments: * 1st: @@ -370,6 +377,18 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s) dfu->write_medium = dfu_write_medium_mmc; dfu->flush_medium = dfu_flush_medium_mmc; dfu->inited = 0; + dfu->free_entity = dfu_free_entity_mmc; + + /* Check if file buffer is ready */ + if (!dfu_file_buf) { + dfu_file_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, + CONFIG_SYS_DFU_MAX_FILE_SIZE); + if (!dfu_file_buf) { + error("Could not memalign 0x%x bytes", + CONFIG_SYS_DFU_MAX_FILE_SIZE); + return -ENOMEM; + } + } return 0; }