From patchwork Fri Sep 13 07:16:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: afzal mohammed X-Patchwork-Id: 274666 X-Patchwork-Delegate: marek.vasut@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 2CFB32C015D for ; Fri, 13 Sep 2013 17:17:17 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BDF424A09B; Fri, 13 Sep 2013 09:17:16 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9XI+byREo1jZ; Fri, 13 Sep 2013 09:17:16 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 88DD34A09C; Fri, 13 Sep 2013 09:17:12 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B36CD4A09C for ; Fri, 13 Sep 2013 09:17:09 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mOIBSS9EBwQH for ; Fri, 13 Sep 2013 09:17:03 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pd0-f176.google.com (mail-pd0-f176.google.com [209.85.192.176]) by theia.denx.de (Postfix) with ESMTPS id 1956B4A09B for ; Fri, 13 Sep 2013 09:16:56 +0200 (CEST) Received: by mail-pd0-f176.google.com with SMTP id q10so881092pdj.35 for ; Fri, 13 Sep 2013 00:16:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=o/DwURpmNT5mGPCqSm01YSwTyErz7IZ2h/pcy+9CTm0=; b=xZlVemFD4GQa5OglF46M1nN9LuXHLOUcPOcHDgQXjT0LNgNgj8Z6y931saByUH7w0Q X9nzHO7zDUVu0JcNUOq8ODSaeUpGYvtsCiOnGxutHcDnADfgp1a6YektNPDpEkWkAvyH eH5d3pWM4nQ6nIxtJj5AdjPZrng0oMRmQ3ffRl4RhxdI5w0Osg40x3OiaIxrIEOfF754 G5WGp0U/0nt9s35LQr0CvDbPGPvg5KYbdgv5jcc5KhM600jkV19HOWynTvB/tWWDCDvP d3c8B0QxXBd9o3cxdP03X/KxdPAyBOm3nuBM0NHZuhM2Wc6CwiSAxLbD5F2gLq2Qo1nP 3laA== X-Received: by 10.66.182.229 with SMTP id eh5mr13725994pac.139.1379056609732; Fri, 13 Sep 2013 00:16:49 -0700 (PDT) Received: from localhost.localdomain ([112.79.44.106]) by mx.google.com with ESMTPSA id ia5sm9693324pbc.42.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 13 Sep 2013 00:16:49 -0700 (PDT) From: Afzal Mohammed To: u-boot@lists.denx.de Date: Fri, 13 Sep 2013 12:46:36 +0530 Message-Id: <5eb509735b5bd634043bbb8f56d088073773b7b8.1379055112.git.afzal.mohd.ma@gmail.com> X-Mailer: git-send-email 1.8.2.135.g7b592fa In-Reply-To: References: Cc: Marek Vasut , Pantelis Antoniou Subject: [U-Boot] [PATCH v3 2/3] dfu: ram support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de DFU spec mentions it as a method to upgrade firmware (software stored in writable non-volatile memory). It also says other potential uses of DFU is beyond scope of the spec. Here such a beyond the scope use is being attempted - directly pumping binary images from host via USB to RAM. This facility is a developer centric one in that it gives advantage over upgrading non-volatile memory for testing new images every time during development and/or testing. Directly putting image onto RAM would speed up upgrade process. This and convenience was the initial thoughts that led to doing this, speed improvement over MMC was only 1 second though - 6 sec on RAM as opposed to 7 sec on MMC in beagle bone, perhaps enabling cache and/or optimizing DFU framework to avoid multiple copy for ram (if worth) may help, and on other platforms and other boot media like NAND maybe improvement would be higher. And for a platform that doesn't yet have proper DFU suppport for non-volatile media's, DFU to RAM can be used. Another minor advantage would be to increase life of mmc/nand as it would be less used during development/testing. usage: ram eg. kernel ram 0x81000000 0x1000000 Downloading images to RAM using DFU is not something new, this is acheived in openmoko also. DFU on RAM can be used for extracting RAM contents to host using dfu upload. Perhaps this can be extended to io for squeezing out register dump through usb, if it is worth. Signed-off-by: Afzal Mohammed Cc: Marek Vasut Cc: Lukasz Majewski Cc: Pantelis Antoniou Acked-by: Lukasz Majewski Acked-by: Marek Vasut --- v3: error used instead of printf v2: remove read/write enumerator define's, instead use new common ones drivers/dfu/Makefile | 1 + drivers/dfu/dfu.c | 7 +++-- drivers/dfu/dfu_ram.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/dfu.h | 18 ++++++++++++ 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 drivers/dfu/dfu_ram.c diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile index fca370a..de9e44e 100644 --- a/drivers/dfu/Makefile +++ b/drivers/dfu/Makefile @@ -12,6 +12,7 @@ LIB = $(obj)libdfu.o COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o COBJS-$(CONFIG_DFU_MMC) += dfu_mmc.o COBJS-$(CONFIG_DFU_NAND) += dfu_nand.o +COBJS-$(CONFIG_DFU_RAM) += dfu_ram.o SRCS := $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 689f5db..56b21c7 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -348,6 +348,9 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, } else if (strcmp(interface, "nand") == 0) { if (dfu_fill_entity_nand(dfu, s)) return -1; + } else if (strcmp(interface, "ram") == 0) { + if (dfu_fill_entity_ram(dfu, s)) + return -1; } else { printf("%s: Device %s not (yet) supported!\n", __func__, interface); @@ -397,14 +400,14 @@ int dfu_config_entities(char *env, char *interface, int num) const char *dfu_get_dev_type(enum dfu_device_type t) { - const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND" }; + const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM" }; return dev_t[t]; } const char *dfu_get_layout(enum dfu_layout l) { const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2", - "EXT3", "EXT4" }; + "EXT3", "EXT4", "RAM_ADDR" }; return dfu_layout[l]; } diff --git a/drivers/dfu/dfu_ram.c b/drivers/dfu/dfu_ram.c new file mode 100644 index 0000000..2e3520c --- /dev/null +++ b/drivers/dfu/dfu_ram.c @@ -0,0 +1,76 @@ +/* + * (C) Copyright 2013 + * Afzal Mohammed + * + * Reference: dfu_mmc.c + * Copyright (C) 2012 Samsung Electronics + * author: Lukasz Majewski + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static int dfu_transfer_medium_ram(enum dfu_op op, struct dfu_entity *dfu, + u64 offset, void *buf, long *len) +{ + if (dfu->layout != DFU_RAM_ADDR) { + error("unsupported layout: %s\n", dfu_get_layout(dfu->layout)); + return -EINVAL; + } + + if (offset > dfu->data.ram.size) { + error("request exceeds allowed area\n"); + return -EINVAL; + } + + if (op == DFU_OP_WRITE) + memcpy(dfu->data.ram.start + offset, buf, *len); + else + memcpy(buf, dfu->data.ram.start + offset, *len); + + return 0; +} + +static int dfu_write_medium_ram(struct dfu_entity *dfu, u64 offset, + void *buf, long *len) +{ + return dfu_transfer_medium_ram(DFU_OP_WRITE, dfu, offset, buf, len); +} + +static int dfu_read_medium_ram(struct dfu_entity *dfu, u64 offset, + void *buf, long *len) +{ + if (!*len) { + *len = dfu->data.ram.size; + return 0; + } + + return dfu_transfer_medium_ram(DFU_OP_READ, dfu, offset, buf, len); +} + +int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s) +{ + char *st; + + dfu->dev_type = DFU_DEV_RAM; + st = strsep(&s, " "); + if (strcmp(st, "ram")) { + error("unsupported device: %s\n", st); + return -ENODEV; + } + + dfu->layout = DFU_RAM_ADDR; + dfu->data.ram.start = (void *)simple_strtoul(s, &s, 16); + dfu->data.ram.size = simple_strtoul(++s, &s, 16); + + dfu->write_medium = dfu_write_medium_ram; + dfu->read_medium = dfu_read_medium_ram; + + dfu->inited = 0; + + return 0; +} diff --git a/include/dfu.h b/include/dfu.h index 6a3e253..6f4bba4 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -19,6 +19,7 @@ enum dfu_device_type { DFU_DEV_MMC = 1, DFU_DEV_ONENAND, DFU_DEV_NAND, + DFU_DEV_RAM, }; enum dfu_layout { @@ -27,6 +28,7 @@ enum dfu_layout { DFU_FS_EXT2, DFU_FS_EXT3, DFU_FS_EXT4, + DFU_RAM_ADDR, }; enum dfu_op { @@ -56,6 +58,11 @@ struct nand_internal_data { unsigned int ubi; }; +struct ram_internal_data { + void *start; + unsigned int size; +}; + static inline unsigned int get_mmc_blk_size(int dev) { return find_mmc_device(dev)->read_bl_len; @@ -81,6 +88,7 @@ struct dfu_entity { union { struct mmc_internal_data mmc; struct nand_internal_data nand; + struct ram_internal_data ram; } data; int (*read_medium)(struct dfu_entity *dfu, @@ -143,4 +151,14 @@ static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s) } #endif +#ifdef CONFIG_DFU_RAM +extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s); +#else +static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s) +{ + puts("RAM support not available!\n"); + return -1; +} +#endif + #endif /* __DFU_ENTITY_H_ */