iBoot/drivers/flash_nand/boot/nand_part_interface.h

234 lines
10 KiB
C

/*
* Copyright (c) 2010-2012 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
/* ========================================================================== */
/*!
@header nand_part_interface
@abstract portable core for (mostly boot-related) nand partitioning logic
@copyright Apple Inc.
@updated 2012-02-21
*/
/* ========================================================================== */
#ifndef _NAND_PART_INTERFACE_H
#define _NAND_PART_INTERFACE_H
__BEGIN_DECLS
/* ========================================================================== */
// disable significant amounts of the logging for tiny build profile
#if (defined(WITH_NAND_PART_BUILD_TINY) && WITH_NAND_PART_BUILD_TINY)
# define NAND_PART_EXTENDED_LOGGING 0
#else
# define NAND_PART_EXTENDED_LOGGING 1
#endif
// enable for local development only; DO NOT SUBMIT with this enabled to trunk
#define NAND_PART_LOCAL_DEBUG_ONLY 0
/* ========================================================================== */
/* property keys */
#define kNandPartCoreVersionMajorKey "VersionMajor"
#define kNandPartCoreVersionMinorKey "VersionMinor"
#define kNandPartCoreGenerationKey "Generation"
#define kNandPartCoreIsFormattedKey "isFormatted"
#define kNandPartCoreIsNewbornKey "isNewborn"
#define kNandPartCoreIsRebornKey "isReborn"
#define kNandPartCoreMaxSparesKey "maxSpares"
/* ========================================================================== */
enum _NandPartLogLevel {
kNandPartLogLevelAlways = 0,
kNandPartLogLevelBug = 1,
kNandPartLogLevelError = 2,
kNandPartLogLevelInfo = 3,
kNandPartLogLevelWarn = 4,
kNandPartLogLevelDebug = 5,
kNandPartLogLevelSpew = 6,
kNandPartLogLevelNever
};
typedef enum _NandPartLogLevel NandPartLogLevel;
extern const char * kNandPartLogTagBug;
extern const char * kNandPartLogTagError;
extern const char * kNandPartLogTagInfo;
extern const char * kNandPartLogTagWarn;
extern const char * kNandPartLogTagDebug;
extern const char * kNandPartLogTagSpew;
/* ========================================================================== */
struct _NandPartGeometry {
bool isPpn;
uint32_t ceCount;
uint32_t blocksPerCE;
uint32_t blockStride;
uint32_t pagesPerMLCBlock;
uint32_t pagesPerSLCBlock;
uint32_t bytesPerBootPage;
uint32_t bytesPerFullPage;
uint32_t bytesPerFullPageMeta;
uint32_t bitsPerCauAddr;
uint32_t bitsPerPageAddr;
uint32_t bitsPerBlockAddr;
};
typedef struct _NandPartGeometry NandPartGeometry;
/* ========================================================================== */
struct _NandPartSpec {
uint32_t type;
uint32_t content;
uint32_t depth;
uint32_t width;
uint32_t flags;
};
typedef struct _NandPartSpec NandPartSpec;
/* ========================================================================== */
struct _NandPartParams {
bool isBootPartErasable;
bool isBootPartWritable;
bool isFormatEnabled;
bool isDebugEnabled;
bool isHostTraceEnabled;
bool isClientTraceEnabled;
bool isPoolAllowed;
uint32_t maxMajorVersion;
NandPartSpec partitionSpecs[kNandPartEntryMaxCount];
};
typedef struct _NandPartParams NandPartParams;
/* ========================================================================== */
struct _NandPartProvider {
void * context;
NandPartGeometry geometry;
NandPartParams params;
void (*lock_interface)(void * context);
void (*unlock_interface)(void * context);
void * (*alloc_mem)(void * context, unsigned size, bool align);
int (*compare_mem)(void * context, const void * left, const void * right, unsigned int size);
void * (*move_mem)(void * context, void * dest, const void * src, unsigned size);
void * (*set_mem)(void * context, void * mem, uint8_t val, unsigned size);
void (*free_mem)(void * context, void * mem, unsigned size);
void (*read_random)(void * context, void * buf, unsigned size);
bool (*read_boot_page)(void * context, uint32_t ce, uint32_t addr, void * buf, bool * is_clean);
bool (*read_full_page)(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta, bool * is_clean);
bool (*write_boot_page)(void * context, uint32_t ce, uint32_t addr, void * buf);
bool (*write_full_page)(void * context, uint32_t ce, uint32_t addr, void * buf, void * meta);
bool (*erase_block)(void * context, uint32_t ce, uint32_t addr, uint32_t block);
bool (*is_block_factory_bad)(void * context, uint32_t ce, uint32_t block);
bool (*validate_spare_list)(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count);
bool (*request_spare_blocks)(void * context, uint32_t * ce_list, uint32_t * block_list, unsigned count, unsigned * quantity);
bool (*set_data_property)(void * context, const char * key, void * buf, unsigned size);
bool (*set_number_property)(void * context, const char * key, uint64_t num, unsigned bits);
bool (*set_string_property)(void * context, const char * key, const char * cstring);
bool (*set_boolean_property)(void * context, const char * key, bool val);
bool (*wait_for_fbbt_service)(void * context);
bool (*create_partition_device)(void * context, NandPartEntry * entry, uint32_t idx);
bool (*publish_partition_device)(void * context, uint32_t idx);
void (*vlogf_message)(void * context, NandPartLogLevel lvl, const char * fmt, va_list ap);
};
typedef struct _NandPartProvider NandPartProvider;
/* ========================================================================== */
struct _NandPartInterface {
void * core;
bool (*load_ptab)(void * core);
bool (*erase_boot_partition)(void * core);
bool (*write_boot_partition)(void * core, void * llbBuf, unsigned llbSize);
bool (*is_block_bad)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock);
const NandPartEntry * (*get_entry)(void * core, uint32_t partIndex);
uint32_t (*get_bank_width)(void * core, uint32_t partIndex);
uint32_t (*get_block_depth)(void * core, uint32_t partIndex);
uint32_t (*get_pages_per_block)(void * core, uint32_t partIndex);
uint32_t (*get_bytes_per_page)(void * core, uint32_t partIndex);
bool (*read_page)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf, bool * isClean);
bool (*write_page)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock, uint32_t pageInBlock, void * buf);
bool (*erase_block)(void * core, uint32_t partIndex, uint32_t partBank, uint32_t partBlock);
bool (*request_ptab_diff)(void * core, uint32_t partIndex, void * buf, unsigned size);
bool (*provide_ptab_diff)(void * core, uint32_t partIndex, const void * buf, unsigned size);
bool (*format_ptab)(void * core);
unsigned (*get_ptab_bytes)(void * core, void * buf, unsigned size);
};
typedef struct _NandPartInterface NandPartInterface;
#define _npiExec(npi, fn, args...) npi->fn(npi->core, ##args)
#define npi_load_ptab(npi) _npiExec(npi, load_ptab)
#define npi_erase_boot_partition(npi) _npiExec(npi, erase_boot_partition)
#define npi_write_boot_partition(npi, buf, size) _npiExec(npi, write_boot_partition, buf, size)
#define npi_is_block_bad(npi, part, bank, block) _npiExec(npi, is_block_bad, part, bank, block)
#define npi_get_entry(npi, part) _npiExec(npi, get_entry, part)
#define npi_get_bank_width(npi, part) _npiExec(npi, get_bank_width, part)
#define npi_get_block_depth(npi, part) _npiExec(npi, get_block_depth, part)
#define npi_get_pages_per_block(npi, part) _npiExec(npi, get_pages_per_block, part)
#define npi_get_bytes_per_page(npi, part) _npiExec(npi, get_bytes_per_page, part)
#define npi_read_page(npi, part, bank, block, page, buf, clean) _npiExec(npi, read_page, part, bank, block, page, buf, clean)
#define npi_write_page(npi, part, bank, block, page, buf) _npiExec(npi, write_page, part, bank, block, page, buf)
#define npi_erase_block(npi, part, bank, block) _npiExec(npi, erase_block, part, bank, block)
#define npi_request_ptab_diff(npi, part, buf, size) _npiExec(npi, request_ptab_diff, part, buf, size)
#define npi_provide_ptab_diff(npi, part, buf, size) _npiExec(npi, provide_ptab_diff, part, buf, size)
#define npi_format_ptab(npi) _npiExec(npi, format_ptab)
#define npi_get_ptab_bytes(npi, buf, size) _npiExec(npi, get_ptab_bytes, buf, size)
/* ========================================================================== */
extern bool nand_part_init(NandPartInterface ** interface, NandPartProvider * provider);
extern void nand_part_dump(NandPartInterface * interface);
/* ========================================================================== */
__END_DECLS
#endif /* _NAND_PART_INTERFACE_H */