コード例 #1
0
ファイル: cfi.c プロジェクト: whitecatboard/LuaOS
void cfi_read(int unit, int addr, int size, char *buf) {
    struct cfi *cfi = &cfid[unit];

    cfi_wait_ready(cfi);
    cfi_send_command(cfi, CMD_READ, &addr, buf, size, 0);
    cfi_wait_ready(cfi);    
}
コード例 #2
0
/*
 * Write the Protection Lock Register to lock down the
 * user-settable segment of the Protection Register.
 * NOTE: this operation is not reversible.
 */
int 
cfi_intel_set_plr(struct cfi_softc *sc)
{
#ifdef CFI_ARMEDANDDANGEROUS
	register_t intr;
	int error;
#endif
	if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
		return EOPNOTSUPP;
	KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));

#ifdef CFI_ARMEDANDDANGEROUS
	/* worthy of console msg */
	device_printf(sc->sc_dev, "set PLR\n");
	intr = intr_disable();
	cfi_write(sc, 0, CFI_INTEL_PP_SETUP);
	cfi_put16(sc, CFI_INTEL_PLR, 0xFFFD);
	intr_restore(intr);
	error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, sc->sc_write_timeout);
	cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
	return error;
#else
	device_printf(sc->sc_dev, "%s: PLR not set, "
	    "CFI_ARMEDANDDANGEROUS not configured\n", __func__);
	return ENXIO;
#endif
}
コード例 #3
0
/*
 * Write the User/OEM 64-bit segment of the PR.
 * XXX should allow writing individual words/bytes
 */
int
cfi_intel_set_oem_pr(struct cfi_softc *sc, uint64_t id)
{
#ifdef CFI_ARMEDANDDANGEROUS
	register_t intr;
	int i, error;
#endif

	if (sc->sc_cmdset != CFI_VEND_INTEL_ECS)
		return EOPNOTSUPP;
	KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width));

#ifdef CFI_ARMEDANDDANGEROUS
	for (i = 7; i >= 4; i--, id >>= 16) {
		intr = intr_disable();
		cfi_write(sc, 0, CFI_INTEL_PP_SETUP);
		cfi_put16(sc, CFI_INTEL_PR(i), id&0xffff);
		intr_restore(intr);
		error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS,
		    sc->sc_write_timeout);
		if (error)
			break;
	}
	cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
	return error;
#else
	device_printf(sc->sc_dev, "%s: OEM PR not set, "
	    "CFI_ARMEDANDDANGEROUS not configured\n", __func__);
	return ENXIO;
#endif
}
コード例 #4
0
ファイル: cfi.c プロジェクト: whitecatboard/LuaOS
int cfi_write(int unit, int addr, int size, char *buf) {
    struct cfi *cfi = &cfid[unit];
    
    enable_write(cfi);
    cfi_send_command(cfi, CMD_PP, &addr, buf, size, 1);
    cfi_wait_ready(cfi);   
    
    return 0; 
}
コード例 #5
0
ファイル: cfi.c プロジェクト: whitecatboard/LuaOS
static int enable_write(struct cfi *cfi) {
    cfi_wait_ready(cfi);
    cfi_send_command(cfi, CMD_WREN, NULL, NULL, 0, 0);
    
    // Wait for write enable latch
    while (!(cfi_read_reg(cfi, CMD_RDSR1) & SR1_WEL_MASK));
    
    return 0;
}
コード例 #6
0
ファイル: cfi.c プロジェクト: whitecatboard/LuaOS
void cfi_erase(int unit, int addr, int size) {
    struct cfi *cfi = &cfid[unit];
    int i, block;    

    // Get the block number
    block = (addr - cfi->pagesiz) / cfi->sectsiz;
    
    if (block == 255) {
        for(i=0;i < 16;i++) {
            enable_write(cfi);
            cfi_send_command(cfi, CMD_P4E, &addr, NULL, 0, 1);  
            addr += cfi->sectsiz / 16;
        }
    } else {
        enable_write(cfi);
        cfi_send_command(cfi, CMD_SE, &addr, NULL, 0, 1);   
    }  
    
    cfi_wait_ready(cfi); 
}
コード例 #7
0
int
cfi_write_block(struct cfi_softc *sc)
{
	union {
		uint8_t		*x8;
		uint16_t	*x16;
		uint32_t	*x32;
	} ptr;
	register_t intr;
	int error, i;

	/* Erase the block. */
	switch (sc->sc_cmdset) {
	case CFI_VEND_INTEL_ECS:
	case CFI_VEND_INTEL_SCS:
		cfi_write(sc, sc->sc_wrofs, CFI_BCS_BLOCK_ERASE);
		cfi_write(sc, sc->sc_wrofs, CFI_BCS_CONFIRM);
		break;
	case CFI_VEND_AMD_SCS:
	case CFI_VEND_AMD_ECS:
		cfi_amd_write(sc, sc->sc_wrofs, AMD_ADDR_START,
		    CFI_AMD_ERASE_SECTOR);
		cfi_amd_write(sc, sc->sc_wrofs, 0, CFI_AMD_BLOCK_ERASE);
		break;
	default:
		/* Better safe than sorry... */
		return (ENODEV);
	}
	error = cfi_wait_ready(sc, sc->sc_wrofs, sc->sc_erase_timeout);
	if (error)
		goto out;

	/* Write the block. */
	ptr.x8 = sc->sc_wrbuf;
	for (i = 0; i < sc->sc_wrbufsz; i += sc->sc_width) {

		/*
		 * Make sure the command to start a write and the
		 * actual write happens back-to-back without any
		 * excessive delays.
		 */
		intr = intr_disable();

		switch (sc->sc_cmdset) {
		case CFI_VEND_INTEL_ECS:
		case CFI_VEND_INTEL_SCS:
			cfi_write(sc, sc->sc_wrofs + i, CFI_BCS_PROGRAM);
			break;
		case CFI_VEND_AMD_SCS:
		case CFI_VEND_AMD_ECS:
			cfi_amd_write(sc, 0, AMD_ADDR_START, CFI_AMD_PROGRAM);
			break;
		}
		switch (sc->sc_width) {
		case 1:
			bus_space_write_1(sc->sc_tag, sc->sc_handle,
			    sc->sc_wrofs + i, *(ptr.x8)++);
			break;
		case 2:
			bus_space_write_2(sc->sc_tag, sc->sc_handle,
			    sc->sc_wrofs + i, *(ptr.x16)++);
			break;
		case 4:
			bus_space_write_4(sc->sc_tag, sc->sc_handle,
			    sc->sc_wrofs + i, *(ptr.x32)++);
			break;
		}

		intr_restore(intr);

		error = cfi_wait_ready(sc, sc->sc_wrofs, sc->sc_write_timeout);
		if (error)
			goto out;
	}

	/* error is 0. */

 out:
	cfi_write(sc, 0, CFI_BCS_READ_ARRAY);
	return (error);
}