flwrite.c 4.15 KB
#include "cpusim.h"
#include "bbnand.h"

void
passed(void) {
    message("test flwrite passed\n");
    test_postamble();
}

void
failed(const char* code) {
    message("test flwrite failed (");
    message(code);
    message(")\n");
    test_postamble();
}

static inline int
flash_status(unsigned dev, unsigned offset, unsigned buffer) {
    IO_WRITE(PI_FLASH_ADDR_REG, offset << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
	    			PI_FLASH_CTRL_RDPH  |
				NAND_CMD_STATUS << PI_FLASH_CTRL_CMD_SHIFT |
				buffer << PI_FLASH_CTRL_BUF_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				1);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return -1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return IO_READ(PI_BUFFER_BASE_REG+buffer*512+offset) >> 24;
}

static inline int
read_page(unsigned dev, unsigned addr, int which_buf) {
    IO_WRITE(PI_FLASH_ADDR_REG, addr << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
	    			PI_FLASH_CTRL_RDPH  |
				0xf << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_READ_0 << PI_FLASH_CTRL_CMD_SHIFT |
				PI_FLASH_CTRL_WRDY |
				which_buf << PI_FLASH_CTRL_BUF_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				PI_FLASH_CTRL_ECC |
				528);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return (IO_READ(PI_FLASH_CTRL_REG) & PI_FLASH_CTRL_DBERR) ? 1 : 0;
}

static inline int
write_page(unsigned dev, unsigned addr, int which_buf) {
    IO_WRITE(PI_FLASH_ADDR_REG, addr << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
	    			PI_FLASH_CTRL_WDPH  |
				0xf << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_DATA_INPUT << PI_FLASH_CTRL_CMD_SHIFT |
				which_buf << PI_FLASH_CTRL_BUF_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				PI_FLASH_CTRL_ECC |
				528);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
				NAND_CMD_PROGRAM << PI_FLASH_CTRL_CMD_SHIFT |
				PI_FLASH_CTRL_WRDY |
				dev << PI_FLASH_CTRL_DEV_SHIFT);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return flash_status(dev, 0, which_buf) != (NAND_STATUS_CMD_PASS|NAND_STATUS_WRITE_OK|NAND_STATUS_READY);
}

static inline int
erase_block(unsigned dev, unsigned int addr) {
    IO_WRITE(PI_FLASH_ADDR_REG, addr << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
				0xe << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_ERASE_0 << PI_FLASH_CTRL_CMD_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				PI_FLASH_CTRL_MCMD);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
				0 << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_ERASE_1 << PI_FLASH_CTRL_CMD_SHIFT |
				PI_FLASH_CTRL_WRDY |
				dev << PI_FLASH_CTRL_DEV_SHIFT);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return flash_status(dev, 0, 0) != (NAND_STATUS_CMD_PASS|NAND_STATUS_READY|NAND_STATUS_WRITE_OK);
}

int
main() {
    int i;
    unsigned short csum = 0;
    test_preamble();
    /* configure flash */
    IO_WRITE(PI_FLASH_CONFIG_REG, 7 << 28 |  // end of cycle time - 2
	    			  5 << 24 |  // read data sample time - 1
				  0x3e << 16 | // RE active time
				  0x1f << 8 |  // WE active time
				  0x3f << 0);  // CLE/ALE active time

    if (erase_block(0, 32)) failed("0");
    if (read_page(0, 1, 0)) failed("1");
    if (write_page(0, 33, 0)) failed("2");
    if (read_page(0, 0, 0)) failed("3");
    if (read_page(0, 33, 1)) failed("4");
    for(i = 0; i < 512/4; i++) {
	unsigned x = IO_READ(PI_BUFFER_1_START+i*4);
	csum += (x >> 24) + ((x >> 16)&0xff) + ((x >> 8)&0xff) + (x&0xff) ;
    }
    for(i = 0; i < 16/4; i++) {
	unsigned x = IO_READ(PI_BUFFER_1_OOB_START+i*4);
	csum += (x >> 24) + ((x >> 16)&0xff) + ((x >> 8)&0xff) + (x&0xff) ;
    }
    IO_WRITE(PI_IDE3_BASE_REG, csum);
    if (csum == 0x01c2)
	passed();
    else
	failed("5");
    return 0;
}