Пример #1
0
static void do_test_libeprom24x(void)
{  
  int value;

  do {
    print_menu();
    
    printf("Enter choice : ");
    scanf("%d",&value);
    
    switch(value) {
    case 1:
      get_prod_info();
      break;
    case 2:
      get_last_error();
      break;
    case 3:
      initialize();
      break;
    case 4:
      finalize();
      break;
    case 5:
      read_u8();
      break;
    case 6:
      read_u16();
      break;
    case 7:
      read_u32();
      break;
    case 8:
      read_to_buffer();
      break;
    case 9:
      write_u8();
      break;
    case 10:
      write_u16();
      break;
    case 11:
      write_u32();
      break;
    case 12:
      write_from_buffer();
      break;
    case 13:
      erase_chip();
      break;
    case 100: /* Exit */
      break;
    default:
      printf("Illegal choice!\n");
    }
  } while (value != 100);

  return;
}
Пример #2
0
/*
 * Erase an address range on the nor chip.  The address range may extend
 * one or more erase sectors.  Return an error is there is a problem erasing.
 */
static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct spi_nor *nor = mtd_to_spi_nor(mtd);
	u32 addr, len;
	uint32_t rem;
	int ret;

	dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
			(long long)instr->len);

	div_u64_rem(instr->len, mtd->erasesize, &rem);
	if (rem)
		return -EINVAL;

	addr = instr->addr;
	len = instr->len;

	ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_ERASE);
	if (ret)
		return ret;

	/* whole-chip erase? */
	if (len == mtd->size) {
		if (erase_chip(nor)) {
			ret = -EIO;
			goto erase_err;
		}

	/* REVISIT in some cases we could speed up erasing large regions
	 * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K.  We may have set up
	 * to use "small sector erase", but that's not always optimal.
	 */

	/* "sector"-at-a-time erase */
	} else {
		while (len) {
			if (nor->erase(nor, addr)) {
				ret = -EIO;
				goto erase_err;
			}

			addr += mtd->erasesize;
			len -= mtd->erasesize;
		}
	}

	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);

	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	return ret;

erase_err:
	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
	instr->state = MTD_ERASE_FAILED;
	return ret;
}
Пример #3
0
/*
 * Erase an address range on the flash chip.  The address range may extend
 * one or more erase sectors.  Return an error is there is a problem erasing.
 */
