393 lines
9.8 KiB
C
393 lines
9.8 KiB
C
/*
|
|
* Copyright (C) 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.
|
|
*/
|
|
#ifndef NVME_PROTOCOL_H
|
|
#define NVME_PROTOCOL_H
|
|
|
|
#include <sys.h>
|
|
|
|
#if( !defined( OSCompileAssert ) )
|
|
# define OSCompileAssert( TEST ) \
|
|
extern int OSCompileAssertFailed[ ( TEST ) ? 1 : -1 ] __unused;
|
|
#endif
|
|
|
|
typedef union nvme_command {
|
|
struct {
|
|
uint8_t opc; // CDW[0] bits 0-7
|
|
uint8_t fuse:2; // CDW[0] bits 8-9
|
|
uint8_t reserved0:3; // CDW[0] bits 10-12
|
|
uint8_t lprp:1; // CDW[0] bit 13
|
|
uint8_t reserved1:2; // CDW[0] bits 14-15
|
|
uint16_t cid; // CDW[0] bits 16-31
|
|
uint32_t nsid; // CDW[1]
|
|
uint64_t reserved2; // CDW[3:2]
|
|
uint64_t mptr; // CDW[5:4]
|
|
uint64_t prp1; // CDW[7:6]
|
|
uint64_t prp2; // CDW[9:8]
|
|
};
|
|
uint32_t cdw[16];
|
|
} nvme_command_t;
|
|
|
|
typedef union nvme_completion {
|
|
struct {
|
|
uint32_t cs;
|
|
uint32_t reserved0;
|
|
uint16_t sqhd;
|
|
uint16_t sqid;
|
|
uint16_t cid;
|
|
uint16_t p:1;
|
|
uint16_t sc:8;
|
|
uint16_t sct:3;
|
|
uint16_t reserved1:2;
|
|
uint16_t m:1;
|
|
uint16_t dnr:1;
|
|
};
|
|
uint32_t cdw[4];
|
|
} nvme_completion_t;
|
|
|
|
typedef struct nvme_identify_namespace {
|
|
uint64_t nsze;
|
|
uint64_t ncap;
|
|
uint64_t nuse;
|
|
uint8_t nfeat;
|
|
uint8_t nlbaf;
|
|
uint8_t flbas;
|
|
uint8_t mc;
|
|
uint8_t dpc;
|
|
uint8_t dps;
|
|
uint8_t reserved1[98];
|
|
struct {
|
|
uint16_t ms;
|
|
uint8_t lbads;
|
|
uint8_t rp:2;
|
|
uint8_t reserved:6;
|
|
} lbaf[16];
|
|
uint8_t reserved2[192];
|
|
uint8_t vs[3712];
|
|
} nvme_identify_namespace_t;
|
|
|
|
typedef struct NVMePowerStateDescriptor
|
|
{
|
|
uint16_t MAXIMUM_POWER;
|
|
uint8_t RESERVED1[2];
|
|
uint32_t ENTRY_LATENCY;
|
|
uint32_t EXIT_LATENCY;
|
|
uint8_t RELATIVE_READ_THROUGHPUT;
|
|
uint8_t RELATIVE_READ_LATENCY;
|
|
uint8_t RELATIVE_WRITE_THROUGHPUT;
|
|
uint8_t RELATIVE_WRITE_LATENCY;
|
|
uint8_t RESERVED2[16];
|
|
} NVMePowerStateDescriptor;
|
|
|
|
OSCompileAssert ( sizeof ( NVMePowerStateDescriptor ) == 32 );
|
|
|
|
enum
|
|
{
|
|
kNVMeIdentifyControllerSerialNumberLen = 20,
|
|
kNVMeIdentifyControllerModelNumberLen = 40,
|
|
kNVMeIdentifyControllerFirmwareRevisionLen = 8,
|
|
kNVMeIdentifyControllerIEEEOUIIDLen = 3,
|
|
kNVMeIdentifyControllerMSPRevisionLen = 16,
|
|
kNVMeIdentifyControllerPTSRevisionLen = 12,
|
|
kNVMeIdentifyControllerBuildTrainLen = 16,
|
|
kNVMeIdentifyControllerNANDTypeLen = 32,
|
|
kNVMeIdentifyControllerNANDVendorLen = 16
|
|
};
|
|
|
|
enum
|
|
{
|
|
NVME_MODESEL_NORMAL = 0,
|
|
NVME_MODESEL_BOOT = 1,
|
|
NVME_MODESEL_READONLY = 2,
|
|
NVME_MODESEL_RECOVERY = 3,
|
|
NVME_MODESEL_MAX = 4
|
|
};
|
|
|
|
#define kNVMeIdentifyControllerNumFuses 8
|
|
|
|
typedef struct NVMeIdentifyControllerStruct
|
|
{
|
|
// Controller Capabilites and Features
|
|
uint16_t PCI_VID;
|
|
uint16_t PCI_SSVID;
|
|
uint8_t SERIAL_NUMBER[kNVMeIdentifyControllerSerialNumberLen];
|
|
uint8_t MODEL_NUMBER[kNVMeIdentifyControllerModelNumberLen];
|
|
uint8_t FW_REVISION[kNVMeIdentifyControllerFirmwareRevisionLen];
|
|
uint8_t RECOMMENDED_ARBITRATION_BURST;
|
|
uint8_t IEEE_OUI_ID[kNVMeIdentifyControllerIEEEOUIIDLen];
|
|
uint8_t MIC;
|
|
uint8_t MAX_DATA_TRANSFER_SIZE;
|
|
uint16_t CONTROLLER_ID;
|
|
uint8_t RESERVED1[176];
|
|
|
|
// Admin Command Set Attributes
|
|
uint16_t OPTIONAL_ADMIN_COMMAND_SUPPORT;
|
|
uint8_t ABORT_COMMAND_LIMIT;
|
|
uint8_t ASYNC_EVENT_REQUEST_LIMIT;
|
|
uint8_t FW_UPDATES;
|
|
uint8_t LOG_PAGE_ATTR;
|
|
uint8_t ERROR_LOG_PAGE_ENTRIES;
|
|
uint8_t NUM_OF_POWER_STATE_SUPPORT;
|
|
uint8_t ADMIN_VENDOR_SPECIFIC_COMMAND_CONFIG;
|
|
uint8_t AUTONOMOUS_POWER_STATE_TRANSITION_ATTR;
|
|
uint8_t RESERVED2[246];
|
|
|
|
// NVM Command Set Attributes
|
|
uint8_t SQ_ENTRY_SIZE;
|
|
uint8_t CQ_ENTRY_SIZE;
|
|
uint8_t RESERVED3[2];
|
|
uint32_t NUMBER_OF_NAMESPACES;
|
|
uint16_t OPTIONAL_NVM_COMMAND_SUPPORT;
|
|
uint16_t FUSE_OP_SUPPORT;
|
|
uint8_t FORMAT_NVM_ATTR;
|
|
uint8_t VOLATILE_WRITE_CACHE;
|
|
uint16_t ATOMIC_WRITE_UNIT_NORMAL;
|
|
uint16_t ATOMIC_WRITE_UNIT_POWER_FAIL;
|
|
uint8_t NVM_VENDOR_SPECIFIC_COMMAND_CONFIG;
|
|
uint8_t RESERVED4[1];
|
|
uint16_t ATOMIC_COMPARE_AND_WRITE_UNIT;
|
|
uint8_t RESERVED5[2];
|
|
uint32_t SGL_SUPPORT;
|
|
uint8_t RESERVED6[164];
|
|
|
|
// I/O Command Set Attributes
|
|
uint8_t RESERVED7[1344];
|
|
|
|
// Power State Descriptors
|
|
NVMePowerStateDescriptor POWER_STATE_DESCRIPTORS[32];
|
|
|
|
// Vendor Specific Runtime Data
|
|
uint8_t MSP_REVISION[kNVMeIdentifyControllerMSPRevisionLen];
|
|
uint32_t TIME_TO_READY;
|
|
uint32_t TRIMMER_STATUS;
|
|
uint8_t BOOT_SOURCE;
|
|
uint8_t BOOT_BLOCK_INDEX;
|
|
uint8_t RESERVED8[2];
|
|
uint8_t S3_CHIP_ID;
|
|
uint8_t S3_CHIP_REVISION;
|
|
uint16_t S3_DEVICE_DESCRIPTOR;
|
|
uint8_t S3_ECC_VERSION_NAND_REVISION;
|
|
uint8_t S3_FTL_MAJOR_VERSION;
|
|
uint8_t S3_FTL_MINOR_VERSION;
|
|
uint8_t S3_DM_VERSION;
|
|
uint8_t S3_CONFIG_VERSION;
|
|
uint8_t S3_FORMAT_UTIL_MAJOR_VERSION;
|
|
uint8_t RESERVED9[6];
|
|
uint8_t ASP_BUILD_TRAIN[kNVMeIdentifyControllerBuildTrainLen];
|
|
uint8_t MSP_BUILD_TRAIN[kNVMeIdentifyControllerBuildTrainLen];
|
|
uint8_t RESERVED10[436];
|
|
// Vendor Specific Production Data
|
|
uint8_t BOARD_TYPE;
|
|
uint8_t NAND_TYPE;
|
|
uint8_t NAND_VENDOR;
|
|
uint8_t DRAM_VENDOR;
|
|
uint8_t NOR_VENDOR;
|
|
uint8_t CHANNELS_BITMAP;
|
|
uint16_t SSD_CAPACITY;
|
|
uint8_t CORNER_TYPE;
|
|
uint8_t ROM_VERSION;
|
|
uint8_t PTS_REVISION[kNVMeIdentifyControllerPTSRevisionLen];
|
|
uint16_t PTS_STATUS_BITMAP;
|
|
uint8_t NAND_TYPE_STRING[kNVMeIdentifyControllerNANDTypeLen];
|
|
uint8_t NAND_VENDOR_STRING[kNVMeIdentifyControllerNANDVendorLen];
|
|
uint32_t MAXIMUM_PRIMARY_NS_SIZE;
|
|
uint8_t RESERVED11[180];
|
|
uint32_t RAW_FUSES[kNVMeIdentifyControllerNumFuses];
|
|
uint8_t RESERVED12[224];
|
|
|
|
} NVMeIdentifyControllerStruct;
|
|
|
|
#define NVME_FUSE_VALUE_FOR_HYNIX 1
|
|
#define NVME_FUSE_VALUE_FOR_SANDISK 3
|
|
#define NVME_FUSE_VALUE_FOR_SAMSUNG 4
|
|
#define NVME_FUSE_VALUE_FOR_TOSHIBA 5
|
|
|
|
typedef enum
|
|
{
|
|
NVME_NAND_DEVICE_HYNIX = NVME_FUSE_VALUE_FOR_HYNIX,
|
|
NVME_NAND_DEVICE_SANDISK = NVME_FUSE_VALUE_FOR_SANDISK,
|
|
NVME_NAND_DEVICE_SAMSUNG = NVME_FUSE_VALUE_FOR_SAMSUNG,
|
|
NVME_NAND_DEVICE_TOSHIBA = NVME_FUSE_VALUE_FOR_TOSHIBA,
|
|
NVME_NAND_NUM_VENDORS
|
|
} NVME_NAND_DEVICE_VENDOR_E;
|
|
|
|
typedef enum
|
|
{
|
|
NVME_LYTH_1X,
|
|
NVME_LYTH_1Y,
|
|
NVME_LYTH_1Z,
|
|
NVME_NAND_NUM_LITHOS
|
|
} NVME_NAND_DEVICE_LITHOGRAPHY_E;
|
|
|
|
typedef enum
|
|
{
|
|
NVME_NAND_DEV_DENSITY_SLC,
|
|
NVME_NAND_DEV_DENSITY_MLC,
|
|
NVME_NAND_DEV_DENSITY_TLC,
|
|
NVME_NAND_NUM_DENSITIES
|
|
} NVME_NAND_DEVICE_DENSITY_E;
|
|
|
|
typedef enum
|
|
{
|
|
NVME_SINGLE_DIMENSION,
|
|
NVME_THREE_DIMENSION,
|
|
NVME_NAND_NUM_DIMENSIONS
|
|
} NVME_NAND_DEVICE_TECHNOLOGY_E;
|
|
|
|
typedef enum {
|
|
NVME_CHIP_S3E,
|
|
NVME_CHIP_S3X,
|
|
NVME_CHIP_NUM_ID
|
|
} NVME_IDCMD_ChipID_E;
|
|
|
|
typedef enum {
|
|
NVME_REV_A,
|
|
NVME_REV_B,
|
|
NVME_REV_C,
|
|
NVME_CHIP_NUM_REV_MAJOR
|
|
} NVME_IDCMD_ChipRevMajor_E;
|
|
|
|
typedef enum {
|
|
B_DIE,
|
|
C_DIE,
|
|
NUM_DIE_TYPES
|
|
} NAND_DEVICE_DIE_TYPE_E;
|
|
|
|
const static char *NVME_VENDOR_STRINGS[NVME_NAND_NUM_VENDORS] =
|
|
{
|
|
"Invalid",
|
|
"Hynix",
|
|
"Invalid",
|
|
"Sandisk",
|
|
"Samsung",
|
|
"Toshiba"
|
|
};
|
|
|
|
const static char *NVME_LITHOGRAPHY_STRINGS[NVME_NAND_NUM_LITHOS] =
|
|
{
|
|
"1x",
|
|
"1y",
|
|
"1z"
|
|
};
|
|
|
|
const static char *NVME_DENSITY_STRINGS[NVME_NAND_NUM_DENSITIES] =
|
|
{
|
|
"SLC",
|
|
"MLC",
|
|
"TLC"
|
|
};
|
|
|
|
const static char *NVME_DIMENSIONS_STRINGS[NVME_NAND_NUM_DIMENSIONS] =
|
|
{
|
|
"1D",
|
|
"3D",
|
|
};
|
|
|
|
const static char *NVME_CHIP_STRINGS[NVME_CHIP_NUM_ID] =
|
|
{
|
|
"S3E",
|
|
"S1X",
|
|
};
|
|
|
|
const static char *NVME_CHIP_DIE_STRINGS[NUM_DIE_TYPES] =
|
|
{
|
|
"b",
|
|
"c"
|
|
};
|
|
|
|
|
|
#define NVME_APPLE_CLASS_CODE (0x018002)
|
|
#define NVME_APPLE_BAR0_SIZE (0x2000)
|
|
|
|
#define NVME_PAGE_SIZE (1<<12)
|
|
#define NVME_PAGE_MASK (NVME_PAGE_SIZE - 1)
|
|
|
|
#define NVME_ADMIN_DELETE_SQ 0x00
|
|
#define NVME_ADMIN_CREATE_SQ 0x01
|
|
#define NVME_ADMIN_DELETE_CQ 0x04
|
|
#define NVME_ADMIN_CREATE_CQ 0x05
|
|
#define NVME_ADMIN_IDENTIFY 0x06
|
|
#define NVME_ADMIN_SET_FEATURES 0x09
|
|
#define NVME_ADMIN_GET_FEATURES 0x0a
|
|
#define NVME_ADMIN_FW_ACTIVATE 0x10
|
|
#define NVME_ADMIN_FW_DOWNLOAD 0x11
|
|
|
|
#define NVME_IO_CMD_FLUSH 0x00
|
|
#define NVME_IO_CMD_WRITE 0x01
|
|
#define NVME_IO_CMD_READ 0x02
|
|
#define NVME_IO_CMD_DATASET_MANAGEMENT 0x09
|
|
|
|
#define NVME_CREATE_SQ_CONTIGUOUS (1<<0)
|
|
#define NVME_CREATE_CQ_CONTIGUOUS (1<<0)
|
|
#define NVME_CREATE_CQ_INTERRUPT_EN (1<<1)
|
|
|
|
|
|
#define NVME_REG_CAP (0x0000)
|
|
#define NVME_REG_VS (0x0008)
|
|
#define NVME_REG_INTMS (0x000c)
|
|
#define NVME_REG_INTMC (0x0010)
|
|
#define NVME_REG_CC (0x0014)
|
|
#define NVME_REG_CSTS (0x001c)
|
|
#define NVME_REG_AQA (0x0024)
|
|
#define NVME_REG_ASQ (0x0028)
|
|
#define NVME_REG_ACQ (0x0030)
|
|
#define NVME_REG_SQ0TDBL (0x1000)
|
|
#define NVME_REG_MODESEL (0x1800)
|
|
#define NVME_REG_MODESTAT (0x1804)
|
|
#define NVME_REG_DDRREQSIZE (0x1808)
|
|
#define NVME_REG_DDRREQALIGN (0x180c)
|
|
#define NVME_REG_DDRBASE (0x1810)
|
|
#define NVME_REG_DDRSIZE (0x1818)
|
|
|
|
// S3E-specific registers
|
|
#define NVME_REG_S3E_TIMEOUT_DEBUG (0x0550)
|
|
#define NVME_REG_S3E_ASSERT_ID (0x1910)
|
|
#define NVME_REG_S3E_ASSERT_LOG1 (0x1914)
|
|
#define NVME_REG_S3E_ASSERT_LOG2 (0x1918)
|
|
#define NVME_REG_S3E_ASSERT_LOG3 (0x191c)
|
|
#define NVME_REG_S3E_ASSERT_EDD0 (0x1980)
|
|
#define NVME_REG_S3E_ASSERT_EDD1 (0x1984)
|
|
#define NVME_REG_S3E_ASSERT_EDD2 (0x1988)
|
|
#define NVME_REG_S3E_ASSERT_EDD3 (0x198c)
|
|
#define NVME_REG_S3E_ASSERT_EDD4 (0x1990)
|
|
#define NVME_REG_S3E_ASSERT_EDD5 (0x1994)
|
|
#define NVME_REG_S3E_ASSERT_EDD6 (0x1998)
|
|
#define NVME_REG_S3E_ASSERT_EDD7 (0x199c)
|
|
|
|
// S3E FA registers
|
|
#define NVME_REG_FA_ACTION (0x195C)
|
|
#define NVME_REG_FA_STATUS (0x1960)
|
|
#define NVME_REG_FA_SIZE (0x1964)
|
|
|
|
// S3E FA actions
|
|
#define NVME_FA_ACTION_DO_FLUSH 1
|
|
#define NVME_FA_ACTION_DO_DUMP_FA 2
|
|
|
|
// S3E FA status values
|
|
#define NVME_FA_STATUS_FLUSH_DONE 1
|
|
#define NVME_FA_STATUS_FA_DONE 2
|
|
|
|
#define NVME_CC_EN (1 << 0)
|
|
#define NVME_CC_MPS(x) (x << 7)
|
|
#define NVME_CC_SHN_NONE (0 << 14)
|
|
#define NVME_CC_SHN_NORMAL (1 << 14)
|
|
#define NVME_CC_SHN_ABRUPT (2 << 14)
|
|
#define NVME_CC_IOSQES(x) (x << 16)
|
|
#define NVME_CC_IOCQES(x) (x << 20)
|
|
|
|
#define NVME_CSTS_RDY (1 << 0)
|
|
#define NVME_CSTS_CFS (1 << 1)
|
|
#define NVME_CSTS_SHST_MASK (3 << 2)
|
|
#define NVME_CSTS_SHST_NORMAL (0 << 2)
|
|
#define NVME_CSTS_SHST_PROCESSING (1 << 2)
|
|
#define NVME_CSTS_SHST_DONE (2 << 2)
|
|
|
|
#endif // NVME_PROTOCOL_H
|