[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