Exemplo n.º 1
0
void fallback_chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
{
	size_t i;
	for (i = 0; i < len; i++)
		chip_writeb(flash, buf[i], addr + i);
	return;
}
Exemplo n.º 2
0
static int stm50_erase_sector(struct flashctx *flash, unsigned int addr)
{
	chipaddr bios = flash->virtual_memory + addr;

	// clear status register
	chip_writeb(flash, 0x50, bios);
	// now start it
	chip_writeb(flash, 0x32, bios);
	chip_writeb(flash, 0xd0, bios);
	programmer_delay(10);

	uint8_t status = wait_82802ab(flash);
	print_status_82802ab(status);

	return status == 0x80;
}
Exemplo n.º 3
0
/* FIXME: needs timeout */
uint8_t wait_82802ab(struct flashctx *flash)
{
	uint8_t status;
	chipaddr bios = flash->virtual_memory;

	chip_writeb(flash, 0x70, bios);
	if ((chip_readb(flash, bios) & 0x80) == 0) {	// it's busy
		while ((chip_readb(flash, bios) & 0x80) == 0) ;
	}

	status = chip_readb(flash, bios);

	/* Reset to get a clean state */
	chip_writeb(flash, 0xFF, bios);

	return status;
}
Exemplo n.º 4
0
int erase_sector_28sf040(struct flashchip *flash, unsigned int address, unsigned int sector_size)
{
	chipaddr bios = flash->virtual_memory;

	/* This command sequence is very similar to erase_block_82802ab. */
	chip_writeb(AUTO_PG_ERASE1, bios);
	chip_writeb(AUTO_PG_ERASE2, bios + address);

	/* wait for Toggle bit ready */
	toggle_ready_jedec(bios);

	if (check_erased_range(flash, address, sector_size)) {
		msg_cerr("ERASE FAILED!\n");
		return -1;
	}
	return 0;
}
Exemplo n.º 5
0
int unlock_82802ab(struct flashctx *flash)
{
	int i;
	//chipaddr wrprotect = flash->virtual_registers + page + 2;

	for (i = 0; i < flash->chip->total_size * 1024; i+= flash->chip->page_size)
		chip_writeb(flash, 0, flash->virtual_registers + i + 2);

	return 0;
}
Exemplo n.º 6
0
/* According to the Winbond W29EE011, W29EE012, W29C010M, W29C011A
 * datasheets this is the only valid probe function for those chips.
 */
