diff options
Diffstat (limited to 'objects/pflash/libflash/test/test-flash.c')
-rw-r--r-- | objects/pflash/libflash/test/test-flash.c | 403 |
1 files changed, 0 insertions, 403 deletions
diff --git a/objects/pflash/libflash/test/test-flash.c b/objects/pflash/libflash/test/test-flash.c deleted file mode 100644 index 0e92d8c..0000000 --- a/objects/pflash/libflash/test/test-flash.c +++ /dev/null @@ -1,403 +0,0 @@ -#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <libflash/libflash.h>
-#include <libflash/libflash-priv.h>
-
-#include "../libflash.c"
-
-#define __unused __attribute__((unused))
-
-#define ERR(fmt...) fprintf(stderr, fmt)
-
-/* Flash commands */
-#define CMD_PP 0x02
-#define CMD_READ 0x03
-#define CMD_WRDI 0x04
-#define CMD_RDSR 0x05
-#define CMD_WREN 0x06
-#define CMD_SE 0x20
-#define CMD_RDSCUR 0x2b
-#define CMD_BE32K 0x52
-#define CMD_CE 0x60
-#define CMD_RDID 0x9f
-#define CMD_EN4B 0xb7
-#define CMD_BE 0xd8
-#define CMD_RDDPB 0xe0
-#define CMD_RDSPB 0xe2
-#define CMD_EX4B 0xe9
-
-/* Flash status bits */
-#define STAT_WIP 0x01
-#define STAT_WEN 0x02
-
-static uint8_t *sim_image;
-static uint32_t sim_image_sz = 0x100000;
-static uint32_t sim_index;
-static uint32_t sim_addr;
-static uint32_t sim_er_size;
-static uint8_t sim_sr;
-static bool sim_fl_4b;
-static bool sim_ct_4b;
-
-static enum sim_state {
- sim_state_idle,
- sim_state_rdid,
- sim_state_rdsr,
- sim_state_read_addr,
- sim_state_read_data,
- sim_state_write_addr,
- sim_state_write_data,
- sim_state_erase_addr,
- sim_state_erase_done,
-} sim_state;
-
-/*
- * Simulated flash & controller
- */
-static int sim_start_cmd(uint8_t cmd)
-{
- if (sim_state != sim_state_idle) {
- ERR("SIM: Command %02x in wrong state %d\n", cmd, sim_state);
- return -1;
- }
-
- sim_index = 0;
- sim_addr = 0;
-
- switch(cmd) {
- case CMD_RDID:
- sim_state = sim_state_rdid;
- break;
- case CMD_RDSR:
- sim_state = sim_state_rdsr;
- break;
- case CMD_EX4B:
- sim_fl_4b = false;
- break;
- case CMD_EN4B:
- sim_fl_4b = true;
- break;
- case CMD_WREN:
- sim_sr |= STAT_WEN;
- break;
- case CMD_READ:
- sim_state = sim_state_read_addr;
- if (sim_ct_4b != sim_fl_4b)
- ERR("SIM: 4b mode mismatch in READ !\n");
- break;
- case CMD_PP:
- sim_state = sim_state_write_addr;
- if (sim_ct_4b != sim_fl_4b)
- ERR("SIM: 4b mode mismatch in PP !\n");
- if (!(sim_sr & STAT_WEN))
- ERR("SIM: PP without WEN, ignoring... \n");
- break;
- case CMD_SE:
- case CMD_BE32K:
- case CMD_BE:
- if (sim_ct_4b != sim_fl_4b)
- ERR("SIM: 4b mode mismatch in SE/BE !\n");
- if (!(sim_sr & STAT_WEN))
- ERR("SIM: SE/BE without WEN, ignoring... \n");
- sim_state = sim_state_erase_addr;
- switch(cmd) {
- case CMD_SE: sim_er_size = 0x1000; break;
- case CMD_BE32K: sim_er_size = 0x8000; break;
- case CMD_BE: sim_er_size = 0x10000; break;
- }
- break;
- case CMD_CE:
- if (!(sim_sr & STAT_WEN)) {
- ERR("SIM: CE without WEN, ignoring... \n");
- break;
- }
- memset(sim_image, 0xff, sim_image_sz);
- sim_sr |= STAT_WIP;
- sim_sr &= ~STAT_WEN;
- break;
- default:
- ERR("SIM: Unsupported command %02x\n", cmd);
- return -1;
- }
- return 0;
-}
-
-static void sim_end_cmd(void)
-{
- /* For write and sector/block erase, set WIP & clear WEN here */
- if (sim_state == sim_state_write_data) {
- sim_sr |= STAT_WIP;
- sim_sr &= ~STAT_WEN;
- }
- sim_state = sim_state_idle;
-}
-
-static bool sim_do_address(const uint8_t **buf, uint32_t *len)
-{
- uint8_t asize = sim_fl_4b ? 4 : 3;
- const uint8_t *p = *buf;
-
- while(*len) {
- sim_addr = (sim_addr << 8) | *(p++);
- *buf = p;
- *len = *len - 1;
- sim_index++;
- if (sim_index >= asize)
- return true;
- }
- return false;
-}
-
-static int sim_wbytes(const void *buf, uint32_t len)
-{
- const uint8_t *b = buf;
- bool addr_complete;
-
- again:
- switch(sim_state) {
- case sim_state_read_addr:
- addr_complete = sim_do_address(&b, &len);
- if (addr_complete) {
- sim_state = sim_state_read_data;
- sim_index = 0;
- if (len)
- goto again;
- }
- break;
- case sim_state_write_addr:
- addr_complete = sim_do_address(&b, &len);
- if (addr_complete) {
- sim_state = sim_state_write_data;
- sim_index = 0;
- if (len)
- goto again;
- }
- break;
- case sim_state_write_data:
- if (!(sim_sr & STAT_WEN))
- break;
- while(len--) {
- uint8_t c = *(b++);
- if (sim_addr >= sim_image_sz) {
- ERR("SIM: Write past end of flash\n");
- return -1;
- }
- /* Flash write only clears bits */
- sim_image[sim_addr] &= c;
- sim_addr = (sim_addr & 0xffffff00) |
- ((sim_addr + 1) & 0xff);
- }
- break;
- case sim_state_erase_addr:
- if (!(sim_sr & STAT_WEN))
- break;
- addr_complete = sim_do_address(&b, &len);
- if (addr_complete) {
- memset(sim_image + sim_addr, 0xff, sim_er_size);
- sim_sr |= STAT_WIP;
- sim_sr &= ~STAT_WEN;
- sim_state = sim_state_erase_done;
- }
- break;
- default:
- ERR("SIM: Write in wrong state %d\n", sim_state);
- return -1;
- }
- return 0;
-}
-
-static int sim_rbytes(void *buf, uint32_t len)
-{
- uint8_t *b = buf;
-
- switch(sim_state) {
- case sim_state_rdid:
- while(len--) {
- switch(sim_index) {
- case 0:
- *(b++) = 0x55;
- break;
- case 1:
- *(b++) = 0xaa;
- break;
- case 2:
- *(b++) = 0x55;
- break;
- default:
- ERR("SIM: RDID index %d\n", sim_index);
- *(b++) = 0;
- break;
- }
- sim_index++;
- }
- break;
- case sim_state_rdsr:
- while(len--) {
- *(b++) = sim_sr;
- if (sim_index > 0)
- ERR("SIM: RDSR index %d\n", sim_index);
- sim_index++;
-
- /* If WIP was 1, clear it, ie, simulate write/erase
- * completion
- */
- sim_sr &= ~STAT_WIP;
- }
- break;
- case sim_state_read_data:
- while(len--) {
- if (sim_addr >= sim_image_sz) {
- ERR("SIM: Read past end of flash\n");
- return -1;
- }
- *(b++) = sim_image[sim_addr++];
- }
- break;
- default:
- ERR("SIM: Read in wrong state %d\n", sim_state);
- return -1;
- }
- return 0;
-}
-
-static int sim_send_addr(uint32_t addr)
-{
- const void *ap;
-
- /* Layout address MSB first in memory */
- addr = cpu_to_be32(addr);
-
- /* Send the right amount of bytes */
- ap = (char *)&addr;
-
- if (sim_ct_4b)
- return sim_wbytes(ap, 4);
- else
- return sim_wbytes(ap + 1, 3);
-}
-
-static int sim_cmd_rd(struct spi_flash_ctrl *ctrl __unused, uint8_t cmd,
- bool has_addr, uint32_t addr, void *buffer,
- uint32_t size)
-{
- int rc;
-
- rc = sim_start_cmd(cmd);
- if (rc)
- goto bail;
- if (has_addr) {
- rc = sim_send_addr(addr);
- if (rc)
- goto bail;
- }
- if (buffer && size)
- rc = sim_rbytes(buffer, size);
- bail:
- sim_end_cmd();
- return rc;
-}
-
-static int sim_cmd_wr(struct spi_flash_ctrl *ctrl __unused, uint8_t cmd,
- bool has_addr, uint32_t addr, const void *buffer,
- uint32_t size)
-{
- int rc;
-
- rc = sim_start_cmd(cmd);
- if (rc)
- goto bail;
- if (has_addr) {
- rc = sim_send_addr(addr);
- if (rc)
- goto bail;
- }
- if (buffer && size)
- rc = sim_wbytes(buffer, size);
- bail:
- sim_end_cmd();
- return rc;
-}
-
-static int sim_set_4b(struct spi_flash_ctrl *ctrl __unused, bool enable)
-{
- sim_ct_4b = enable;
-
- return 0;
-}
-
-static int sim_read(struct spi_flash_ctrl *ctrl __unused, uint32_t pos,
- void *buf, uint32_t len)
-{
- if (sim_ct_4b != sim_fl_4b)
- ERR("SIM: 4b mode mismatch in autoread !\n");
- if ((pos + len) < pos)
- return -1;
- if ((pos + len) > sim_image_sz)
- return -1;
- memcpy(buf, sim_image + pos, len);
- return 0;
-};
-
-struct spi_flash_ctrl sim_ctrl = {
- .cmd_wr = sim_cmd_wr,
- .cmd_rd = sim_cmd_rd,
- .set_4b = sim_set_4b,
- .read = sim_read,
-};
-
-int main(void)
-{
- struct flash_chip *fl;
- uint32_t total_size, erase_granule;
- const char *name;
- uint16_t *test;
- int i, rc;
-
- sim_image = malloc(sim_image_sz);
- memset(sim_image, 0xff, sim_image_sz);
- test = malloc(0x10000 * 2);
-
- rc = flash_init(&sim_ctrl, &fl);
- if (rc) {
- ERR("flash_init failed with err %d\n", rc);
- exit(1);
- }
- rc = flash_get_info(fl, &name, &total_size, &erase_granule);
- if (rc) {
- ERR("flash_get_info failed with err %d\n", rc);
- exit(1);
- }
-
- /* Make up a test pattern */
- for (i=0; i<0x10000;i++)
- test[i] = cpu_to_be16(i);
-
- /* Write 64k of stuff at 0 and at 128k */
- printf("Writing test patterns...\n");
- flash_smart_write(fl, 0, test, 0x10000);
- flash_smart_write(fl, 0x20000, test, 0x10000);
-
- /* Write "Hello world" straddling the 64k boundary */
-#define HW "Hello World"
- printf("Writing test string...\n");
- flash_smart_write(fl, 0xfffc, HW, sizeof(HW));
-
- /* Check result */
- if (memcmp(sim_image + 0xfffc, HW, sizeof(HW))) {
- ERR("Test string mismatch !\n");
- exit(1);
- }
- printf("Test string pass\n");
- if (memcmp(sim_image, test, 0xfffc)) {
- ERR("Test pattern mismatch !\n");
- exit(1);
- }
- printf("Test pattern pass\n");
- flash_exit(fl);
-
- return 0;
-}
-
|