Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.