static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct m25p *flash = mtd_to_m25p(mtd);
	u32 addr,len;

	DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
			flash->spi->dev.bus_id, __func__, "at",
			(u32)instr->addr, instr->len);

	/* sanity checks */
	if (instr->addr + instr->len > flash->mtd.size)
		return -EINVAL;
	if ((instr->addr % mtd->erasesize) != 0
			|| (instr->len % mtd->erasesize) != 0) {
		return -EINVAL;
	}

	addr = instr->addr;
	len = instr->len;

	mutex_lock(&flash->lock);

	/* whole-chip erase? */
	if (len == flash->mtd.size && erase_chip(flash)) {
		instr->state = MTD_ERASE_FAILED;
		mutex_unlock(&flash->lock);
		return -EIO;

	/* REVISIT in some cases we could speed up erasing large regions
	 * by using OPCODE_SE instead of OPCODE_BE_4K.  We may have set up
	 * to use "small sector erase", but that's not always optimal.
	 */

	/* "sector"-at-a-time erase */
	} else {
		while (len) {
			if (erase_sector(flash, addr)) {
				instr->state = MTD_ERASE_FAILED;
				mutex_unlock(&flash->lock);
				return -EIO;
			}

			addr += mtd->erasesize;
			len -= mtd->erasesize;
		}
	}

	mutex_unlock(&flash->lock);

	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	return 0;
}
Пример #4
0
static void enable_parallel_programming(void) // TODO
{
#if 1
	PGMW1 &= ~(PAGEL | XA1 | XA0 | BS1);
	read_switch();
	// Applied +5V & +12V
	erase_chip();
	write_fuse(0, 0x99E0);
#else
	_delay_us(100);
	PGMW2 &= ~RESETb;
	xtal1_pulse();
	xtal1_pulse();
	xtal1_pulse();
	PGMW1 &= ~(PAGEL | XA1 | XA0 | BS1);
	_delay_us(1);
	read_switch();
	apply_high_voltage_to_reset();
	_delay_us(1);
#endif
}
Пример #5
0
int
main(int argc, char *argv[])
{


    char *mode;

    if (argc == 1) { printf("Syntax: epsiflash erase|read|burn [filename]\n"); exit (1);}

    hardware_init();
    filename = argv[2];
    mode = argv[1];

    probe_chip();
    printf("Chip: %s - %dKB, %s\n", chips[chipindex].name, chips[chipindex].size / 1024, chips[chipindex].adapter);

    if (strcmp(chips[chipindex].name,"UNKNOWN")==0) {
        fprintf(stderr,"Chip is unsupported or not inserted properly\n");
        exit(-1);
    }


    if (strcmp(mode,"burn")==0) {
      program_chip();
      printf("\n");
      exit(1);
    }

    if (strcmp(mode,"read")==0) {
     read_chip(); 
     printf("\n");
     exit(1);
    }
    if (strcmp(mode, "erase")==0) {
     erase_chip();
     printf("\n");
     exit(1);
    }
    return 0;
}
Пример #6
0
int main(int argc, char *argv[])
{
    const char *pname = argv[0];
    uint32_t address = 0, read_size = 0, write_size = 0;
    uint32_t erase_start = 0, erase_size = 0;
    bool erase = false, do_clear = false;
    bool program = false, erase_all = false, info = false, do_read = false;
    bool enable_4B = false, disable_4B = false;
    bool show_help = false, show_version = false;
    bool no_action = false, tune = false;
    char *write_file = NULL, *read_file = NULL, *part_name = NULL;
    bool ffs_toc_seen = false;
    int rc;

    while(1) {
        static struct option long_opts[] = {
            {"address",	required_argument,	NULL,	'a'},
            {"size",	required_argument,	NULL,	's'},
            {"partition",	required_argument,	NULL,	'P'},
            {"bmc",		no_argument,		NULL,	'b'},
            {"enable-4B",	no_argument,		NULL,	'4'},
            {"disable-4B",	no_argument,		NULL,	'3'},
            {"read",	required_argument,	NULL,	'r'},
            {"erase-all",	no_argument,		NULL,	'E'},
            {"erase",	no_argument,		NULL,	'e'},
            {"program",	required_argument,	NULL,	'p'},
            {"force",	no_argument,		NULL,	'f'},
            {"info",	no_argument,		NULL,	'i'},
            {"tune",	no_argument,		NULL,	't'},
            {"dummy",	no_argument,		NULL,	'd'},
            {"help",	no_argument,		NULL,	'h'},
            {"version",	no_argument,		NULL,	'v'},
            {"debug",	no_argument,		NULL,	'g'},
            {"side",	required_argument,	NULL,	'S'},
            {"toc",		required_argument,	NULL,	'T'},
            {"clear",   no_argument,        NULL,   'c'}
        };
        int c, oidx = 0;

        c = getopt_long(argc, argv, "a:s:P:r:43Eep:fdihvbtgS:T:c",
                        long_opts, &oidx);
        if (c == EOF)
            break;
        switch(c) {
        case 'a':
            address = strtoul(optarg, NULL, 0);
            break;
        case 's':
            read_size = write_size = strtoul(optarg, NULL, 0);
            break;
        case 'P':
            part_name = strdup(optarg);
            break;
        case '4':
            enable_4B = true;
            break;
        case '3':
            disable_4B = true;
            break;
        case 'r':
            do_read = true;
            read_file = strdup(optarg);
            break;
        case 'E':
            erase_all = erase = true;
            break;
        case 'e':
            erase = true;
            break;
        case 'p':
            program = true;
            write_file = strdup(optarg);
            break;
        case 'f':
            must_confirm = false;
            break;
        case 'd':
            must_confirm = false;
            dummy_run = true;
            break;
        case 'i':
            info = true;
            break;
        case 'b':
            bmc_flash = true;
            break;
        case 't':
            tune = true;
            break;
        case 'v':
            show_version = true;
            break;
        case 'h':
            show_help = show_version = true;
            break;
        case 'g':
            libflash_debug = true;
            break;
        case 'S':
            flash_side = atoi(optarg);
            break;
        case 'T':
            ffs_toc_seen = true;
            ffs_toc = strtoul(optarg, NULL, 0);
            break;
        case 'c':
            do_clear = true;
            break;
        default:
            exit(1);
        }
    }

    /* Check if we need to access the flash at all (which will
     * also tune them as a side effect
     */
    no_action = !erase && !program && !info && !do_read &&
                !enable_4B && !disable_4B && !tune && !do_clear;

    /* Nothing to do, if we didn't already, print usage */
    if (no_action && !show_version)
        show_help = show_version = true;

    if (show_version)
        print_version();
    if (show_help)
        print_help(pname);

    if (no_action)
        return 0;

    /* --enable-4B and --disable-4B are mutually exclusive */
    if (enable_4B && disable_4B) {
        fprintf(stderr, "--enable-4B and --disable-4B are mutually"
                " exclusive !\n");
        exit(1);
    }

    /* 4B not supported on BMC flash */
    if (enable_4B && bmc_flash) {
        fprintf(stderr, "--enable-4B not supported on BMC flash !\n");
        exit(1);
    }

    /* partitions not supported on BMC flash */
    if (part_name && bmc_flash) {
        fprintf(stderr, "--partition not supported on BMC flash !\n");
        exit(1);
    }

    /* part-name and erase-all make no sense together */
    if (part_name && erase_all) {
        fprintf(stderr, "--partition and --erase-all are mutually"
                " exclusive !\n");
        exit(1);
    }

    /* Read command should always come with a file */
    if (do_read && !read_file) {
        fprintf(stderr, "Read with no file specified !\n");
        exit(1);
    }

    /* Program command should always come with a file */
    if (program && !write_file) {
        fprintf(stderr, "Program with no file specified !\n");
        exit(1);
    }

    /* If both partition and address specified, error out */
    if (address && part_name) {
        fprintf(stderr, "Specify partition or address, not both !\n");
        exit(1);
    }

    if (do_clear && !part_name) {
        fprintf(stderr, "--clear only supported on a partition name\n");
        exit(1);
    }

    /* Explicitly only support two sides */
    if (flash_side != 0 && flash_side != 1) {
        fprintf(stderr, "Unexpected value for --side '%d'\n", flash_side);
        exit(1);
    }

    if (ffs_toc_seen && flash_side) {
        fprintf(stderr, "--toc and --side are exclusive");
        exit(1);
    }

    /* If file specified but not size, get size from file
     */
    if (write_file && !write_size) {
        struct stat stbuf;

        if (stat(write_file, &stbuf)) {
            perror("Failed to get file size");
            exit(1);
        }
        write_size = stbuf.st_size;
    }

    if (bmc_flash) {
        if (arch_flash_bmc(NULL, 1) == -1) {
            fprintf(stderr, "Can't switch to BMC flash on this architecture\n");
            exit(1);
        }
    }

    if (arch_flash_init(&bl, NULL, true))
        exit(1);

    on_exit(exiting, NULL);


    rc = blocklevel_get_info(bl, &fl_name,
                             &fl_total_size, &fl_erase_granule);
    if (rc) {
        fprintf(stderr, "Error %d getting flash info\n", rc);
        exit(1);
    }

    /* If -t is passed, then print a nice message */
    if (tune)
        printf("Flash and controller tuned\n");

    /* If read specified and no read_size, use flash size */
    if (do_read && !read_size && !part_name)
        read_size = fl_total_size;

    /* We have a partition specified, grab the details */
    if (part_name)
        lookup_partition(part_name);

    /* We have a partition, adjust read/write size if needed */
    if (ffsh && ffs_index >= 0) {
        uint32_t pstart, pmaxsz, pactsize;
        bool ecc;
        int rc;

        rc = ffs_part_info(ffsh, ffs_index, NULL,
                           &pstart, &pmaxsz, &pactsize, &ecc);
        if (rc) {
            fprintf(stderr,"Failed to get partition info\n");
            exit(1);
        }

        if (!ecc && do_clear) {
            fprintf(stderr, "The partition on which to do --clear "
                    "does not have ECC, are you sure?\n");
            check_confirm();
            /* Still confirm later on */
            must_confirm = true;
        }

        /* Read size is obtained from partition "actual" size */
        if (!read_size)
            read_size = pactsize;

        /* Write size is max size of partition */
        if (!write_size)
            write_size = pmaxsz;

        /* Crop write size to partition size */
        if (write_size > pmaxsz) {
            printf("WARNING: Size (%d bytes) larger than partition"
                   " (%d bytes), cropping to fit\n",
                   write_size, pmaxsz);
            write_size = pmaxsz;
        }

        /* If erasing, check partition alignment */
        if (erase && ((pstart | pmaxsz) & 0xfff)) {
            fprintf(stderr,"Partition not aligned properly\n");
            exit(1);
        }

        /* Set address */
        address = pstart;
    }

    /* Align erase boundaries */
    if (erase && !erase_all) {
        uint32_t mask = 0xfff;
        uint32_t erase_end;

        /* Dummy size for erase, will be adjusted later */
        if (!write_size)
            write_size = 1;
        erase_start = address & ~mask;
        erase_end = ((address + write_size) + mask) & ~mask;
        erase_size = erase_end - erase_start;

        if (erase_start != address || erase_size != write_size)
            fprintf(stderr, "WARNING: Erase region adjusted"
                    " to 0x%08x..0x%08x\n",
                    erase_start, erase_end);
    }

    /* Process commands */
    if (enable_4B)
        enable_4B_addresses();
    if (disable_4B)
        disable_4B_addresses();
    if (info) {
        /*
         * Don't pass through modfied TOC value if the modification was done
         * because of --size, but still respect if it came from --toc (we
         * assume the user knows what they're doing in that case)
         */
        print_flash_info(flash_side ? 0 : ffs_toc);
    }

    /* Unlock flash (PNOR only) */
    if ((erase || program || do_clear) && !bmc_flash) {
        need_relock = arch_flash_set_wrprotect(bl, false);
        if (need_relock == -1) {
            fprintf(stderr, "Architecture doesn't support write protection on flash\n");
            need_relock = 0;
            exit (1);
        }
    }
    if (do_read)
        do_read_file(read_file, address, read_size);
    if (erase_all)
        erase_chip();
    else if (erase)
        erase_range(erase_start, erase_size, program);
    if (program)
        program_file(write_file, address, write_size);
    if (do_clear)
        set_ecc(address, write_size);
    return 0;
}
Пример #7
0
int main(int argc, char *argv[]) {
	char *file_name = NULL;
	unsigned char options = 0x00;

	signal(SIGINT, sigint_handler);

	if (argc < 2)
		usage();

	for (int i = 1; i < argc; i++) {
		if (argv[i][0] != '-') {
			if (!file_name)
				file_name = argv[i];
			else
				usage();
		} else {
			if (options || strlen(argv[i]) > 2)
				usage();

			switch (argv[i][1]) {
				case 's':
					options |= OPTIONS_SKIP_VALIDATION;
				break;
				case 'l':
					options |= OPTIONS_LIST_DEVICES;
				break;
				case 'e':
					options |= OPTIONS_ERASE_CHIP;
				break;
				case 'h':
					options |= OPTIONS_HELP;
				break;
				case 'v':
					options |= OPTIONS_VERSION;
				break;
				default:
					usage();
				break;
			}
		}
	}

	if (!file_name && (options & OPTIONS_SKIP_VALIDATION))
		usage();
	if (file_name && (options & ~OPTIONS_SKIP_VALIDATION))
		usage();

	switch (options) {
		case OPTIONS_LIST_DEVICES:
			list_devices();
		break;
		case OPTIONS_ERASE_CHIP:
			erase_chip();
		break;
		case OPTIONS_HELP:
			usage();
		break;
		case OPTIONS_VERSION:
			printf("saturn-loader "VERSION", "
			       "© 2016 Andrew Milkovich"
			       ", see LICENSE for details\n");
			exit(0);
		break;
		default:
			flash(file_name, options & OPTIONS_SKIP_VALIDATION);
		break;
	}

	return 0;
}
Пример #8
0
uint8_t
flash(FlashControl* flash_control,bool bmc_flash, uint32_t address, char* write_file, char* obj_path)
{
	bool has_sfc = false, has_ast = false, use_lpc = true;
	bool erase = true, program = true;

	int rc;
	printf("flasher: %s, BMC = %d, address = 0x%x\n",write_file,bmc_flash,address);
#ifdef __arm__
	/* Check platform */
	check_platform(&has_sfc, &has_ast);

	/* Prepare for access */
	if(bmc_flash) {
		if(!has_ast) {
			fprintf(stderr, "No BMC on this platform\n");
			return FLASH_SETUP_ERROR;
		}
		rc = flash_access_setup_bmc(use_lpc, erase || program);
		if(rc) {
			return FLASH_SETUP_ERROR;
		}
	} else {
		if(!has_ast && !has_sfc) {
			fprintf(stderr, "No BMC nor SFC on this platform\n");
			return FLASH_SETUP_ERROR;
		}
		rc = flash_access_setup_pnor(use_lpc, has_sfc, erase || program);
		if(rc) {
			return FLASH_SETUP_ERROR;
		}
	}

	rc = flash_get_info(fl_chip, &fl_name,
			&fl_total_size, &fl_erase_granule);
	if(rc) {
		fprintf(stderr, "Error %d getting flash info\n", rc);
		return FLASH_SETUP_ERROR;
	}
#endif
	if(strcmp(write_file,"")!=0)
	{
		// If file specified but not size, get size from file
		struct stat stbuf;
		if(stat(write_file, &stbuf)) {
			perror("Failed to get file size");
			return FLASH_ERROR;
		}
		uint32_t write_size = stbuf.st_size;
#ifdef __arm__
		rc = erase_chip();
		if(rc) {
			return FLASH_ERROR;
		}
		rc = program_file(flash_control, write_file, address, write_size);
		if(rc) {
			return FLASH_ERROR;
		}
#endif

		printf("Flash done\n");
	}
	else
	{
		printf("Flash tuned\n");
	}
	return FLASH_OK;
}