CONFIG_DFU_NAND
This enables support for exposing NAND devices via DFU.
+ CONFIG_DFU_RAM
+ This enables support for exposing RAM via DFU.
+ Note: DFU spec refer to non-volatile memory usage, but
+ allow usages beyond the scope of spec - here RAM usage,
+ one that would help mostly the developer.
+
CONFIG_SYS_DFU_DATA_BUF_SIZE
Dfu transfer uses a buffer before writing data to the
raw storage device. Make the size (in bytes) of this buffer
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))
} 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);
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];
}
--- /dev/null
+/*
+ * (C) Copyright 2013
+ * Afzal Mohammed <afzal.mohd.ma@gmail.com>
+ *
+ * Reference: dfu_mmc.c
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dfu.h>
+
+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);
+ s++;
+ 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;
+}
DFU_DEV_MMC = 1,
DFU_DEV_ONENAND,
DFU_DEV_NAND,
+ DFU_DEV_RAM,
};
enum dfu_layout {
DFU_FS_EXT2,
DFU_FS_EXT3,
DFU_FS_EXT4,
+ DFU_RAM_ADDR,
};
enum dfu_op {
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;
union {
struct mmc_internal_data mmc;
struct nand_internal_data nand;
+ struct ram_internal_data ram;
} data;
int (*read_medium)(struct dfu_entity *dfu,
}
#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_ */