1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
diff -urN linux-2.6.17/drivers/mtd/maps/bcm963xx-flash.c linux-2.6.17-brcm63xx/drivers/mtd/maps/bcm963xx-flash.c
--- linux-2.6.17/drivers/mtd/maps/bcm963xx-flash.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.17-brcm63xx/drivers/mtd/maps/bcm963xx-flash.c 2006-08-03 16:29:52.000000000 +0200
@@ -0,0 +1,116 @@
+/*
+ * $Id$
+ * Copyright (C) 2006 Florian Fainelli
+ * Copyright (C) $Date$ $Author$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This is the BCM963xx flash map driver, in its actual state it only supports BCM96348 devices
+ * this driver is able to manage both bootloader we found on these boards : CFE and RedBoot
+ *
+ * RedBoot :
+ * - this bootloader allows us to parse partitions and therefore deduce the MTD partition table
+ *
+ * CFE :
+ * - we have to use a "physically mapped flash" defined bellow
+ *
+ */
+
+#include <asm/io.h>
+#include <linux/init.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#define WINDOW_ADDR 0x1e400000 /* Real address of the flash */
+#define WINDOW_SIZE 0x800000 /* Size of flash */
+#define BUSWIDTH 2 /* Buswidth */
+
+extern int boot_loader_type; /* For RedBoot / CFE detection */
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
+static struct mtd_partition *parsed_parts;
+
+static void __exit bcm963xx_mtd_cleanup(void);
+
+static struct mtd_info *bcm963xx_mtd_info;
+
+static struct map_info bcm963xx_map = {
+ .name = "bcm963xx",
+ .size = WINDOW_SIZE,
+ .bankwidth = BUSWIDTH,
+ .phys = WINDOW_ADDR,
+};
+
+static struct mtd_partition bcm963xx_parts[] = {
+ { name: "bootloader", size: 0, offset: 0, mask_flags: MTD_WRITEABLE },
+ { name: "rootfs", size: 0, offset: 0},
+ { name: "jffs2", size: 5 * 0x10000, offset: 57*0x10000}
+};
+
+static int __init bcm963xx_mtd_init(void)
+{
+ printk("bcm963xx: 0x%08x at 0x%08x\n", WINDOW_SIZE, WINDOW_ADDR);
+ bcm963xx_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+ if (!bcm963xx_map.virt) {
+ printk("bcm963xx: Failed to ioremap\n");
+ return -EIO;
+ }
+
+ simple_map_init(&bcm963xx_map);
+
+ bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map);
+
+ if (bcm963xx_mtd_info) {
+ bcm963xx_mtd_info->owner = THIS_MODULE;
+ int parsed_nr_parts = 0;
+ char * part_type;
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+ if (parsed_nr_parts == 0) {
+ int ret = parse_redboot_partitions(bcm963xx_mtd_info, &parsed_parts, 0);
+ if (ret > 0) {
+ part_type = "RedBoot";
+ parsed_nr_parts = ret;
+ }
+ }
+#endif
+ add_mtd_partitions(bcm963xx_mtd_info, parsed_parts, parsed_nr_parts);
+
+ return 0;
+ }
+ iounmap(bcm963xx_map.virt);
+ return -ENXIO;
+}
+
+static void __exit bcm963xx_mtd_cleanup(void)
+{
+ if (bcm963xx_mtd_info) {
+ del_mtd_partitions(bcm963xx_mtd_info);
+ map_destroy(bcm963xx_mtd_info);
+ }
+
+ if (bcm963xx_map.virt) {
+ iounmap(bcm963xx_map.virt);
+ bcm963xx_map.virt = 0;
+ }
+}
+
+module_init(bcm963xx_mtd_init);
+module_exit(bcm963xx_mtd_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Florian Fainelli");
diff -urN linux-2.6.17/drivers/mtd/maps/Kconfig linux-2.6.17-brcm63xx/drivers/mtd/maps/Kconfig
--- linux-2.6.17/drivers/mtd/maps/Kconfig 2006-06-18 03:49:35.000000000 +0200
+++ linux-2.6.17-brcm63xx/drivers/mtd/maps/Kconfig 2006-08-03 16:32:05.000000000 +0200
@@ -224,6 +224,13 @@
Flash memory access on 4G Systems MTX-1 Board. If you have one of
these boards and would like to use the flash chips on it, say 'Y'.
+config MTD_BCM963XX
+ tristate "BCM963xx Flash device"
+ depends on MIPS && MIPS_BRCM
+ help
+ Flash memory access on BCM963xx boards. Currently only works with
+ RedBoot, CFE support coming soon.
+
config MTD_DILNETPC
tristate "CFI Flash device mapped on DIL/Net PC"
depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
diff -urN linux-2.6.17/drivers/mtd/maps/Makefile linux-2.6.17-brcm63xx/drivers/mtd/maps/Makefile
--- linux-2.6.17/drivers/mtd/maps/Makefile 2006-06-18 03:49:35.000000000 +0200
+++ linux-2.6.17-brcm63xx/drivers/mtd/maps/Makefile 2006-08-03 16:32:27.000000000 +0200
@@ -71,3 +71,4 @@
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
+obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
diff -urN linux-2.6.17/drivers/mtd/redboot.c linux-2.6.17-brcm63xx/drivers/mtd/redboot.c
--- linux-2.6.17/drivers/mtd/redboot.c 2006-06-18 03:49:35.000000000 +0200
+++ linux-2.6.17-brcm63xx/drivers/mtd/redboot.c 2006-08-03 16:32:39.000000000 +0200
@@ -39,7 +39,7 @@
return 1;
}
-static int parse_redboot_partitions(struct mtd_info *master,
+int parse_redboot_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long fis_origin)
{
@@ -120,11 +120,19 @@
goto out;
}
+ if (!fis_origin) {
+ for (i = 0; i < numslots; i++) {
+ if (!strncmp(buf[i].name, "RedBoot", 8)) {
+ fis_origin = (buf[i].flash_base & (master->size << 1) - 1);
+ }
+ }
+ }
+
for (i = 0; i < numslots; i++) {
struct fis_list *new_fl, **prev;
if (buf[i].name[0] == 0xff)
- continue;
+ break;
if (!redboot_checksum(&buf[i]))
break;
@@ -135,11 +143,10 @@
goto out;
}
new_fl->img = &buf[i];
- if (fis_origin) {
- buf[i].flash_base -= fis_origin;
- } else {
- buf[i].flash_base &= master->size-1;
- }
+ if (fis_origin) {
+ buf[i].flash_base -= fis_origin;
+ }
+ buf[i].flash_base &= (master->size << 1) - 1;
/* I'm sure the JFFS2 code has done me permanent damage.
* I now think the following is _normal_
|