diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-05-28 18:41:04 -0400 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-06-10 18:06:59 -0400 |
commit | 40a360c2a4feef97a8f7041e655b2a42e51e0224 (patch) | |
tree | 75dfea3064d7c3243788c72cb9f30e2ce6241dea /objects/pflash/libflash | |
parent | a73122191a7aba80f97332687a2e03cfb0336981 (diff) | |
download | talos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.tar.gz talos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.zip |
Reorganize directory structure
Moving to directory per-application layout. This facilitates
building single applications which is useful in the Yocto build
environment since different applications satisfy different OpenBMC
build requirements.
A number of issues are also addressed:
- All applications were pulling in libsystemd and the gdbus libs
irrespective of whether or not they were needed.
- gpio.o duplicated in every application - moved to libopenbmc_intf
- Added install target
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'objects/pflash/libflash')
-rw-r--r-- | objects/pflash/libflash/ffs.h | 144 | ||||
-rw-r--r-- | objects/pflash/libflash/libffs.c | 265 | ||||
-rw-r--r-- | objects/pflash/libflash/libffs.h | 41 | ||||
-rw-r--r-- | objects/pflash/libflash/libflash-priv.h | 217 | ||||
-rw-r--r-- | objects/pflash/libflash/libflash.c | 691 | ||||
-rw-r--r-- | objects/pflash/libflash/libflash.h | 69 | ||||
-rw-r--r-- | objects/pflash/libflash/test/Makefile | 2 | ||||
-rw-r--r-- | objects/pflash/libflash/test/test-flash.c | 403 |
8 files changed, 0 insertions, 1832 deletions
diff --git a/objects/pflash/libflash/ffs.h b/objects/pflash/libflash/ffs.h deleted file mode 100644 index 36b0b00..0000000 --- a/objects/pflash/libflash/ffs.h +++ /dev/null @@ -1,144 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/pnor/ffs.h $ */
-/* */
-/* IBM CONFIDENTIAL */
-/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2013 */
-/* */
-/* p1 */
-/* */
-/* Object Code Only (OCO) source materials */
-/* Licensed Internal Code Source Materials */
-/* IBM HostBoot Licensed Internal Code */
-/* */
-/* The source code for this program is not published or otherwise */
-/* divested of its trade secrets, irrespective of what has been */
-/* deposited with the U.S. Copyright Office. */
-/* */
-/* Origin: 30 */
-/* */
-/* IBM_PROLOG_END_TAG */
-/*
- * Copyright (c) International Business Machines Corp., 2012
- *
- * FSP Flash Structure
- *
- * This header defines the layout for the FSP Flash Structure.
- */
-
-#ifndef __FFS_H__
-#define __FFS_H__
-
-/* Pull in the correct header depending on what is being built */
-#if defined(__KERNEL__)
-#include <linux/types.h>
-#else
-#include <stdint.h>
-#endif
-
-/* The version of this partition implementation */
-#define FFS_VERSION_1 1
-
-/* Magic number for the partition header (ASCII 'PART') */
-#define FFS_MAGIC 0x50415254
-
-/* The maximum length of the partition name */
-#define PART_NAME_MAX 15
-
-/*
- * Sizes of the data structures
- */
-#define FFS_HDR_SIZE sizeof(struct ffs_hdr)
-#define FFS_ENTRY_SIZE sizeof(struct ffs_entry)
-
-/*
- * Sizes of the data structures w/o checksum
- */
-#define FFS_HDR_SIZE_CSUM (FFS_HDR_SIZE - sizeof(uint32_t))
-#define FFS_ENTRY_SIZE_CSUM (FFS_ENTRY_SIZE - sizeof(uint32_t))
-
-/* pid of logical partitions/containers */
-#define FFS_PID_TOPLEVEL 0xFFFFFFFF
-
-/*
- * Type of image contained w/in partition
- */
-enum type {
- FFS_TYPE_DATA = 1,
- FFS_TYPE_LOGICAL = 2,
- FFS_TYPE_PARTITION = 3,
-};
-
-/*
- * Flag bit definitions
- */
-#define FFS_FLAGS_PROTECTED 0x0001
-#define FFS_FLAGS_U_BOOT_ENV 0x0002
-
-/*
- * Number of user data words
- */
-#define FFS_USER_WORDS 16
-
-/**
- * struct ffs_entry - Partition entry
- *
- * @name: Opaque null terminated string
- * @base: Starting offset of partition in flash (in hdr.block_size)
- * @size: Partition size (in hdr.block_size)
- * @pid: Parent partition entry (FFS_PID_TOPLEVEL for toplevel)
- * @id: Partition entry ID [1..65536]
- * @type: Describe type of partition
- * @flags: Partition attributes (optional)
- * @actual: Actual partition size (in bytes)
- * @resvd: Reserved words for future use
- * @user: User data (optional)
- * @checksum: Partition entry checksum (includes all above)
- */
-struct ffs_entry {
- char name[PART_NAME_MAX + 1];
- uint32_t base;
- uint32_t size;
- uint32_t pid;
- uint32_t id;
- uint32_t type;
- uint32_t flags;
- uint32_t actual;
- uint32_t resvd[4];
- struct {
- uint32_t data[FFS_USER_WORDS];
- } user;
- uint32_t checksum;
-} __attribute__ ((packed));
-
-/**
- * struct ffs_hdr - FSP Flash Structure header
- *
- * @magic: Eye catcher/corruption detector
- * @version: Version of the structure
- * @size: Size of partition table (in block_size)
- * @entry_size: Size of struct ffs_entry element (in bytes)
- * @entry_count: Number of struct ffs_entry elements in @entries array
- * @block_size: Size of block on device (in bytes)
- * @block_count: Number of blocks on device
- * @resvd: Reserved words for future use
- * @checksum: Header checksum
- * @entries: Pointer to array of partition entries
- */
-struct ffs_hdr {
- uint32_t magic;
- uint32_t version;
- uint32_t size;
- uint32_t entry_size;
- uint32_t entry_count;
- uint32_t block_size;
- uint32_t block_count;
- uint32_t resvd[4];
- uint32_t checksum;
- struct ffs_entry entries[];
-} __attribute__ ((packed));
-
-
-#endif /* __FFS_H__ */
diff --git a/objects/pflash/libflash/libffs.c b/objects/pflash/libflash/libffs.c deleted file mode 100644 index db7104d..0000000 --- a/objects/pflash/libflash/libffs.c +++ /dev/null @@ -1,265 +0,0 @@ -/*
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <ccan/endian/endian.h>
-
-#include "libffs.h"
-
-enum ffs_type {
- ffs_type_flash,
- ffs_type_image,
-};
-
-struct ffs_handle {
- struct ffs_hdr hdr; /* Converted header */
- enum ffs_type type;
- struct flash_chip *chip;
- uint32_t flash_offset;
- uint32_t max_size;
- void *cache;
- uint32_t cached_size;
-};
-
-static uint32_t ffs_checksum(void* data, size_t size)
-{
- uint32_t i, csum = 0;
-
- for (i = csum = 0; i < (size/4); i++)
- csum ^= ((uint32_t *)data)[i];
- return csum;
-}
-
-static int ffs_check_convert_header(struct ffs_hdr *dst, struct ffs_hdr *src)
-{
- dst->magic = be32_to_cpu(src->magic);
- if (dst->magic != FFS_MAGIC)
- return FFS_ERR_BAD_MAGIC;
- dst->version = be32_to_cpu(src->version);
- if (dst->version != FFS_VERSION_1)
- return FFS_ERR_BAD_VERSION;
- if (ffs_checksum(src, FFS_HDR_SIZE) != 0)
- return FFS_ERR_BAD_CKSUM;
- dst->size = be32_to_cpu(src->size);
- dst->entry_size = be32_to_cpu(src->entry_size);
- dst->entry_count = be32_to_cpu(src->entry_count);
- dst->block_size = be32_to_cpu(src->block_size);
- dst->block_count = be32_to_cpu(src->block_count);
-
- return 0;
-}
-
-int ffs_open_flash(struct flash_chip *chip, uint32_t offset,
- uint32_t max_size, struct ffs_handle **ffs)
-{
- struct ffs_hdr hdr;
- struct ffs_handle *f;
- uint32_t fl_size, erase_size;
- int rc;
-
- if (!ffs)
- return FLASH_ERR_PARM_ERROR;
- *ffs = NULL;
-
- /* Grab some info about our flash chip */
- rc = flash_get_info(chip, NULL, &fl_size, &erase_size);
- if (rc) {
- FL_ERR("FFS: Error %d retrieving flash info\n", rc);
- return rc;
- }
- if ((offset + max_size) < offset)
- return FLASH_ERR_PARM_ERROR;
- if ((offset + max_size) > fl_size)
- return FLASH_ERR_PARM_ERROR;
-
- /* Read flash header */
- rc = flash_read(chip, offset, &hdr, sizeof(hdr));
- if (rc) {
- FL_ERR("FFS: Error %d reading flash header\n", rc);
- return rc;
- }
-
- /* Allocate ffs_handle structure and start populating */
- f = malloc(sizeof(*f));
- if (!f)
- return FLASH_ERR_MALLOC_FAILED;
- memset(f, 0, sizeof(*f));
- f->type = ffs_type_flash;
- f->flash_offset = offset;
- f->max_size = max_size ? max_size : (fl_size - offset);
- f->chip = chip;
-
- /* Convert and check flash header */
- rc = ffs_check_convert_header(&f->hdr, &hdr);
- if (rc) {
- FL_ERR("FFS: Error %d checking flash header\n", rc);
- free(f);
- return rc;
- }
-
- /*
- * Decide how much of the image to grab to get the whole
- * partition map.
- */
- f->cached_size = f->hdr.block_size * f->hdr.size;
- FL_DBG("FFS: Partition map size: 0x%x\n", f->cached_size);
-
- /* Align to erase size */
- f->cached_size |= (erase_size - 1);
- f->cached_size &= ~(erase_size - 1);
- FL_DBG("FFS: Aligned to: 0x%x\n", f->cached_size);
-
- /* Allocate cache */
- f->cache = malloc(f->cached_size);
- if (!f->cache) {
- free(f);
- return FLASH_ERR_MALLOC_FAILED;
- }
-
- /* Read the cached map */
- rc = flash_read(chip, offset, f->cache, f->cached_size);
- if (rc) {
- FL_ERR("FFS: Error %d reading flash partition map\n", rc);
- free(f);
- }
- if (rc == 0)
- *ffs = f;
- return rc;
-}
-
-#if 0 /* XXX TODO: For FW updates so we can copy nvram around */
-int ffs_open_image(void *image, uint32_t size, uint32_t offset,
- struct ffs_handle **ffs)
-{
-}
-#endif
-
-void ffs_close(struct ffs_handle *ffs)
-{
- if (ffs->cache)
- free(ffs->cache);
- free(ffs);
-}
-
-static struct ffs_entry *ffs_get_part(struct ffs_handle *ffs, uint32_t index,
- uint32_t *out_offset)
-{
- uint32_t esize = ffs->hdr.entry_size;
- uint32_t offset = FFS_HDR_SIZE + index * esize;
-
- if (index > ffs->hdr.entry_count)
- return NULL;
- if (out_offset)
- *out_offset = offset;
- return (struct ffs_entry *)(ffs->cache + offset);
-}
-
-static int ffs_check_convert_entry(struct ffs_entry *dst, struct ffs_entry *src)
-{
- if (ffs_checksum(src, FFS_ENTRY_SIZE) != 0)
- return FFS_ERR_BAD_CKSUM;
- memcpy(dst->name, src->name, sizeof(dst->name));
- dst->base = be32_to_cpu(src->base);
- dst->size = be32_to_cpu(src->size);
- dst->pid = be32_to_cpu(src->pid);
- dst->id = be32_to_cpu(src->id);
- dst->type = be32_to_cpu(src->type);
- dst->flags = be32_to_cpu(src->flags);
- dst->actual = be32_to_cpu(src->actual);
-
- return 0;
-}
-
-int ffs_lookup_part(struct ffs_handle *ffs, const char *name,
- uint32_t *part_idx)
-{
- struct ffs_entry ent;
- uint32_t i;
- int rc;
-
- /* Lookup the requested partition */
- for (i = 0; i < ffs->hdr.entry_count; i++) {
- struct ffs_entry *src_ent = ffs_get_part(ffs, i, NULL);
- rc = ffs_check_convert_entry(&ent, src_ent);
- if (rc) {
- FL_ERR("FFS: Bad entry %d in partition map\n", i);
- continue;
- }
- if (!strncmp(name, ent.name, sizeof(ent.name)))
- break;
- }
- if (i >= ffs->hdr.entry_count)
- return FFS_ERR_PART_NOT_FOUND;
- if (part_idx)
- *part_idx = i;
- return 0;
-}
-
-int ffs_part_info(struct ffs_handle *ffs, uint32_t part_idx,
- char **name, uint32_t *start,
- uint32_t *total_size, uint32_t *act_size)
-{
- struct ffs_entry *raw_ent;
- struct ffs_entry ent;
- char *n;
- int rc;
-
- if (part_idx >= ffs->hdr.entry_count)
- return FFS_ERR_PART_NOT_FOUND;
-
- raw_ent = ffs_get_part(ffs, part_idx, NULL);
- if (!raw_ent)
- return FFS_ERR_PART_NOT_FOUND;
-
- rc = ffs_check_convert_entry(&ent, raw_ent);
- if (rc) {
- FL_ERR("FFS: Bad entry %d in partition map\n", part_idx);
- return rc;
- }
- if (start)
- *start = ent.base * ffs->hdr.block_size;
- if (total_size)
- *total_size = ent.size * ffs->hdr.block_size;
- if (act_size)
- *act_size = ent.actual;
- if (name) {
- n = malloc(PART_NAME_MAX + 1);
- memset(n, 0, PART_NAME_MAX + 1);
- strncpy(n, ent.name, PART_NAME_MAX);
- *name = n;
- }
- return 0;
-}
-
-int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx,
- uint32_t act_size)
-{
- struct ffs_entry *ent;
- uint32_t offset;
-
- if (part_idx >= ffs->hdr.entry_count) {
- FL_DBG("FFS: Entry out of bound\n");
- return FFS_ERR_PART_NOT_FOUND;
- }
-
- ent = ffs_get_part(ffs, part_idx, &offset);
- if (!ent) {
- FL_DBG("FFS: Entry not found\n");
- return FFS_ERR_PART_NOT_FOUND;
- }
- FL_DBG("FFS: part index %d at offset 0x%08x\n",
- part_idx, offset);
-
- if (ent->actual == cpu_to_be32(act_size)) {
- FL_DBG("FFS: ent->actual alrady matches: 0x%08x==0x%08x\n",
- cpu_to_be32(act_size), ent->actual);
- return 0;
- }
- ent->actual = cpu_to_be32(act_size);
- ent->checksum = ffs_checksum(ent, FFS_ENTRY_SIZE_CSUM);
- if (!ffs->chip)
- return 0;
- return flash_smart_write(ffs->chip, offset, ent, FFS_ENTRY_SIZE);
-}
diff --git a/objects/pflash/libflash/libffs.h b/objects/pflash/libflash/libffs.h deleted file mode 100644 index 9853987..0000000 --- a/objects/pflash/libflash/libffs.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __LIBFFS_H
-#define __LIBFFS_H
-
-#include <libflash/libflash.h>
-#include <libflash/ffs.h>
-
-/* FFS handle, opaque */
-struct ffs_handle;
-
-/* Error codes:
- *
- * < 0 = flash controller errors
- * 0 = success
- * > 0 = libffs / libflash errors
- */
-#define FFS_ERR_BAD_MAGIC 100
-#define FFS_ERR_BAD_VERSION 101
-#define FFS_ERR_BAD_CKSUM 102
-#define FFS_ERR_PART_NOT_FOUND 103
-
-int ffs_open_flash(struct flash_chip *chip, uint32_t offset,
- uint32_t max_size, struct ffs_handle **ffs);
-
-/* TODO
-int ffs_open_image(void *image, uint32_t size, struct ffs_handle **ffs);
-*/
-
-void ffs_close(struct ffs_handle *ffs);
-
-int ffs_lookup_part(struct ffs_handle *ffs, const char *name,
- uint32_t *part_idx);
-
-int ffs_part_info(struct ffs_handle *ffs, uint32_t part_idx,
- char **name, uint32_t *start,
- uint32_t *total_size, uint32_t *act_size);
-
-int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx,
- uint32_t act_size);
-
-
-#endif /* __LIBFFS_H */
diff --git a/objects/pflash/libflash/libflash-priv.h b/objects/pflash/libflash/libflash-priv.h deleted file mode 100644 index cf40e2e..0000000 --- a/objects/pflash/libflash/libflash-priv.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef __LIBFLASH_PRIV_H
-#define __LIBFLASH_PRIV_H
-
-#include <ccan/endian/endian.h>
-#include <ccan/array_size/array_size.h>
-#include <ccan/container_of/container_of.h>
-
-/* Flash commands */
-#define CMD_WRSR 0x01 /* Write Status Register (also config. on Macronix) */
-#define CMD_PP 0x02 /* Page Program */
-#define CMD_READ 0x03 /* READ */
-#define CMD_WRDI 0x04 /* Write Disable */
-#define CMD_RDSR 0x05 /* Read Status Register */
-#define CMD_WREN 0x06 /* Write Enable */
-#define CMD_RDCR 0x15 /* Read configuration register (Macronix) */
-#define CMD_SE 0x20 /* Sector (4K) Erase */
-#define CMD_RDSCUR 0x2b /* Read Security Register (Macronix) */
-#define CMD_BE32K 0x52 /* Block (32K) Erase */
-#define CMD_RDSFDP 0x5a /* Read SFDP JEDEC info */
-#define CMD_CE 0x60 /* Chip Erase (Macronix/Winbond) */
-#define CMD_MIC_WREVCONF 0x61 /* Micron Write Enhanced Volatile Config */
-#define CMD_MIC_RDEVCONF 0x65 /* Micron Read Enhanced Volatile Config */
-#define CMD_MIC_RDFLST 0x70 /* Micron Read Flag Status */
-#define CMD_MIC_WRVCONF 0x81 /* Micron Write Volatile Config */
-#define CMD_MIC_RDVCONF 0x85 /* Micron Read Volatile Config */
-#define CMD_RDID 0x9f /* Read JEDEC ID */
-#define CMD_EN4B 0xb7 /* Enable 4B addresses */
-#define CMD_MIC_BULK_ERASE 0xc7 /* Micron Bulk Erase */
-#define CMD_BE 0xd8 /* Block (64K) Erase */
-#define CMD_RDDPB 0xe0 /* Read dynamic protection (Macronix) */
-#define CMD_RDSPB 0xe2 /* Read static protection (Macronix) */
-#define CMD_EX4B 0xe9 /* Exit 4B addresses */
-
-/* Flash status bits */
-#define STAT_WIP 0x01
-#define STAT_WEN 0x02
-
-/* This isn't exposed to clients but is to controllers */
-struct flash_info {
- uint32_t id;
- uint32_t size;
- uint32_t flags;
-#define FL_ERASE_4K 0x00000001 /* Supports 4k erase */
-#define FL_ERASE_32K 0x00000002 /* Supports 32k erase */
-#define FL_ERASE_64K 0x00000004 /* Supports 64k erase */
-#define FL_ERASE_CHIP 0x00000008 /* Supports 0x60 cmd chip erase */
-#define FL_ERASE_BULK 0x00000010 /* Supports 0xc7 cmd bulk erase */
-#define FL_MICRON_BUGS 0x00000020 /* Various micron bug workarounds */
-#define FL_ERASE_ALL (FL_ERASE_4K | FL_ERASE_32K | FL_ERASE_64K | \
- FL_ERASE_CHIP)
-#define FL_CAN_4B 0x00000010 /* Supports 4b mode */
- const char *name;
-};
-
-/* Flash controller, return negative values for errors */
-struct spi_flash_ctrl {
- /*
- * The controller can provide basically two interfaces,
- * either a fairly high level one and a lower level one.
- *
- * If all functions of the high level interface are
- * implemented then the low level one is optional. A
- * controller can implement some of the high level one
- * in which case the missing ones will be handled by
- * libflash using the low level interface.
- *
- * There are also some common functions.
- */
-
- /* **************************************************
- * Misc / common functions
- * **************************************************/
-
- /*
- * - setup(ctrl, tsize)
- *
- * Provides the controller with an option to configure itself
- * based on the specific flash type. It can also override some
- * settings in the info block such as available erase sizes etc...
- * which can be needed for high level controllers. It can also
- * override the total flash size.
- */
- int (*setup)(struct spi_flash_ctrl *ctrl, uint32_t *tsize);
-
- /*
- * - set_4b(ctrl, enable)
- *
- * enable : Switch to 4bytes (true) or 3bytes (false) address mode
- *
- * Set the controller's address size. If the controller doesn't
- * implement the low level command interface, then this must also
- * configure the flash chip itself. Otherwise, libflash will do it.
- *
- * Note that if this isn't implemented, then libflash might still
- * try to switch large flash chips to 4b mode if the low level cmd
- * interface is implemented. It will then also stop using the high
- * level command interface since it's assumed that it cannot handle
- * 4b addresses.
- */
- int (*set_4b)(struct spi_flash_ctrl *ctrl, bool enable);
-
-
-
- /* **************************************************
- * High level interface
- * **************************************************/
-
- /*
- * Read chip ID. This can return up to 16 bytes though the
- * current libflash will only use 3 (room for things like
- * extended micron stuff).
- *
- * id_size is set on entry to the buffer size and need to
- * be adjusted to the actual ID size read.
- *
- * If NULL, libflash will use cmd_rd to send normal RDID (0x9f)
- * command.
- */
- int (*chip_id)(struct spi_flash_ctrl *ctrl, uint8_t *id_buf,
- uint32_t *id_size);
-
- /*
- * Read from flash. There is no specific constraint on
- * alignment or size other than not reading outside of
- * the chip.
- *
- * If NULL, libflash will use cmd_rd to send normal
- * READ (0x03) commands.
- */
- int (*read)(struct spi_flash_ctrl *ctrl, uint32_t addr, void *buf,
- uint32_t size);
-
- /*
- * Write to flash. There is no specific constraint on
- * alignment or size other than not reading outside of
- * the chip. The driver is responsible for handling
- * 256-bytes page alignment and to send the write enable
- * commands when needed.
- *
- * If absent, libflash will use cmd_wr to send WREN (0x06)
- * and PP (0x02) commands.
- *
- * Note: This does not need to handle erasing. libflash
- * will ensure that this is never used for changing a bit
- * value from 0 to 1.
- */
- int (*write)(struct spi_flash_ctrl *ctrl, uint32_t addr,
- const void *buf, uint32_t size);
-
- /*
- * Erase. This will be called for erasing a portion of
- * the flash using a granularity (alignment of start and
- * size) that is no less than the smallest supported
- * erase size in the info block (*). The driver is
- * responsible to send write enable commands when needed.
- *
- * If absent, libflash will use cmd_wr to send WREN (0x06)
- * and either of SE (0x20), BE32K (0x52) or BE (0xd8)
- * based on what the flash chip supports.
- *
- * (*) Note: This is called with addr=0 and size=0xffffffff
- * in which case this is used as a "chip erase". Return
- * FLASH_ERR_CHIP_ER_NOT_SUPPORTED if not supported. Some
- * future version of libflash might then emulate it using
- * normal erase commands.
- */
- int (*erase)(struct spi_flash_ctrl *ctrl, uint32_t addr,
- uint32_t size);
-
- /* **************************************************
- * Low level interface
- * **************************************************/
-
- /* Note: For commands with no data, libflash will might use
- * either cmd_rd or cmd_wr.
- */
-
- /*
- * - cmd_rd(ctrl, cmd, has_addr, address, buffer, size);
- *
- * cmd : command opcode
- * has_addr : send an address after the command
- * address : address to send
- * buffer : buffer for additional data to read (or NULL)
- * size : size of additional data read (or NULL)
- *
- * Sends a command and optionally read additional data
- */
- int (*cmd_rd)(struct spi_flash_ctrl *ctrl, uint8_t cmd,
- bool has_addr, uint32_t addr, void *buffer,
- uint32_t size);
- /*
- * - cmd_wr(ctrl, cmd, has_addr, address, buffer, size);
- *
- * cmd : command opcode
- * has_addr : send an address after the command
- * address : address to send
- * buffer : buffer for additional data to write (or NULL)
- * size : size of additional data write (or NULL)
- *
- * Sends a command and optionally write additional data
- */
- int (*cmd_wr)(struct spi_flash_ctrl *ctrl, uint8_t cmd,
- bool has_addr, uint32_t addr, const void *buffer,
- uint32_t size);
-
- /* The core will establish this at init, after chip ID has
- * been probed
- */
- struct flash_info *finfo;
-};
-
-extern int fl_wren(struct spi_flash_ctrl *ct);
-extern int fl_read_stat(struct spi_flash_ctrl *ct, uint8_t *stat);
-extern int fl_sync_wait_idle(struct spi_flash_ctrl *ct);
-
-#endif /* LIBFLASH_PRIV_H */
diff --git a/objects/pflash/libflash/libflash.c b/objects/pflash/libflash/libflash.c deleted file mode 100644 index 762d9e7..0000000 --- a/objects/pflash/libflash/libflash.c +++ /dev/null @@ -1,691 +0,0 @@ -#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libflash.h"
-#include "libflash-priv.h"
-
-static const struct flash_info flash_info[] = {
- { 0xc22019, 0x02000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL25635F"},
- { 0xc2201a, 0x04000000, FL_ERASE_ALL | FL_CAN_4B, "Macronix MXxxL51235F"},
- { 0xef4018, 0x01000000, FL_ERASE_ALL, "Winbond W25Q128BV" },
- { 0xef4019, 0x02000000, FL_ERASE_ALL | FL_CAN_4B | FL_ERASE_64K|FL_ERASE_BULK, "Winbond W25Q256BV"},
- { 0x20ba20, 0x04000000, FL_ERASE_4K | FL_ERASE_64K | FL_CAN_4B |
- FL_ERASE_BULK | FL_MICRON_BUGS,
- "Micron N25Qx512Ax" },
- { 0x20ba19, 0x02000000, FL_ERASE_4K | FL_ERASE_64K | FL_CAN_4B |
- FL_ERASE_BULK | FL_MICRON_BUGS,
- "Micron N25Q256Ax" },
- { 0x1940ef, 0x02000000, FL_ERASE_4K | FL_ERASE_64K | FL_CAN_4B |
- FL_ERASE_BULK | FL_MICRON_BUGS,
- "Micron N25Qx256Ax" },
- { 0x55aa55, 0x00100000, FL_ERASE_ALL | FL_CAN_4B, "TEST_FLASH" },
-
-};
-
-struct flash_chip {
- struct spi_flash_ctrl *ctrl; /* Controller */
- struct flash_info info; /* Flash info */
- uint32_t tsize; /* Corrected flash size */
- uint32_t min_erase_mask; /* Minimum erase size */
- bool mode_4b; /* Flash currently in 4b mode */
- struct flash_req *cur_req; /* Current request */
- void *smart_buf; /* Buffer for smart writes */
-};
-
-bool libflash_debug;
-
-int fl_read_stat(struct spi_flash_ctrl *ct, uint8_t *stat)
-{
- return ct->cmd_rd(ct, CMD_RDSR, false, 0, stat, 1);
-}
-
-static void fl_micron_status(struct spi_flash_ctrl *ct)
-{
- uint8_t flst;
-
- /*
- * After a success status on a write or erase, we
- * need to do that command or some chip variants will
- * lock
- */
- ct->cmd_rd(ct, CMD_MIC_RDFLST, false, 0, &flst, 1);
-}
-
-/* Synchronous write completion, probably need a yield hook */
-int fl_sync_wait_idle(struct spi_flash_ctrl *ct)
-{
- uint8_t stat;
- int rc;
-
- /* XXX Add timeout */
- for (;;) {
- rc = fl_read_stat(ct, &stat);
- if (rc) return rc;
- if (!(stat & STAT_WIP)) {
- if (ct->finfo->flags & FL_MICRON_BUGS)
- fl_micron_status(ct);
- return 0;
- }
- }
- /* return FLASH_ERR_WIP_TIMEOUT; */
-}
-
-/* Exported for internal use */
-int fl_wren(struct spi_flash_ctrl *ct)
-{
- int i, rc;
- uint8_t stat;
-
- /* Some flashes need it to be hammered */
- for (i = 0; i < 1000; i++) {
- rc = ct->cmd_wr(ct, CMD_WREN, false, 0, NULL, 0);
- if (rc) return rc;
- rc = fl_read_stat(ct, &stat);
- if (rc) return rc;
- if (stat & STAT_WIP) {
- FL_ERR("LIBFLASH: WREN has WIP status set !\n");
- rc = fl_sync_wait_idle(ct);
- if (rc)
- return rc;
- continue;
- }
- if (stat & STAT_WEN)
- return 0;
- }
- return FLASH_ERR_WREN_TIMEOUT;
-}
-
-int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
-
- /* XXX Add sanity/bound checking */
-
- /*
- * If the controller supports read and either we are in 3b mode
- * or we are in 4b *and* the controller supports it, then do a
- * high level read.
- */
- if ((!c->mode_4b || ct->set_4b) && ct->read)
- return ct->read(ct, pos, buf, len);
-
- /* Otherwise, go manual if supported */
- if (!ct->cmd_rd)
- return FLASH_ERR_CTRL_CMD_UNSUPPORTED;
- return ct->cmd_rd(ct, CMD_READ, true, pos, buf, len);
-}
-
-static void fl_get_best_erase(struct flash_chip *c, uint32_t dst, uint32_t size,
- uint32_t *chunk, uint8_t *cmd)
-{
- /* Smaller than 32k, use 4k */
- if ((dst & 0x7fff) || (size < 0x8000)) {
- *chunk = 0x1000;
- *cmd = CMD_SE;
- return;
- }
- /* Smaller than 64k and 32k is supported, use it */
- if ((c->info.flags & FL_ERASE_32K) &&
- ((dst & 0xffff) || (size < 0x10000))) {
- *chunk = 0x8000;
- *cmd = CMD_BE32K;
- return;
- }
- /* If 64K is not supported, use whatever smaller size is */
- if (!(c->info.flags & FL_ERASE_64K)) {
- if (c->info.flags & FL_ERASE_32K) {
- *chunk = 0x8000;
- *cmd = CMD_BE32K;
- } else {
- *chunk = 0x1000;
- *cmd = CMD_SE;
- }
- return;
- }
- /* Allright, let's go for 64K */
- *chunk = 0x10000;
- *cmd = CMD_BE;
-}
-
-int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- uint32_t chunk;
- uint8_t cmd;
- int rc;
-
- /* Some sanity checking */
- if (((dst + size) <= dst) || !size || (dst + size) > c->tsize)
- return FLASH_ERR_PARM_ERROR;
-
- /* Check boundaries fit erase blocks */
- if ((dst | size) & c->min_erase_mask)
- return FLASH_ERR_ERASE_BOUNDARY;
-
- FL_DBG("LIBFLASH: Erasing 0x%08x..0%08x...\n", dst, dst + size);
-
- /* Use controller erase if supported */
- if (ct->erase)
- return ct->erase(ct, dst, size);
-
- /* Allright, loop as long as there's something to erase */
- while(size) {
- /* How big can we make it based on alignent & size */
- fl_get_best_erase(c, dst, size, &chunk, &cmd);
-
- /* Poke write enable */
- rc = fl_wren(ct);
- if (rc)
- return rc;
-
- /* Send erase command */
- rc = ct->cmd_wr(ct, cmd, true, dst, NULL, 0);
- if (rc)
- return rc;
-
- /* Wait for write complete */
- rc = fl_sync_wait_idle(ct);
- if (rc)
- return rc;
-
- size -= chunk;
- dst += chunk;
- }
- return 0;
-}
-
-int flash_erase_chip(struct flash_chip *c)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- int rc;
-
- /* XXX TODO: Fallback to using normal erases */
- if (!(c->info.flags & (FL_ERASE_CHIP|FL_ERASE_BULK)))
- return FLASH_ERR_CHIP_ER_NOT_SUPPORTED;
-
- FL_DBG("LIBFLASH: Erasing chip...\n");
-
- /* Use controller erase if supported */
- if (ct->erase)
- return ct->erase(ct, 0, 0xffffffff);
-
- rc = fl_wren(ct);
- if (rc) return rc;
-
- if (c->info.flags & FL_ERASE_CHIP)
- rc = ct->cmd_wr(ct, CMD_CE, false, 0, NULL, 0);
- else
- rc = ct->cmd_wr(ct, CMD_MIC_BULK_ERASE, false, 0, NULL, 0);
- if (rc)
- return rc;
-
- /* Wait for write complete */
- return fl_sync_wait_idle(ct);
-}
-
-static int fl_wpage(struct flash_chip *c, uint32_t dst, const void *src,
- uint32_t size)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- int rc;
-
- if (size < 1 || size > 0x100)
- return FLASH_ERR_BAD_PAGE_SIZE;
-
- rc = fl_wren(ct);
- if (rc) return rc;
-
- rc = ct->cmd_wr(ct, CMD_PP, true, dst, src, size);
- if (rc)
- return rc;
-
- /* Wait for write complete */
- return fl_sync_wait_idle(ct);
-}
-
-int flash_write(struct flash_chip *c, uint32_t dst, const void *src,
- uint32_t size, bool verify)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- uint32_t todo = size;
- uint32_t d = dst;
- const void *s = src;
- uint8_t vbuf[0x100];
- int rc;
-
- /* Some sanity checking */
- if (((dst + size) <= dst) || !size || (dst + size) > c->tsize)
- return FLASH_ERR_PARM_ERROR;
-
- FL_DBG("LIBFLASH: Writing to 0x%08x..0%08x...\n", dst, dst + size);
-
- /*
- * If the controller supports write and either we are in 3b mode
- * or we are in 4b *and* the controller supports it, then do a
- * high level write.
- */
- if ((!c->mode_4b || ct->set_4b) && ct->write) {
- rc = ct->write(ct, dst, src, size);
- if (rc)
- return rc;
- goto writing_done;
- }
-
- /* Otherwise, go manual if supported */
- if (!ct->cmd_wr)
- return FLASH_ERR_CTRL_CMD_UNSUPPORTED;
-
- /* Iterate for each page to write */
- while(todo) {
- uint32_t chunk;
-
- /* Handle misaligned start */
- chunk = 0x100 - (d & 0xff);
- if (chunk > 0x100)
- chunk = 0x100;
- if (chunk > todo)
- chunk = todo;
-
- rc = fl_wpage(c, d, s, chunk);
- if (rc) return rc;
- d += chunk;
- s += chunk;
- todo -= chunk;
- }
-
- writing_done:
- if (!verify)
- return 0;
-
- /* Verify */
- FL_DBG("LIBFLASH: Verifying...\n");
-
- while(size) {
- uint32_t chunk;
-
- chunk = sizeof(vbuf);
- if (chunk > size)
- chunk = size;
- rc = flash_read(c, dst, vbuf, chunk);
- if (rc) return rc;
- if (memcmp(vbuf, src, chunk)) {
- FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst);
- return FLASH_ERR_VERIFY_FAILURE;
- }
- dst += chunk;
- src += chunk;
- size -= chunk;
- }
- return 0;
-}
-
-enum sm_comp_res {
- sm_no_change,
- sm_need_write,
- sm_need_erase,
-};
-
-static enum sm_comp_res flash_smart_comp(struct flash_chip *c,
- const void *src,
- uint32_t offset, uint32_t size)
-{
- uint8_t *b = c->smart_buf + offset;
- const uint8_t *s = src;
- bool is_same = true;
- uint32_t i;
-
- /* SRC DEST NEED_ERASE
- * 0 1 0
- * 1 1 0
- * 0 0 0
- * 1 0 1
- */
- for (i = 0; i < size; i++) {
- /* Any bit need to be set, need erase */
- if (s[i] & ~b[i])
- return sm_need_erase;
- if (is_same && (b[i] != s[i]))
- is_same = false;
- }
- return is_same ? sm_no_change : sm_need_write;
-}
-
-int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
- uint32_t size)
-{
- uint32_t er_size = c->min_erase_mask + 1;
- uint32_t end = dst + size;
- int rc;
-
- /* Some sanity checking */
- if (end <= dst || !size || end > c->tsize) {
- FL_DBG("LIBFLASH: Smart write param error\n");
- return FLASH_ERR_PARM_ERROR;
- }
-
- FL_DBG("LIBFLASH: Smart writing to 0x%08x..0%08x...\n",
- dst, dst + size);
-
- /* As long as we have something to write ... */
- while(dst < end) {
- uint32_t page, off, chunk;
- enum sm_comp_res sr;
-
- /* Figure out which erase page we are in and read it */
- page = dst & ~c->min_erase_mask;
- off = dst & c->min_erase_mask;
- FL_DBG("LIBFLASH: reading page 0x%08x..0x%08x...",
- page, page + er_size);
- rc = flash_read(c, page, c->smart_buf, er_size);
- if (rc) {
- FL_DBG(" error %d!\n", rc);
- return rc;
- }
-
- /* Locate the chunk of data we are working on */
- chunk = er_size - off;
- if (size < chunk)
- chunk = size;
-
- /* Compare against what we are writing and ff */
- sr = flash_smart_comp(c, src, off, chunk);
- switch(sr) {
- case sm_no_change:
- /* Identical, skip it */
- FL_DBG(" same !\n");
- break;
- case sm_need_write:
- /* Just needs writing over */
- FL_DBG(" need write !\n");
- rc = flash_write(c, dst, src, chunk, true);
- if (rc) {
- FL_DBG("LIBFLASH: Write error %d !\n", rc);
- return rc;
- }
- break;
- case sm_need_erase:
- FL_DBG(" need erase !\n");
- rc = flash_erase(c, page, er_size);
- if (rc) {
- FL_DBG("LIBFLASH: erase error %d !\n", rc);
- return rc;
- }
- /* Then update the portion of the buffer and write the block */
- memcpy(c->smart_buf + off, src, chunk);
- rc = flash_write(c, page, c->smart_buf, er_size, true);
- if (rc) {
- FL_DBG("LIBFLASH: write error %d !\n", rc);
- return rc;
- }
- break;
- }
- dst += chunk;
- src += chunk;
- size -= chunk;
- }
- return 0;
-}
-
-static int fl_chip_id(struct spi_flash_ctrl *ct, uint8_t *id_buf,
- uint32_t *id_size)
-{
- int rc;
- uint8_t stat;
-
- /* Check initial status */
- rc = fl_read_stat(ct, &stat);
- if (rc)
- return rc;
-
- /* If stuck writing, wait for idle */
- if (stat & STAT_WIP) {
- FL_ERR("LIBFLASH: Flash in writing state ! Waiting...\n");
- rc = fl_sync_wait_idle(ct);
- if (rc)
- return rc;
- } else
- FL_DBG("LIBFLASH: Init status: %02x\n", stat);
-
- /* Fallback to get ID manually */
- rc = ct->cmd_rd(ct, CMD_RDID, false, 0, id_buf, 3);
- if (rc)
- return rc;
- *id_size = 3;
-
- return 0;
-}
-
-static int flash_identify(struct flash_chip *c)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- const struct flash_info *info;
- uint32_t iid, id_size;
-#define MAX_ID_SIZE 16
- uint8_t id[MAX_ID_SIZE];
- int rc, i;
-
- if (ct->chip_id) {
- /* High level controller interface */
- id_size = MAX_ID_SIZE;
- rc = ct->chip_id(ct, id, &id_size);
- } else
- rc = fl_chip_id(ct, id, &id_size);
- if (rc)
- return rc;
- if (id_size < 3)
- return FLASH_ERR_CHIP_UNKNOWN;
-
- /* Convert to a dword for lookup */
- iid = id[0];
- iid = (iid << 8) | id[1];
- iid = (iid << 8) | id[2];
-
- FL_DBG("LIBFLASH: Flash ID: %02x.%02x.%02x (%06x)\n",
- id[0], id[1], id[2], iid);
-
- /* Lookup in flash_info */
- for (i = 0; i < ARRAY_SIZE(flash_info); i++) {
- info = &flash_info[i];
- if (info->id == iid)
- break;
- }
- if (info->id != iid)
- return FLASH_ERR_CHIP_UNKNOWN;
-
- c->info = *info;
- c->tsize = info->size;
- ct->finfo = &c->info;
-
- /*
- * Let controller know about our settings and possibly
- * override them
- */
- if (ct->setup) {
- rc = ct->setup(ct, &c->tsize);
- if (rc)
- return rc;
- }
-
- /* Calculate min erase granularity */
- if (c->info.flags & FL_ERASE_4K)
- c->min_erase_mask = 0xfff;
- else if (c->info.flags & FL_ERASE_32K)
- c->min_erase_mask = 0x7fff;
- else if (c->info.flags & FL_ERASE_64K)
- c->min_erase_mask = 0xffff;
- else {
- /* No erase size ? oops ... */
- FL_ERR("LIBFLASH: No erase sizes !\n");
- return FLASH_ERR_CTRL_CONFIG_MISMATCH;
- }
-
- FL_DBG("LIBFLASH: Found chip %s size %dM erase granule: %dK\n",
- c->info.name, c->tsize >> 20, (c->min_erase_mask + 1) >> 10);
-
- return 0;
-}
-
-static int flash_set_4b(struct flash_chip *c, bool enable)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- int rc;
-
- /* Some flash chips want this */
- rc = fl_wren(ct);
- if (rc) {
- FL_ERR("LIBFLASH: Error %d enabling write for set_4b\n", rc);
- /* Ignore the error & move on (could be wrprotect chip) */
- }
-
- /* Ignore error in case chip is write protected */
-
- return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, 0);
-}
-
-int flash_force_4b_mode(struct flash_chip *c, bool enable_4b)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- int rc;
-
- /*
- * We only allow force 4b if both controller and flash do 4b
- * as this is mainly used if a 3rd party tries to directly
- * access a direct mapped read region
- */
- if (enable_4b && !((c->info.flags & FL_CAN_4B) && ct->set_4b))
- return FLASH_ERR_4B_NOT_SUPPORTED;
-
- /* Only send to flash directly on controllers that implement
- * the low level callbacks
- */
- if (ct->cmd_wr) {
- rc = flash_set_4b(c, enable_4b);
- if (rc)
- return rc;
- }
-
- /* Then inform the controller */
- if (ct->set_4b)
- rc = ct->set_4b(ct, enable_4b);
- return rc;
-}
-
-static int flash_configure(struct flash_chip *c)
-{
- struct spi_flash_ctrl *ct = c->ctrl;
- int rc;
-
- /* Crop flash size if necessary */
- if (c->tsize > 0x01000000 && !(c->info.flags & FL_CAN_4B)) {
- FL_ERR("LIBFLASH: Flash chip cropped to 16M, no 4b mode\n");
- c->tsize = 0x01000000;
- }
-
- /* If flash chip > 16M, enable 4b mode */
- if (c->tsize > 0x01000000) {
- FL_DBG("LIBFLASH: Flash >16MB, enabling 4B mode...\n");
-
- /* Set flash to 4b mode if we can */
- if (ct->cmd_wr) {
- rc = flash_set_4b(c, true);
- if (rc) {
- FL_ERR("LIBFLASH: Failed to set flash 4b mode\n");
- return rc;
- }
- }
-
-
- /* Set controller to 4b mode if supported */
- if (ct->set_4b) {
- FL_DBG("LIBFLASH: Enabling controller 4B mode...\n");
- rc = ct->set_4b(ct, true);
- if (rc) {
- FL_ERR("LIBFLASH: Failed"
- " to set controller 4b mode\n");
- return rc;
- }
- }
- } else {
- FL_DBG("LIBFLASH: Flash <=16MB, disabling 4B mode...\n");
-
- /*
- * If flash chip supports 4b mode, make sure we disable
- * it in case it was left over by the previous user
- */
- if (c->info.flags & FL_CAN_4B) {
- rc = flash_set_4b(c, false);
- if (rc) {
- FL_ERR("LIBFLASH: Failed to"
- " clear flash 4b mode\n");
- return rc;
- }
- }
-
- /* Set controller to 3b mode if mode switch is supported */
- if (ct->set_4b) {
- FL_DBG("LIBFLASH: Disabling controller 4B mode...\n");
- rc = ct->set_4b(ct, false);
- if (rc) {
- FL_ERR("LIBFLASH: Failed to"
- " clear controller 4b mode\n");
- return rc;
- }
- }
- }
- return 0;
-}
-
-int flash_get_info(struct flash_chip *chip, const char **name,
- uint32_t *total_size, uint32_t *erase_granule)
-{
- if (name)
- *name = chip->info.name;
- if (total_size)
- *total_size = chip->tsize;
- if (erase_granule)
- *erase_granule = chip->min_erase_mask + 1;
- return 0;
-}
-
-int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash)
-{
- struct flash_chip *c;
- int rc;
-
- *flash = NULL;
- c = malloc(sizeof(struct flash_chip));
- if (!c)
- return FLASH_ERR_MALLOC_FAILED;
- memset(c, 0, sizeof(*c));
- c->ctrl = ctrl;
-
- rc = flash_identify(c);
- if (rc) {
- FL_ERR("LIBFLASH: Flash identification failed\n");
- goto bail;
- }
- c->smart_buf = malloc(c->min_erase_mask + 1);
- if (!c->smart_buf) {
- FL_ERR("LIBFLASH: Failed to allocate smart buffer !\n");
- rc = FLASH_ERR_MALLOC_FAILED;
- goto bail;
- }
- rc = flash_configure(c);
- if (rc)
- FL_ERR("LIBFLASH: Flash configuration failed\n");
- bail:
- if (rc) {
- free(c);
- return rc;
- }
- *flash = c;
- return 0;
-}
-
-void flash_exit(struct flash_chip *chip)
-{
- /* XXX Make sure we are idle etc... */
- free(chip);
-}
-
diff --git a/objects/pflash/libflash/libflash.h b/objects/pflash/libflash/libflash.h deleted file mode 100644 index a341c54..0000000 --- a/objects/pflash/libflash/libflash.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __LIBFLASH_H
-#define __LIBFLASH_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#ifndef FL_INF
-#define FL_INF(fmt...) do { printf(fmt); } while(0)
-#endif
-
-#ifndef FL_DBG
-#define FL_DBG(fmt...) do { if (libflash_debug) printf(fmt); } while(0)
-#endif
-
-#ifndef FL_ERR
-#define FL_ERR(fmt...) do { printf(fmt); } while(0)
-#endif
-
-extern bool libflash_debug;
-
-/* API status/return:
- *
- * <0 = flash controller errors passed through,
- * 0 = success
- * >0 = libflash error
- */
-
-#define FLASH_ERR_MALLOC_FAILED 1
-#define FLASH_ERR_CHIP_UNKNOWN 2
-#define FLASH_ERR_PARM_ERROR 3
-#define FLASH_ERR_ERASE_BOUNDARY 4
-#define FLASH_ERR_WREN_TIMEOUT 5
-#define FLASH_ERR_WIP_TIMEOUT 6
-#define FLASH_ERR_BAD_PAGE_SIZE 7
-#define FLASH_ERR_VERIFY_FAILURE 8
-#define FLASH_ERR_4B_NOT_SUPPORTED 9
-#define FLASH_ERR_CTRL_CONFIG_MISMATCH 10
-#define FLASH_ERR_CHIP_ER_NOT_SUPPORTED 11
-#define FLASH_ERR_CTRL_CMD_UNSUPPORTED 12
-#define FLASH_ERR_CTRL_TIMEOUT 13
-
-/* Flash chip, opaque */
-struct flash_chip;
-struct spi_flash_ctrl;
-
-int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash);
-void flash_exit(struct flash_chip *chip);
-
-int flash_get_info(struct flash_chip *chip, const char **name,
- uint32_t *total_size, uint32_t *erase_granule);
-
-/* libflash sets the 4b mode automatically based on the flash
- * size and controller capabilities but it can be overriden
- */
-int flash_force_4b_mode(struct flash_chip *chip, bool enable_4b);
-
-int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len);
-int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size);
-int flash_write(struct flash_chip *c, uint32_t dst, const void *src,
- uint32_t size, bool verify);
-int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
- uint32_t size);
-
-/* chip erase may not be supported by all chips/controllers, get ready
- * for FLASH_ERR_CHIP_ER_NOT_SUPPORTED
- */
-int flash_erase_chip(struct flash_chip *c);
-
-#endif /* __LIBFLASH_H */
diff --git a/objects/pflash/libflash/test/Makefile b/objects/pflash/libflash/test/Makefile deleted file mode 100644 index e357e20..0000000 --- a/objects/pflash/libflash/test/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -test_flash: test-flash.c - $(CC) -o $@ $^ -Wall -I../../ -include ../../config.h 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;
-}
-
|