Example #1
0
/*
 *  Verify flash contents to ram contents.
 */
int
fl_verify_device(void *fl_base, void *data_base, int data_size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	void *fl_last;
	int ok;
	int i;


	dev = fl_devident(fl_base, &map);
	if(dev == NULL) {
		return(-3);	/* No flash device found at address */
	}

	if(data_size == -1 || (int)data_base == -1) {
		return(-4);		/* Bad parameters */
	}
	if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) {
		return(-4);	/* Size larger than device array */
	}

	if(verbose) {
		printf("Verifying FLASH. ");
	}

	for(i = 0; i < data_size; i += map->fl_map_width) {
		fl_last = fl_base;
		switch(map->fl_map_bus) {
		case FL_BUS_8:
			ok = (*((u_char *)fl_base) == *((u_char *)data_base));
			fl_base++;
			data_base++;
			break;

		case FL_BUS_16:
			ok = (*((u_short *)fl_base) == *((u_short *)data_base));
			fl_base += 2;
			data_base += 2;
			break;

		case FL_BUS_32:
			ok = (*((u_int *)fl_base) == *((u_int *)data_base));
			fl_base += 4;
			data_base += 4;
			break;

		case FL_BUS_64:
			movequad(&widedata, fl_base);
			ok = (bcmp(data_base, (void *)&widedata, 8) == 0);
			data_base += 8;
			fl_base += 8;
			break; 

		case FL_BUS_8_ON_64:
			ok = (*((u_char *)map->fl_map_base +
				   (((int)fl_base - map->fl_map_base) << 3)) ==
				*(u_char *)data_base++);
			fl_base++;
			break;
		}

		if(verbose & !ok) {
			printf(" error offset %p\n", fl_last);
			{
			char str[100];
			int timeout;
			printf("erase all chip(y/N)?");
			gets(str);
			if(str[0]=='y'||str[0]=='Y')
			{
				tgt_flashwrite_enable();
				fl_write_protect_unlock(map, dev, 0);/* Disable write protection of SST49LF040B/SST49LF008A */
				printf("Erasing all FLASH blocks. ");
				(*dev->functions->erase_chip)(map, dev);
				delay(1000);
				for(timeout = 0 ;
					((ok = (*dev->functions->isbusy)(map, dev, 0xffffffff,0, TRUE)) == 1)
						&& (timeout < PFLASH_MAX_TIMEOUT); timeout++) {
						delay(1000);
					if(verbose) {
						dotik(256, 0);
					}
				}
				delay(1000);

				if(!(timeout < PFLASH_MAX_TIMEOUT)) {
					(*dev->functions->erase_suspend)(map, dev);
				}
				(*dev->functions->reset)(map, dev);
				tgt_flashwrite_disable();
				fl_write_protect_lock(map, dev, 0);/* Enable write protection of SST49LF040B/SST49LF008A */
			}
		   }
			break;
		}
		else if(verbose) {
			dotik(32, 0);
		}
	}

	if(verbose && ok) {
		printf("\b No Errors found.\n");
	}
	
	return(ok);
}
Example #2
0
/*
 *  Program a flash device. Assumed that the area is erased already.
 */
int
fl_program_device(void *fl_base, void *data_base, int data_size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	int ok;
	int i, off;
	
	if(tgt_flashwrite_enable() == 0) {
		return(-2);	/* Flash can't be write enabled */
	}
	dev = fl_devident(fl_base, &map);
	if(dev == NULL) {
		tgt_flashwrite_disable();
		return(-3);	/* No flash device found at address */
	}

	if(data_size == -1 || (int)data_base == -1) {
		return(-4);		/* Bad parameters */
	}
	if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) {
		return(-4);	/* Size larger than device array */
	}

	off = (int)(fl_base - map->fl_map_base) + map->fl_map_offset;
	if(verbose) {
		printf("Programming FLASH. ");
	}

	tgt_flashwrite_enable();
    fl_write_protect_unlock(map, dev, 0);/* Disable write protection of SST49LF040B/SST49LF008A */

	for(i = 0; i < data_size; i += map->fl_map_width) {

		ok = (*dev->functions->program)(map, dev, (int)off, data_base);

		switch(map->fl_map_bus) {
		case FL_BUS_8:
		case FL_BUS_8_ON_64:
			off++;
			data_base++;
			break;

		case FL_BUS_16:
			data_base += 2;
			off += 2;
			break;

		case FL_BUS_32:
			data_base += 4;
			off += 4;
			break;

		case FL_BUS_64:
			data_base += 8;
			off += 8;
			break; 
		}

		if(verbose) {
			dotik(256, 0);
		}
	}

	(*dev->functions->reset)(map, dev);

	if(verbose) {
		printf("\b Done.\n");
	}
	
	tgt_flashwrite_disable();
    fl_write_protect_lock(map, dev, 0);/* Enable write protection of SST49LF040B/SST49LF008A */
	return(ok);
}
Example #3
0
/*
 *  Erase the flash device(s) addressed.
 */
int
fl_erase_device(void *base, int size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	int mask, ok, block;
	int timeout;

	if(tgt_flashwrite_enable() == 0) {
		printf("Flash can't be write enabled\n");
		return(-2);	/* Flash can't be write enabled */
	}

	dev = fl_devident(base, &map);
	if(dev == NULL) {
		printf("No flash found at %x\n",(u_int32_t)base);
		return(-3);	/* No flash device found at address */
	}

	/*
	 * Sanity checks!
	 */
	if(size == -1 && (int)base == map->fl_map_base) {
		size = map->fl_map_size;	/* Entire flash */
	}

        if(dev->fl_varsecsize != NULL) {
                int offset = (int)(base - map->fl_map_base) + map->fl_map_offset;
                int totalsize;
		printf("offset=%x,base=%x\n",offset,map->fl_map_base);

                for(block=0, totalsize=0; totalsize < offset; block++) {
                        totalsize += dev->fl_varsecsize[block] * map->fl_map_chips;
                }

                mask = ((dev->fl_varsecsize[block] * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }
                base -= map->fl_map_base;

        } else {
                mask = ((dev->fl_secsize * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }

                base -= map->fl_map_base;
                block = (int)base / map->fl_map_chips / dev->fl_secsize;
                size = (size + mask) & ~mask; /* Round up to catch entire flash */
        }
        
        tgt_flashwrite_enable();
        fl_write_protect_unlock(map, dev, 0);/* Disable write protection of SST49LF040B/SST49LF008A */
        
	while(size > 0) {
		int boffs = (int)base;
#if 0
		if(size == map->fl_map_size &&
			dev->fl_cap & (FL_CAP_DE|FL_CAP_A7)) {
			/*
			 * Erase entire devices using the BULK erase feature
			 */
			if(verbose) {
				printf("Erasing all FLASH blocks. ");
			}

			(*dev->functions->erase_chip)(map, dev);

			size = 0;
		}
		else {
#endif
			/*
			 * Not entire flash or no BULK erase feature. We
			 * use sector/block erase.
			 */
			if(verbose) {
				printf("\rErasing FLASH block %3d      \b\b\b\b\b", block);
			}

			if((*dev->functions->erase_sector)(map, dev, boffs) != 0) {

				printf("\nError: Failed to enter erase mode\n");
				(*dev->functions->erase_suspend)(map, dev);
				(*dev->functions->reset)(map, dev);
				return(-4);
			}

                        if(dev->fl_varsecsize != NULL) {
                                base += dev->fl_varsecsize[block] * map->fl_map_chips;
                                size -= dev->fl_varsecsize[block] * map->fl_map_chips;
                                block++;
                        } else {
                                base += dev->fl_secsize * map->fl_map_chips;
                                size -= dev->fl_secsize * map->fl_map_chips;
                                block++;
                        }
//		}

		delay(1000);
		for(timeout = 0 ;
		    ((ok = (*dev->functions->isbusy)(map, dev, 0xffffffff, boffs, TRUE)) == 1)
				&& (timeout < PFLASH_MAX_TIMEOUT); timeout++) {
				delay(1000);
			if(verbose) {
				dotik(256, 0);
			}
		}
		delay(1000);

		if(!(timeout < PFLASH_MAX_TIMEOUT)) {
			(*dev->functions->erase_suspend)(map, dev);
		}
		(*dev->functions->reset)(map, dev);

		if(verbose) {
			if(!(timeout < PFLASH_MAX_TIMEOUT)) {
/* XXX if timed out what should really happen here? This doesn't look right. */
				printf("\b\b, command timed out!\n");
			} else {
				printf("\b Done.\n");
			}
		}
	}

	tgt_flashwrite_disable();
    fl_write_protect_lock(map, dev, 0);/* Enable write protection of SST49LF040B/SST49LF008A */
	return(ok);
}



int fl_program(void *fl_base, void *data_base, int data_size, int verbose)
{
        char *nvrambuf;
        char *nvramsecbuf;
	    char *nvram;
		int offs,count,left;
		struct fl_device *dev=fl_devident(fl_base,0);
		int nvram_size=dev->fl_secsize;

	nvramsecbuf = (char *)malloc(nvram_size);
	if(nvramsecbuf == 0) {
		printf("Warning! Unable to malloc nvrambuffer!\n");
		return(-1);
	}
      nvram = fl_base;
	  left = data_size;
	  while(left)
	  {

		offs = (int)nvram &(nvram_size - 1);
        nvram  = (int)nvram & ~(nvram_size - 1);
		count = min(nvram_size-offs,left);
		 

        memcpy(nvramsecbuf, nvram, nvram_size);		
		nvrambuf = nvramsecbuf + offs;
		memcpy(nvrambuf,data_base,count);
#ifdef NVRAM_IN_FLASH
#ifndef LS3B_SPI_BOOT        
		if(fl_erase_device(nvram, nvram_size, verbose)) {
		printf("Error! Nvram erase failed!\n");
		free(nvramsecbuf);
                return(0);
        }
        
		if(fl_program_device(nvram, nvramsecbuf, nvram_size, verbose)) {
		printf("Error! Nvram program failed!\n");
		free(nvramsecbuf);
                return(0);
        }
#else
        spi_erase( (unsigned long)(nvram)- tgt_flashmap()->fl_map_base, nvram_size);
		if( spi_program(nvramsecbuf, (unsigned long)(nvram)- tgt_flashmap()->fl_map_base, nvram_size, 0) ) { 
		     printf("Error! Nvram program failed!\n");
		     free(nvramsecbuf);
		     return(0);
		}
#endif
#endif

		data_base += count;
		nvram += nvram_size;
		left -= count;
		}
	free(nvramsecbuf);
        return 0;
}
Example #4
0
/*
 *  Try to figure out what kind of flash there is on given address.
 */
struct fl_device *
fl_devident(void *base, struct fl_map **m)
{
	struct fl_device *dev;
	struct fl_map *map;
	char mfgid, chipid;

	/* If we can't write to flash, we can't identify */
	if(!tgt_flashwrite_enable()) {
		return((struct fl_device *)NULL);
	}

	map = fl_find_map(base);

	if(map != NULL) {
		fl_autoselect(map);

		switch(map->fl_map_bus) {
		case FL_BUS_8:

#ifndef LS3B_SPI_BOOT 
			mfgid = inb(map->fl_map_base);
			chipid = inb(map->fl_map_base+1);
#else
			mfgid = loongson_spi_readid();
			chipid = loongson_spi_readchipid();
#endif
			if(chipid == mfgid) { /* intel 16 bit flash mem */
				chipid = inb(map->fl_map_base+3);
			}
			break;

		case FL_BUS_8_ON_64:
			mfgid = inb(map->fl_map_base);
			chipid = inb(map->fl_map_base+8);
			break;

		case FL_BUS_16:
			mfgid = inw(map->fl_map_base);
			chipid = inw(map->fl_map_base+2);
			break;

		case FL_BUS_32:
			mfgid = inl(map->fl_map_base);
			chipid = inl(map->fl_map_base+4);
			break;

		case FL_BUS_64:
			mfgid = inw(map->fl_map_base);
			chipid = inw(map->fl_map_base+8);
			break;
		}
		fl_reset(map);

		/* Lookup device type using manufacturer and device id */
		for(dev = &fl_known_dev[0]; dev->fl_name != 0; dev++) {
			if(dev->fl_mfg == mfgid && dev->fl_id == chipid) {
				tgt_flashwrite_disable();
				if(m) {
					*m = map;
				}
				return(dev);	/* GOT IT! */
			}
		}
		printf("Mfg %2x, Id %2x\n", mfgid, chipid);
	}
	
	tgt_flashwrite_disable();
	outb((map->fl_map_base), 0xf0);
	outb((map->fl_map_base), 0x90);
	outb((map->fl_map_base), 0x00);

	return((struct fl_device *)NULL);
}
Example #5
0
/*
 *  Verify flash contents to ram contents.
 */
int
fl_verify_device(void *fl_base, void *data_base, int data_size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	void *fl_last;
	int ok;
	int i;


	dev = fl_devident(fl_base, &map);
	if(dev == NULL) {
		return(-3);	/* No flash device found at address */
	}

	if(data_size == -1 || (int)data_base == -1) {
		return(-4);		/* Bad parameters */
	}
	if((data_size + ((int)fl_base - map->fl_map_base)) > map->fl_map_size) {
		return(-4);	/* Size larger than device array */
	}

	if(verbose) {
		printf("Verifying FLASH. ");
	}

	for(i = 0; i < data_size; i += map->fl_map_width) {
		fl_last = fl_base;
		switch(map->fl_map_bus) {
		case FL_BUS_8:
			ok = (*((u_char *)fl_base) == *((u_char *)data_base)); fl_base += 1; data_base += 1;
			break;

		case FL_BUS_16:
			ok = (*(u_short *)fl_base == *((u_short *)data_base)); fl_base += 2; data_base += 2;
			break;

		case FL_BUS_32:
			ok = (*(u_int *)fl_base == *(u_int *)data_base); fl_base += 4; data_base += 4;
			break;

		case FL_BUS_64:
			movequad(&widedata, fl_base);
			ok = (bcmp(data_base, (void *)&widedata, 8) == 0);
			data_base += 8;
			fl_base += 8;
			break; 

		case FL_BUS_8_ON_64:
			ok = (*((u_char *)map->fl_map_base +
				   (((int)fl_base - map->fl_map_base) << 3)) ==
				*(u_char *)data_base++);
			fl_base++;
			break;
		}

		if(verbose & !ok) {
			printf(" error offset %p\n", fl_last);
			{
			char str[100];
			int timeout;
			printf("erase all chip(y/N)?");
			gets(str);
			if(str[0]=='y'||str[0]=='Y')
			{
				tgt_flashwrite_enable();
				printf("Erasing all FLASH blocks. ");
				fl_erase_device(map->fl_map_base,map->fl_map_size,FALSE);
				tgt_flashwrite_disable();
			}
			}
			break;
		}
		else if(verbose) {
			dotik(32, 0);
		}
	}

	if(verbose && ok) {
		printf("\b No Errors found.\n");
	}
	
	return(ok);
}
Example #6
0
  __attribute__((weak))fl_erase_device(void *base, int size, int verbose)
{
	struct fl_map *map;
	struct fl_device *dev;
	int mask, ok, block;
	int timeout;

	if(tgt_flashwrite_enable() == 0) {
		printf("Flash can't be write enabled\n");
		return(-2);	/* Flash can't be write enabled */
	}

	dev = fl_devident(base, &map);
	if(dev == NULL) {
		printf("No flash found at %x\n",(u_int32_t)base);
		return(-3);	/* No flash device found at address */
	}

	/*
	 * Sanity checks!
	 */
	if(size == -1 && (int)base == map->fl_map_base) {
		size = map->fl_map_size;	/* Entire flash */
	}

        if(dev->fl_varsecsize != NULL) {
                int offset = (int)(base - map->fl_map_base) + map->fl_map_offset;
                int totalsize;
		printf("offset=%x,base=%x\n",offset,map->fl_map_base);

                for(block=0, totalsize=0; totalsize < offset; block++) {
                        totalsize += dev->fl_varsecsize[block] * map->fl_map_chips;
                }

                mask = ((dev->fl_varsecsize[block] * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }
                base -= map->fl_map_base;

        } else {
                mask = ((dev->fl_secsize * map->fl_map_width / map->fl_map_chips) - 1);
                if((int)base & mask) {
                        size += (int)base & mask;
                        base = (void *)((int)base & ~mask);
                } else if((size + ((int)base - map->fl_map_base)) > map->fl_map_size) {
                        return(-4);	/* End beyound end of flash */
                }

                base -= map->fl_map_base;
                block = (int)base / map->fl_map_chips / dev->fl_secsize;
                size = (size + mask) & ~mask; /* Round up to catch entire flash */
        }
        
        tgt_flashwrite_enable();
        
	while(size > 0) {
		int boffs = (int)base;
		if(size == map->fl_map_size &&
			dev->fl_cap & (FL_CAP_DE|FL_CAP_A7)) {
			/*
			 * Erase entire devices using the BULK erase feature
			 */
			if(verbose) {
				printf("Erasing all FLASH blocks. ");
			}

			(*dev->functions->erase_chip)(map, dev);

			size = 0;
		}
		else {
			/*
			 * Not entire flash or no BULK erase feature. We
			 * use sector/block erase.
			 */
			if(verbose) {
				printf("\rErasing FLASH block %3d      \b\b\b\b\b", block);
			}

			if((*dev->functions->erase_sector)(map, dev, boffs) != 0) {
				printf("\nError: Failed to enter erase mode\n");
				(*dev->functions->erase_suspend)(map, dev);
				(*dev->functions->reset)(map, dev);
				return(-4);
			}

                        if(dev->fl_varsecsize != NULL) {
                                base += dev->fl_varsecsize[block] * map->fl_map_chips;
                                size -= dev->fl_varsecsize[block] * map->fl_map_chips;
                                block++;
                        } else {
                                base += dev->fl_secsize * map->fl_map_chips;
                                size -= dev->fl_secsize * map->fl_map_chips;
                                block++;
                        }
		}

		delay(1000);
		for(timeout = 0 ;
		    ((ok = (*dev->functions->isbusy)(map, dev, 0xffffffff, boffs, TRUE)) == 1)
				&& (timeout < PFLASH_MAX_TIMEOUT); timeout++) {
				delay(1000);
			if(verbose) {
				dotik(256, 0);
			}
		}
		delay(1000);

		if(!(timeout < PFLASH_MAX_TIMEOUT)) {
			(*dev->functions->erase_suspend)(map, dev);
		}
		(*dev->functions->reset)(map, dev);

		if(verbose) {
			if(!(timeout < PFLASH_MAX_TIMEOUT)) {
/* XXX if timed out what should really happen here? This doesn't look right. */
				printf("\b\b, command timed out!\n");
			} else {
				printf("\b Done.\n");
			}
		}
	}

	tgt_flashwrite_disable();
	return(ok);
}