diff --git a/sys/dev/fdt/fdt_slicer.c b/sys/dev/fdt/fdt_slicer.c | |
index 462cb4d80fe..bc468108732 100644 | |
--- a/sys/dev/fdt/fdt_slicer.c | |
+++ b/sys/dev/fdt/fdt_slicer.c | |
@@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); | |
#include <dev/ofw/ofw_bus.h> | |
#include <dev/ofw/openfirm.h> | |
+#include <geom/geom.h> | |
+ | |
#ifdef DEBUG | |
#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ | |
printf(fmt,##args); } while (0) | |
@@ -46,26 +48,33 @@ __FBSDID("$FreeBSD$"); | |
#define debugf(fmt, args...) | |
#endif | |
+#define ROOTFSMAGIC 0x622f2123 | |
+ | |
static int fill_slices(device_t dev, const char *provider, | |
+ struct g_consumer *cp, | |
struct flash_slice *slices, int *slices_num); | |
static void fdt_slicer_init(void); | |
static int | |
-fill_slices_from_node(phandle_t node, struct flash_slice *slices, int *count) | |
+fill_slices_from_node(struct g_consumer *cp, phandle_t node, struct flash_slice *slices, int *count) | |
{ | |
char *label; | |
phandle_t child; | |
u_long base, size; | |
int flags, i; | |
ssize_t nmlen; | |
+ int blksize; | |
+ uint8_t *buf; | |
+ uint32_t mgc; | |
+ int j; | |
i = 0; | |
for (child = OF_child(node); child != 0; child = OF_peer(child)) { | |
flags = FLASH_SLICES_FLAG_NONE; | |
/* Nodes with a compatible property are not slices. */ | |
- if (OF_hasprop(child, "compatible")) | |
- continue; | |
+// if (OF_hasprop(child, "compatible")) | |
+// continue; | |
if (i == FLASH_SLICES_MAX_NUM) { | |
debugf("not enough buffer for slice i=%d\n", i); | |
@@ -98,6 +107,27 @@ fill_slices_from_node(phandle_t node, struct flash_slice *slices, int *count) | |
if (OF_hasprop(child, "read-only")) | |
flags |= FLASH_SLICES_FLAG_RO; | |
+ blksize = cp->provider->stripesize; | |
+ | |
+ if (strcmp(label, "firmware") == 0 && | |
+ fdt_is_compatible_strict(child, "denx,uimage")) { | |
+ for (j = 0; j < size; j += 0x10000) { | |
+ g_topology_unlock(); | |
+ buf = g_read_data(cp, base + j, blksize, NULL); | |
+ mgc = (buf[3] << 24) | (buf[2] << 16) | | |
+ (buf[1] << 8) | buf[0]; | |
+ g_topology_lock(); | |
+ g_free(buf); | |
+ | |
+ if (mgc == ROOTFSMAGIC) { | |
+ base += j; | |
+ label = "rootfs"; | |
+ size -= j; | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ | |
/* Fill slice entry data. */ | |
slices[i].base = base; | |
slices[i].size = size; | |
@@ -111,7 +141,7 @@ fill_slices_from_node(phandle_t node, struct flash_slice *slices, int *count) | |
} | |
static int | |
-fill_slices(device_t dev, const char *provider __unused, | |
+fill_slices(device_t dev, const char *provider, struct g_consumer *cp, | |
struct flash_slice *slices, int *slices_num) | |
{ | |
phandle_t child, node; | |
@@ -135,9 +165,9 @@ fill_slices(device_t dev, const char *provider __unused, | |
*/ | |
child = fdt_find_compatible(node, "fixed-partitions", false); | |
if (child == 0) | |
- return fill_slices_from_node(node, slices, slices_num); | |
+ return fill_slices_from_node(cp, node, slices, slices_num); | |
else | |
- return fill_slices_from_node(child, slices, slices_num); | |
+ return fill_slices_from_node(cp, child, slices, slices_num); | |
} | |
static void | |
diff --git a/sys/geom/geom_flashmap.c b/sys/geom/geom_flashmap.c | |
index 71007a4f793..2f056e64771 100644 | |
--- a/sys/geom/geom_flashmap.c | |
+++ b/sys/geom/geom_flashmap.c | |
@@ -66,7 +66,8 @@ static struct { | |
static g_taste_t g_flashmap_taste; | |
static int g_flashmap_load(device_t dev, struct g_provider *pp, | |
- flash_slicer_t slicer, struct g_flashmap_head *head); | |
+ struct g_consumer *cp, flash_slicer_t slicer, | |
+ struct g_flashmap_head *head); | |
static int g_flashmap_modify(struct g_flashmap *gfp, struct g_geom *gp, | |
const char *devname, int secsize, struct g_flashmap_head *slices); | |
static void g_flashmap_print(struct g_flashmap_slice *slice); | |
@@ -163,7 +164,7 @@ g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) | |
if (slicer == NULL) | |
break; | |
- if (g_flashmap_load(dev, pp, slicer, &head) == 0) | |
+ if (g_flashmap_load(dev, pp, cp, slicer, &head) == 0) | |
break; | |
g_flashmap_modify(gfp, gp, cp->provider->name, | |
@@ -183,8 +184,8 @@ g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) | |
} | |
static int | |
-g_flashmap_load(device_t dev, struct g_provider *pp, flash_slicer_t slicer, | |
- struct g_flashmap_head *head) | |
+g_flashmap_load(device_t dev, struct g_provider *pp, struct g_consumer *cp, | |
+ flash_slicer_t slicer, struct g_flashmap_head *head) | |
{ | |
struct flash_slice *slices; | |
struct g_flashmap_slice *slice; | |
@@ -192,7 +193,7 @@ g_flashmap_load(device_t dev, struct g_provider *pp, flash_slicer_t slicer, | |
slices = malloc(sizeof(struct flash_slice) * FLASH_SLICES_MAX_NUM, | |
M_FLASHMAP, M_WAITOK | M_ZERO); | |
- if (slicer(dev, pp->name, slices, &nslices) == 0) { | |
+ if (slicer(dev, pp->name, cp, slices, &nslices) == 0) { | |
for (i = 0; i < nslices; i++) { | |
slice = malloc(sizeof(struct g_flashmap_slice), | |
M_FLASHMAP, M_WAITOK); | |
diff --git a/sys/sys/slicer.h b/sys/sys/slicer.h | |
index 675b5acc2dd..f23ccef955a 100644 | |
--- a/sys/sys/slicer.h | |
+++ b/sys/sys/slicer.h | |
@@ -32,6 +32,9 @@ | |
#define _FLASH_SLICER_H_ | |
#include <sys/types.h> | |
+#include <sys/malloc.h> | |
+ | |
+#include <geom/geom.h> | |
#define FLASH_SLICES_MAX_NUM 8 | |
#define FLASH_SLICES_MAX_NAME_LEN (32 + 1) | |
@@ -51,7 +54,7 @@ struct flash_slice { | |
#ifdef _KERNEL | |
typedef int (*flash_slicer_t)(device_t dev, const char *provider, | |
- struct flash_slice *slices, int *slices_num); | |
+ struct g_consumer *cp, struct flash_slice *slices, int *slices_num); | |
#define FLASH_SLICES_TYPE_NAND 0 | |
#define FLASH_SLICES_TYPE_CFI 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment