Exemplo n.º 1
0
STATIC_PREFIX void debugrom_save_to_spi(int argc, char * argv[])
{
    spi_init();
    if(argc!=4)
        return;
    unsigned dest,src,size;
    if(get_dword(argv[1],&dest)||get_dword(argv[2],&src) || get_dword(argv[3],&size))
        return;
    spi_program(dest,src,size);
}
Exemplo n.º 2
0
void handle_write(struct usb_ep *ep,struct usb_request *req)
{
	struct cloner *cloner = req->context;

	if(req->status == -ECONNRESET) {
		cloner->ack = -ECONNRESET;
		return;
	}

	if (req->actual != req->length) {
		printf("write transfer length is err,actual=%08x,length=%08x\n",req->actual,req->length);
		cloner->ack = -EIO;
		return;
	}

	if(cloner->cmd_type == VR_UPDATE_CFG) {
		cloner->ack = 0;
		return;
	}

	if (cloner->args->transfer_data_chk) {
		uint32_t tmp_crc = local_crc32(0xffffffff,req->buf,req->actual);
		if (cloner->cmd->write.crc != tmp_crc) {
			printf("crc is errr! src crc=%08x crc=%08x\n",cloner->cmd->write.crc,tmp_crc);
			cloner->ack = -EINVAL;
			return;
		}
	}
#define OPS(x,y) ((x<<16)|(y&0xffff))
	switch(cloner->cmd->write.ops) {
		case OPS(I2C,RAW):
			cloner->ack = i2c_program(cloner);
			break;
#ifdef CONFIG_JZ_NAND_MGR
		case OPS(NAND,IMAGE):
			cloner->ack = nand_program(cloner);
			break;
#endif
#ifdef CONFIG_MTD_NAND_JZ
		case OPS(NAND, MTD_RAW):
			cloner->ack = nand_mtd_raw_program(cloner);
			break;
		case OPS(NAND, MTD_UBI):
			cloner->ack = nand_mtd_ubi_program(cloner);
			break;
#endif
#ifdef CONFIG_JZ_MMC
		case OPS(MMC,0):
		case OPS(MMC,1):
		case OPS(MMC,2):
			cloner->ack = mmc_program(cloner,cloner->cmd->write.ops & 0xffff);
			break;
#endif
#ifdef CONFIG_CMD_EFUSE
		case OPS(EFUSE,RAW):
			cloner->ack = efuse_program(cloner);
			break;
#endif
		case OPS(SPI_NOR,RAW):
			cloner->ack = spi_program(cloner);
			break;
#ifdef CONFIG_MTD_SPINAND
		case OPS(SPI_NAND,RAW):
			cloner->ack = spinand_program(cloner);
			break;
#endif
#ifdef CONFIG_JZ_SFC
		case OPS(SFC_NOR,RAW):
			cloner->ack = sfc_program(cloner);
			break;
#endif
#ifdef CONFIG_MTD_SFCNAND
		case OPS(SFC_NAND,RAW):
			cloner->ack = spinand_program(cloner);
			break;
#endif
		case OPS(MEMORY,RAW):
			cloner->ack = 0;
			break;
		case OPS(REGISTER,RAW):
			{
				volatile unsigned int *tmp = (void *)cloner->cmd->write.partation;
				if((unsigned)tmp > 0xb0000000 && (unsigned)tmp < 0xb8000000) {
					*tmp = *((int*)cloner->write_req->buf);
					cloner->ack = 0;
				} else {
					printf("OPS(REGISTER,RAW): not supported address.");
					cloner->ack = -ENODEV;
				}
			}
			break;
		default:
			cloner->ack = clmg_write(cloner);
	}
#undef OPS
}
Exemplo n.º 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;
}