234 lines
10 KiB
C
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 */
|