iBoot/drivers/flash_nand/boot/nand_part.h

426 lines
17 KiB
C
Raw Permalink Normal View History

2023-07-08 13:03:17 -07:00
/*
* Copyright (c) 2008-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
@abstract definition of device-resident persistent partition table
@copyright Apple Inc.
@updated 2012-02-21
*/
/* ========================================================================== */
#ifndef _NAND_PART_H
#define _NAND_PART_H
#include <sys/types.h>
__BEGIN_DECLS
// =============================================================================
// feature introduction version history
#define kNandPartFeatureInitialVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeatureFBBTCacheVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeatureEffaceableVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeatureIgnoreFBBTVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeatureTrimDeviceVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeatureFuneralDirgeVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeatureCleanEntryFlagsVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeaturePortableCoreVersionMajor ((uint32_t)0x00000000)
#define kNandPartFeaturePoolPartitionVersionMajor ((uint32_t)0x00000001)
#define kNandPartFeatureInitialVersionMinor ((uint32_t)0x00000001)
#define kNandPartFeatureFBBTCacheVersionMinor ((uint32_t)0x00000002)
#define kNandPartFeatureEffaceableVersionMinor ((uint32_t)0x00000003)
#define kNandPartFeatureIgnoreFBBTVersionMinor ((uint32_t)0x00000004)
#define kNandPartFeatureTrimDeviceVersionMinor ((uint32_t)0x00000005)
#define kNandPartFeatureFuneralDirgeVersionMinor ((uint32_t)0x00000006)
#define kNandPartFeatureCleanEntryFlagsVersionMinor ((uint32_t)0x00000007)
#define kNandPartFeaturePortableCoreVersionMinor ((uint32_t)0x00000008)
#define kNandPartFeaturePoolPartitionVersionMinor ((uint32_t)0x00000009)
// =============================================================================
// release version history - for historical reference only
#define kNandPartReleaseNorthstarVersionMajor kNandPartFeatureFBBTCacheVersionMajor
#define kNandPartReleaseNorthstarVersionMinor kNandPartFeatureFBBTCacheVersionMinor
#define kNandPartReleaseNorthstar2VersionMajor kNandPartFeatureFBBTCacheVersionMajor
#define kNandPartReleaseNorthstar2VersionMinor kNandPartFeatureFBBTCacheVersionMinor
#define kNandPartReleaseApexVersionMajor kNandPartFeatureIgnoreFBBTVersionMajor
#define kNandPartReleaseApexVersionMinor kNandPartFeatureIgnoreFBBTVersionMinor
#define kNandPartReleaseBakerVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
#define kNandPartReleaseBakerVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
#define kNandPartReleaseDurangoVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
#define kNandPartReleaseDurangoVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
#define kNandPartReleaseTellurideVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
#define kNandPartReleaseTellurideVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
#define kNandPartReleaseHoodooVersionMajor kNandPartFeatureFuneralDirgeVersionMajor
#define kNandPartReleaseHoodooVersionMinor kNandPartFeatureFuneralDirgeVersionMinor
#define kNandPartReleaseSundanceVersionMajor kNandPartFeaturePoolPartitionVersionMajor
#define kNandPartReleaseSundanceVersionMinor kNandPartFeaturePoolPartitionVersionMinor
// =============================================================================
// general constants
#define kNandPartSectorSize 512
#define kNandPartSectorsPerPage 3
#define kNandPartPageSize (kNandPartSectorSize * kNandPartSectorsPerPage)
#define kNandPartBankMax 16
// =============================================================================
// partition header
typedef struct _NandPartHeader {
uint32_t magic;
uint32_t should_be_zero;
uint32_t versionMajor;
uint32_t versionMinor;
uint32_t generation;
uint8_t reserved[12];
} __attribute__((__packed__)) NandPartHeader;
#define kNandPartHeaderMagic 'Grdn'
#define kNandPartHeaderVersionMajor kNandPartReleaseSundanceVersionMajor
#define kNandPartHeaderVersionMinor kNandPartReleaseSundanceVersionMinor
#define kNandPartHeaderMaxSize (kNandPartSectorSize / 16)
// =============================================================================
// partition factory BBT cache
typedef struct _NandPartFBBTCacheInfo {
uint32_t blockDepth;
uint32_t entryCount;
} __attribute__((__packed__)) NandPartFBBTCacheInfo;
#define kNandPartFBBTCacheMaxSize (kNandPartSectorSize - kNandPartHeaderMaxSize)
#define kNandPartFBBTCacheEntriesMaxSize (kNandPartFBBTCacheMaxSize - sizeof(NandPartFBBTCacheInfo))
typedef struct _NandPartFBBTCacheEntry {
uint32_t bankNum;
uint32_t blockAddr;
} __attribute__((__packed__)) NandPartFBBTCacheEntry;
#define kNandPartFBBTCacheEntryCount (kNandPartFBBTCacheEntriesMaxSize / sizeof(NandPartFBBTCacheEntry))
typedef struct _NandPartFBBTCache {
NandPartFBBTCacheInfo info;
NandPartFBBTCacheEntry entries[kNandPartFBBTCacheEntryCount];
} __attribute__((__packed__)) NandPartFBBTCache;
// =============================================================================
// partition device info
typedef struct _NandPartDevice {
uint32_t should_be_zero[2];
uint32_t should_be_one;
uint32_t numOfCS;
uint32_t blocksPerCS;
uint32_t pagesPerBlock;
uint32_t sectorsPerPage;
uint32_t spareBytesPerPage;
uint32_t flags;
} __attribute__((__packed__)) NandPartDevice;
#define kNandPartDeviceFlagNone ((uint32_t)0x00000000)
#define kNandPartDeviceFlagNeedsCemetery (((uint32_t)0x1) << 0)
#define kNandPartDeviceFlagExplicitEntries (((uint32_t)0x1) << 1)
#define kNandPartDeviceFlagAllowPool (((uint32_t)0x1) << 2)
// =============================================================================
// cemetery
//
// Where bad blocks go to die.
#define kNandPartCemeteryGate ((uint32_t) 0xDeadCafe)
#define kNandPartCemeteryCapacity 256
#define nandPartCemeteryPlotsSize(capacity) (((capacity) / 8) + (((capacity) % 8) ? 1 : 0))
#define kNandPartCemeteryPlotsSize nandPartCemeteryPlotsSize(kNandPartCemeteryCapacity)
typedef struct _NandPartCemetery {
uint32_t gate;
uint16_t capacity;
uint8_t flags;
uint8_t reserved[3];
uint8_t plots[kNandPartCemeteryPlotsSize];
uint8_t locks[2];
} __attribute__((__packed__)) NandPartCemetery;
#define kNandPartCemeteryFlagIgnoreLocks ((uint8_t)0x01)
// =============================================================================
// spare blocks
#define kNandPartSpareMaxCount 64
#define kNandPartSpareMagic 'spAr'
typedef struct _NandPartSpareLocation {
uint8_t block[3];
uint8_t ce;
} __attribute__((__packed__)) NandPartSpareLocation;
typedef struct _NandPartSpare {
uint32_t magic;
uint16_t count;
uint8_t flags;
uint8_t reserved[3];
NandPartSpareLocation locations[kNandPartSpareMaxCount];
uint8_t checks[2];
} __attribute__((__packed__)) NandPartSpare;
#define kNandPartSpareFlagIgnoreChecks ((uint8_t)0x01)
#define kNandPartSpareMinExtraCount 4
// =============================================================================
// block substitutions
#define kNandPartSubstMaxCount kNandPartSpareMaxCount
#define kNandPartSubstMagic 'subs'
typedef struct _NandPartSubst {
uint32_t magic;
uint16_t count;
uint8_t flags;
uint8_t reserved[3];
uint8_t maps[kNandPartSubstMaxCount];
uint8_t checks[2];
} __attribute__((__packed__)) NandPartSubst;
#define kNandPartSubstFlagIgnoreChecks ((uint8_t)0x01)
#define kNandPartSubstFlagCorrectedChecks ((uint8_t)0x02)
// =============================================================================
// unused
#define kNandPartUnusedSize (kNandPartSectorSize \
- sizeof(NandPartDevice) \
- sizeof(NandPartCemetery) \
- sizeof(NandPartSpare) \
- sizeof(NandPartSubst))
// =============================================================================
// partition content
#define kNandPartContentUndefined 0x00000000
#define kNandPartContentNone 'none'
#define kNandPartContentBootBlock 'boot'
#define kNandPartContentDiagData 'diag'
#define kNandPartContentSyscfg 'scfg'
#define kNandPartContentFirmware 'firm'
#define kNandPartContentNVRAM 'nvrm'
#define kNandPartContentFilesystem 'fsys'
#define kNandPartContentEffaceable 'plog'
#define kNandPartContentBadBlockTable 'fbbt'
#define kNandPartContentErased 0xFFFFFFFF
#define kNandPartContentNameUnformatted "Unformatted"
#define kNandPartContentNameUnallocated "Unallocated"
#define kNandPartContentNameUnrecognized "Unrecognized"
#define kNandPartContentNameBootBlock "Boot Block"
#define kNandPartContentNameDiagData "Diagnostic Data"
#define kNandPartContentNameSyscfg "System Config"
#define kNandPartContentNameNVRAM "NVRAM"
#define kNandPartContentNameFirmware "Firmware"
#define kNandPartContentNameFilesystem "Filesystem"
#define kNandPartContentNameEffaceable "Effaceable"
#define kNandPartContentNameBadBlockTable "Bad Block Table"
// =============================================================================
// partition entry
typedef struct _NandPartEntryInfo {
uint32_t content;
uint32_t reserved_0;
uint32_t reserved_1;
uint32_t flags;
} __attribute__((__packed__)) NandPartEntryInfo;
typedef struct _NandPartEntrySlice {
uint32_t content;
uint32_t offset;
uint32_t depth;
uint32_t flags;
} __attribute__((__packed__)) NandPartEntrySlice;
typedef struct _NandPartEntryPool {
uint32_t content;
uint32_t width;
uint32_t depth;
uint32_t flags;
} __attribute__((__packed__)) NandPartEntryPool;
typedef union _NandPartEntry {
struct {
uint32_t content;
uint32_t reserved_0;
uint32_t reserved_1;
uint32_t flags;
} __attribute__((__packed__));
NandPartEntryInfo info;
NandPartEntrySlice slice;
NandPartEntryPool pool;
} NandPartEntry;
#define kNandPartEntryMaxCount (kNandPartSectorSize / sizeof(NandPartEntry))
#define kNandPartEntryFlagsNone 0x00000000
#define kNandPartEntryFlagsTypeInfo 0x00000001
#define kNandPartEntryFlagsTypeSlice 0x00000002
#define kNandPartEntryFlagsTypePool 0x00000008
#define kNandPartEntryFlagsUnpartitioned 0x80000000
#define kNandPartEntryFlagsTypeMask (kNandPartEntryFlagsTypeInfo | \
kNandPartEntryFlagsTypeSlice | \
kNandPartEntryFlagsTypePool | \
kNandPartEntryFlagsUnpartitioned)
#define kNandPartEntryFlagsIsBulk 0x00000004
#define kNandPartEntryFlagsUsingSLCBlocks 0x00000100
#define kNandPartEntryFlagsUsingFullPages 0x00000200
#define kNandPartEntryFlagsIgnoreFBBT 0x40000000
#define kNandPartEntryFlagsMiscMask (kNandPartEntryFlagsIsBulk | \
kNandPartEntryFlagsUsingSLCBlocks | \
kNandPartEntryFlagsUsingFullPages | \
kNandPartEntryFlagsIgnoreFBBT)
#define kNandPartEntryFlagsMask (kNandPartEntryFlagsTypeMask | \
kNandPartEntryFlagsMiscMask)
// =============================================================================
// partition table
typedef struct _NandPartTable {
NandPartHeader header;
NandPartFBBTCache fbbtCache;
NandPartDevice device;
NandPartCemetery cemetery;
NandPartSpare spare;
NandPartSubst subst;
uint8_t unused[kNandPartUnusedSize];
NandPartEntry entries[kNandPartEntryMaxCount];
} __attribute__((__packed__)) NandPartTable;
#define kNandPartTableLayoutIsValid (sizeof(NandPartTable) == kNandPartPageSize)
#define kNandPartTableCopies 2
// =============================================================================
// partition table incremental differences
//
// incremental difference information about the current partition
// table state that is stored in metadata of other on-nand containers
// (e.g. nvram, effaceable) rather than in partition table itself
typedef struct _NandPartDiffHeader {
uint32_t magic;
uint16_t size;
uint16_t sequence;
uint32_t versionMajor;
uint32_t versionMinor;
uint32_t generation;
uint16_t flags;
uint8_t reserved[10];
} __attribute__((__packed__)) NandPartDiffHeader;
typedef struct _NandPartDiff {
NandPartDiffHeader header;
NandPartCemetery cemetery;
uint8_t checks[2];
} __attribute__((__packed__)) NandPartDiff;
#define kNandPartDiffMagic 'Diff'
#define kNandPartDiffFlagIgnoreChecks ((uint16_t)0x0001)
// =============================================================================
// boot loader
#define kNandPartLoaderPageCount 128
#define kNandPartLoaderMaxPages (kNandPartLoaderPageCount - kNandPartTableCopies - 1)
#define kNandPartLoaderMaxSize (kNandPartLoaderMaxPages * kNandPartPageSize)
// =============================================================================
// generally useful macros
#define isMaskSet(_msk, _val) ((_msk) == ((_msk) & (_val)))
__END_DECLS
#endif /* ! _NAND_PART_H */