From c9356be30741b5192c79038fa4f8a2ac5b5f35c1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Nov 2014 17:16:43 -0700 Subject: dm: Split the simple malloc() implementation into its own file The simple malloc() implementation is used when memory is tight. It provides a simple buffer with an incrementing pointer. At present the implementation is inside dlmalloc. Move it into its own file so that it is easier to find. Rather than using relocation as a signal that the full malloc() is available, add a special GD_FLG_FULL_MALLOC_INIT flag. This signals that the simple malloc() should no longer be used. In some cases, such as SPL, even the code space used by the full malloc() is wasteful. Add a CONFIG_SYS_MALLOC_SIMPLE option to provide only the simple malloc. In this case the full malloc is not available at all. It saves about 1KB of code space and about 0.5KB of data on Thumb 2. Acked-by: Tom Rini Signed-off-by: Simon Glass --- common/Makefile | 3 +++ common/board_r.c | 3 ++- common/dlmalloc.c | 19 +++++-------------- common/malloc_simple.c | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 common/malloc_simple.c (limited to 'common') diff --git a/common/Makefile b/common/Makefile index 6cc4de8..7a5c58e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -251,6 +251,9 @@ obj-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o obj-y += console.o obj-$(CONFIG_CROS_EC) += cros_ec.o obj-y += dlmalloc.o +ifdef CONFIG_SYS_MALLOC_F_LEN +obj-y += malloc_simple.o +endif obj-y += image.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o obj-$(CONFIG_OF_LIBFDT) += image-fdt.o diff --git a/common/board_r.c b/common/board_r.c index 7c33900..19c6427 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -99,7 +99,8 @@ static int initr_trace(void) static int initr_reloc(void) { - gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + /* tell others: relocation done */ + gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT; bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); return 0; diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 991229d..6453ee9 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -2184,17 +2184,8 @@ Void_t* mALLOc(bytes) size_t bytes; INTERNAL_SIZE_T nb; #ifdef CONFIG_SYS_MALLOC_F_LEN - if (gd && !(gd->flags & GD_FLG_RELOC)) { - ulong new_ptr; - void *ptr; - - new_ptr = gd->malloc_ptr + bytes; - if (new_ptr > gd->malloc_limit) - panic("Out of pre-reloc memory"); - ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes); - gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr)); - return ptr; - } + if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT)) + return malloc_simple(bytes); #endif /* check if mem_malloc_init() was run */ @@ -2462,7 +2453,7 @@ void fREe(mem) Void_t* mem; #ifdef CONFIG_SYS_MALLOC_F_LEN /* free() is a no-op - all the memory will be freed on relocation */ - if (!(gd->flags & GD_FLG_RELOC)) + if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) return; #endif @@ -2618,7 +2609,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes; if (oldmem == NULL) return mALLOc(bytes); #ifdef CONFIG_SYS_MALLOC_F_LEN - if (!(gd->flags & GD_FLG_RELOC)) { + if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) { /* This is harder to support and should not be needed */ panic("pre-reloc realloc() is not supported"); } @@ -2970,7 +2961,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; else { #ifdef CONFIG_SYS_MALLOC_F_LEN - if (!(gd->flags & GD_FLG_RELOC)) { + if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) { MALLOC_ZERO(mem, sz); return mem; } diff --git a/common/malloc_simple.c b/common/malloc_simple.c new file mode 100644 index 0000000..afdacff --- /dev/null +++ b/common/malloc_simple.c @@ -0,0 +1,39 @@ +/* + * Simple malloc implementation + * + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void *malloc_simple(size_t bytes) +{ + ulong new_ptr; + void *ptr; + + new_ptr = gd->malloc_ptr + bytes; + if (new_ptr > gd->malloc_limit) + panic("Out of pre-reloc memory"); + ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes); + gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr)); + return ptr; +} + +#ifdef CONFIG_SYS_MALLOC_SIMPLE +void *calloc(size_t nmemb, size_t elem_size) +{ + size_t size = nmemb * elem_size; + void *ptr; + + ptr = malloc(size); + memset(ptr, '\0', size); + + return ptr; +} +#endif -- cgit v1.1 From fb4f5e7c911745de1a6c7d0051abca9d2a4cd920 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Nov 2014 17:16:45 -0700 Subject: dm: spl: Make simple malloc() available when enabled Set up the simple malloc() implementation when requested, in preference to the full malloc(). Signed-off-by: Simon Glass --- common/spl/spl.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/spl/spl.c b/common/spl/spl.c index f01a21c..6b90ad8 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -139,9 +139,13 @@ void board_init_r(gd_t *dummy1, ulong dummy2) u32 boot_device; debug(">>spl:board_init_r()\n"); -#ifdef CONFIG_SYS_SPL_MALLOC_START +#if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; +#elif defined(CONFIG_SYS_MALLOC_F_LEN) + gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_ptr = 0; #endif #ifndef CONFIG_PPC @@ -238,6 +242,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2) default: debug("Unsupported OS image.. Jumping nevertheless..\n"); } +#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) + debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, + gd->malloc_ptr / 1024); +#endif + jump_to_image_no_args(&spl_image); } -- cgit v1.1 From 1151651831ff11b3f40d132bb9ab012e95a8faa1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Nov 2014 17:16:46 -0700 Subject: dm: spl: Allow driver model to be used When enabled, set up driver model for SPL. This allows SPL to use the same drivers as the main U-Boot. Signed-off-by: Simon Glass Acked-by: Tom Rini --- common/spl/spl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'common') diff --git a/common/spl/spl.c b/common/spl/spl.c index 6b90ad8..3cd19f0 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -7,6 +7,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -147,6 +149,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2) gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN; gd->malloc_ptr = 0; #endif +#ifdef CONFIG_SPL_DM + dm_init_and_scan(true); +#endif #ifndef CONFIG_PPC /* -- cgit v1.1 From c1a6f371ae65f1a3709e872e08bed51321e292fc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 11 Nov 2014 10:46:17 -0700 Subject: dm: i2c: Move error reporting into a common function Factor out the common code to make it easier to adjust it. Signed-off-by: Simon Glass Reviewed-by: Tom Rini Acked-by: Heiko Schocher --- common/cmd_i2c.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'common') diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 3a75f94..c266b88 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -198,6 +198,19 @@ static uint get_alen(char *arg) return alen; } +enum i2c_err_op { + I2C_ERR_READ, + I2C_ERR_WRITE, +}; + +static int i2c_report_err(int ret, enum i2c_err_op op) +{ + printf("Error %s the chip: %d\n", + op == I2C_ERR_READ ? "reading" : "writing", ret); + + return CMD_RET_FAILURE; +} + /** * do_i2c_read() - Handle the "i2c read" command-line command * @cmdtp: Command data struct pointer @@ -245,7 +258,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16); if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) { - puts ("Error reading the chip.\n"); + i2c_report_err(-1, I2C_ERR_READ); return 1; } return 0; @@ -286,8 +299,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ while (length-- > 0) { if (i2c_write(chip, devaddr++, alen, memaddr++, 1) != 0) { - puts("Error writing to the chip.\n"); - return 1; + return i2c_report_err(-1, I2C_ERR_WRITE); } /* * No write delay with FRAM devices. @@ -370,7 +382,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0) - puts ("Error reading the chip.\n"); + i2c_report_err(-1, I2C_ERR_READ); else { printf("%04x:", addr); cp = linebuf; @@ -452,7 +464,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] while (count-- > 0) { if (i2c_write(chip, addr++, alen, &byte, 1) != 0) - puts ("Error writing the chip.\n"); + i2c_report_err(-1, I2C_ERR_WRITE); /* * Wait for the write to complete. The write can take * up to 10mSec (we allow a little more time). @@ -528,7 +540,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] addr++; } if (err > 0) - puts ("Error reading the chip,\n"); + i2c_report_err(-1, I2C_ERR_READ); else printf ("%08lx\n", crc); @@ -601,7 +613,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg do { printf("%08lx:", addr); if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) - puts ("\nError reading the chip,\n"); + i2c_report_err(-1, I2C_ERR_READ); else { data = cpu_to_be32(data); if (size == 1) @@ -644,7 +656,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg */ bootretry_reset_cmd_timeout(); if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) - puts ("Error writing the chip.\n"); + i2c_report_err(-1, I2C_ERR_WRITE); #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); #endif @@ -783,7 +795,7 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] */ while (1) { if (i2c_read(chip, addr, alen, bytes, length) != 0) - puts ("Error reading the chip.\n"); + i2c_report_err(-1, I2C_ERR_READ); udelay(delay); } @@ -1341,7 +1353,7 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) chip = simple_strtoul(argv[1], NULL, 16); if (i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)) != 0) { - puts("Error reading EDID content.\n"); + i2c_report_err(-1, I2C_ERR_READ); return 1; } -- cgit v1.1