1/* 2 * Physical mapping layer for MTD using the Axis partitiontable format 3 * 4 * Copyright (c) 2001-2007 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 */ 14 15#include <linux/module.h> 16#include <linux/types.h> 17#include <linux/kernel.h> 18#include <linux/init.h> 19#include <linux/slab.h> 20 21#include <linux/mtd/concat.h> 22#include <linux/mtd/map.h> 23#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtdram.h> 25#include <linux/mtd/partitions.h> 26 27#include <asm/axisflashmap.h> 28#include <asm/mmu.h> 29 30#define MEM_CSE0_SIZE (0x04000000) 31#define MEM_CSE1_SIZE (0x04000000) 32 33#define FLASH_UNCACHED_ADDR KSEG_E 34#define FLASH_CACHED_ADDR KSEG_F 35 36#define PAGESIZE (512) 37 38#if CONFIG_ETRAX_FLASH_BUSWIDTH==1 39#define flash_data __u8 40#elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 41#define flash_data __u16 42#elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 43#define flash_data __u32 44#endif 45 46/* From head.S */ 47extern unsigned long romfs_in_flash; /* 1 when romfs_start, _length in flash */ 48extern unsigned long romfs_start, romfs_length; 49extern unsigned long nand_boot; /* 1 when booted from nand flash */ 50 51struct partition_name { 52 char name[6]; 53}; 54 55/* The master mtd for the entire flash. */ 56struct mtd_info* axisflash_mtd = NULL; 57 58/* Map driver functions. */ 59 60static map_word flash_read(struct map_info *map, unsigned long ofs) 61{ 62 map_word tmp; 63 tmp.x[0] = *(flash_data *)(map->map_priv_1 + ofs); 64 return tmp; 65} 66 67static void flash_copy_from(struct map_info *map, void *to, 68 unsigned long from, ssize_t len) 69{ 70 memcpy(to, (void *)(map->map_priv_1 + from), len); 71} 72 73static void flash_write(struct map_info *map, map_word d, unsigned long adr) 74{ 75 *(flash_data *)(map->map_priv_1 + adr) = (flash_data)d.x[0]; 76} 77 78/* 79 * The map for chip select e0. 80 * 81 * We run into tricky coherence situations if we mix cached with uncached 82 * accesses to we only use the uncached version here. 83 * 84 * The size field is the total size where the flash chips may be mapped on the 85 * chip select. MTD probes should find all devices there and it does not matter 86 * if there are unmapped gaps or aliases (mirrors of flash devices). The MTD 87 * probes will ignore them. 88 * 89 * The start address in map_priv_1 is in virtual memory so we cannot use 90 * MEM_CSE0_START but must rely on that FLASH_UNCACHED_ADDR is the start 91 * address of cse0. 92 */ 93static struct map_info map_cse0 = { 94 .name = "cse0", 95 .size = MEM_CSE0_SIZE, 96 .bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH, 97 .read = flash_read, 98 .copy_from = flash_copy_from, 99 .write = flash_write, 100 .map_priv_1 = FLASH_UNCACHED_ADDR 101}; 102 103/* 104 * The map for chip select e1. 105 * 106 * If there was a gap between cse0 and cse1, map_priv_1 would get the wrong 107 * address, but there isn't. 108 */ 109static struct map_info map_cse1 = { 110 .name = "cse1", 111 .size = MEM_CSE1_SIZE, 112 .bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH, 113 .read = flash_read, 114 .copy_from = flash_copy_from, 115 .write = flash_write, 116 .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE 117}; 118 119#define MAX_PARTITIONS 7 120#ifdef CONFIG_ETRAX_NANDBOOT 121#define NUM_DEFAULT_PARTITIONS 4 122#define DEFAULT_ROOTFS_PARTITION_NO 2 123#define DEFAULT_MEDIA_SIZE 0x2000000 /* 32 megs */ 124#else 125#define NUM_DEFAULT_PARTITIONS 3 126#define DEFAULT_ROOTFS_PARTITION_NO (-1) 127#define DEFAULT_MEDIA_SIZE 0x800000 /* 8 megs */ 128#endif 129 130#if (MAX_PARTITIONS < NUM_DEFAULT_PARTITIONS) 131#error MAX_PARTITIONS must be >= than NUM_DEFAULT_PARTITIONS 132#endif 133 134/* Initialize the ones normally used. */ 135static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { 136 { 137 .name = "part0", 138 .size = CONFIG_ETRAX_PTABLE_SECTOR, 139 .offset = 0 140 }, 141 { 142 .name = "part1", 143 .size = 0, 144 .offset = 0 145 }, 146 { 147 .name = "part2", 148 .size = 0, 149 .offset = 0 150 }, 151 { 152 .name = "part3", 153 .size = 0, 154 .offset = 0 155 }, 156 { 157 .name = "part4", 158 .size = 0, 159 .offset = 0 160 }, 161 { 162 .name = "part5", 163 .size = 0, 164 .offset = 0 165 }, 166 { 167 .name = "part6", 168 .size = 0, 169 .offset = 0 170 }, 171}; 172 173 174/* If no partition-table was found, we use this default-set. 175 * Default flash size is 8MB (NOR). CONFIG_ETRAX_PTABLE_SECTOR is most 176 * likely the size of one flash block and "filesystem"-partition needs 177 * to be >=5 blocks to be able to use JFFS. 178 */ 179static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = { 180 { 181 .name = "boot firmware", 182 .size = CONFIG_ETRAX_PTABLE_SECTOR, 183 .offset = 0 184 }, 185 { 186 .name = "kernel", 187 .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR, 188 .offset = CONFIG_ETRAX_PTABLE_SECTOR 189 }, 190#define FILESYSTEM_SECTOR (11 * CONFIG_ETRAX_PTABLE_SECTOR) 191#ifdef CONFIG_ETRAX_NANDBOOT 192 { 193 .name = "rootfs", 194 .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR, 195 .offset = FILESYSTEM_SECTOR 196 }, 197#undef FILESYSTEM_SECTOR 198#define FILESYSTEM_SECTOR (21 * CONFIG_ETRAX_PTABLE_SECTOR) 199#endif 200 { 201 .name = "rwfs", 202 .size = DEFAULT_MEDIA_SIZE - FILESYSTEM_SECTOR, 203 .offset = FILESYSTEM_SECTOR 204 } 205}; 206 207#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE 208/* Main flash device */ 209static struct mtd_partition main_partition = { 210 .name = "main", 211 .size = 0, 212 .offset = 0 213}; 214#endif 215 216/* Auxiliary partition if we find another flash */ 217static struct mtd_partition aux_partition = { 218 .name = "aux", 219 .size = 0, 220 .offset = 0 221}; 222 223/* 224 * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash 225 * chips in that order (because the amd_flash-driver is faster). 226 */ 227static struct mtd_info *probe_cs(struct map_info *map_cs) 228{ 229 struct mtd_info *mtd_cs = NULL; 230 231 printk(KERN_INFO 232 "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", 233 map_cs->name, map_cs->size, map_cs->map_priv_1); 234 235#ifdef CONFIG_MTD_CFI 236 mtd_cs = do_map_probe("cfi_probe", map_cs); 237#endif 238#ifdef CONFIG_MTD_JEDECPROBE 239 if (!mtd_cs) 240 mtd_cs = do_map_probe("jedec_probe", map_cs); 241#endif 242 243 return mtd_cs; 244} 245 246/* 247 * Probe each chip select individually for flash chips. If there are chips on 248 * both cse0 and cse1, the mtd_info structs will be concatenated to one struct 249 * so that MTD partitions can cross chip boundries. 250 * 251 * The only known restriction to how you can mount your chips is that each 252 * chip select must hold similar flash chips. But you need external hardware 253 * to do that anyway and you can put totally different chips on cse0 and cse1 254 * so it isn't really much of a restriction. 255 */ 256extern struct mtd_info* __init crisv32_nand_flash_probe (void); 257static struct mtd_info *flash_probe(void) 258{ 259 struct mtd_info *mtd_cse0; 260 struct mtd_info *mtd_cse1; 261 struct mtd_info *mtd_total; 262 struct mtd_info *mtds[2]; 263 int count = 0; 264 265 if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL) 266 mtds[count++] = mtd_cse0; 267 if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL) 268 mtds[count++] = mtd_cse1; 269 270 if (!mtd_cse0 && !mtd_cse1) { 271 /* No chip found. */ 272 return NULL; 273 } 274 275 if (count > 1) { 276 /* Since the concatenation layer adds a small overhead we 277 * could try to figure out if the chips in cse0 and cse1 are 278 * identical and reprobe the whole cse0+cse1 window. But since 279 * flash chips are slow, the overhead is relatively small. 280 * So we use the MTD concatenation layer instead of further 281 * complicating the probing procedure. 282 */ 283 mtd_total = mtd_concat_create(mtds, count, "cse0+cse1"); 284 if (!mtd_total) { 285 printk(KERN_ERR "%s and %s: Concatenation failed!\n", 286 map_cse0.name, map_cse1.name); 287 288 /* The best we can do now is to only use what we found 289 * at cse0. */ 290 mtd_total = mtd_cse0; 291 map_destroy(mtd_cse1); 292 } 293 } else 294 mtd_total = mtd_cse0 ? mtd_cse0 : mtd_cse1; 295 296 return mtd_total; 297} 298 299/* 300 * Probe the flash chip(s) and, if it succeeds, read the partition-table 301 * and register the partitions with MTD. 302 */ 303static int __init init_axis_flash(void) 304{ 305 struct mtd_info *main_mtd; 306 struct mtd_info *aux_mtd = NULL; 307 int err = 0; 308 int pidx = 0; 309 struct partitiontable_head *ptable_head = NULL; 310 struct partitiontable_entry *ptable; 311 int ptable_ok = 0; 312 static char page[PAGESIZE]; 313 size_t len; 314 int ram_rootfs_partition = -1; /* -1 => no RAM rootfs partition */ 315 int part; 316 317 /* We need a root fs. If it resides in RAM, we need to use an 318 * MTDRAM device, so it must be enabled in the kernel config, 319 * but its size must be configured as 0 so as not to conflict 320 * with our usage. 321 */ 322#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) 323 if (!romfs_in_flash && !nand_boot) { 324 printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " 325 "device; configure CONFIG_MTD_MTDRAM with size = 0!\n"); 326 panic("This kernel cannot boot from RAM!\n"); 327 } 328#endif 329 330 main_mtd = flash_probe(); 331 if (main_mtd) 332 printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n", 333 main_mtd->name, main_mtd->size); 334 335#ifdef CONFIG_ETRAX_NANDFLASH 336 aux_mtd = crisv32_nand_flash_probe(); 337 if (aux_mtd) 338 printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n", 339 aux_mtd->name, aux_mtd->size); 340 341#ifdef CONFIG_ETRAX_NANDBOOT 342 { 343 struct mtd_info *tmp_mtd; 344 345 printk(KERN_INFO "axisflashmap: Set to boot from NAND flash, " 346 "making NAND flash primary device.\n"); 347 tmp_mtd = main_mtd; 348 main_mtd = aux_mtd; 349 aux_mtd = tmp_mtd; 350 } 351#endif /* CONFIG_ETRAX_NANDBOOT */ 352#endif /* CONFIG_ETRAX_NANDFLASH */ 353 354 if (!main_mtd && !aux_mtd) { 355 /* There's no reason to use this module if no flash chip can 356 * be identified. Make sure that's understood. 357 */ 358 printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); 359 } 360 361#if 0 /* Dump flash memory so we can see what is going on */ 362 if (main_mtd) { 363 int sectoraddr, i; 364 for (sectoraddr = 0; sectoraddr < 2*65536+4096; 365 sectoraddr += PAGESIZE) { 366 main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len, 367 page); 368 printk(KERN_INFO 369 "Sector at %d (length %d):\n", 370 sectoraddr, len); 371 for (i = 0; i < PAGESIZE; i += 16) { 372 printk(KERN_INFO 373 "%02x %02x %02x %02x " 374 "%02x %02x %02x %02x " 375 "%02x %02x %02x %02x " 376 "%02x %02x %02x %02x\n", 377 page[i] & 255, page[i+1] & 255, 378 page[i+2] & 255, page[i+3] & 255, 379 page[i+4] & 255, page[i+5] & 255, 380 page[i+6] & 255, page[i+7] & 255, 381 page[i+8] & 255, page[i+9] & 255, 382 page[i+10] & 255, page[i+11] & 255, 383 page[i+12] & 255, page[i+13] & 255, 384 page[i+14] & 255, page[i+15] & 255); 385 } 386 } 387 } 388#endif 389 390 if (main_mtd) { 391 main_mtd->owner = THIS_MODULE; 392 axisflash_mtd = main_mtd; 393 394 loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR; 395 396 /* First partition (rescue) is always set to the default. */ 397 pidx++; 398#ifdef CONFIG_ETRAX_NANDBOOT 399 /* We know where the partition table should be located, 400 * it will be in first good block after that. 401 */ 402 int blockstat; 403 do { 404 blockstat = mtd_block_isbad(main_mtd, ptable_sector); 405 if (blockstat < 0) 406 ptable_sector = 0; /* read error */ 407 else if (blockstat) 408 ptable_sector += main_mtd->erasesize; 409 } while (blockstat && ptable_sector); 410#endif 411 if (ptable_sector) { 412 mtd_read(main_mtd, ptable_sector, PAGESIZE, &len, 413 page); 414 ptable_head = &((struct partitiontable *) page)->head; 415 } 416 417#if 0 /* Dump partition table so we can see what is going on */ 418 printk(KERN_INFO 419 "axisflashmap: flash read %d bytes at 0x%08x, data: " 420 "%02x %02x %02x %02x %02x %02x %02x %02x\n", 421 len, CONFIG_ETRAX_PTABLE_SECTOR, 422 page[0] & 255, page[1] & 255, 423 page[2] & 255, page[3] & 255, 424 page[4] & 255, page[5] & 255, 425 page[6] & 255, page[7] & 255); 426 printk(KERN_INFO 427 "axisflashmap: partition table offset %d, data: " 428 "%02x %02x %02x %02x %02x %02x %02x %02x\n", 429 PARTITION_TABLE_OFFSET, 430 page[PARTITION_TABLE_OFFSET+0] & 255, 431 page[PARTITION_TABLE_OFFSET+1] & 255, 432 page[PARTITION_TABLE_OFFSET+2] & 255, 433 page[PARTITION_TABLE_OFFSET+3] & 255, 434 page[PARTITION_TABLE_OFFSET+4] & 255, 435 page[PARTITION_TABLE_OFFSET+5] & 255, 436 page[PARTITION_TABLE_OFFSET+6] & 255, 437 page[PARTITION_TABLE_OFFSET+7] & 255); 438#endif 439 } 440 441 if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) 442 && (ptable_head->size < 443 (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + 444 PARTITIONTABLE_END_MARKER_SIZE)) 445 && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + 446 ptable_head->size - 447 PARTITIONTABLE_END_MARKER_SIZE) 448 == PARTITIONTABLE_END_MARKER)) { 449 /* Looks like a start, sane length and end of a 450 * partition table, lets check csum etc. 451 */ 452 struct partitiontable_entry *max_addr = 453 (struct partitiontable_entry *) 454 ((unsigned long)ptable_head + sizeof(*ptable_head) + 455 ptable_head->size); 456 unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; 457 unsigned char *p; 458 unsigned long csum = 0; 459 460 ptable = (struct partitiontable_entry *) 461 ((unsigned long)ptable_head + sizeof(*ptable_head)); 462 463 /* Lets be PARANOID, and check the checksum. */ 464 p = (unsigned char*) ptable; 465 466 while (p <= (unsigned char*)max_addr) { 467 csum += *p++; 468 csum += *p++; 469 csum += *p++; 470 csum += *p++; 471 } 472 ptable_ok = (csum == ptable_head->checksum); 473 474 /* Read the entries and use/show the info. */ 475 printk(KERN_INFO "axisflashmap: " 476 "Found a%s partition table at 0x%p-0x%p.\n", 477 (ptable_ok ? " valid" : "n invalid"), ptable_head, 478 max_addr); 479 480 /* We have found a working bootblock. Now read the 481 * partition table. Scan the table. It ends with 0xffffffff. 482 */ 483 while (ptable_ok 484 && ptable->offset != PARTITIONTABLE_END_MARKER 485 && ptable < max_addr 486 && pidx < MAX_PARTITIONS - 1) { 487 488 axis_partitions[pidx].offset = offset + ptable->offset; 489#ifdef CONFIG_ETRAX_NANDFLASH 490 if (main_mtd->type == MTD_NANDFLASH) { 491 axis_partitions[pidx].size = 492 (((ptable+1)->offset == 493 PARTITIONTABLE_END_MARKER) ? 494 main_mtd->size : 495 ((ptable+1)->offset + offset)) - 496 (ptable->offset + offset); 497 498 } else 499#endif /* CONFIG_ETRAX_NANDFLASH */ 500 axis_partitions[pidx].size = ptable->size; 501#ifdef CONFIG_ETRAX_NANDBOOT 502 /* Save partition number of jffs2 ro partition. 503 * Needed if RAM booting or root file system in RAM. 504 */ 505 if (!nand_boot && 506 ram_rootfs_partition < 0 && /* not already set */ 507 ptable->type == PARTITION_TYPE_JFFS2 && 508 (ptable->flags & PARTITION_FLAGS_READONLY_MASK) == 509 PARTITION_FLAGS_READONLY) 510 ram_rootfs_partition = pidx; 511#endif /* CONFIG_ETRAX_NANDBOOT */ 512 pidx++; 513 ptable++; 514 } 515 } 516 517 /* Decide whether to use default partition table. */ 518 /* Only use default table if we actually have a device (main_mtd) */ 519 520 struct mtd_partition *partition = &axis_partitions[0]; 521 if (main_mtd && !ptable_ok) { 522 memcpy(axis_partitions, axis_default_partitions, 523 sizeof(axis_default_partitions)); 524 pidx = NUM_DEFAULT_PARTITIONS; 525 ram_rootfs_partition = DEFAULT_ROOTFS_PARTITION_NO; 526 } 527 528 /* Add artificial partitions for rootfs if necessary */ 529 if (romfs_in_flash) { 530 /* rootfs is in directly accessible flash memory = NOR flash. 531 Add an overlapping device for the rootfs partition. */ 532 printk(KERN_INFO "axisflashmap: Adding partition for " 533 "overlapping root file system image\n"); 534 axis_partitions[pidx].size = romfs_length; 535 axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; 536 axis_partitions[pidx].name = "romfs"; 537 axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; 538 ram_rootfs_partition = -1; 539 pidx++; 540 } else if (romfs_length && !nand_boot) { 541 /* romfs exists in memory, but not in flash, so must be in RAM. 542 * Configure an MTDRAM partition. */ 543 if (ram_rootfs_partition < 0) { 544 /* None set yet, put it at the end */ 545 ram_rootfs_partition = pidx; 546 pidx++; 547 } 548 printk(KERN_INFO "axisflashmap: Adding partition for " 549 "root file system image in RAM\n"); 550 axis_partitions[ram_rootfs_partition].size = romfs_length; 551 axis_partitions[ram_rootfs_partition].offset = romfs_start; 552 axis_partitions[ram_rootfs_partition].name = "romfs"; 553 axis_partitions[ram_rootfs_partition].mask_flags |= 554 MTD_WRITEABLE; 555 } 556 557#ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE 558 if (main_mtd) { 559 main_partition.size = main_mtd->size; 560 err = mtd_device_register(main_mtd, &main_partition, 1); 561 if (err) 562 panic("axisflashmap: Could not initialize " 563 "partition for whole main mtd device!\n"); 564 } 565#endif 566 567 /* Now, register all partitions with mtd. 568 * We do this one at a time so we can slip in an MTDRAM device 569 * in the proper place if required. */ 570 571 for (part = 0; part < pidx; part++) { 572 if (part == ram_rootfs_partition) { 573 /* add MTDRAM partition here */ 574 struct mtd_info *mtd_ram; 575 576 mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 577 if (!mtd_ram) 578 panic("axisflashmap: Couldn't allocate memory " 579 "for mtd_info!\n"); 580 printk(KERN_INFO "axisflashmap: Adding RAM partition " 581 "for rootfs image.\n"); 582 err = mtdram_init_device(mtd_ram, 583 (void *)partition[part].offset, 584 partition[part].size, 585 partition[part].name); 586 if (err) 587 panic("axisflashmap: Could not initialize " 588 "MTD RAM device!\n"); 589 /* JFFS2 likes to have an erasesize. Keep potential 590 * JFFS2 rootfs happy by providing one. Since image 591 * was most likely created for main mtd, use that 592 * erasesize, if available. Otherwise, make a guess. */ 593 mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize : 594 CONFIG_ETRAX_PTABLE_SECTOR); 595 } else { 596 err = mtd_device_register(main_mtd, &partition[part], 597 1); 598 if (err) 599 panic("axisflashmap: Could not add mtd " 600 "partition %d\n", part); 601 } 602 } 603 604 if (aux_mtd) { 605 aux_partition.size = aux_mtd->size; 606 err = mtd_device_register(aux_mtd, &aux_partition, 1); 607 if (err) 608 panic("axisflashmap: Could not initialize " 609 "aux mtd device!\n"); 610 611 } 612 613 return err; 614} 615 616/* This adds the above to the kernels init-call chain. */ 617module_init(init_axis_flash); 618 619EXPORT_SYMBOL(axisflash_mtd); 620