int probe_w29ee011(struct flashctx *flash)
{
	chipaddr bios = flash->virtual_memory;
	uint8_t id1, id2;

	if (!chip_to_probe || strcmp(chip_to_probe, flash->chip->name)) {
		msg_cdbg("Old Winbond W29* probe method disabled because "
			 "the probing sequence puts the AMIC A49LF040A in "
			 "a funky state. Use 'flashrom -c %s' if you "
			 "have a board with such a chip.\n", flash->chip->name);
		return 0;
	}

	/* Issue JEDEC Product ID Entry command */
	chip_writeb(flash, 0xAA, bios + 0x5555);
	programmer_delay(10);
	chip_writeb(flash, 0x55, bios + 0x2AAA);
	programmer_delay(10);
	chip_writeb(flash, 0x80, bios + 0x5555);
	programmer_delay(10);
	chip_writeb(flash, 0xAA, bios + 0x5555);
	programmer_delay(10);
	chip_writeb(flash, 0x55, bios + 0x2AAA);
	programmer_delay(10);
	chip_writeb(flash, 0x60, bios + 0x5555);
	programmer_delay(10);

	/* Read product ID */
	id1 = chip_readb(flash, bios);
	id2 = chip_readb(flash, bios + 0x01);

	/* Issue JEDEC Product ID Exit command */
	chip_writeb(flash, 0xAA, bios + 0x5555);
	programmer_delay(10);
	chip_writeb(flash, 0x55, bios + 0x2AAA);
	programmer_delay(10);
	chip_writeb(flash, 0xF0, bios + 0x5555);
	programmer_delay(10);

	msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);

	if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id)
		return 1;

	return 0;
}
Exemplo n.º 7
0
int erase_block_82802ab(struct flashctx *flash, unsigned int page,
			unsigned int pagesize)
{
	chipaddr bios = flash->virtual_memory;
	uint8_t status;

	// clear status register
	chip_writeb(flash, 0x50, bios + page);

	// now start it
	chip_writeb(flash, 0x20, bios + page);
	chip_writeb(flash, 0xd0, bios + page);
	programmer_delay(10);

	// now let's see what the register is
	status = wait_82802ab(flash);
	print_status_82802ab(status);

	/* FIXME: Check the status register for errors. */
	return 0;
}
Exemplo n.º 8
0
int probe_m29f400bt(struct flashctx *flash)
{
	chipaddr bios = flash->virtual_memory;
	uint8_t id1, id2;

	chip_writeb(flash, 0xAA, bios + 0xAAA);
	chip_writeb(flash, 0x55, bios + 0x555);
	chip_writeb(flash, 0x90, bios + 0xAAA);

	programmer_delay(10);

	id1 = chip_readb(flash, bios);
	/* The data sheet says id2 is at (bios + 0x01) and id2 listed in
	 * flash.h does not match. It should be possible to use JEDEC probe.
	 */
	id2 = chip_readb(flash, bios + 0x02);

	chip_writeb(flash, 0xAA, bios + 0xAAA);
	chip_writeb(flash, 0x55, bios + 0x555);
	chip_writeb(flash, 0xF0, bios + 0xAAA);

	programmer_delay(10);

	msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);

	if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id)
		return 1;

	return 0;
}
Exemplo n.º 9
0
/* chunksize is 1 */
int write_28sf040(struct flashchip *flash, uint8_t *src, int start, int len)
{
	int i;
	chipaddr bios = flash->virtual_memory;
	chipaddr dst = flash->virtual_memory + start;

	for (i = 0; i < len; i++) {
		/* transfer data from source to destination */
		if (*src == 0xFF) {
			dst++, src++;
			/* If the data is 0xFF, don't program it */
			continue;
		}
		/*issue AUTO PROGRAM command */
		chip_writeb(AUTO_PGRM, dst);
		chip_writeb(*src++, dst++);

		/* wait for Toggle bit ready */
		toggle_ready_jedec(bios);
	}

	return 0;
}
Exemplo n.º 10
0
static void write_lockbits_49fl00x(const struct flashctx *flash,
				   unsigned int size, unsigned char bits,
				   unsigned int block_size)
{
	unsigned int i, left = size;
	chipaddr bios = flash->virtual_registers;

	for (i = 0; left >= block_size; i++, left -= block_size) {
		/* pm49fl002 */
		if (block_size == 16384 && i % 2)
			continue;

		chip_writeb(flash, bits, bios + (i * block_size) + 2);
	}
}
Exemplo n.º 11
0
int unlock_28f004s5(struct flashctx *flash)
{
	chipaddr bios = flash->virtual_memory;
	uint8_t mcfg, bcfg, need_unlock = 0, can_unlock = 0;
	int i;

	/* Clear status register */
	chip_writeb(flash, 0x50, bios);

	/* Read identifier codes */
	chip_writeb(flash, 0x90, bios);

	/* Read master lock-bit */
	mcfg = chip_readb(flash, bios + 0x3);
	msg_cdbg("master lock is ");
	if (mcfg) {
		msg_cdbg("locked!\n");
	} else {
		msg_cdbg("unlocked!\n");
		can_unlock = 1;
	}

	/* Read block lock-bits */
	for (i = 0; i < flash->chip->total_size * 1024; i+= (64 * 1024)) {
		bcfg = chip_readb(flash, bios + i + 2); // read block lock config
		msg_cdbg("block lock at %06x is %slocked!\n", i, bcfg ? "" : "un");
		if (bcfg) {
			need_unlock = 1;
		}
	}

	/* Reset chip */
	chip_writeb(flash, 0xFF, bios);

	/* Unlock: clear block lock-bits, if needed */
	if (can_unlock && need_unlock) {
		msg_cdbg("Unlock: ");
		chip_writeb(flash, 0x60, bios);
		chip_writeb(flash, 0xD0, bios);
		chip_writeb(flash, 0xFF, bios);
		msg_cdbg("Done!\n");
	}

	/* Error: master locked or a block is locked */
	if (!can_unlock && need_unlock) {
		msg_cerr("At least one block is locked and lockdown is active!\n");
		return -1;
	}

	return 0;
}
Exemplo n.º 12
0
static int unlock_w39_fwh_block(struct flashchip *flash, int offset)
{
	chipaddr wrprotect = flash->virtual_registers + offset + 2;
	uint8_t locking;

	locking = chip_readb(wrprotect);
	/* Read or write lock present? */
	if (locking & ((1 << 2) | (1 << 0))) {
		/* Lockdown active? */
		if (locking & (1 << 1)) {
			msg_cerr("Can't unlock block at 0x%x!\n", offset);
			return -1;
		} else {
			msg_cdbg("Unlocking block at 0x%x\n", offset);
			chip_writeb(0, wrprotect);
		}
	}

	return 0;
}
Exemplo n.º 13
0
/* Page size is usually 256 bytes */
static int it8716f_spi_page_program(struct flashchip *flash, uint8_t *buf, int start)
{
	int i;
	int result;
	chipaddr bios = flash->virtual_memory;

	result = spi_write_enable();
	if (result)
		return result;
	/* FIXME: The command below seems to be redundant or wrong. */
	OUTB(0x06, it8716f_flashport + 1);
	OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
	for (i = 0; i < flash->page_size; i++) {
		chip_writeb(buf[i], bios + start + i);
	}
	OUTB(0, it8716f_flashport);
	/* Wait until the Write-In-Progress bit is cleared.
	 * This usually takes 1-10 ms, so wait in 1 ms steps.
	 */
	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
		programmer_delay(1000);
	return 0;
}
Exemplo n.º 14
0
int erase_m29f400bt(struct flashctx *flash)
{
	chipaddr bios = flash->virtual_memory;

	chip_writeb(flash, 0xAA, bios + 0xAAA);
	chip_writeb(flash, 0x55, bios + 0x555);
	chip_writeb(flash, 0x80, bios + 0xAAA);

	chip_writeb(flash, 0xAA, bios + 0xAAA);
	chip_writeb(flash, 0x55, bios + 0x555);
	chip_writeb(flash, 0x10, bios + 0xAAA);

	programmer_delay(10);
	toggle_ready_jedec(flash, bios);

	/* FIXME: Check the status register for errors. */
	return 0;
}
Exemplo n.º 15
0
int block_erase_m29f400bt(struct flashctx *flash, unsigned int start,
			  unsigned int len)
{
	chipaddr bios = flash->virtual_memory;
	chipaddr dst = bios + start;

	chip_writeb(flash, 0xAA, bios + 0xAAA);
	chip_writeb(flash, 0x55, bios + 0x555);
	chip_writeb(flash, 0x80, bios + 0xAAA);

	chip_writeb(flash, 0xAA, bios + 0xAAA);
	chip_writeb(flash, 0x55, bios + 0x555);
	chip_writeb(flash, 0x30, dst);

	programmer_delay(10);
	toggle_ready_jedec(flash, bios);

	/* FIXME: Check the status register for errors. */
	return 0;
}
Exemplo n.º 16
0
static uint8_t w39_idmode_readb(struct flashchip *flash, int offset)
{
	chipaddr bios = flash->virtual_memory;
	uint8_t val;

	/* Product Identification Entry */
	chip_writeb(0xAA, bios + 0x5555);
	chip_writeb(0x55, bios + 0x2AAA);
	chip_writeb(0x90, bios + 0x5555);
	programmer_delay(10);

	/* Read something, maybe hardware lock bits */
	val = chip_readb(bios + offset);

	/* Product Identification Exit */
	chip_writeb(0xAA, bios + 0x5555);
	chip_writeb(0x55, bios + 0x2AAA);
	chip_writeb(0xF0, bios + 0x5555);
	programmer_delay(10);

	return val;
}
Exemplo n.º 17
0
/* Little-endian fallback for drivers not supporting 16 bit accesses */
void fallback_chip_writew(const struct flashctx *flash, uint16_t val,
			  chipaddr addr)
{
	chip_writeb(flash, val & 0xff, addr);
	chip_writeb(flash, (val >> 8) & 0xff, addr + 1);
}