25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/slab.h>
38 #define BCM63XX_EXTENDED_SIZE 0xBFC00000
40 #define BCM63XX_MIN_CFE_SIZE 0x10000
41 #define BCM63XX_MIN_NVRAM_SIZE 0x10000
43 #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0
45 static int bcm63xx_detect_cfe(
struct mtd_info *master)
58 if (
strncmp(
"cfe-v", buf, 5) == 0)
66 return strncmp(
"CFE1CFE1", buf, 8);
69 static int bcm63xx_parse_cfe_partitions(
struct mtd_info *master,
74 int nrparts = 3, curpart = 0;
79 unsigned int rootfsaddr, kerneladdr, spareaddr;
80 unsigned int rootfslen, kernellen, sparelen, totallen;
81 unsigned int cfelen, nvramlen;
85 bool rootfs_first =
false;
87 if (bcm63xx_detect_cfe(master))
102 if (retlen !=
sizeof(
struct bcm_tag)) {
110 char *boardid = &(buf->
board_id[0]);
118 pr_info(
"CFE boot tag found with version %s and board type %s\n",
119 tagversion, boardid);
124 sparelen = master->
size - spareaddr - nvramlen;
126 if (rootfsaddr < kerneladdr) {
128 rootfslen = kerneladdr - rootfsaddr;
132 rootfsaddr = kerneladdr + kernellen;
133 rootfslen = spareaddr - rootfsaddr;
136 pr_warn(
"CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
142 sparelen = master->
size - cfelen - nvramlen;
157 parts = kzalloc(
sizeof(*parts) * nrparts + 10 * nrparts,
GFP_KERNEL);
164 parts[curpart].
name =
"CFE";
165 parts[curpart].
offset = 0;
166 parts[curpart].
size = cfelen;
170 int kernelpart = curpart;
172 if (rootfslen > 0 && rootfs_first)
174 parts[kernelpart].
name =
"kernel";
175 parts[kernelpart].
offset = kerneladdr;
176 parts[kernelpart].
size = kernellen;
181 int rootfspart = curpart;
183 if (kernellen > 0 && rootfs_first)
185 parts[rootfspart].
name =
"rootfs";
186 parts[rootfspart].
offset = rootfsaddr;
187 parts[rootfspart].
size = rootfslen;
188 if (sparelen > 0 && !rootfs_first)
189 parts[rootfspart].
size += sparelen;
193 parts[curpart].
name =
"nvram";
194 parts[curpart].
offset = master->
size - nvramlen;
195 parts[curpart].
size = nvramlen;
199 parts[curpart].
name =
"linux";
200 parts[curpart].
offset = cfelen;
201 parts[curpart].
size = master->
size - cfelen - nvramlen;
203 for (i = 0; i < nrparts; i++)
204 pr_info(
"Partition %d is %s offset %lx and length %lx\n", i,
205 parts[i].
name, (
long unsigned int)(parts[i].
offset),
206 (
long unsigned int)(parts[i].
size));
208 pr_info(
"Spare partition is offset %x and length %x\n", spareaddr,
219 .parse_fn = bcm63xx_parse_cfe_partitions,
220 .name =
"bcm63xxpart",
223 static int __init bcm63xx_cfe_parser_init(
void)
228 static void __exit bcm63xx_cfe_parser_exit(
void)