[U-Boot] [PATCH 4/4] dfu: target-specific implementation for Goni
Andrzej Pietrasiewicz
andrzej.p at samsung.com
Wed Nov 9 10:52:23 CET 2011
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
---
board/samsung/goni/Makefile | 2 +
board/samsung/goni/flash.c | 341 +++++++++++++++++++++++++++++++++++++++++++
board/samsung/goni/flash.h | 28 ++++
board/samsung/goni/goni.c | 17 ++
include/configs/s5p_goni.h | 4 +
5 files changed, 392 insertions(+), 0 deletions(-)
create mode 100644 board/samsung/goni/flash.c
create mode 100644 board/samsung/goni/flash.h
diff --git a/board/samsung/goni/Makefile b/board/samsung/goni/Makefile
index ecde7a7..3f13cb8 100644
--- a/board/samsung/goni/Makefile
+++ b/board/samsung/goni/Makefile
@@ -31,6 +31,8 @@ LIB = $(obj)lib$(BOARD).o
COBJS-y := goni.o onenand.o
SOBJS := lowlevel_init.o
+COBJS-$(CONFIG_DFU_FOR_BOARD) += flash.o
+
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS-y))
SOBJS := $(addprefix $(obj),$(SOBJS))
diff --git a/board/samsung/goni/flash.c b/board/samsung/goni/flash.c
new file mode 100644
index 0000000..29c7ec1
--- /dev/null
+++ b/board/samsung/goni/flash.c
@@ -0,0 +1,341 @@
+/*
+ * flash.c -- board flashing routines
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * author: Andrzej Pietrasiewicz <andrzej.p at samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <dfu_backend.h>
+#include <flash_entity.h>
+#include <linux/types.h>
+#include <jffs2/load_kernel.h>
+
+#define MMC_BLOCK_SZ (256 * 1024)
+#define MMC_UBOOT_OFFSET 128
+#define MMC_UBOOT_SZ 512
+#define MMC_NAME_LEN 12
+#define SHORT_PART_NAME 15
+#define LONG_PART_NAME 20
+#define CALLOC_STRUCT(n, type) (struct type *) calloc(n, sizeof(struct type))
+#define DEFAULT_MMC_PART_NAME "mmc-default-part"
+
+/* partition IDs counted from 0, eg. mmc0-pri-1's ID is 0 */
+#define UIMAGE_PART_ID 1
+#define EXTENDED_PART_ID 3
+#define UMS_PART_ID 7
+#define UIMAGE_PART_NAME "mmc0-pri-2"
+
+#define USE_MMC_UBOOT
+#define USE_MMC
+
+/*
+ * MMC u-boot partitions
+ */
+static struct mbr_part_data *uboot_pdata;
+
+static u8 uboot_part_num;
+static u8 used_uboot_parts;
+
+int use_uboot(struct mbr_part_data *pdata, u8 i)
+{
+ /*
+ * Use i and pdata[i] members to decide if the partition is used
+ */
+ return 1;
+}
+
+char *alloc_uboot_name(u8 i)
+{
+ char *name = calloc(SHORT_PART_NAME, 1);
+
+ if (name) {
+ sprintf(name, "mmc-u-boot");
+ return name;
+ }
+
+ return DEFAULT_MMC_PART_NAME;
+}
+
+/*
+ * MMC partitions and MMC operations
+ */
+struct mmc *mmc;
+
+static struct mbr_part_data *mmc_pdata;
+
+static u8 mmc_part_num;
+static u8 used_mmc_parts;
+
+static u8 mmc_buf[MMC_BLOCK_SZ];
+
+static int extended_lba;
+
+static int mmc_mbr_dev;
+
+static u8 pri_count;
+static u8 ext_count = 4;
+
+/*
+ * Define files available in the UIMAGE partition which has FAT on it.
+ * Only flat structure without subdirectories is supported.
+ */
+static char *uImage_part_files[] = {
+ "uImage",
+};
+#define UIMAGE_PART_NUM_FILES ARRAY_SIZE(uImage_part_files)
+
+/*
+ * Return number of flash entities per this partition
+ */
+u8 use_mmc(struct mbr_part_data *pdata, u8 i)
+{
+ /*
+ * Use i and pdata[i] members to decide if the partition is used
+ */
+ if (i == UIMAGE_PART_ID)
+ return UIMAGE_PART_NUM_FILES;
+ if (i == EXTENDED_PART_ID)
+ return 0; /* do not expose the extended partition as a whole */
+ if (i == UMS_PART_ID)
+ return 0; /* do not expose UMS; there is a separate command */
+ return 1;
+}
+
+char *alloc_mmc_name(struct mbr_part_data *pdata, u8 i, u8 l)
+{
+ char *name = calloc(MMC_NAME_LEN, 1);
+
+ if (name) {
+ sprintf(name, "mmc0-");
+ if (pdata[i].primary)
+ sprintf(name + strlen(name), "pri-%d",
+ l ? pri_count : ++pri_count);
+ else
+ sprintf(name + strlen(name), "ext-%d",
+ l ? ext_count : ++ext_count);
+
+ return name;
+ }
+
+ return DEFAULT_MMC_PART_NAME;
+}
+
+/*
+ * FAT operations
+ */
+static u8 fat_buf[MMC_FAT_BLOCK_SZ];
+
+/*
+ * Transport layer to storage adaptation
+ */
+
+static int prepare_fat(void *ctx, u8 mode)
+{
+ struct flash_entity_ctx *ct = ctx;
+
+ set_fat_filename(ct->associated);
+ if (!strncmp(ct->this_entity->name, UIMAGE_PART_NAME,
+ strlen(UIMAGE_PART_NAME)))
+ set_fat_part_num(UIMAGE_PART_ID + 1);
+ return generic_prepare(ctx, mode);
+}
+
+/*
+ * Flash entities definitions for this board
+ */
+static struct flash_entity *flash_ents;
+
+static void customize_entities(struct flash_entity *fe, u8 n_ents)
+{
+ int i;
+ for (i = 0; i < n_ents; ++i) {
+ /* i counts all entities, not just mmc entities */
+ /* add similar "if" blocks for other customizable entities */
+ if (!strcmp(fe[i].name, UIMAGE_PART_NAME)) {
+ struct flash_entity_ctx *ctx;
+ char *name, file_number;
+
+ fe[i].prepare = prepare_fat;
+ ctx = fe[i].ctx;
+ ctx->length = min(ctx->length, MMC_FAT_BLOCK_SZ);
+ ctx->buf = fat_buf;
+ ctx->buf_len = ctx->length;
+ ctx->read = read_fat;
+ ctx->write = write_fat;
+ file_number = (char)ctx->associated;
+ /* by design file_number cannot exceed array size */
+ ctx->associated = uImage_part_files[file_number];
+
+ name = calloc(LONG_PART_NAME, 1);
+ if (name) {
+ sprintf(name, "%s-%s", fe[i].name,
+ (char *)ctx->associated);
+ free(fe[i].name);
+ fe[i].name = name;
+ }
+
+ continue;
+ }
+ }
+}
+
+static inline void generic_flash_entity(struct flash_entity *fe)
+{
+ fe->prepare = generic_prepare;
+ fe->finish = generic_finish;
+ fe->read_block = read_block;
+ fe->write_block = write_block;
+}
+
+static inline void generic_flash_entity_ctx(struct flash_entity_ctx *ctx,
+ struct flash_entity *fe)
+{
+ ctx->buf = mmc_buf;
+ ctx->buf_len = MMC_BLOCK_SZ;
+ ctx->read = read_mmc;
+ ctx->write = write_mmc;
+ ctx->erase = NULL;
+ ctx->this_entity = fe;
+ fe->ctx = ctx;
+}
+
+void register_flash_areas(void)
+{
+ u8 i, j;
+
+#ifdef USE_MMC
+ mmc = find_mmc_device(mmc_mbr_dev);
+ if (mmc && !mmc_init(mmc)) {
+ mmc_part_num = read_mbr(mmc, NULL, &extended_lba, mmc_mbr_dev);
+ if (mmc_part_num) {
+ mmc_pdata = CALLOC_STRUCT(mmc_part_num,
+ mbr_part_data);
+ if (mmc_pdata) {
+ if (!read_mbr(mmc, mmc_pdata, &extended_lba, mmc_mbr_dev)) {
+ free(mmc_pdata);
+ mmc_pdata = NULL;
+ }
+ set_fat_dev(&mmc->block_dev);
+ }
+ }
+ }
+ used_mmc_parts = 0;
+ for (i = 0; mmc_pdata && i < mmc_part_num; ++i)
+ used_mmc_parts += use_mmc(mmc_pdata, i);
+ pri_count = 0;
+ ext_count = 4;
+#endif
+
+#ifdef USE_MMC_UBOOT
+ if (mmc) {
+ uboot_part_num = 1;
+ if (uboot_part_num) {
+ uboot_pdata = CALLOC_STRUCT(uboot_part_num,
+ mbr_part_data);
+ if (uboot_pdata)
+ for (i = 0; i < uboot_part_num; ++i) {
+ uboot_pdata[i].offset =
+ MMC_UBOOT_OFFSET;
+ uboot_pdata[i].length =
+ MMC_UBOOT_SZ;
+ uboot_pdata[i].primary = 0;
+ }
+ }
+ }
+ used_uboot_parts = 0;
+ for (i = 0; uboot_pdata && i < uboot_part_num; ++i)
+ used_uboot_parts += use_uboot(uboot_pdata, i);
+#endif
+
+ flash_ents = CALLOC_STRUCT(used_uboot_parts + used_mmc_parts,
+ flash_entity);
+ if (!flash_ents)
+ goto partinfo_alloc_rollback;
+
+ j = 0;
+ for (i = 0; i < uboot_part_num; ++i)
+ if (use_uboot(uboot_pdata, i)) {
+ struct flash_entity *fe;
+ struct flash_entity_ctx *ctx;
+
+ fe = &flash_ents[j++];
+ fe->name = alloc_uboot_name(i);
+ generic_flash_entity(fe);
+
+ ctx = CALLOC_STRUCT(1, flash_entity_ctx);
+ if (!ctx)
+ goto flash_ents_alloc_rollback;
+ generic_flash_entity_ctx(ctx, fe);
+ ctx->offset = uboot_pdata[i].offset * MMC_SECTOR_SZ;
+ ctx->length = uboot_pdata[i].length * MMC_SECTOR_SZ;
+ }
+ uboot_part_num = used_uboot_parts;
+
+ for (i = 0; i < mmc_part_num; ++i) {
+ u8 k = use_mmc(mmc_pdata, i);
+ u8 l;
+ for (l = 0; l < k; ++l) {
+ struct flash_entity *fe;
+ struct flash_entity_ctx *ctx;
+
+ fe = &flash_ents[j++];
+ fe->name = alloc_mmc_name(mmc_pdata, i, l);
+ generic_flash_entity(fe);
+
+ ctx = CALLOC_STRUCT(1, flash_entity_ctx);
+ if (!ctx)
+ goto flash_ents_alloc_rollback;
+ generic_flash_entity_ctx(ctx, fe);
+ ctx->offset = mmc_pdata[i].offset * MMC_SECTOR_SZ;
+ ctx->length = mmc_pdata[i].length * MMC_SECTOR_SZ;
+ ctx->associated = (void *)l;
+ }
+ }
+ mmc_part_num = used_mmc_parts;
+ customize_entities(flash_ents, uboot_part_num + mmc_part_num);
+ register_flash_entities(flash_ents, uboot_part_num + mmc_part_num);
+printf("NUM ENTITIES:%d\n", uboot_part_num + mmc_part_num);
+
+ return;
+
+flash_ents_alloc_rollback:
+ while (j--) {
+ free(flash_ents[j].name);
+ free(flash_ents[j].ctx);
+ }
+ free(flash_ents);
+
+partinfo_alloc_rollback:
+ free(uboot_pdata);
+ free(mmc_pdata);
+}
+
+void unregister_flash_areas(void)
+{
+ int j = uboot_part_num + mmc_part_num;
+ while (j--) {
+ free(flash_ents[j].name);
+ free(flash_ents[j].ctx);
+ }
+ free(flash_ents);
+ free(uboot_pdata);
+ free(mmc_pdata);
+}
+
diff --git a/board/samsung/goni/flash.h b/board/samsung/goni/flash.h
new file mode 100644
index 0000000..ffe4d6d
--- /dev/null
+++ b/board/samsung/goni/flash.h
@@ -0,0 +1,28 @@
+/*
+ * flash.h -- board flashing routines interface
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * author: Andrzej Pietrasiewicz <andrzej.p at samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef FLASH_GONI_H_
+#define FLASH_GONI_H_
+
+void register_flash_areas(void);
+void unregister_flash_areas(void);
+
+#endif
diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c
index c4fc3e9..7e693be 100644
--- a/board/samsung/goni/goni.c
+++ b/board/samsung/goni/goni.c
@@ -29,6 +29,9 @@
#include <asm/arch/hs_otg.h>
#include <asm/arch/cpu.h>
#include <max8998_pmic.h>
+
+#include "flash.h"
+
DECLARE_GLOBAL_DATA_PTR;
static struct s5pc110_gpio *s5pc110_gpio;
@@ -144,4 +147,18 @@ struct s3c_plat_otg_data s5pc110_otg_data = {
.regs_phy = S5PC110_PHY_BASE,
.regs_otg = S5PC110_OTG_BASE,
};
+
+#ifdef CONFIG_DFU_FOR_BOARD
+void board_dfu_init(void)
+{
+ register_flash_areas();
+ s3c_udc_probe(&s5pc110_otg_data);
+}
+
+void board_dfu_cleanup(void)
+{
+ unregister_flash_areas();
+}
+#endif
+
#endif
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index df97802..3881f92 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -86,6 +86,8 @@
#define CONFIG_CMD_ONENAND
#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_DEVICE_FIRMWARE_UPGRADE
#define CONFIG_BOOTDELAY 1
#define CONFIG_ZERO_BOOTDELAY_CHECK
@@ -241,4 +243,6 @@
#define CONFIG_USB_GADGET_S3C_UDC_OTG 1
#define CONFIG_USB_GADGET_DUALSPEED 1
+#define CONFIG_DFU_GADGET
+#define CONFIG_DFU_FOR_BOARD
#endif /* __CONFIG_H */
--
1.7.0.4
More information about the U-Boot
mailing list