1/* 2 * Physical mapping layer for MTD using the Axis partitiontable format 3 * 4 * Copyright (c) 2001, 2002 Axis Communications AB 5 * 6 * This file is under the GPL. 7 * 8 * First partition is always sector 0 regardless of if we find a partitiontable 9 * or not. In the start of the next sector, there can be a partitiontable that 10 * tells us what other partitions to define. If there isn't, we use a default 11 * partition split defined below. 12 * 13 * $Log: axisflashmap.c,v $ 14 * Revision 1.1.1.1 2008/10/15 03:26:01 james26_jang 15 * Initial. 16 * 17 * Revision 1.1.1.1 2008/07/21 09:14:22 james26_jang 18 * New UI, New QoS, New wireless driver(4.151.10.29), ipmonitor. 19 * 20 * Revision 1.1.1.1 2008/07/02 14:38:28 james26_jang 21 * 4.100.10.29, New QoS and New UI. 22 * 23 * Revision 1.1.1.1 2007/02/15 12:10:52 jiahao 24 * initial update 25 * 26 * Revision 1.1.1.1 2007/01/25 12:51:48 jiahao_jhou 27 * 28 * 29 * Revision 1.1.1.1 2003/02/03 22:37:20 mhuang 30 * LINUX_2_4 branch snapshot from linux-mips.org CVS 31 * 32 * Revision 1.23 2002/05/13 12:12:28 johana 33 * Allow compile without CONFIG_MTD_MTDRAM but warn at compiletime and 34 * be informative at runtime. 35 * 36 * Revision 1.22 2002/05/13 10:24:44 johana 37 * Added #if checks on MTDRAM CONFIG 38 * 39 * Revision 1.21 2002/05/06 16:05:20 johana 40 * Removed debug printout. 41 * 42 * Revision 1.20 2002/05/06 16:03:00 johana 43 * No more cramfs as root hack in generic code. 44 * It's handled by axisflashmap using mtdram. 45 * 46 * Revision 1.19 2002/03/15 17:10:28 bjornw 47 * Changed comment about cached access since we changed this before 48 * 49 * Revision 1.18 2002/03/05 17:06:15 jonashg 50 * Try amd_flash probe before cfi_probe since amd_flash driver can handle two 51 * (or more) flash chips of different model and the cfi driver cannot. 52 * 53 * Revision 1.17 2001/11/12 19:42:38 pkj 54 * Fixed compiler warnings. 55 * 56 * Revision 1.16 2001/11/08 11:18:58 jonashg 57 * Always read from uncached address to avoid problems with flushing 58 * cachelines after write and MTD-erase. No performance loss have been 59 * seen yet. 60 * 61 * Revision 1.15 2001/10/19 12:41:04 jonashg 62 * Name of probe has changed in MTD. 63 * 64 * Revision 1.14 2001/09/21 07:14:10 jonashg 65 * Made root filesystem (cramfs) use mtdblock driver when booting from flash. 66 * 67 * Revision 1.13 2001/08/15 13:57:35 jonashg 68 * Entire MTD updated to the linux 2.4.7 version. 69 * 70 * Revision 1.12 2001/06/11 09:50:30 jonashg 71 * Oops, 2MB is 0x200000 bytes. 72 * 73 * Revision 1.11 2001/06/08 11:39:44 jonashg 74 * Changed sizes and offsets in axis_default_partitions to use 75 * CONFIG_ETRAX_PTABLE_SECTOR. 76 * 77 * Revision 1.10 2001/05/29 09:42:03 jonashg 78 * Use macro for end marker length instead of sizeof. 79 * 80 * Revision 1.9 2001/05/29 08:52:52 jonashg 81 * Gave names to the magic fours (size of the ptable end marker). 82 * 83 * Revision 1.8 2001/05/28 15:36:20 jonashg 84 * * Removed old comment about ptable location in flash (it's a CONFIG_ option). 85 * * Variable ptable was initialized twice to the same value. 86 * 87 * Revision 1.7 2001/04/05 13:41:46 markusl 88 * Updated according to review remarks 89 * 90 * Revision 1.6 2001/03/07 09:21:21 bjornw 91 * No need to waste .data 92 * 93 * Revision 1.5 2001/03/06 16:27:01 jonashg 94 * Probe the entire flash area for flash devices. 95 * 96 * Revision 1.4 2001/02/23 12:47:15 bjornw 97 * Uncached flash in LOW_MAP moved from 0xe to 0x8 98 * 99 * Revision 1.3 2001/02/16 12:11:45 jonashg 100 * MTD driver amd_flash is now included in MTD CVS repository. 101 * (It's now in drivers/mtd). 102 * 103 * Revision 1.2 2001/02/09 11:12:22 jonashg 104 * Support for AMD compatible non-CFI flash chips. 105 * Only tested with Toshiba TC58FVT160 so far. 106 * 107 * Revision 1.1 2001/01/12 17:01:18 bjornw 108 * * Added axisflashmap.c, a physical mapping for MTD that reads and understands 109 * Axis partition-table format. 110 * 111 * 112 */ 113 114#include <linux/module.h> 115#include <linux/types.h> 116#include <linux/kernel.h> 117#include <linux/config.h> 118 119#include <linux/mtd/mtd.h> 120#include <linux/mtd/map.h> 121#include <linux/mtd/partitions.h> 122#include <linux/mtd/mtdram.h> 123 124#include <asm/axisflashmap.h> 125#include <asm/mmu.h> 126 127#ifdef CONFIG_CRIS_LOW_MAP 128#define FLASH_UNCACHED_ADDR KSEG_8 129#define FLASH_CACHED_ADDR KSEG_5 130#else 131#define FLASH_UNCACHED_ADDR KSEG_E 132#define FLASH_CACHED_ADDR KSEG_F 133#endif 134 135/* 136 * WINDOW_SIZE is the total size where the flash chips may be mapped. 137 * MTD probes should find all devices there and it does not matter 138 * if there are unmapped gaps or aliases (mirrors of flash devices). 139 * The MTD probes will ignore them. 140 */ 141 142#define WINDOW_SIZE (128 * 1024 * 1024) 143 144extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* From head.S */ 145 146/* 147 * Map driver 148 * 149 * We run into tricky coherence situations if we mix cached with uncached 150 * accesses to we use the uncached version here. 151 */ 152 153static __u8 flash_read8(struct map_info *map, unsigned long ofs) 154{ 155 return *(__u8 *)(FLASH_UNCACHED_ADDR + ofs); 156} 157 158static __u16 flash_read16(struct map_info *map, unsigned long ofs) 159{ 160 return *(__u16 *)(FLASH_UNCACHED_ADDR + ofs); 161} 162 163static __u32 flash_read32(struct map_info *map, unsigned long ofs) 164{ 165 return *(volatile unsigned int *)(FLASH_UNCACHED_ADDR + ofs); 166} 167 168static void flash_copy_from(struct map_info *map, void *to, 169 unsigned long from, ssize_t len) 170{ 171 memcpy(to, (void *)(FLASH_UNCACHED_ADDR + from), len); 172} 173 174static void flash_write8(struct map_info *map, __u8 d, unsigned long adr) 175{ 176 *(__u8 *)(FLASH_UNCACHED_ADDR + adr) = d; 177} 178 179static void flash_write16(struct map_info *map, __u16 d, unsigned long adr) 180{ 181 *(__u16 *)(FLASH_UNCACHED_ADDR + adr) = d; 182} 183 184static void flash_write32(struct map_info *map, __u32 d, unsigned long adr) 185{ 186 *(__u32 *)(FLASH_UNCACHED_ADDR + adr) = d; 187} 188 189static struct map_info axis_map = { 190 name: "Axis flash", 191 size: WINDOW_SIZE, 192 buswidth: CONFIG_ETRAX_FLASH_BUSWIDTH, 193 read8: flash_read8, 194 read16: flash_read16, 195 read32: flash_read32, 196 copy_from: flash_copy_from, 197 write8: flash_write8, 198 write16: flash_write16, 199 write32: flash_write32, 200}; 201 202/* If no partition-table was found, we use this default-set. 203 */ 204 205#define MAX_PARTITIONS 7 206#define NUM_DEFAULT_PARTITIONS 3 207 208/* Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the 209 * size of one flash block and "filesystem"-partition needs 5 blocks to be able 210 * to use JFFS. 211 */ 212static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = { 213 { 214 name: "boot firmware", 215 size: CONFIG_ETRAX_PTABLE_SECTOR, 216 offset: 0 217 }, 218 { 219 name: "kernel", 220 size: 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR), 221 offset: CONFIG_ETRAX_PTABLE_SECTOR 222 }, 223 { 224 name: "filesystem", 225 size: 5 * CONFIG_ETRAX_PTABLE_SECTOR, 226 offset: 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR) 227 } 228}; 229 230static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { 231 { 232 name: "part0", 233 size: 0, 234 offset: 0 235 }, 236 { 237 name: "part1", 238 size: 0, 239 offset: 0 240 }, 241 { 242 name: "part2", 243 size: 0, 244 offset: 0 245 }, 246 { 247 name: "part3", 248 size: 0, 249 offset: 0 250 }, 251 { 252 name: "part4", 253 size: 0, 254 offset: 0 255 }, 256 { 257 name: "part5", 258 size: 0, 259 offset: 0 260 }, 261 { 262 name: "part6", 263 size: 0, 264 offset: 0 265 }, 266}; 267 268/* 269 * This is the master MTD device for which all the others are just 270 * auto-relocating aliases. 271 */ 272static struct mtd_info *mymtd; 273 274/* CFI-scan the flash, and if there was a chip, read the partition-table 275 * and register the partitions with MTD. 276 */ 277 278static int __init 279init_axis_flash(void) 280{ 281 int err = 0; 282 int pidx = 0; 283 struct partitiontable_head *ptable_head; 284 struct partitiontable_entry *ptable; 285 int use_default_ptable = 1; /* Until proven otherwise */ 286 const char *pmsg = " /dev/flash%d at 0x%x, size 0x%x\n"; 287 288 printk(KERN_NOTICE "Axis flash mapping: %x at %lx\n", 289 WINDOW_SIZE, FLASH_CACHED_ADDR); 290#ifdef CONFIG_MTD_AMDSTD 291 mymtd = (struct mtd_info *)do_map_probe("amd_flash", &axis_map); 292#endif 293 294#ifdef CONFIG_MTD_CFI 295 if (!mymtd) { 296 mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &axis_map); 297 } 298#endif 299 300 if(!mymtd) { 301 printk("%s: No flash chip found!\n", axis_map.name); 302 return -ENXIO; 303 } 304 305 mymtd->module = THIS_MODULE; 306 307 ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + 308 CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET); 309 pidx++; /* first partition is always set to the default */ 310 311 if ((ptable_head->magic == PARTITION_TABLE_MAGIC) 312 && (ptable_head->size < 313 (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + 314 PARTITIONTABLE_END_MARKER_SIZE)) 315 && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + 316 ptable_head->size - 317 PARTITIONTABLE_END_MARKER_SIZE) 318 == PARTITIONTABLE_END_MARKER)) { 319 /* Looks like a start, sane length and end of a 320 * partition table, lets check csum etc. 321 */ 322 int ptable_ok = 0; 323 struct partitiontable_entry *max_addr = 324 (struct partitiontable_entry *) 325 ((unsigned long)ptable_head + sizeof(*ptable_head) + 326 ptable_head->size); 327 unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; 328 unsigned char *p; 329 unsigned long csum = 0; 330 331 ptable = (struct partitiontable_entry *) 332 ((unsigned long)ptable_head + sizeof(*ptable_head)); 333 334 /* Lets be PARANOID, and check the checksum. */ 335 p = (unsigned char*) ptable; 336 337 while (p <= (unsigned char*)max_addr) { 338 csum += *p++; 339 csum += *p++; 340 csum += *p++; 341 csum += *p++; 342 } 343 /* printk(" total csum: 0x%08X 0x%08X\n", 344 csum, ptable_head->checksum); */ 345 ptable_ok = (csum == ptable_head->checksum); 346 347 /* Read the entries and use/show the info. */ 348 printk(" Found %s partition table at 0x%08lX-0x%08lX.\n", 349 (ptable_ok ? "valid" : "invalid"), 350 (unsigned long)ptable_head, 351 (unsigned long)max_addr); 352 353 /* We have found a working bootblock. Now read the 354 partition table. Scan the table. It ends when 355 there is 0xffffffff, that is, empty flash. */ 356 357 while (ptable_ok 358 && ptable->offset != 0xffffffff 359 && ptable < max_addr 360 && pidx < MAX_PARTITIONS) { 361 362 axis_partitions[pidx].offset = offset + ptable->offset; 363 axis_partitions[pidx].size = ptable->size; 364 365 printk(pmsg, pidx, axis_partitions[pidx].offset, 366 axis_partitions[pidx].size); 367 pidx++; 368 ptable++; 369 } 370 use_default_ptable = !ptable_ok; 371 } 372 373 if (use_default_ptable) { 374 printk(" Using default partition table\n"); 375 err = add_mtd_partitions(mymtd, axis_default_partitions, 376 NUM_DEFAULT_PARTITIONS); 377 } else { 378 if (romfs_in_flash) { 379 axis_partitions[pidx].name = "romfs"; 380 axis_partitions[pidx].size = romfs_length; 381 axis_partitions[pidx].offset = romfs_start - 382 FLASH_CACHED_ADDR; 383 axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; 384 385 printk(" Adding readonly partition for romfs image:\n"); 386 printk(pmsg, pidx, axis_partitions[pidx].offset, 387 axis_partitions[pidx].size); 388 pidx++; 389 } 390 391 err = add_mtd_partitions(mymtd, axis_partitions, pidx); 392 } 393 if (!err && !romfs_in_flash) { 394#ifdef CONFIG_MTD_MTDRAM 395 /* Allocate, initialise and forget the mtd ram struct 396 * when booting from RAM 397 */ 398 struct mtd_info *romfs_mtd = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 399 printk("MTD RAM device romfs_start: 0x%08lX len %lu\n", 400 romfs_start, romfs_length); 401 402#if (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) 403#error "You must set CONFIG_MTDRAM_TOTAL_SIZE and CONFIG_MTDRAM_ABS_POS to 0" 404#endif 405 err = mtdram_init_device(romfs_mtd, (void*)romfs_start, 406 romfs_length, "romfs in RAM"); 407#else 408#warning ###################################### 409#warning # You must enable CONFIG_MTD_MTDRAM # 410#warning # with TOTAL_SIZE 0 and ABS_POS 0 to # 411#warning # be able to boot with cramfs in RAM # 412#warning ###################################### 413/* Maybe overkill to save these bytes in non debug builds, but let's do it.. 414 * (No point in printing if we don't have a debug port anyway...) 415 */ 416#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL 417 printk("## Can't mount romfs in RAM using MTDRAM.\n"); 418 printk("## You must enable MTD_MTDRAM with TOTAL_SIZE 0 and ABS_POS 0\n"); 419#endif 420#endif /* CONFIG_MTD_MTDRAM */ 421 } 422 return err; 423} 424 425/* This adds the above to the kernels init-call chain */ 426 427module_init(init_axis_flash); 428 429