Index: sys/dev/bhnd/cores/chipc/chipc_slicer.c =================================================================== --- sys/dev/bhnd/cores/chipc/chipc_slicer.c +++ sys/dev/bhnd/cores/chipc/chipc_slicer.c @@ -80,7 +80,7 @@ int chipc_slicer_cfi(device_t dev, const char *provider __unused, - struct flash_slice *slices, int *nslices) + struct g_consumer *cp, struct flash_slice *slices, int *nslices) { struct cfi_softc *sc; device_t parent; @@ -106,7 +106,7 @@ int chipc_slicer_spi(device_t dev, const char *provider __unused, - struct flash_slice *slices, int *nslices) + struct g_consumer *cp, struct flash_slice *slices, int *nslices) { struct chipc_spi_softc *sc; device_t chipc, spi, spibus; Index: sys/dev/fdt/fdt_slicer.c =================================================================== --- sys/dev/fdt/fdt_slicer.c +++ sys/dev/fdt/fdt_slicer.c @@ -39,6 +39,8 @@ #include #include +#include + #ifdef DEBUG #define debugf(fmt, args...) do { printf("%s(): ", __func__); \ printf(fmt,##args); } while (0) @@ -46,26 +48,33 @@ #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 @@ 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 @@ } 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 @@ */ 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 Index: sys/dev/mmc/mmcsd.c =================================================================== --- sys/dev/mmc/mmcsd.c +++ sys/dev/mmc/mmcsd.c @@ -198,7 +198,7 @@ static daddr_t mmcsd_rw(struct mmcsd_part *part, struct bio *bp); static int mmcsd_set_blockcount(struct mmcsd_softc *sc, u_int count, bool rel); static int mmcsd_slicer(device_t dev, const char *provider, - struct flash_slice *slices, int *nslices); + struct g_consumer *cp, struct flash_slice *slices, int *nslices); static int mmcsd_switch_part(device_t bus, device_t dev, uint16_t rca, u_int part); @@ -624,7 +624,7 @@ } static int -mmcsd_slicer(device_t dev, const char *provider, +mmcsd_slicer(device_t dev, const char *provider, struct g_consumer *cp, struct flash_slice *slices, int *nslices) { char name[MMCSD_PART_NAMELEN]; Index: sys/geom/geom_flashmap.c =================================================================== --- sys/geom/geom_flashmap.c +++ sys/geom/geom_flashmap.c @@ -66,7 +66,8 @@ 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 @@ 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 @@ } 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 @@ 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); Index: sys/sys/slicer.h =================================================================== --- sys/sys/slicer.h +++ sys/sys/slicer.h @@ -32,6 +32,9 @@ #define _FLASH_SLICER_H_ #include +#include + +#include #define FLASH_SLICES_MAX_NUM 8 #define FLASH_SLICES_MAX_NAME_LEN (32 + 1) @@ -51,7 +54,7 @@ #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