bool flash_init(FlashIO* io, void (*text_fn)(const char*), void (*send_fn)(const void* data, int length)) { flash_send_fn = send_fn; #if defined(ALLOW_VERBOSE) debug_fn = text_fn; #endif i2c_init(io->i2c); if (i2c_is_present(io->i2c)) { // Probe memory device to find its size. flash_probe(io); #if defined(ALLOW_VERBOSE) if (debug_fn) { char buff[32]; snprintf(buff, sizeof(buff), "flash_init(%d,%d)\r\n", io->info.pages, io->info.page_size); debug(buff); } #endif } return true; }
int flash_env_init(void) { DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_OMAP2420H4 int flash_probe(void); if(flash_probe() == 0) goto bad_flash; #endif #ifdef CMD_SAVEENV if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { gd->env_addr = (ulong)&(env_ptr->data); gd->env_valid = 1; return(0); } #endif #ifdef CONFIG_OMAP2420H4 bad_flash: #endif gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 0; return (0); }
int env_init(void) { DECLARE_GLOBAL_DATA_PTR; int crc1_ok = 0, crc2_ok = 0; uchar flag1 = flash_addr->flags; uchar flag2 = flash_addr_new->flags; ulong addr_default = (ulong)&default_environment[0]; ulong addr1 = (ulong)&(flash_addr->data); ulong addr2 = (ulong)&(flash_addr_new->data); #ifdef CONFIG_OMAP2420H4 int flash_probe(void); if(flash_probe() == 0) goto bad_flash; #endif crc1_ok = (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc); crc2_ok = (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc); if (crc1_ok && ! crc2_ok) { gd->env_addr = addr1; gd->env_valid = 1; } else if (! crc1_ok && crc2_ok) { gd->env_addr = addr2; gd->env_valid = 1; } else if (! crc1_ok && ! crc2_ok) { gd->env_addr = addr_default; gd->env_valid = 0; } else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) { gd->env_addr = addr1; gd->env_valid = 1; } else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) { gd->env_addr = addr2; gd->env_valid = 1; } else if (flag1 == flag2) { gd->env_addr = addr1; gd->env_valid = 2; } else if (flag1 == 0xFF) { gd->env_addr = addr1; gd->env_valid = 2; } else if (flag2 == 0xFF) { gd->env_addr = addr2; gd->env_valid = 2; } #ifdef CONFIG_OMAP2420H4 bad_flash: #endif return (0); }
int __init lart_flash_init (void) { int result; memset (&mtd,0,sizeof (mtd)); printk ("MTD driver for LART. Written by Abraham vd Merwe <*****@*****.**>\n"); printk ("%s: Probing for 28F160x3 flash on LART...\n",module_name); if (!flash_probe ()) { printk (KERN_WARNING "%s: Found no LART compatible flash device\n",module_name); return (-ENXIO); } printk ("%s: This looks like a LART board to me.\n",module_name); mtd.name = module_name; mtd.type = MTD_NORFLASH; mtd.writesize = 1; mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; mtd.numeraseregions = ARRAY_SIZE(erase_regions); mtd.eraseregions = erase_regions; mtd.erase = flash_erase; mtd.read = flash_read; mtd.write = flash_write; mtd.owner = THIS_MODULE; #ifdef LART_DEBUG printk (KERN_DEBUG "mtd.name = %s\n" "mtd.size = 0x%.8x (%uM)\n" "mtd.erasesize = 0x%.8x (%uK)\n" "mtd.numeraseregions = %d\n", mtd.name, mtd.size,mtd.size / (1024*1024), mtd.erasesize,mtd.erasesize / 1024, mtd.numeraseregions); if (mtd.numeraseregions) for (result = 0; result < mtd.numeraseregions; result++) printk (KERN_DEBUG "\n\n" "mtd.eraseregions[%d].offset = 0x%.8x\n" "mtd.eraseregions[%d].erasesize = 0x%.8x (%uK)\n" "mtd.eraseregions[%d].numblocks = %d\n", result,mtd.eraseregions[result].offset, result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024, result,mtd.eraseregions[result].numblocks); #ifdef HAVE_PARTITIONS printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) printk (KERN_DEBUG "\n\n" "lart_partitions[%d].name = %s\n" "lart_partitions[%d].offset = 0x%.8x\n" "lart_partitions[%d].size = 0x%.8x (%uK)\n", result,lart_partitions[result].name, result,lart_partitions[result].offset, result,lart_partitions[result].size,lart_partitions[result].size / 1024); #endif #endif #ifndef HAVE_PARTITIONS result = add_mtd_device (&mtd); #else result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions)); #endif return (result); }
/* * Probe the flash chip(s) and, if it succeeds, read the partition-table * and register the partitions with MTD. */ static int __init init_axis_flash(void) { struct mtd_info *main_mtd; struct mtd_info *aux_mtd = NULL; int err = 0; int pidx = 0; struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int ptable_ok = 0; static char page[PAGESIZE]; size_t len; int ram_rootfs_partition = -1; /* -1 => no RAM rootfs partition */ int part; /* We need a root fs. If it resides in RAM, we need to use an * MTDRAM device, so it must be enabled in the kernel config, * but its size must be configured as 0 so as not to conflict * with our usage. */ #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) if (!romfs_in_flash && !nand_boot) { printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " "device; configure CONFIG_MTD_MTDRAM with size = 0!\n"); panic("This kernel cannot boot from RAM!\n"); } #endif #ifndef CONFIG_ETRAX_VCS_SIM main_mtd = flash_probe(); if (main_mtd) printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n", main_mtd->name, main_mtd->size); #ifdef CONFIG_ETRAX_NANDFLASH aux_mtd = crisv32_nand_flash_probe(); if (aux_mtd) printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n", aux_mtd->name, aux_mtd->size); #ifdef CONFIG_ETRAX_NANDBOOT { struct mtd_info *tmp_mtd; printk(KERN_INFO "axisflashmap: Set to boot from NAND flash, " "making NAND flash primary device.\n"); tmp_mtd = main_mtd; main_mtd = aux_mtd; aux_mtd = tmp_mtd; } #endif /* CONFIG_ETRAX_NANDBOOT */ #endif /* CONFIG_ETRAX_NANDFLASH */ if (!main_mtd && !aux_mtd) { /* There's no reason to use this module if no flash chip can * be identified. Make sure that's understood. */ printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); } #if 0 /* Dump flash memory so we can see what is going on */ if (main_mtd) { int sectoraddr, i; for (sectoraddr = 0; sectoraddr < 2*65536+4096; sectoraddr += PAGESIZE) { main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len, page); printk(KERN_INFO "Sector at %d (length %d):\n", sectoraddr, len); for (i = 0; i < PAGESIZE; i += 16) { printk(KERN_INFO "%02x %02x %02x %02x " "%02x %02x %02x %02x " "%02x %02x %02x %02x " "%02x %02x %02x %02x\n", page[i] & 255, page[i+1] & 255, page[i+2] & 255, page[i+3] & 255, page[i+4] & 255, page[i+5] & 255, page[i+6] & 255, page[i+7] & 255, page[i+8] & 255, page[i+9] & 255, page[i+10] & 255, page[i+11] & 255, page[i+12] & 255, page[i+13] & 255, page[i+14] & 255, page[i+15] & 255); } } } #endif if (main_mtd) { main_mtd->owner = THIS_MODULE; axisflash_mtd = main_mtd; loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR; /* First partition (rescue) is always set to the default. */ pidx++; #ifdef CONFIG_ETRAX_NANDBOOT /* We know where the partition table should be located, * it will be in first good block after that. */ int blockstat; do { blockstat = main_mtd->block_isbad(main_mtd, ptable_sector); if (blockstat < 0) ptable_sector = 0; /* read error */ else if (blockstat) ptable_sector += main_mtd->erasesize; } while (blockstat && ptable_sector); #endif if (ptable_sector) { main_mtd->read(main_mtd, ptable_sector, PAGESIZE, &len, page); ptable_head = &((struct partitiontable *) page)->head; } #if 0 /* Dump partition table so we can see what is going on */ printk(KERN_INFO "axisflashmap: flash read %d bytes at 0x%08x, data: " "%02x %02x %02x %02x %02x %02x %02x %02x\n", len, CONFIG_ETRAX_PTABLE_SECTOR, page[0] & 255, page[1] & 255, page[2] & 255, page[3] & 255, page[4] & 255, page[5] & 255, page[6] & 255, page[7] & 255); printk(KERN_INFO "axisflashmap: partition table offset %d, data: " "%02x %02x %02x %02x %02x %02x %02x %02x\n", PARTITION_TABLE_OFFSET, page[PARTITION_TABLE_OFFSET+0] & 255, page[PARTITION_TABLE_OFFSET+1] & 255, page[PARTITION_TABLE_OFFSET+2] & 255, page[PARTITION_TABLE_OFFSET+3] & 255, page[PARTITION_TABLE_OFFSET+4] & 255, page[PARTITION_TABLE_OFFSET+5] & 255, page[PARTITION_TABLE_OFFSET+6] & 255, page[PARTITION_TABLE_OFFSET+7] & 255); #endif } if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + ptable_head->size - PARTITIONTABLE_END_MARKER_SIZE) == PARTITIONTABLE_END_MARKER)) { /* Looks like a start, sane length and end of a * partition table, lets check csum etc. */ struct partitiontable_entry *max_addr = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head) + ptable_head->size); unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; unsigned char *p; unsigned long csum = 0; ptable = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head)); /* Lets be PARANOID, and check the checksum. */ p = (unsigned char*) ptable; while (p <= (unsigned char*)max_addr) { csum += *p++; csum += *p++; csum += *p++; csum += *p++; } ptable_ok = (csum == ptable_head->checksum); /* Read the entries and use/show the info. */ printk(KERN_INFO "axisflashmap: " "Found a%s partition table at 0x%p-0x%p.\n", (ptable_ok ? " valid" : "n invalid"), ptable_head, max_addr); /* We have found a working bootblock. Now read the * partition table. Scan the table. It ends with 0xffffffff. */ while (ptable_ok && ptable->offset != PARTITIONTABLE_END_MARKER && ptable < max_addr && pidx < MAX_PARTITIONS - 1) { axis_partitions[pidx].offset = offset + ptable->offset; #ifdef CONFIG_ETRAX_NANDFLASH if (main_mtd->type == MTD_NANDFLASH) { axis_partitions[pidx].size = (((ptable+1)->offset == PARTITIONTABLE_END_MARKER) ? main_mtd->size : ((ptable+1)->offset + offset)) - (ptable->offset + offset); } else #endif /* CONFIG_ETRAX_NANDFLASH */ axis_partitions[pidx].size = ptable->size; #ifdef CONFIG_ETRAX_NANDBOOT /* Save partition number of jffs2 ro partition. * Needed if RAM booting or root file system in RAM. */ if (!nand_boot && ram_rootfs_partition < 0 && /* not already set */ ptable->type == PARTITION_TYPE_JFFS2 && (ptable->flags & PARTITION_FLAGS_READONLY_MASK) == PARTITION_FLAGS_READONLY) ram_rootfs_partition = pidx; #endif /* CONFIG_ETRAX_NANDBOOT */ pidx++; ptable++; } } /* Decide whether to use default partition table. */ /* Only use default table if we actually have a device (main_mtd) */ struct mtd_partition *partition = &axis_partitions[0]; if (main_mtd && !ptable_ok) { memcpy(axis_partitions, axis_default_partitions, sizeof(axis_default_partitions)); pidx = NUM_DEFAULT_PARTITIONS; ram_rootfs_partition = DEFAULT_ROOTFS_PARTITION_NO; } /* Add artificial partitions for rootfs if necessary */ if (romfs_in_flash) { /* rootfs is in directly accessible flash memory = NOR flash. Add an overlapping device for the rootfs partition. */ printk(KERN_INFO "axisflashmap: Adding partition for " "overlapping root file system image\n"); axis_partitions[pidx].size = romfs_length; axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].name = "romfs"; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; ram_rootfs_partition = -1; pidx++; } else if (romfs_length && !nand_boot) { /* romfs exists in memory, but not in flash, so must be in RAM. * Configure an MTDRAM partition. */ if (ram_rootfs_partition < 0) { /* None set yet, put it at the end */ ram_rootfs_partition = pidx; pidx++; } printk(KERN_INFO "axisflashmap: Adding partition for " "root file system image in RAM\n"); axis_partitions[ram_rootfs_partition].size = romfs_length; axis_partitions[ram_rootfs_partition].offset = romfs_start; axis_partitions[ram_rootfs_partition].name = "romfs"; axis_partitions[ram_rootfs_partition].mask_flags |= MTD_WRITEABLE; } #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE if (main_mtd) { main_partition.size = main_mtd->size; err = mtd_device_register(main_mtd, &main_partition, 1); if (err) panic("axisflashmap: Could not initialize " "partition for whole main mtd device!\n"); } #endif /* Now, register all partitions with mtd. * We do this one at a time so we can slip in an MTDRAM device * in the proper place if required. */ for (part = 0; part < pidx; part++) { if (part == ram_rootfs_partition) { /* add MTDRAM partition here */ struct mtd_info *mtd_ram; mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!mtd_ram) panic("axisflashmap: Couldn't allocate memory " "for mtd_info!\n"); printk(KERN_INFO "axisflashmap: Adding RAM partition " "for rootfs image.\n"); err = mtdram_init_device(mtd_ram, (void *)partition[part].offset, partition[part].size, partition[part].name); if (err) panic("axisflashmap: Could not initialize " "MTD RAM device!\n"); /* JFFS2 likes to have an erasesize. Keep potential * JFFS2 rootfs happy by providing one. Since image * was most likely created for main mtd, use that * erasesize, if available. Otherwise, make a guess. */ mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize : CONFIG_ETRAX_PTABLE_SECTOR); } else { err = mtd_device_register(main_mtd, &partition[part], 1); if (err) panic("axisflashmap: Could not add mtd " "partition %d\n", part); } } #endif /* CONFIG_EXTRAX_VCS_SIM */ #ifdef CONFIG_ETRAX_VCS_SIM /* For simulator, always use a RAM partition. * The rootfs will be found after the kernel in RAM, * with romfs_start and romfs_end indicating location and size. */ struct mtd_info *mtd_ram; mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!mtd_ram) { panic("axisflashmap: Couldn't allocate memory for " "mtd_info!\n"); } printk(KERN_INFO "axisflashmap: Adding RAM partition for romfs, " "at %u, size %u\n", (unsigned) romfs_start, (unsigned) romfs_length); err = mtdram_init_device(mtd_ram, (void *)romfs_start, romfs_length, "romfs"); if (err) { panic("axisflashmap: Could not initialize MTD RAM " "device!\n"); } #endif /* CONFIG_EXTRAX_VCS_SIM */ #ifndef CONFIG_ETRAX_VCS_SIM if (aux_mtd) { aux_partition.size = aux_mtd->size; err = mtd_device_register(aux_mtd, &aux_partition, 1); if (err) panic("axisflashmap: Could not initialize " "aux mtd device!\n"); } #endif /* CONFIG_EXTRAX_VCS_SIM */ return err; }
/* * Probe the flash chip(s) and, if it succeeds, read the partition-table * and register the partitions with MTD. */ static int __init init_axis_flash(void) { struct mtd_info *mymtd; int err = 0; int pidx = 0; struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int use_default_ptable = 1; /* Until proven otherwise. */ const char *pmsg = KERN_INFO " /dev/flash%d at 0x%08x, size 0x%08x\n"; static char page[512]; size_t len; #ifndef CONFIG_ETRAXFS_SIM mymtd = flash_probe(); mymtd->read(mymtd, CONFIG_ETRAX_PTABLE_SECTOR, 512, &len, page); ptable_head = (struct partitiontable_head *)(page + PARTITION_TABLE_OFFSET); if (!mymtd) { /* There's no reason to use this module if no flash chip can * be identified. Make sure that's understood. */ printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); } else { printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", mymtd->name, mymtd->size); axisflash_mtd = mymtd; } if (mymtd) { mymtd->owner = THIS_MODULE; } pidx++; /* First partition is always set to the default. */ if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + ptable_head->size - PARTITIONTABLE_END_MARKER_SIZE) == PARTITIONTABLE_END_MARKER)) { /* Looks like a start, sane length and end of a * partition table, lets check csum etc. */ int ptable_ok = 0; struct partitiontable_entry *max_addr = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head) + ptable_head->size); unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; unsigned char *p; unsigned long csum = 0; ptable = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head)); /* Lets be PARANOID, and check the checksum. */ p = (unsigned char*) ptable; while (p <= (unsigned char*)max_addr) { csum += *p++; csum += *p++; csum += *p++; csum += *p++; } ptable_ok = (csum == ptable_head->checksum); /* Read the entries and use/show the info. */ printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", (ptable_ok ? " valid" : "n invalid"), ptable_head, max_addr); /* We have found a working bootblock. Now read the * partition table. Scan the table. It ends when * there is 0xffffffff, that is, empty flash. */ while (ptable_ok && ptable->offset != 0xffffffff && ptable < max_addr && pidx < MAX_PARTITIONS) { axis_partitions[pidx].offset = offset + ptable->offset + (crisv32_nand_boot ? 16384 : 0); axis_partitions[pidx].size = ptable->size; printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; ptable++; } use_default_ptable = !ptable_ok; } if (romfs_in_flash) { /* Add an overlapping device for the root partition (romfs). */ axis_partitions[pidx].name = "romfs"; if (crisv32_nand_boot) { char* data = kmalloc(1024, GFP_KERNEL); int len; int offset = crisv32_nand_cramfs_offset & ~(1024-1); char* tmp; mymtd->read(mymtd, offset, 1024, &len, data); tmp = &data[crisv32_nand_cramfs_offset % 512]; axis_partitions[pidx].size = *(unsigned*)(tmp + 4); axis_partitions[pidx].offset = crisv32_nand_cramfs_offset; kfree(data); } else { axis_partitions[pidx].size = romfs_length; axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; } axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; printk(KERN_INFO " Adding readonly flash partition for romfs image:\n"); printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; } if (mymtd) { if (use_default_ptable) { printk(KERN_INFO " Using default partition table.\n"); err = add_mtd_partitions(mymtd, axis_default_partitions, NUM_DEFAULT_PARTITIONS); } else { err = add_mtd_partitions(mymtd, axis_partitions, pidx); } if (err) { panic("axisflashmap could not add MTD partitions!\n"); } } /* CONFIG_EXTRAXFS_SIM */ #endif if (!romfs_in_flash) { /* Create an RAM device for the root partition (romfs). */ #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) /* No use trying to boot this kernel from RAM. Panic! */ printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " "device due to kernel (mis)configuration!\n"); panic("This kernel cannot boot from RAM!\n"); #else struct mtd_info *mtd_ram; mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!mtd_ram) { panic("axisflashmap couldn't allocate memory for " "mtd_info!\n"); } printk(KERN_INFO " Adding RAM partition for romfs image:\n"); printk(pmsg, pidx, romfs_start, romfs_length); err = mtdram_init_device(mtd_ram, (void*)romfs_start, romfs_length, "romfs"); if (err) { panic("axisflashmap could not initialize MTD RAM " "device!\n"); } #endif } return err; }
static int __init init_axis_flash(void) { struct mtd_info *mymtd; int err = 0; int pidx = 0; struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int use_default_ptable = 1; const char pmsg[] = " /dev/flash%d at 0x%08x, size 0x%08x\n"; if (!(mymtd = flash_probe())) { printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); } else { printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", mymtd->name, mymtd->size); axisflash_mtd = mymtd; } if (mymtd) { mymtd->owner = THIS_MODULE; ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET); } pidx++; if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + ptable_head->size - PARTITIONTABLE_END_MARKER_SIZE) == PARTITIONTABLE_END_MARKER)) { int ptable_ok = 0; struct partitiontable_entry *max_addr = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head) + ptable_head->size); unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; unsigned char *p; unsigned long csum = 0; ptable = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head)); p = (unsigned char*) ptable; while (p <= (unsigned char*)max_addr) { csum += *p++; csum += *p++; csum += *p++; csum += *p++; } ptable_ok = (csum == ptable_head->checksum); printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", (ptable_ok ? " valid" : "n invalid"), ptable_head, max_addr); while (ptable_ok && ptable->offset != 0xffffffff && ptable < max_addr && pidx < MAX_PARTITIONS) { axis_partitions[pidx].offset = offset + ptable->offset; axis_partitions[pidx].size = ptable->size; printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; ptable++; } use_default_ptable = !ptable_ok; } if (romfs_in_flash) { axis_partitions[pidx].name = "romfs"; axis_partitions[pidx].size = romfs_length; axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; printk(KERN_INFO " Adding readonly flash partition for romfs image:\n"); printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; } #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE if (mymtd) { main_partition.size = mymtd->size; err = mtd_device_register(mymtd, &main_partition, 1); if (err) panic("axisflashmap: Could not initialize " "partition for whole main mtd device!\n"); } #endif if (mymtd) { if (use_default_ptable) { printk(KERN_INFO " Using default partition table.\n"); err = mtd_device_register(mymtd, axis_default_partitions, NUM_DEFAULT_PARTITIONS); } else { err = mtd_device_register(mymtd, axis_partitions, pidx); } if (err) panic("axisflashmap could not add MTD partitions!\n"); } if (!romfs_in_flash) { #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " "device due to kernel (mis)configuration!\n"); panic("This kernel cannot boot from RAM!\n"); #else struct mtd_info *mtd_ram; mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!mtd_ram) panic("axisflashmap couldn't allocate memory for " "mtd_info!\n"); printk(KERN_INFO " Adding RAM partition for romfs image:\n"); printk(pmsg, pidx, (unsigned)romfs_start, (unsigned)romfs_length); err = mtdram_init_device(mtd_ram, (void *)romfs_start, romfs_length, "romfs"); if (err) panic("axisflashmap could not initialize MTD RAM " "device!\n"); #endif } return err; }
void setup_arch(char **cmdline_p) { int bootmap_size; #if defined(CAT_ROMARRAY) && defined(DEBUG) extern int __data_rom_start; extern int __data_start; int *romarray = (int *)((int) &__data_rom_start + (int)&_edata - (int)&__data_start); #endif #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) /* we need to initialize the Flashrom device here since we might * do things with flash early on in the boot */ flash_probe(); #endif memory_start = PAGE_ALIGN(_ramstart); memory_end = _ramend; /* by now the stack is part of the init task */ init_mm.start_code = (unsigned long) &_stext; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; #if 0 /* DAVIDM - don't set brk just incase someone decides to use it */ init_mm.brk = (unsigned long) &_end; #else init_mm.brk = (unsigned long) 0; #endif #if defined (CONFIG_M68360) m360_cpm_reset(); /* Calculate the real system clock value. */ { unsigned int local_pllcr = (unsigned int)(pquicc->sim_pllcr); if( local_pllcr & MCU_PREEN ) // If the prescaler is dividing by 128 { int mf = (int)(pquicc->sim_pllcr & 0x0fff); system_clock = (OSCILLATOR / 128) * (mf + 1); } else { int mf = (int)(pquicc->sim_pllcr & 0x0fff); system_clock = (OSCILLATOR) * (mf + 1); } } /* Setup SMC 2 as a serial console */ serial_console_setup(&sercons, NULL); console_360_init(0, 0); #endif config_BSP(&command_line[0], sizeof(command_line)); printk("\r\nuClinux/" CPU "\n"); /* (es) */ #ifdef CONFIG_UCDIMM printk("uCdimm by Lineo, Inc. <www.lineo.com>\n"); #endif #ifdef CONFIG_M68VZ328 printk("M68VZ328 support by Evan Stawnyczy <*****@*****.**>\n"); #endif /* (/es) */ #ifdef CONFIG_COLDFIRE printk("COLDFIRE port done by Greg Ungerer, [email protected]\n"); #ifdef CONFIG_M5307 printk("Modified for M5307 by Dave Miller, [email protected]\n"); #endif #ifdef CONFIG_ELITE printk("Modified for M5206eLITE by Rob Scott, [email protected]\n"); #endif #ifdef CONFIG_TELOS printk("Modified for Omnia ToolVox by James D. Schettine, [email protected]\n"); #endif #endif printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n"); #if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 ) printk("TRG SuperPilot FLASH card support <*****@*****.**>\n"); #endif #if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 ) printk("PalmV support by Lineo Inc. <*****@*****.**>\n"); #endif #ifdef CONFIG_M68EZ328ADS printk("M68EZ328ADS board support (C) 1999 Vladimir Gurevich <*****@*****.**>\n"); #endif #ifdef CONFIG_ALMA_ANS printk("Alma Electronics board support (C) 1999 Vladimir Gurevich <*****@*****.**>\n"); #endif #if defined (CONFIG_M68360) printk("QUICC port done by SED Systems <*****@*****.**>,\n"); printk("based on 2.0.38 port by Lineo Inc. <*****@*****.**>.\n"); #endif #ifdef CONFIG_DRAGEN2 printk("DragonEngine II board support by Georges Menie\n"); #endif #ifdef CONFIG_CWEZ328 printk("cwez328 board support by 2002 Andrew Ip <*****@*****.**> and Inky Lung <*****@*****.**>\n"); #endif #ifdef CONFIG_CWVZ328 printk("cwvz328 board support by 2002 Andrew Ip <*****@*****.**> and Inky Lung <*****@*****.**>\n"); #endif #ifdef DEBUG printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, (int) &_sdata, (int) &_edata, (int) &_sbss, (int) &_ebss); printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " "STACK=0x%06x-0x%06x\n", #ifdef CAT_ROMARRAY (int) romarray, ((int) romarray) + romarray[2], #else (int) &_ebss, (int) memory_start, #endif (int) memory_start, (int) memory_end, (int) memory_end, (int) _ramend); #endif #ifdef CONFIG_BLK_DEV_BLKMEM ROOT_DEV = MKDEV(BLKMEM_MAJOR,0); #endif /* Keep a copy of command line */ *cmdline_p = &command_line[0]; memcpy(saved_command_line, command_line, sizeof(saved_command_line)); saved_command_line[sizeof(saved_command_line)-1] = 0; #ifdef DEBUG if (strlen(*cmdline_p)) printk("Command line: '%s'\n", *cmdline_p); #endif /*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/ #ifdef CONFIG_CONSOLE #ifdef CONFIG_FRAMEBUFFER conswitchp = &fb_con; #else conswitchp = 0; #endif #endif /* * give all the memory to the bootmap allocator, tell it to put the * boot mem_map at the start of memory */ bootmap_size = init_bootmem_node( NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */ PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */ memory_end >> PAGE_SHIFT); /* * free the usable memory, we have to make sure we do not free * the bootmem bitmap so we then reserve it after freeing it :-) */ free_bootmem(memory_start, memory_end - memory_start); reserve_bootmem(memory_start, bootmap_size); /* * get kmalloc into gear */ paging_init(); #ifdef DEBUG printk("Done setup_arch\n"); #endif }
static int __init init_axis_flash(void) { struct mtd_info *main_mtd; struct mtd_info *aux_mtd = NULL; int err = 0; int pidx = 0; struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int ptable_ok = 0; static char page[PAGESIZE]; size_t len; int ram_rootfs_partition = -1; int part; #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) if (!romfs_in_flash && !nand_boot) { printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " "device; configure CONFIG_MTD_MTDRAM with size = 0!\n"); panic("This kernel cannot boot from RAM!\n"); } #endif #ifndef CONFIG_ETRAX_VCS_SIM main_mtd = flash_probe(); if (main_mtd) printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n", main_mtd->name, main_mtd->size); #ifdef CONFIG_ETRAX_NANDFLASH aux_mtd = crisv32_nand_flash_probe(); if (aux_mtd) printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n", aux_mtd->name, aux_mtd->size); #ifdef CONFIG_ETRAX_NANDBOOT { struct mtd_info *tmp_mtd; printk(KERN_INFO "axisflashmap: Set to boot from NAND flash, " "making NAND flash primary device.\n"); tmp_mtd = main_mtd; main_mtd = aux_mtd; aux_mtd = tmp_mtd; } #endif #endif if (!main_mtd && !aux_mtd) { printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); } #if 0 if (main_mtd) { int sectoraddr, i; for (sectoraddr = 0; sectoraddr < 2*65536+4096; sectoraddr += PAGESIZE) { main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len, page); printk(KERN_INFO "Sector at %d (length %d):\n", sectoraddr, len); for (i = 0; i < PAGESIZE; i += 16) { printk(KERN_INFO "%02x %02x %02x %02x " "%02x %02x %02x %02x " "%02x %02x %02x %02x " "%02x %02x %02x %02x\n", page[i] & 255, page[i+1] & 255, page[i+2] & 255, page[i+3] & 255, page[i+4] & 255, page[i+5] & 255, page[i+6] & 255, page[i+7] & 255, page[i+8] & 255, page[i+9] & 255, page[i+10] & 255, page[i+11] & 255, page[i+12] & 255, page[i+13] & 255, page[i+14] & 255, page[i+15] & 255); } } } #endif if (main_mtd) { main_mtd->owner = THIS_MODULE; axisflash_mtd = main_mtd; loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR; pidx++; #ifdef CONFIG_ETRAX_NANDBOOT int blockstat; do { blockstat = mtd_block_isbad(main_mtd, ptable_sector); if (blockstat < 0) ptable_sector = 0; else if (blockstat) ptable_sector += main_mtd->erasesize; } while (blockstat && ptable_sector); #endif if (ptable_sector) { mtd_read(main_mtd, ptable_sector, PAGESIZE, &len, page); ptable_head = &((struct partitiontable *) page)->head; } #if 0 printk(KERN_INFO "axisflashmap: flash read %d bytes at 0x%08x, data: " "%02x %02x %02x %02x %02x %02x %02x %02x\n", len, CONFIG_ETRAX_PTABLE_SECTOR, page[0] & 255, page[1] & 255, page[2] & 255, page[3] & 255, page[4] & 255, page[5] & 255, page[6] & 255, page[7] & 255); printk(KERN_INFO "axisflashmap: partition table offset %d, data: " "%02x %02x %02x %02x %02x %02x %02x %02x\n", PARTITION_TABLE_OFFSET, page[PARTITION_TABLE_OFFSET+0] & 255, page[PARTITION_TABLE_OFFSET+1] & 255, page[PARTITION_TABLE_OFFSET+2] & 255, page[PARTITION_TABLE_OFFSET+3] & 255, page[PARTITION_TABLE_OFFSET+4] & 255, page[PARTITION_TABLE_OFFSET+5] & 255, page[PARTITION_TABLE_OFFSET+6] & 255, page[PARTITION_TABLE_OFFSET+7] & 255); #endif } if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) + ptable_head->size - PARTITIONTABLE_END_MARKER_SIZE) == PARTITIONTABLE_END_MARKER)) { struct partitiontable_entry *max_addr = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head) + ptable_head->size); unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; unsigned char *p; unsigned long csum = 0; ptable = (struct partitiontable_entry *) ((unsigned long)ptable_head + sizeof(*ptable_head)); p = (unsigned char*) ptable; while (p <= (unsigned char*)max_addr) { csum += *p++; csum += *p++; csum += *p++; csum += *p++; } ptable_ok = (csum == ptable_head->checksum); printk(KERN_INFO "axisflashmap: " "Found a%s partition table at 0x%p-0x%p.\n", (ptable_ok ? " valid" : "n invalid"), ptable_head, max_addr); while (ptable_ok && ptable->offset != PARTITIONTABLE_END_MARKER && ptable < max_addr && pidx < MAX_PARTITIONS - 1) { axis_partitions[pidx].offset = offset + ptable->offset; #ifdef CONFIG_ETRAX_NANDFLASH if (main_mtd->type == MTD_NANDFLASH) { axis_partitions[pidx].size = (((ptable+1)->offset == PARTITIONTABLE_END_MARKER) ? main_mtd->size : ((ptable+1)->offset + offset)) - (ptable->offset + offset); } else #endif axis_partitions[pidx].size = ptable->size; #ifdef CONFIG_ETRAX_NANDBOOT if (!nand_boot && ram_rootfs_partition < 0 && ptable->type == PARTITION_TYPE_JFFS2 && (ptable->flags & PARTITION_FLAGS_READONLY_MASK) == PARTITION_FLAGS_READONLY) ram_rootfs_partition = pidx; #endif pidx++; ptable++; } } struct mtd_partition *partition = &axis_partitions[0]; if (main_mtd && !ptable_ok) { memcpy(axis_partitions, axis_default_partitions, sizeof(axis_default_partitions)); pidx = NUM_DEFAULT_PARTITIONS; ram_rootfs_partition = DEFAULT_ROOTFS_PARTITION_NO; } if (romfs_in_flash) { printk(KERN_INFO "axisflashmap: Adding partition for " "overlapping root file system image\n"); axis_partitions[pidx].size = romfs_length; axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].name = "romfs"; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; ram_rootfs_partition = -1; pidx++; } else if (romfs_length && !nand_boot) { if (ram_rootfs_partition < 0) { ram_rootfs_partition = pidx; pidx++; } printk(KERN_INFO "axisflashmap: Adding partition for " "root file system image in RAM\n"); axis_partitions[ram_rootfs_partition].size = romfs_length; axis_partitions[ram_rootfs_partition].offset = romfs_start; axis_partitions[ram_rootfs_partition].name = "romfs"; axis_partitions[ram_rootfs_partition].mask_flags |= MTD_WRITEABLE; } #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE if (main_mtd) { main_partition.size = main_mtd->size; err = mtd_device_register(main_mtd, &main_partition, 1); if (err) panic("axisflashmap: Could not initialize " "partition for whole main mtd device!\n"); } #endif for (part = 0; part < pidx; part++) { if (part == ram_rootfs_partition) { struct mtd_info *mtd_ram; mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!mtd_ram) panic("axisflashmap: Couldn't allocate memory " "for mtd_info!\n"); printk(KERN_INFO "axisflashmap: Adding RAM partition " "for rootfs image.\n"); err = mtdram_init_device(mtd_ram, (void *)partition[part].offset, partition[part].size, partition[part].name); if (err) panic("axisflashmap: Could not initialize " "MTD RAM device!\n"); mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize : CONFIG_ETRAX_PTABLE_SECTOR); } else { err = mtd_device_register(main_mtd, &partition[part], 1); if (err) panic("axisflashmap: Could not add mtd " "partition %d\n", part); } } #endif #ifdef CONFIG_ETRAX_VCS_SIM struct mtd_info *mtd_ram; mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); if (!mtd_ram) { panic("axisflashmap: Couldn't allocate memory for " "mtd_info!\n"); } printk(KERN_INFO "axisflashmap: Adding RAM partition for romfs, " "at %u, size %u\n", (unsigned) romfs_start, (unsigned) romfs_length); err = mtdram_init_device(mtd_ram, (void *)romfs_start, romfs_length, "romfs"); if (err) { panic("axisflashmap: Could not initialize MTD RAM " "device!\n"); } #endif #ifndef CONFIG_ETRAX_VCS_SIM if (aux_mtd) { aux_partition.size = aux_mtd->size; err = mtd_device_register(aux_mtd, &aux_partition, 1); if (err) panic("axisflashmap: Could not initialize " "aux mtd device!\n"); } #endif return err; }
Retcode generic_install_flash(Environ *e, Flash_methods *methods) { Retcode ret; Package *pkg; Byte *prop; Flash *f; Int plen = 0; Self self; int i; DPRINTF(("generic_install_flash: e=%#x\n", e)); memset(&self, 0, sizeof self); self.meths = methods; self.width = methods->width; self.buf = (uByte *)malloc(4 * self.width); if (self.buf == NULL) return NO_ERROR; for (i = methods->unitcells - 1; i >= 0; i--) PUSH(e, methods->unit[i]); PUSH(e, methods->size); DPRINTF(("generic_install_flash: about to map-in\n", ret)); ret = execute_static_method_name(e, e->root, "map-in", CSTR); DPRINTF(("generic_install_flash: map-in returns %d\n", ret)); if (ret != NO_ERROR) return ret; POPT(e, self.addr, void *); DPRINTF(("generic_install_flash: self.addr %p\n", self.addr)); if (self.addr == (void *)0) { DPRINTF(("generic_install_flash: unable to map-in\n")); return E_NO_DEVICE; } /* show the mapping */ //PUSH(e, (Cell)self.addr); //f_mapq(e); f = flash_probe(e, &self); DPRINTF(("flash_probe: ret=%p\n", f)); free((void *)self.buf); PUSH(e, self.addr); PUSH(e, methods->size); ret = execute_static_method_name(e, e->root, "map-out", CSTR); DPRINTF(("generic_install_flash: map-out returns %d\n", ret)); if (!f) return E_NO_DEVICE; IFCKSP(e, 0, 3); pkg = new_pkg_name(e->currpkg, "flash"); if (pkg == NULL) return E_OUT_OF_MEMORY; pkg->self = (struct pself*)methods; /* set the type of this device */ prop_set_str(pkg->props, "device_type", CSTR, "block", CSTR); /* encode "reg" property for unit address */ prop = prop_alloc(e, methods->unitcells * 2 * sizeof (Int)); if (prop == NULL) return E_OUT_OF_MEMORY; for (i = 0; i < methods->unitcells; i++) prop_encode_int(prop + plen, &plen, methods->unit[i]); for (i = 0; i < methods->unitcells - 1; i++) prop_encode_int(prop + plen, &plen, 0); prop_encode_int(prop + plen, &plen, f->size * (methods->width / f->width)); ret = add_property(pkg->props, "reg", CSTR, prop, plen); /* add device specific information */ prop_set_str(pkg->props, "manufacture", CSTR, f->manufname, CSTR); prop_set_str(pkg->props, "device", CSTR, f->devname, CSTR); prop_set_int(pkg->props, "id", CSTR, (f->manufid << 16) | f->devid); prop_set_int(pkg->props, "bias", CSTR, methods->bias); if (ret == NO_ERROR) ret = init_entries(e, pkg->dict, flash_methods); return ret; }