Merge branch 'master' of https://github.com/CTCaer/hekate
All checks were successful
Build / Build (push) Successful in 26s

This commit is contained in:
2026-06-17 00:36:24 +02:00
10 changed files with 948 additions and 500 deletions

View File

@@ -1,11 +1,11 @@
# IPL Version.
BLVERSION_MAJOR := 6
BLVERSION_MINOR := 5
BLVERSION_HOTFX := 2
BLVERSION_HOTFX := 3
BLVERSION_REL := 0
# Nyx Version.
NYXVERSION_MAJOR := 1
NYXVERSION_MINOR := 9
NYXVERSION_HOTFX := 2
NYXVERSION_HOTFX := 3
NYXVERSION_REL := 0

View File

@@ -2,7 +2,7 @@
* Header for MultiMediaCard (MMC)
*
* Copyright 2002 Hewlett-Packard Company
* Copyright 2018-2021 CTCaer
* Copyright 2018-2026 CTCaer
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
@@ -44,15 +44,12 @@
#define MMC_BUS_TEST_R 14 /* adtc R1 */
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define MMC_BUS_TEST_W 19 /* adtc R1 */
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
/* class 2 */
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
@@ -63,11 +60,13 @@
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define MMC_PROGRAM_CID 26 /* adtc R1 */
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
#define MMC_SET_TIME 49 /* adtc R1 */
/* class 6 */
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
#define MMC_SEND_WR_PROTECT_TYPE 31 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
@@ -85,27 +84,32 @@
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
#define MMC_VENDOR_60_CMD 60 /* Vendor Defined */
#define MMC_VENDOR_61_CMD 61 /* Vendor Defined */
#define MMC_VENDOR_62_CMD 62 /* Vendor Defined */
#define MMC_VENDOR_63_CMD 63 /* Vendor Defined */
/* class 10 */
#define MMC_PROTOCOL_RD 53 /* adtc R1 */
#define MMC_PROTOCOL_WR 54 /* adtc R1 */
/* class 11 */
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
#define MMC_QUEUED_TASK_PARAMS 44 /* ac [20:16] task id R1 */
#define MMC_QUEUED_TASK_ADDR 45 /* ac [31:0] data addr R1 */
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
/* class 12 */
#define MMC_VENDOR_CMD_60 60 /* Vendor Defined */
#define MMC_VENDOR_CMD_61 61 /* Vendor Defined */
#define MMC_VENDOR_CMD_62 62 /* Vendor Defined */
#define MMC_VENDOR_CMD_63 63 /* Vendor Defined */
/*
* MMC_SWITCH argument format:
*
* [31:26] Always 0
* [25:24] Access Mode
* [23:16] Location of target Byte in EXT_CSD
* [15:08] Value Byte
* [07:03] Always 0
* [02:00] Command Set
* [31:26] Always 0
* [25:24] Access Mode
* [23:16] Location of target Byte in EXT_CSD
* [15:08] Value Byte
* [07:03] Always 0
* [02:00] Command Set
*/
/*
@@ -123,102 +127,81 @@
* c : clear by read
*/
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
#define R1_CC_ERROR (1 << 20) /* erx, c */
#define R1_ERROR (1 << 19) /* erx, c */
#define R1_UNDERRUN (1 << 18) /* ex, c */
#define R1_OVERRUN (1 << 17) /* ex, c */
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) ((x) & 0xFFFFE000)
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
#define R1_SKIP_STATE_CHECK (1 << 4) /* Custom state to skip expected state check */
#define R1_AKE_SEQ_ERROR (1 << 3)
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
#define R1_CC_ERROR (1 << 20) /* erx, c */
#define R1_ERROR (1 << 19) /* erx, c */
#define R1_UNDERRUN (1 << 18) /* ex, c */
#define R1_OVERRUN (1 << 17) /* ex, c */
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) ((x) & 0xFFFFE000)
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
#define R1_SKIP_STATE_CHECK (1 << 4) /* Custom state to skip expected state check */
#define R1_AKE_SEQ_ERROR (1 << 3)
/* R1_CURRENT_STATE 12:9 */
#define R1_STATE(x) ((x) << 9)
#define R1_STATE_IDLE 0
#define R1_STATE_READY 1
#define R1_STATE_IDENT 2
#define R1_STATE_STBY 3
#define R1_STATE_TRAN 4
#define R1_STATE_DATA 5
#define R1_STATE_RCV 6
#define R1_STATE_PRG 7
#define R1_STATE_DIS 8
/*
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
* R1 is the low order byte; R2 is the next highest byte, when present.
*/
#define R1_SPI_IDLE (1 << 0)
#define R1_SPI_ERASE_RESET (1 << 1)
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
#define R1_SPI_COM_CRC (1 << 3)
#define R1_SPI_ERASE_SEQ (1 << 4)
#define R1_SPI_ADDRESS (1 << 5)
#define R1_SPI_PARAMETER (1 << 6)
/* R1 bit 7 is always zero */
#define R2_SPI_CARD_LOCKED (1 << 8)
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
#define R2_SPI_ERROR (1 << 10)
#define R2_SPI_CC_ERROR (1 << 11)
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
#define R2_SPI_WP_VIOLATION (1 << 13)
#define R2_SPI_ERASE_PARAM (1 << 14)
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
#define R1_STATE(x) ((x) << 9)
#define R1_STATE_IDLE 0
#define R1_STATE_READY 1
#define R1_STATE_IDENT 2
#define R1_STATE_STBY 3
#define R1_STATE_TRAN 4
#define R1_STATE_DATA 5
#define R1_STATE_RCV 6
#define R1_STATE_PRG 7
#define R1_STATE_DIS 8
/*
* OCR bits are mostly in host.h
*/
#define MMC_CARD_VDD_18 (1 << 7) /* Card VDD voltage 1.8 */
#define MMC_CARD_VDD_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */
#define MMC_CARD_CCS (1 << 30) /* Card Capacity status bit */
#define MMC_CARD_BUSY (1 << 31) /* Card Power up status bit */
#define MMC_OCR_VCCQ_18 (1 << 7) /* Card VDD voltage 1.8 */
#define MMC_OCR_VCCQ_20_26 (0x7F << 8) /* Card VDD voltage 2.0 ~ 2.6 */
#define MMC_OCR_VCCQ_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */
#define MMC_OCR_HCS (2 << 29) /* Host Capacity status bit */
#define MMC_OCR_CCS MMC_OCR_HCS /* Card Capacity status bit */
#define MMC_OCR_BUSY (1 << 31) /* Card Power up status bit */
/*
* Card Command Classes (CCC)
*/
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
/* (and for SPI, CMD58,59) */
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
/* (CMD11) */
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
/* (CMD16,17,18) */
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
/* (CMD20) */
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
/* (CMD16,24,25,26,27) */
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
/* (CMD32,33,34,35,36,37,38,39) */
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
/* (CMD28,29,30) */
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
/* (CMD16,CMD42) */
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
/* (CMD55,56,57,ACMD*) */
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
/* (CMD5,39,40,52,53) */
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
/* (CMD6,34,35,36,37,50) */
/* (11) Reserved */
/* (CMD?) */
@@ -227,228 +210,224 @@
* CSD field definitions
*/
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
/*
* EXT_CSD fields
*/
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
#define EXT_CSD_FLUSH_CACHE 32 /* W */
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* RO, 3 bytes */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
#define EXT_CSD_BKOPS_EN 163 /* R/W */
#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
#define EXT_CSD_RPMB_MULT 168 /* RO */
#define EXT_CSD_FW_CONFIG 169 /* R/W */
#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_TRIM_MULT 232 /* RO */
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
#define EXT_CSD_DEVICE_VERSION 262 /* RO, 2 bytes */
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_HPI_FEATURES 503 /* RO */
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
#define EXT_CSD_FLUSH_CACHE 32 /* W */
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* RO, 3 bytes */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
#define EXT_CSD_BKOPS_EN 163 /* R/W */
#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
#define EXT_CSD_RPMB_MULT 168 /* RO */
#define EXT_CSD_FW_CONFIG 169 /* R/W */
#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_TRIM_MULT 232 /* RO */
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
#define EXT_CSD_DEVICE_VERSION 262 /* RO, 2 bytes */
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_HPI_FEATURES 503 /* RO */
/*
* EXT_CSD field definitions
*/
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
#define EXT_CSD_CMD_SET_SECURE (1<<1)
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
#define EXT_CSD_CMD_SET_SECURE (1<<1)
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
EXT_CSD_CARD_TYPE_HS_52)
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | EXT_CSD_CARD_TYPE_HS_52)
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_2V)
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
/* SDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
EXT_CSD_CARD_TYPE_HS200_1_2V)
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | EXT_CSD_CARD_TYPE_HS200_1_2V)
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
#define EXT_CSD_TIMING_HS 1 /* High speed */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
#define EXT_CSD_TIMING_HS 1 /* High speed */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
#define EXT_CSD_SEC_ER_EN (1<<0)
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
#define EXT_CSD_SEC_ER_EN (1<<0)
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
#define EXT_CSD_RST_N_EN_MASK 0x3
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
#define EXT_CSD_RST_N_EN_MASK 0x3
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
#define EXT_CSD_NO_POWER_NOTIFICATION 0
#define EXT_CSD_POWER_ON 1
#define EXT_CSD_POWER_OFF_SHORT 2
#define EXT_CSD_POWER_OFF_LONG 3
#define EXT_CSD_NO_POWER_NOTIFICATION 0
#define EXT_CSD_POWER_ON 1
#define EXT_CSD_POWER_OFF_SHORT 2
#define EXT_CSD_POWER_OFF_LONG 3
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
/*
* EXCEPTION_EVENT_STATUS field
*/
#define EXT_CSD_URGENT_BKOPS (1<<0)
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
#define EXT_CSD_PACKED_FAILURE (1<<3)
#define EXT_CSD_URGENT_BKOPS (1<<0)
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
#define EXT_CSD_PACKED_FAILURE (1<<3)
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
/*
* BKOPS status level
*/
#define EXT_CSD_BKOPS_OK 0x0
#define EXT_CSD_BKOPS_NON_CRITICAL 0x1
#define EXT_CSD_BKOPS_PERF_IMPACTED 0x2
#define EXT_CSD_BKOPS_CRITICAL 0x3
#define EXT_CSD_BKOPS_OK 0x0
#define EXT_CSD_BKOPS_NON_CRITICAL 0x1
#define EXT_CSD_BKOPS_PERF_IMPACTED 0x2
#define EXT_CSD_BKOPS_CRITICAL 0x3
/*
* BKOPS modes
*/
#define EXT_CSD_BKOPS_MANUAL 0x01 /* STICKY! */
#define EXT_CSD_BKOPS_AUTO 0x02
#define EXT_CSD_BKOPS_MANUAL 0x01 /* STICKY! */
#define EXT_CSD_BKOPS_AUTO 0x02
/*
* Command Queue
*/
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
/*
* MMC_SWITCH access modes
*/
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
/*
* Erase/trim/discard
*/
#define MMC_ERASE_ARG 0x00000000
#define MMC_SECURE_ERASE_ARG 0x80000000
#define MMC_TRIM_ARG 0x00000001
#define MMC_DISCARD_ARG 0x00000003
#define MMC_SECURE_TRIM1_ARG 0x80000001
#define MMC_SECURE_TRIM2_ARG 0x80008000
#define MMC_SECURE_ARGS 0x80000000
#define MMC_TRIM_ARGS 0x00008001
#define MMC_ERASE_ARG 0x00000000
#define MMC_SECURE_ERASE_ARG 0x80000000
#define MMC_TRIM_ARG 0x00000001
#define MMC_DISCARD_ARG 0x00000003
#define MMC_SECURE_TRIM1_ARG 0x80000001
#define MMC_SECURE_TRIM2_ARG 0x80008000
#define MMC_SECURE_ARGS 0x80000000
#define MMC_TRIM_ARGS 0x00008001
/*
* Vendor definitions and structs
*/
#define MMC_SANDISK_HEALTH_REPORT 0x96C9D71C
#define MMC_SANDISK_HEALTH_REPORT 0x96C9D71C
#endif /* MMC_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
* Copyright (c) 2018-2025 CTCaer
* Copyright (c) 2018-2026 CTCaer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -11,52 +11,96 @@
#ifndef SD_DEF_H
#define SD_DEF_H
/* SD commands type argument response */
/* SD commands type argument response */
/* class 0 */
/* This is basically the same command as for MMC with some quirks. */
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
#define SD_VOLTAGE_SWITCH 11 /* ac R1 */
/* Class 1 */
#define SD_Q_MANAGEMENT 43 /* ac R1b */
#define SD_Q_TASK_INFO_A 44 /* ac R1 */
#define SD_Q_TASK_INFO_B 45 /* ac R1 */
#define SD_Q_RD_TASK 46 /* adtc R1 */
#define SD_Q_WR_TASK 47 /* adtc R1 */
/* Class 2 */
#define SD_ADDR_EXT 22 /* ac [5:0] R1 */
/* class 10 */
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
#define SD_SEND_TUNING_BLOCK 19 /* ac R1b */
#define SD_SPEED_CLASS_CONTROL 20 /* ac [31:0] R1 */
#define SD_ADDRESS_EXTENSION 22 /* ac [5:0] UC ext addr R1 */
/* class 5 */
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
/* Class 9 */
#define SD_IO_SEND_OP_COND 5 /* bcr [31:0] OCR R4 */
#define SD_IO_RW_DIRECT 52 /* ac R5 */
#define SD_IO_RW_EXTENDED 53 /* adtc R5 */
/* class 10 */
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
#define SD_CMD_SYSTEM_34 34 /* cmd system defined */
#define SD_CMD_SYSTEM_35 35 /* cmd system defined */
#define SD_CMD_SYSTEM_36 36 /* cmd system defined */
#define SD_CMD_SYSTEM_37 37 /* cmd system defined */
#define SD_CMD_SYSTEM_50 50 /* cmd system defined */
#define SD_CMD_SYSTEM_57 57 /* cmd system defined */
/* class 11 */
#define SD_READ_EXTR_SINGLE 48 /* adtc [31:0] R1 */
#define SD_WRITE_EXTR_SINGLE 49 /* adtc [31:0] R1 */
#define SD_READ_EXTR_MULTI 58 /* adtc [31:0] R1 */
#define SD_WRITE_EXTR_MULTI 59 /* adtc [31:0] R1 */
#define SD_VENDOR_CMD_60 60 /* vendor defined */
#define SD_VENDOR_CMD_61 61 /* vendor defined */
#define SD_VENDOR_CMD_62 62 /* vendor defined */
#define SD_VENDOR_CMD_63 63 /* vendor defined */
/* Application commands */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_SD_STATUS 13 /* adtc R1 */
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SEND_NUM_WR_BLOCKS 22 /* adtc R1 */
#define SD_APP_SET_WR_BLK_ERASE_COUNT 23 /* ac R1 */
#define SD_APP_SD_SEND_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */
#define SD_APP_SEND_SCR 51 /* adtc R1 */
/* Application secure commands */
#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */
#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */
#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */
#define SD_APP_SECURE_ERASE 38 /* adtc R1b */
#define SD_APP_GET_MKB 43 /* adtc [31:0] See below R1 */
#define SD_APP_GET_MID 44 /* adtc R1 */
#define SD_APP_SET_CER_RN1 45 /* adtc R1 */
#define SD_APP_GET_CER_RN2 46 /* adtc R1 */
#define SD_APP_SET_CER_RES2 47 /* adtc R1 */
#define SD_APP_GET_CER_RES1 48 /* adtc R1 */
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
/* Application sd secure commands */
#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */
#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */
#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */
#define SD_APP_SECURE_ERASE 38 /* adtc R1b */
#define SD_APP_GET_MKB 43 /* adtc [31:0] See below R1 */
#define SD_APP_GET_MID 44 /* adtc R1 */
#define SD_APP_SET_CER_RN1 45 /* adtc R1 */
#define SD_APP_GET_CER_RN2 46 /* adtc R1 */
#define SD_APP_SET_CER_RES2 47 /* adtc R1 */
#define SD_APP_GET_CER_RES1 48 /* adtc R1 */
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
/* ICR bit definitions */
#define SD_ICR_PATTERN 0xAA /* Check pattern */
#define SD_ICR_VHS_27_36 (1U << 8) /* VDD IO voltage 2.7 ~ 3.6 */
#define SD_ICR_VHS_170_195 (2U << 8) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only) */
#define SD_ICR_PCIE (1U << 12) /* PCIE availability */
#define SD_ICR_PCIE_12 (1U << 13) /* PCIE IO voltage 1.2 */
/* OCR bit definitions */
#define SD_OCR_VDD_18 (1U << 7) /* VDD voltage 1.8 */
#define SD_VHS_27_36 (1U << 8) /* VDD voltage 2.7 ~ 3.6 */
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD voltage 3.2 ~ 3.3 */
#define SD_OCR_VDD_170_195 (1U << 7) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only or support) */
#define SD_OCR_VDD_27_28 (1U << 15) /* VDD IO voltage 2.7 ~ 2.8 */
#define SD_OCR_VDD_28_29 (1U << 16) /* VDD IO voltage 2.8 ~ 2.9 */
#define SD_OCR_VDD_29_30 (1U << 17) /* VDD IO voltage 2.9 ~ 3.0 */
#define SD_OCR_VDD_30_31 (1U << 18) /* VDD IO voltage 3.0 ~ 3.1 */
#define SD_OCR_VDD_31_32 (1U << 19) /* VDD IO voltage 3.1 ~ 3.2 */
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD IO voltage 3.2 ~ 3.3 */
#define SD_OCR_VDD_33_34 (1U << 21) /* VDD IO voltage 3.3 ~ 3.4 */
#define SD_OCR_VDD_34_35 (1U << 22) /* VDD IO voltage 3.4 ~ 3.5 */
#define SD_OCR_VDD_35_36 (1U << 23) /* VDD IO voltage 3.5 ~ 3.6 */
#define SD_OCR_S18R (1U << 24) /* 1.8V switching request */
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
#define SD_OCR_XPC (1U << 28) /* SDXC power control */
#define SD_OCR_CCS (1U << 30) /* Card Capacity Status */
#define SD_OCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
#define SD_OCR_HO2T (1U << 27) /* SDUC support */
#define SD_OCR_CO2T SD_OCR_HO2T /* SDUC Status */
#define SD_OCR_XPC (1U << 28) /* SDXC power control - Max Performance */
#define SD_OCR_FB (1U << 29) /* eSD Fast Boot Support */
#define SD_OCR_UHSII (1U << 29) /* UHS-II Card Status */
#define SD_OCR_HCS (1U << 30) /* Host Capacity Support */
#define SD_OCR_CCS SD_OCR_HCS /* Card Capacity Status */
#define SD_OCR_BUSY (1U << 31) /* Card Power up Status */
/*

View File

@@ -79,7 +79,17 @@ static int _sdmmc_storage_check_card_status(u32 res)
return 0;
}
static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)
static int _sdmmc_storage_check_cached_card_status(sdmmc_t *sdmmc)
{
u32 resp;
sdmmc_get_cached_rsp(sdmmc, &resp, SDMMC_RSP_TYPE_1);
if (_sdmmc_storage_check_card_status(resp))
return 1;
return 0;
}
static int _sdmmc_storage_execute_cmd_ex_masked(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, cmd, arg, SDMMC_RSP_TYPE_1, check_busy);
@@ -97,10 +107,10 @@ static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *re
return 1;
}
static int _sdmmc_storage_execute_cmd_type1(sdmmc_storage_t *storage, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
static int _sdmmc_storage_execute_cmd_ex_state(sdmmc_storage_t *storage, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
{
u32 tmp;
return _sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, cmd, arg, check_busy, expected_state, 0);
return _sdmmc_storage_execute_cmd_ex_masked(storage, &tmp, cmd, arg, check_busy, expected_state, 0);
}
static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage)
@@ -125,7 +135,7 @@ static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage)
static int _sdmmc_storage_select_card(sdmmc_storage_t *storage)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SELECT_CARD, storage->rca << 16, 1, R1_SKIP_STATE_CHECK);
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SELECT_CARD, storage->rca << 16, 1, R1_SKIP_STATE_CHECK);
}
static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage)
@@ -142,12 +152,12 @@ static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage)
static int _sdmmc_storage_set_blocklen(sdmmc_storage_t *storage, u32 blocklen)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_BLOCKLEN, blocklen, 0, R1_STATE_TRAN);
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SET_BLOCKLEN, blocklen, 0, R1_STATE_TRAN);
}
static int _sdmmc_storage_get_status(sdmmc_storage_t *storage, u32 *resp, u32 mask)
{
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, MMC_SEND_STATUS, storage->rca << 16, 0, R1_STATE_TRAN, mask);
return _sdmmc_storage_execute_cmd_ex_masked(storage, resp, MMC_SEND_STATUS, storage->rca << 16, 0, R1_STATE_TRAN, mask);
}
static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
@@ -156,11 +166,11 @@ static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
return _sdmmc_storage_get_status(storage, &tmp, 0);
}
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
int sdmmc_storage_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_62_CMD, arg, SDMMC_RSP_TYPE_1, 1);
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0))
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_CMD_62, arg, SDMMC_RSP_TYPE_1, 1);
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
return 1;
u32 resp;
@@ -186,14 +196,14 @@ int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg)
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
{
// Request health report.
if (sdmmc_storage_execute_vendor_cmd(storage, MMC_SANDISK_HEALTH_REPORT))
if (sdmmc_storage_vendor_cmd(storage, MMC_SANDISK_HEALTH_REPORT))
return 2;
u32 tmp = 0;
sdmmc_cmd_t cmdbuf;
sdmmc_req_t reqbuf;
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_63_CMD, 0, SDMMC_RSP_TYPE_1, 0); // similar to CMD17 with arg 0x0.
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_CMD_63, 0, SDMMC_RSP_TYPE_1, 0); // similar to CMD17 with arg 0x0.
reqbuf.buf = buf;
reqbuf.num_sectors = 1;
@@ -202,16 +212,39 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf)
reqbuf.is_multi_block = 0;
reqbuf.is_auto_stop_trn = 0;
u32 blkcnt_out;
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, &blkcnt_out))
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
{
sdmmc_stop_transmission(storage->sdmmc, &tmp);
_sdmmc_storage_get_status(storage, &tmp, 0);
return 1;
}
return 0;
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
int sdmmc_storage_gen_cmd(sdmmc_storage_t *storage, u32 arg, void *buf)
{
u32 tmp = 0;
sdmmc_cmd_t cmdbuf;
sdmmc_req_t reqbuf;
sdmmc_init_cmd(&cmdbuf, MMC_GEN_CMD, arg, SDMMC_RSP_TYPE_1, 0);
reqbuf.buf = buf;
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = !(arg & 1);
reqbuf.is_multi_block = 0;
reqbuf.is_auto_stop_trn = 0;
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
{
_sdmmc_storage_get_status(storage, &tmp, 0);
return 1;
}
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)
@@ -241,11 +274,7 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
return 1;
}
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
if (_sdmmc_storage_check_card_status(tmp))
return 1;
return 0;
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
int sdmmc_storage_end(sdmmc_storage_t *storage)
@@ -401,7 +430,7 @@ int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, v
* MMC specific functions.
*/
static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u32 power)
static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *rocr, u32 power)
{
sdmmc_cmd_t cmdbuf;
@@ -409,11 +438,11 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
switch (power)
{
case SDMMC_POWER_1_8:
arg = MMC_CARD_CCS | MMC_CARD_VDD_18;
arg = MMC_OCR_HCS | MMC_OCR_VCCQ_18;
break;
case SDMMC_POWER_3_3:
arg = MMC_CARD_CCS | MMC_CARD_VDD_27_34;
arg = MMC_OCR_HCS | MMC_OCR_VCCQ_27_34;
break;
default:
@@ -424,7 +453,7 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
return 1;
return sdmmc_get_cached_rsp(storage->sdmmc, pout, SDMMC_RSP_TYPE_3);
return sdmmc_get_cached_rsp(storage->sdmmc, rocr, SDMMC_RSP_TYPE_3);
}
static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
@@ -433,15 +462,15 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
while (true)
{
u32 cond = 0;
if (_mmc_storage_get_op_cond_inner(storage, &cond, power))
u32 rocr = 0;
if (_mmc_storage_get_op_cond_inner(storage, &rocr, power))
break;
// Check if power up is done.
if (cond & MMC_CARD_BUSY)
if (rocr & MMC_OCR_BUSY)
{
// Check if card is high capacity.
if (cond & MMC_CARD_CCS)
if (rocr & MMC_OCR_CCS)
storage->has_sector_access = 1;
return 0;
@@ -457,7 +486,7 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
static int _mmc_storage_set_relative_addr(sdmmc_storage_t *storage)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SET_RELATIVE_ADDR, storage->rca << 16, 0, R1_SKIP_STATE_CHECK);
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SET_RELATIVE_ADDR, storage->rca << 16, 0, R1_SKIP_STATE_CHECK);
}
static void _mmc_storage_parse_cid(sdmmc_storage_t *storage)
@@ -562,44 +591,14 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage)
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
return 1;
u32 tmp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
_mmc_storage_parse_ext_csd(storage);
return _sdmmc_storage_check_card_status(tmp);
}
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 address, u32 len, void *buf)
{
if (!(storage->scr.cmds & BIT(2)))
return 1;
sdmmc_cmd_t cmdbuf;
u32 arg = fno << 27 | page << 18 | address << 9 | (len - 1);
sdmmc_init_cmd(&cmdbuf, SD_READ_EXTR_SINGLE, arg, SDMMC_RSP_TYPE_1, 0);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = 0;
reqbuf.is_multi_block = 0;
reqbuf.is_auto_stop_trn = 0;
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
return 1;
u32 tmp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
return _sdmmc_storage_check_card_status(tmp);
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
static int _mmc_storage_switch(sdmmc_storage_t *storage, u32 arg)
{
return _sdmmc_storage_execute_cmd_type1(storage, MMC_SWITCH, arg, 1, R1_SKIP_STATE_CHECK);
return _sdmmc_storage_execute_cmd_ex_state(storage, MMC_SWITCH, arg, 1, R1_SKIP_STATE_CHECK);
}
static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)
@@ -828,18 +827,18 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_state, u32 mask, sdmmc_cmd_t *cmdbuf, sdmmc_req_t *req, u32 *blkcnt_out)
{
u32 tmp;
if (_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))
if (_sdmmc_storage_execute_cmd_ex_masked(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask))
return 1;
return sdmmc_execute_cmd(storage->sdmmc, cmdbuf, req, blkcnt_out);
}
static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state)
static int _sd_storage_execute_app_cmd_tran(sdmmc_storage_t *storage, u32 cmd, u32 arg)
{
if (_sdmmc_storage_execute_cmd_type1(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN))
if (_sdmmc_storage_execute_cmd_ex_state(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN))
return 1;
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);
return _sdmmc_storage_execute_cmd_ex_state(storage, cmd, arg, 0, R1_STATE_TRAN);
}
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
@@ -898,23 +897,23 @@ void _sd_storage_debug_print_csd(const u32 *raw_csd)
void _sd_storage_debug_print_scr(const u32 *raw_scr)
{
u32 resp[4];
memcpy(&resp[2], raw_scr, 8);
u32 scr[4];
memcpy(&scr[2], raw_scr, 8);
gfx_printf("\n");
gfx_printf("SCR_STRUCTURE: %X\n", unstuff_bits(resp, 60, 4));
gfx_printf("SD_SPEC: %X\n", unstuff_bits(resp, 56, 4));
gfx_printf("DATA_STAT_AFTER_ERASE: %X\n", unstuff_bits(resp, 55, 1));
gfx_printf("SD_SECURITY: %X\n", unstuff_bits(resp, 52, 3));
gfx_printf("SD_BUS widths: %X\n", unstuff_bits(resp, 48, 4));
gfx_printf("SD_SPEC3: %X\n", unstuff_bits(resp, 47, 1));
gfx_printf("EX_SECURITY: %X\n", unstuff_bits(resp, 43, 4));
gfx_printf("SD_SPEC4: %X\n", unstuff_bits(resp, 42, 1));
gfx_printf("SD_SPECX: %X\n", unstuff_bits(resp, 38, 4));
gfx_printf("CMD_SUPPORT: %X\n", unstuff_bits(resp, 32, 4));
gfx_printf("VENDOR: %08X\n", unstuff_bits(resp, 0, 32));
gfx_printf("--RSVD-- %X\n", unstuff_bits(resp, 36, 2));
gfx_printf("SCR_STRUCTURE: %X\n", unstuff_bits(scr, 60, 4));
gfx_printf("SD_SPEC: %X\n", unstuff_bits(scr, 56, 4));
gfx_printf("DATA_STAT_AFTER_ERASE: %X\n", unstuff_bits(scr, 55, 1));
gfx_printf("SD_SECURITY: %X\n", unstuff_bits(scr, 52, 3));
gfx_printf("SD_BUS widths: %X\n", unstuff_bits(scr, 48, 4));
gfx_printf("SD_SPEC3: %X\n", unstuff_bits(scr, 47, 1));
gfx_printf("EX_SECURITY: %X\n", unstuff_bits(scr, 43, 4));
gfx_printf("SD_SPEC4: %X\n", unstuff_bits(scr, 42, 1));
gfx_printf("SD_SPECX: %X\n", unstuff_bits(scr, 38, 4));
gfx_printf("CMD_SUPPORT: %X\n", unstuff_bits(scr, 32, 4));
gfx_printf("VENDOR: %08X\n", unstuff_bits(scr, 0, 32));
gfx_printf("--RSVD-- %X\n", unstuff_bits(scr, 36, 2));
}
void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
@@ -952,11 +951,6 @@ void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
gfx_printf("DISCARD_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 313, 1));
gfx_printf("FULE_SUPPORT: %X\n", unstuff_bits(raw_ssr1, 312, 1));
gfx_printf("--RSVD-- %02X %X %02X %02X %04X\n",
unstuff_bits(raw_ssr0, 496, 6), unstuff_bits(raw_ssr0, 424, 4),
unstuff_bits(raw_ssr1, 378, 6), unstuff_bits(raw_ssr1, 340, 6),
unstuff_bits(raw_ssr1, 314, 14));
gfx_printf("VENDOR_1: %06X %08X\n",
unstuff_bits(raw_ssr1, 288, 24), unstuff_bits(raw_ssr1, 256, 32));
@@ -966,81 +960,174 @@ void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
gfx_printf("VENDOR_3: %08X %08X %08X %08X\n",
unstuff_bits(raw_ssr3, 96 - 0, 32), unstuff_bits(raw_ssr3, 64, 32),
unstuff_bits(raw_ssr3, 32 - 0, 32), unstuff_bits(raw_ssr3, 0, 32));
gfx_printf("--RSVD-- %02X %X %02X %02X %04X\n",
unstuff_bits(raw_ssr0, 496, 6), unstuff_bits(raw_ssr0, 424, 4),
unstuff_bits(raw_ssr1, 378, 6), unstuff_bits(raw_ssr1, 340, 6),
unstuff_bits(raw_ssr1, 314, 14));
}
#endif
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
void sd_storage_get_vendor_info(sdmmc_storage_t *storage, sd_vendor_info_t *info)
{
// CID Reserved.
info->cid_rsvd = storage->cid.rsvd;
// CSD Reserved.
info->csd_rsvd8_9 = unstuff_bits((u32 *)storage->raw_csd, 8, 2);
info->csd_rsvd16_20 = unstuff_bits((u32 *)storage->raw_csd, 16, 5);
info->csd_rsvd29_30 = unstuff_bits((u32 *)storage->raw_csd, 29, 2);
info->csd_rsvd120_125 = unstuff_bits((u32 *)storage->raw_csd, 120, 6);
// SCR Vendor and Reserved.
u32 scr[4];
memcpy(&scr[2], storage->raw_scr, 8);
info->scr_vendor = storage->scr.vendor;
info->scr_rsvd = unstuff_bits(scr, 36, 2);
// SSR Vendor and Reserved.
u32 raw_ssr0[4]; // 511:384.
u32 raw_ssr1[4]; // 383:256.
u32 raw_ssr2[4]; // 255:128.
u32 raw_ssr3[4]; // 127:0.
memcpy(raw_ssr0, &storage->raw_ssr[0], 16);
memcpy(raw_ssr1, &storage->raw_ssr[16], 16);
memcpy(raw_ssr2, &storage->raw_ssr[32], 16);
memcpy(raw_ssr3, &storage->raw_ssr[48], 16);
info->ssr_vendor0_31 = unstuff_bits(raw_ssr3, 0, 32);
info->ssr_vendor32_63 = unstuff_bits(raw_ssr3, 32, 32);
info->ssr_vendor64_95 = unstuff_bits(raw_ssr3, 64, 32);
info->ssr_vendor96_127 = unstuff_bits(raw_ssr3, 96, 32);
info->ssr_vendor128_159 = unstuff_bits(raw_ssr2, 128, 32);
info->ssr_vendor160_191 = unstuff_bits(raw_ssr2, 160, 32);
info->ssr_vendor192_223 = unstuff_bits(raw_ssr2, 192, 32);
info->ssr_vendor224_255 = unstuff_bits(raw_ssr2, 224, 32);
info->ssr_vendor256_287 = unstuff_bits(raw_ssr1, 256, 32);
info->ssr_vendor288_311 = unstuff_bits(raw_ssr1, 288, 24);
info->ssr_rsvd314_327 = unstuff_bits(raw_ssr1, 314, 14);
info->ssr_rsvd340_345 = unstuff_bits(raw_ssr1, 340, 6);
info->ssr_rsvd378_383 = unstuff_bits(raw_ssr1, 378, 6);
info->ssr_rsvd424_427 = unstuff_bits(raw_ssr0, 424, 4);
info->ssr_rsvd496_501 = unstuff_bits(raw_ssr0, 496, 6);
}
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 address, u32 len, void *buf)
{
if (!(storage->scr.cmds & BIT(2)))
return 1;
sdmmc_cmd_t cmdbuf;
u32 arg = fno << 27 | page << 18 | address << 9 | (len - 1);
sdmmc_init_cmd(&cmdbuf, SD_READ_EXTR_SINGLE, arg, SDMMC_RSP_TYPE_1, 0);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
reqbuf.blksize = SDMMC_DAT_BLOCKSIZE;
reqbuf.num_sectors = 1;
reqbuf.is_write = 0;
reqbuf.is_multi_block = 0;
reqbuf.is_auto_stop_trn = 0;
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
return 1;
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sd_v1)
{
sdmmc_cmd_t cmdbuf;
u16 vhd_pattern = SD_VHS_27_36 | 0xAA;
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_7, 0);
u16 icr = SD_ICR_PCIE | SD_ICR_VHS_27_36 | SD_ICR_PATTERN;
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, icr, SDMMC_RSP_TYPE_7, 0);
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
{
// The SD Card is version 1.X (SDSC) if there is no response.
// The SD Card is version 1.XX if there is no response.
if (storage->sdmmc->error_sts == SDHCI_ERR_INT_CMD_TIMEOUT)
{
*is_sdsc = 1;
*is_sd_v1 = true;
return 0;
}
return 1;
}
// For Card version >= 2.0, parse results.
u32 resp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_7);
// For version >= 2.0, parse results.
u32 ricr = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &ricr, SDMMC_RSP_TYPE_7);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
gfx_printf("ICR: %08X -> %08X\n", icr, ricr);
#endif
// Check if VHS was accepted and pattern was properly returned.
if ((ricr & 0xFFF) == (icr & 0xFFF))
{
storage->has_pcie = ricr & SD_ICR_PCIE;
// Check if VHD was accepted and pattern was properly returned.
if ((resp & 0xFFF) == vhd_pattern)
return 0;
}
return 1;
}
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, bool is_sdsc, int bus_uhs_support)
static int _sd_storage_send_op_cond(sdmmc_storage_t *storage, u32 *rocr, u32 ocr, bool is_sd_v1)
{
sdmmc_cmd_t cmdbuf;
// Support for Current > 150mA.
u32 arg = !is_sdsc ? SD_OCR_XPC : 0;
// Support for handling block-addressed SDHC cards.
arg |= !is_sdsc ? SD_OCR_CCS : 0;
// Support for 1.8V signaling.
arg |= (bus_uhs_support && !is_sdsc) ? SD_OCR_S18R : 0;
// Support for 3.3V power supply (VDD1).
arg |= SD_OCR_VDD_32_33;
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
sdmmc_init_cmd(&cmdbuf, SD_APP_SD_SEND_OP_COND, ocr, SDMMC_RSP_TYPE_3, 0);
if (_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sdsc ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
if (_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sd_v1 ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
return 1;
return sdmmc_get_cached_rsp(storage->sdmmc, cond, SDMMC_RSP_TYPE_3);
return sdmmc_get_cached_rsp(storage->sdmmc, rocr, SDMMC_RSP_TYPE_3);
}
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int bus_uhs_support)
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sd_v1, int lv_support)
{
u32 timeout = get_tmr_ms() + 1500;
// Host in 3.3V power supply (VDD1).
u32 ocr = SD_OCR_VDD_32_33;
if (!is_sd_v1)
{
// Support for Current > 150mA.
ocr |= SD_OCR_XPC;
// Support for handling block-addressed SDHC/SDXC/SDUC cards.
ocr |= SD_OCR_HCS;
// Support and request 1.8V signaling.
ocr |= lv_support ? SD_OCR_S18R : 0;
}
while (true)
{
u32 cond = 0;
if (_sd_storage_get_op_cond_once(storage, &cond, is_sdsc, bus_uhs_support))
u32 rocr = 0;
if (_sd_storage_send_op_cond(storage, &rocr, ocr, is_sd_v1))
break;
// Check if power up is done.
if (cond & SD_OCR_BUSY)
if (rocr & SD_OCR_BUSY)
{
DPRINTF("[SD] op cond: %08X, lv: %d\n", cond, bus_uhs_support);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
gfx_printf("ROCR: %08X (%d)\n", rocr, lv_support);
#else
DPRINTF("[SD] rocr: %08X, lv: %d\n", rocr, lv_support);
#endif
// Check if card is high capacity.
if (cond & SD_OCR_CCS)
storage->has_sector_access = 1;
// Check if card is higher capacity.
if (rocr & SD_OCR_CCS)
storage->has_sector_access = 1; // Non-SDUC.
// Check if card supports 1.8V signaling.
if (cond & SD_ROCR_S18A && bus_uhs_support && !storage->is_low_voltage)
// Check if card accepted 1.8V signaling.
if (rocr & SD_OCR_S18A && lv_support)
{
// Switch to 1.8V signaling.
if (!_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))
if (!_sdmmc_storage_execute_cmd_ex_state(storage, SD_VOLTAGE_SWITCH, 0, 0, R1_STATE_READY))
{
if (sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_UHS_SDR12))
return 1;
@@ -1080,13 +1167,13 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
break;
u32 resp = 0;
if (sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_6))
u32 rca = 0;
if (sdmmc_get_cached_rsp(storage->sdmmc, &rca, SDMMC_RSP_TYPE_6))
break;
if (resp >> 16)
if (rca >> 16)
{
storage->rca = resp >> 16;
storage->rca = rca >> 16;
return 0;
}
@@ -1098,31 +1185,71 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
return 1;
}
u8 sd_storage_get_scr_sda_ver(sdmmc_storage_t *storage)
{
u8 version = 0;
u8 sda_spec = storage->scr.sda_vsn;
u8 sda_spec3 = storage->scr.sda_spec & 1;
u8 sda_spec4 = (storage->scr.sda_spec >> 1) & 1;
u8 sda_specx = storage->scr.sda_spec >> 4;
switch (sda_spec)
{
case 0:
version = 1;
break;
case 1:
version = 1;
break;
case 2:
if (!sda_spec3)
version = 2;
else if (!sda_spec4 && !sda_specx)
version = 3;
else
version = sda_specx + 4;
break;
}
return version;
}
static void _sd_storage_parse_scr(sdmmc_storage_t *storage)
{
// unstuff_bits can parse only 4 u32
u32 resp[4];
u32 scr[4];
u8 sda_spec3 = 0;
u8 sda_spec4 = 0;
u8 sda_specx = 0;
memcpy(&resp[2], storage->raw_scr, 8);
memcpy(&scr[2], storage->raw_scr, 8);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
_sd_storage_debug_print_scr((u32 *)storage->raw_scr);
#endif
storage->scr.sda_vsn = unstuff_bits(resp, 56, 4);
storage->scr.bus_widths = unstuff_bits(resp, 48, 4);
storage->scr.sda_vsn = unstuff_bits(scr, 56, 4);
storage->scr.bus_widths = unstuff_bits(scr, 48, 4);
// If v2.0 is supported, check if Physical Layer Spec v3.0 is supported.
if (storage->scr.sda_vsn == SCR_SPEC_VER_2)
storage->scr.sda_spec3 = unstuff_bits(resp, 47, 1);
if (storage->scr.sda_spec3)
sda_spec3 = unstuff_bits(scr, 47, 1);
if (sda_spec3)
{
u8 sda_spec4 = unstuff_bits(resp, 42, 1);
sda_spec4 = unstuff_bits(scr, 42, 1);
sda_specx = unstuff_bits(scr, 38, 4);
if (sda_spec4)
storage->scr.cmds = unstuff_bits(resp, 32, 4);
storage->scr.cmds = unstuff_bits(scr, 32, 4);
else
storage->scr.cmds = unstuff_bits(resp, 32, 2);
storage->scr.cmds = unstuff_bits(scr, 32, 2);
}
storage->scr.sda_spec = sda_spec3 | (sda_spec4 << 1) | (sda_specx << 4);
storage->scr.vendor = unstuff_bits(scr, 0, 32);
}
int sd_storage_get_scr(sdmmc_storage_t *storage)
@@ -1143,8 +1270,6 @@ int sd_storage_get_scr(sdmmc_storage_t *storage)
if (_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL))
return 1;
u32 tmp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
//Prepare buffer for unstuff_bits
for (u32 i = 0; i < 8; i += 4)
{
@@ -1155,10 +1280,10 @@ int sd_storage_get_scr(sdmmc_storage_t *storage)
}
_sd_storage_parse_scr(storage);
return _sdmmc_storage_check_card_status(tmp);
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
static int _sd_storage_switch_get_all(sdmmc_storage_t *storage, void *buf)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0);
@@ -1174,9 +1299,7 @@ static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
return 1;
u32 tmp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
return _sdmmc_storage_check_card_status(tmp);
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, u32 arg)
@@ -1198,9 +1321,7 @@ static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL))
return 1;
u32 tmp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
return _sdmmc_storage_check_card_status(tmp);
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
static void _sd_storage_set_power_limit(sdmmc_storage_t *storage, u16 power_limit, u8 *buf)
@@ -1378,9 +1499,19 @@ int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fm
if (!buf)
buf = (u8 *)SDMMC_ALT_DMA_BUFFER;
if (_sd_storage_switch_get(storage, buf))
if (_sd_storage_switch_get_all(storage, buf))
return 1;
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
gfx_printf("\nFMD: %04X %04X %04X %04X %04X %04X\n",
buf[13] | (buf[12] << 8),
buf[11] | (buf[10] << 8),
buf[9] | (buf[8] << 8),
buf[7] | (buf[6] << 8),
buf[5] | (buf[4] << 8),
buf[3] | (buf[2] << 8));
#endif
fmodes->access_mode = buf[13] | (buf[12] << 8);
fmodes->cmd_system = buf[11] | (buf[10] << 8);
fmodes->driver_strength = buf[9] | (buf[8] << 8);
@@ -1389,7 +1520,7 @@ int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fm
return 0;
}
static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type)
static int _sd_storage_set_uhs_bus_speed(sdmmc_storage_t *storage, u32 type)
{
sd_func_modes_t fmodes;
u8 *buf = storage->raw_ext_csd;
@@ -1490,14 +1621,14 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type)
return 1;
DPRINTF("[SD] after setup clock\n");
if (sdmmc_tuning_execute(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK))
if (sdmmc_tuning_execute(storage->sdmmc, type, SD_SEND_TUNING_BLOCK))
return 1;
DPRINTF("[SD] after tuning\n");
return _sdmmc_storage_check_status(storage);
}
static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage)
static int _sd_storage_set_hs25_bus_speed(sdmmc_storage_t *storage)
{
sd_func_modes_t fmodes;
u8 *buf = storage->raw_ext_csd;
@@ -1520,6 +1651,64 @@ static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage)
return sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_HS25);
}
bool sd_storage_get_ddr200_support(sdmmc_storage_t *storage)
{
// DDR200 CID reserved/SCR vendor (hex):
// Samsung 0x1B: A 00000000
// Longsys 0xAD: A 00000000
// Kowin 0x22: 7 33333039 33333039 SMART?
// Phison 0x27: 0 01196432 Byte2: DDR2XX (25 == DDR225)?
// Taishin 0x9F: 0 01006432
// Non-DDR200:
// Phison 0x27: 0 01000000
// Taishin 0x9F: 0 01000000
// Taishin 0x9F: 7 33333039 Supported but slow nand?
sd_func_modes_t fmodes = { 0 };
if (sd_storage_get_fmodes(storage, storage->raw_ext_csd, &fmodes))
return false;
// Introduced first in 2018 via Sandisk Quickflow.
if (storage->cid.year < 2018)
return false;
// No DDR200 if no SDR104.
if (!(fmodes.access_mode & SD_MODE_UHS_SDR104))
return false;
// Can't enter DDR200 mode without Vendor Command System mode.
if (!(fmodes.cmd_system & SD_CMD_SYSTEM_VND))
return false;
// Assume no support if 4.10 and lower. (Should be < 6?)
if (sd_storage_get_scr_sda_ver(storage) < 5)
return false;
// Sandisk.
if (storage->cid.manfid == 0x03)
{
// 0x80: DDR200, 0x85: DDR225, 0x86: DDR250? 0x87:DDR275?
if (storage->cid.prv >= 0x80)
return true;
else
return false;
}
// CID Reserved bits.
if (storage->cid.rsvd == 0xA || // Samsung / Longsys.
storage->cid.rsvd == 0x7) // Taishin A / Kowin.
return true;
// SCR Vendor bits.
u32 scr_vnd = storage->scr.vendor & 0xFFFF;
if (scr_vnd == 0x6432) // Phison / Taishin B. "d2".
return true;
return false;
}
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage)
{
u32 au_size = storage->ssr.uhs_au_size;
@@ -1706,9 +1895,6 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage)
if (_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL))
return 1;
u32 tmp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1);
// Convert buffer to LE.
for (u32 i = 0; i < SDMMC_CMD_BLOCKSIZE; i += 4)
{
@@ -1720,7 +1906,7 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage)
_sd_storage_parse_ssr(storage);
return _sdmmc_storage_check_card_status(tmp);
return _sdmmc_storage_check_cached_card_status(storage->sdmmc);
}
static void _sd_storage_parse_cid(sdmmc_storage_t *storage)
@@ -1741,6 +1927,7 @@ static void _sd_storage_parse_cid(sdmmc_storage_t *storage)
storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4);
storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4);
storage->cid.serial = unstuff_bits(raw_cid, 24, 32);
storage->cid.rsvd = unstuff_bits(raw_cid, 20, 4);
storage->cid.year = unstuff_bits(raw_cid, 12, 8) + 2000;
storage->cid.month = unstuff_bits(raw_cid, 8, 4);
}
@@ -1778,7 +1965,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
storage->sec_cnt = storage->csd.capacity;
}
static bool _sdmmc_storage_get_bus_uhs_support(u32 bus_width, u32 type)
static bool _sd_storage_get_bus_uhs_support(u32 bus_width, u32 type)
{
switch (type)
{
@@ -1806,9 +1993,8 @@ void sdmmc_storage_init_wait_sd()
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
{
u32 tmp = 0;
bool is_sdsc = 0;
bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type);
bool is_sd_v1 = false;
bool lv_support = _sd_storage_get_bus_uhs_support(bus_width, type);
DPRINTF("[SD]-[init: bus: %d, type: %d]\n", bus_width, type);
@@ -1829,11 +2015,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
return 1;
DPRINTF("[SD] went to idle state\n");
if (_sd_storage_send_if_cond(storage, &is_sdsc))
if (_sd_storage_send_if_cond(storage, &is_sd_v1))
return 1;
DPRINTF("[SD] after send if cond\n");
DPRINTF("[SD] sent if cond\n");
if (_sd_storage_get_op_cond(storage, is_sdsc, bus_uhs_support))
if (_sd_storage_get_op_cond(storage, is_sd_v1, lv_support))
return 1;
DPRINTF("[SD] got op cond\n");
@@ -1855,7 +2041,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
{
if (sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_DS12))
return 1;
DPRINTF("[SD] after setup default clock\n");
DPRINTF("[SD] after setup default hs clock\n");
}
if (_sdmmc_storage_select_card(storage))
@@ -1867,7 +2053,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
DPRINTF("[SD] set blocklen to SD_BLOCKSIZE\n");
// Disconnect Card Detect resistor from DAT3.
if (_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN))
if (_sd_storage_execute_app_cmd_tran(storage, SD_APP_SET_CLR_CARD_DETECT, 0))
return 1;
DPRINTF("[SD] cleared card detect\n");
@@ -1878,7 +2064,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
// If card supports a wider bus and if it's not SD Version 1.0 switch bus width.
if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & BIT(SD_BUS_WIDTH_4)) && storage->scr.sda_vsn)
{
if (_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))
if (_sd_storage_execute_app_cmd_tran(storage, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4))
return 1;
sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);
@@ -1892,13 +2078,13 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
if (storage->is_low_voltage)
{
if (_sd_storage_enable_uhs_low_volt(storage, type))
if (_sd_storage_set_uhs_bus_speed(storage, type))
return 1;
DPRINTF("[SD] enabled UHS\n");
}
else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default speed and not SD Version 1.0.
else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default HS speed and not SD Version 1.0.
{
if (_sd_storage_enable_hs_high_volt(storage))
if (_sd_storage_set_hs25_bus_speed(storage))
return 1;
DPRINTF("[SD] enabled HS\n");
@@ -1935,7 +2121,7 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
{
u32 resp;
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_60_CMD, 0, SDMMC_RSP_TYPE_1, 1);
sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_CMD_60, 0, SDMMC_RSP_TYPE_1, 1);
sdmmc_req_t reqbuf;
reqbuf.buf = buf;
@@ -1951,10 +2137,9 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf)
return 1;
}
if (sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_1))
return 1;
if (_sdmmc_storage_check_card_status(resp))
if (_sdmmc_storage_check_cached_card_status(storage->sdmmc))
return 1;
return _sdmmc_storage_check_status(storage);
}

View File

@@ -117,15 +117,16 @@ typedef struct _mmc_sandisk_report_t
typedef struct _mmc_cid
{
u32 manfid;
u32 manfid; // SDA assigned.
u8 prod_name[8];
u32 serial;
u16 oemid;
u16 oemid; // SDA assigned.
u16 year;
u8 prv;
u8 hwrev;
u8 fwrev;
u8 month;
u32 rsvd;
} mmc_cid_t;
typedef struct _mmc_csd
@@ -161,9 +162,10 @@ typedef struct _mmc_ext_csd
typedef struct _sd_scr
{
u8 sda_vsn;
u8 sda_spec3;
u8 sda_spec;
u8 bus_widths;
u8 cmds;
u32 vendor;
} sd_scr_t;
typedef struct _sd_ssr
@@ -188,6 +190,46 @@ typedef struct _sd_ext_reg_t
int valid;
} sd_ext_reg_t;
typedef struct _sd_func_modes_t
{
u16 access_mode;
u16 cmd_system;
u16 driver_strength;
u16 power_limit;
} sd_func_modes_t;
typedef struct _sd_vendor_info_t
{
// CID Reserved.
u8 cid_rsvd; // 4-bit.
// CSD Reserved.
u8 csd_rsvd8_9; // 2-bit.
u8 csd_rsvd16_20; // 5-bit.
u8 csd_rsvd29_30; // 2-bit.
u8 csd_rsvd120_125; // 6-bit.
u32 scr_vendor;
u8 scr_rsvd; // 2-bit.
u32 ssr_vendor0_31;
u32 ssr_vendor32_63;
u32 ssr_vendor64_95;
u32 ssr_vendor96_127;
u32 ssr_vendor128_159;
u32 ssr_vendor160_191;
u32 ssr_vendor192_223;
u32 ssr_vendor224_255;
u32 ssr_vendor256_287;
u32 ssr_vendor288_311; // 24-bit.
u16 ssr_rsvd314_327; // 14-bit.
u8 ssr_rsvd340_345; // 6-bit.
u8 ssr_rsvd378_383; // 6-bit.
u8 ssr_rsvd424_427; // 4-bit.
u8 ssr_rsvd496_501; // 6-bit.
} sd_vendor_info_t;
/*! SDMMC storage context. */
typedef struct _sdmmc_storage_t
{
@@ -196,6 +238,7 @@ typedef struct _sdmmc_storage_t
int initialized;
int is_low_voltage;
int has_sector_access;
int has_pcie;
u32 rca;
u32 sec_cnt;
u32 partition;
@@ -213,14 +256,6 @@ typedef struct _sdmmc_storage_t
sd_ext_reg_t ser;
} sdmmc_storage_t;
typedef struct _sd_func_modes_t
{
u16 access_mode;
u16 cmd_system;
u16 driver_strength;
u16 power_limit;
} sd_func_modes_t;
int sdmmc_storage_end(sdmmc_storage_t *storage);
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
@@ -230,7 +265,8 @@ void sdmmc_storage_init_wait_sd();
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type);
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
int sdmmc_storage_gen_cmd(sdmmc_storage_t *storage, u32 arg, void *buf);
int sdmmc_storage_vendor_cmd(sdmmc_storage_t *storage, u32 arg);
int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf);
int mmc_storage_get_ext_csd(sdmmc_storage_t *storage);
@@ -238,10 +274,13 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage);
int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u32 len, void *buf);
int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions);
int sd_storage_get_scr(sdmmc_storage_t *storage);
u8 sd_storage_get_scr_sda_ver(sdmmc_storage_t *storage);
int sd_storage_get_ssr(sdmmc_storage_t *storage);
u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage);
void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf);
int sd_storage_parse_perf_enhance(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u8 *buf);
bool sd_storage_get_ddr200_support(sdmmc_storage_t *storage);
void sd_storage_get_vendor_info(sdmmc_storage_t *storage, sd_vendor_info_t *info);
#endif

View File

@@ -908,7 +908,7 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
u16 norintsts = sdmmc->regs->norintsts;
u16 errintsts = sdmmc->regs->errintsts;
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
DPRINTF("norintsts %04X, errintsts %04X\n", norintsts, errintsts);
if (pout)
*pout = norintsts;
@@ -917,7 +917,7 @@ static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
if (norintsts & SDHCI_INT_ERROR)
{
#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC%d: intsts %08X, errintsts %08X", sdmmc->id + 1, norintsts, errintsts);
EPRINTFARGS("SDMMC%d: intsts %04X, errintsts %04X", sdmmc->id + 1, norintsts, errintsts);
#endif
sdmmc->error_sts = errintsts;
sdmmc->regs->errintsts = errintsts;
@@ -1128,7 +1128,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
{
#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC%d: Wrong Response type %08X!", sdmmc->id + 1, cmd->rsp_type);
EPRINTFARGS("SDMMC%d: Wrong Response type %d!", sdmmc->id + 1, cmd->rsp_type);
#endif
return 1;
}

View File

@@ -968,4 +968,6 @@ static const kip1_id_t _kip_ids[] =
{ "FS", "\x56\x25\x17\xA1\x92\xC3\xC8\xF0", _fs_patches_2100_exfat }, // FS 21.2.0 exFAT
{ "FS", "\xB7\xA2\x97\x39\xB7\xED\xDE\xFC", _fs_patches_2200 }, // FS 22.0.0
{ "FS", "\xFB\x0B\x68\xDB\x24\x03\xD1\x19", _fs_patches_2200_exfat }, // FS 22.0.0 exFAT
{ "FS", "\x53\x6D\x93\x84\x69\xFE\x73\xBE", _fs_patches_2200 }, // FS 22.5.0
{ "FS", "\xD4\x45\x28\x29\x5B\x41\x92\xBA", _fs_patches_2200_exfat }, // FS 22.5.0 exFAT
};

View File

@@ -1426,7 +1426,7 @@ ment_t ment_top[] = {
MDEF_END()
};
menu_t menu_top = { ment_top, "hekate v6.5.2", 0, 0 };
menu_t menu_top = { ment_top, "hekate v6.5.3", 0, 0 };
extern void pivot_stack(u32 stack_top);

View File

@@ -413,7 +413,7 @@ hw_info_t *hw_info = NULL;
//! TODO: Limits assumed based on known samples.
#define WAFER_20NM_X_MIN -9
#define WAFER_20NM_X_MAX 15
#define WAFER_20NM_X_MAX 16
#define WAFER_20NM_Y_MIN 1
#define WAFER_20NM_Y_MAX 24
@@ -1618,8 +1618,171 @@ static lv_res_t _create_mbox_emmc_sandisk_report(lv_obj_t * btn)
out:
free(buf);
free (txt_buf);
free (txt_buf2);
free(txt_buf);
free(txt_buf2);
lv_mbox_add_btns(mbox, mbox_btn_map, nyx_mbox_action); // Important. After set_text.
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_top(mbox, true);
return LV_RES_OK;
}
static lv_res_t _create_mbox_sd_vendor_info(lv_obj_t * btn)
{
lv_obj_t *dark_bg = lv_obj_create(lv_layer_top(), NULL);
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
static const char * mbox_btn_map[] = { "\251", "\222Close", "\251", "" };
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
lv_mbox_set_text(mbox, "#C7EA46 SD Vendor/Reserved Data#\nPlease wait..");
manual_system_maintenance(true);
u8 *buf = zalloc(EMMC_BLOCKSIZE);
char *txt_buf = (char *)malloc(SZ_32K);
char *txt_buf2 = (char *)malloc(SZ_32K);
txt_buf[0] = 0;
txt_buf2[0] = 0;
// Create SoC Info container.
lv_obj_t *h1 = lv_cont_create(mbox, NULL);
lv_cont_set_style(h1, &lv_style_transp_tight);
lv_cont_set_fit(h1, false, true);
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 4);
lv_obj_set_click(h1, false);
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
lv_obj_t * lb_desc = lv_label_create(h1, NULL);
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
lv_label_set_recolor(lb_desc, true);
lv_label_set_style(lb_desc, &monospace_text);
lv_obj_set_width(lb_desc, LV_HOR_RES / 9 * 2);
lv_obj_t * lb_desc2 = lv_label_create(h1, NULL);
lv_label_set_long_mode(lb_desc2, LV_LABEL_LONG_BREAK);
lv_label_set_recolor(lb_desc2, true);
lv_label_set_style(lb_desc2, &monospace_text);
lv_obj_set_width(lb_desc2, LV_HOR_RES / 9 * 2);
lv_obj_align(lb_desc2, lb_desc, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
if (sd_mount())
{
lv_label_set_text(lb_desc, "#FFDD00 Failed to init SD!#");
goto out;
}
sd_vendor_info_t sd_info;
sd_storage_get_vendor_info(&sd_storage, &sd_info);
s_printf(txt_buf,
"#00DDFF Vendor/Reserved Registers#\n"
"#FF8000 CID[023:020]:# %X\n\n"
"#FF8000 CSD[009:008]:# %X\n"
"#FF8000 CSD[020:016]:# %02X\n"
"#FF8000 CSD[030:029]:# %X\n"
"#FF8000 CSD[125:120]:# %02X\n"
"#FF8000 SCR Vendor:# %08X\n"
"#FF8000 SCR[037:036]:# %X\n\n"
"#FF8000 SSR[031:000]:# %08X\n"
"#FF8000 SSR[063:032]:# %08X\n"
"#FF8000 SSR[095:064]:# %08X\n"
"#FF8000 SSR[127:096]:# %08X\n"
"#FF8000 SSR[159:128]:# %08X\n"
"#FF8000 SSR[191:160]:# %08X\n"
"#FF8000 SSR[223:192]:# %08X\n"
"#FF8000 SSR[255:224]:# %08X\n"
"#FF8000 SSR[287:256]:# %08X\n"
"#FF8000 SSR[311:288]:# %06X",
sd_info.cid_rsvd,
sd_info.csd_rsvd8_9,
sd_info.csd_rsvd16_20,
sd_info.csd_rsvd29_30,
sd_info.csd_rsvd120_125,
sd_info.scr_vendor,
sd_info.scr_rsvd,
sd_info.ssr_vendor0_31,
sd_info.ssr_vendor32_63,
sd_info.ssr_vendor64_95,
sd_info.ssr_vendor96_127,
sd_info.ssr_vendor128_159,
sd_info.ssr_vendor160_191,
sd_info.ssr_vendor192_223,
sd_info.ssr_vendor224_255,
sd_info.ssr_vendor256_287,
sd_info.ssr_vendor288_311);
s_printf(txt_buf2,
"#FF8000 SSR[327:314]:# %04X\n"
"#FF8000 SSR[345:340]:# %02X\n"
"#FF8000 SSR[383:378]:# %02X\n"
"#FF8000 SSR[427:424]:# %X\n"
"#FF8000 SSR[501:496]:# %02X\n\n",
sd_info.ssr_rsvd314_327,
sd_info.ssr_rsvd340_345,
sd_info.ssr_rsvd378_383,
sd_info.ssr_rsvd424_427,
sd_info.ssr_rsvd496_501);
if (!sdmmc_storage_gen_cmd(&sd_storage, 0x00000001, buf))
{
const u32 health_rpt_args[] = {
0x00000001, // Sandisk.
0x11000001, // ATP.
0x110005F1, // AData.
0x110005F3,
0x110005F5,
0x110005F7,
0x110005F9, // Transcend.
0x110005FB, // Micron.
0x110005FD, // Innodisk.
0x110005FF,
(sd_storage.rca << 16) | 1,
(sd_storage.cid.oemid << 16) | 1, // 0x53420001: Swissbit.
// 0x00000010, // Apacer, 2-Step.
// 0x00000021,
};
strcpy(txt_buf2 + strlen(txt_buf2), "#00DDFF Health Report Data#");
for (u32 i = 0; i < ARRAY_SIZE(health_rpt_args); i++)
{
sdmmc_storage_gen_cmd(&sd_storage, health_rpt_args[i], buf);
u8 test = 0;
for (u32 i = 0; i < 512; i++)
test |= buf[i];
if (test)
s_printf(txt_buf2 + strlen(txt_buf2), "\n#FF8000 %08X:# Has data!", health_rpt_args[i]);
else
s_printf(txt_buf2 + strlen(txt_buf2), "\n#FF8000 %08X:# Empty", health_rpt_args[i]);
}
}
else
strcpy(txt_buf2 + strlen(txt_buf2), "#00DDFF Health Report Data#\n#FFDD00 Not supported!#");
lv_mbox_set_text(mbox, "#C7EA46 SD Vendor/Reserved Data#");
lv_label_set_text(lb_desc, txt_buf);
lv_label_set_text(lb_desc2, txt_buf2);
sd_unmount();
out:
free(buf);
free(txt_buf);
free(txt_buf2);
lv_mbox_add_btns(mbox, mbox_btn_map, nyx_mbox_action); // Important. After set_text.
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
@@ -2278,6 +2441,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
{
lv_obj_t *win = nyx_create_standard_window(SYMBOL_SD" microSD Card Info", NULL);
lv_win_add_btn(win, NULL, SYMBOL_SD" Benchmark", _create_mbox_sd_bench);
lv_win_add_btn(win, NULL, SYMBOL_FILE_ALT" Vendor Registers", _create_mbox_sd_vendor_info);
lv_obj_t *desc = lv_cont_create(win, NULL);
lv_obj_set_size(desc, LV_HOR_RES / 2 / 6 * 2, LV_VER_RES - (LV_DPI * 11 / 8) * 5 / 2);
@@ -2301,7 +2465,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
}
lv_label_set_text(lb_desc,
"#00DDFF Card ID:#\n"
"#00DDFF Card ID#\n"
"Vendor ID:\n"
"Model:\n"
"OEM ID:\n"
@@ -2319,8 +2483,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
char *txt_buf = (char *)malloc(SZ_16K);
txt_buf[0] = '\n';
txt_buf[1] = 0;
s_printf(txt_buf, "#00DDFF v%d.00#\n", sd_storage_get_scr_sda_ver(&sd_storage));
// Identify manufacturer.
switch (sd_storage.cid.manfid)
@@ -2361,6 +2524,9 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
case 0x1D:
strcat(txt_buf, "AData ");
break;
case 0x22:
strcat(txt_buf, "Kowin"); // #E: Digiera.
break;
case 0x27:
strcat(txt_buf, "Phison ");
break;
@@ -2389,7 +2555,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
strcat(txt_buf, "Bongiovi ");
break;
case 0x74:
strcat(txt_buf, "Jiaelec ");
strcat(txt_buf, "Jiaelec "); // Transcend.
break;
case 0x76:
strcat(txt_buf, "Patriot ");
@@ -2413,7 +2579,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
strcat(txt_buf, "Taishin ");
break;
case 0xAD:
strcat(txt_buf, "Longsys ");
strcat(txt_buf, "Longsys "); // Lexar/FORESEE.
break;
default:
strcat(txt_buf, "Unknown ");
@@ -2423,13 +2589,38 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
// UHS-I max power limit is 400mA, no matter what the card says.
u32 max_power_nominal = sd_storage.max_power > 400 ? 400 : sd_storage.max_power;
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c\n%c%c (%04X)\n%X\n%X\n%08x\n%02d/%04d\n\n%d mW (%d mA)\n",
// Check for secret bits.
bool secret_bits = false;
sd_vendor_info_t sd_info = { 0 };
sd_storage_get_vendor_info(&sd_storage, &sd_info);
// Partially known bits.
if (sd_info.cid_rsvd && sd_info.cid_rsvd != 0x7 && sd_info.cid_rsvd != 0xA)
secret_bits = true;
if (sd_info.scr_vendor &&
sd_info.scr_vendor != 0x33333039 &&
sd_info.scr_vendor != 0x01196432 &&
sd_info.scr_vendor != 0x01006432 &&
sd_info.scr_vendor != 0x01000000)
secret_bits = true;
// Unknown bits.
sd_info.cid_rsvd = 0;
sd_info.scr_vendor = 0;
u8 *sd_info8 = (u8 *)&sd_info;
for (u32 i = 0; i < sizeof(sd_vendor_info_t); i++)
secret_bits |= !!sd_info8[i];
gfx_hexdump(0, sd_info8, sizeof(sd_vendor_info_t));
s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c\n%c%c (%04X)\n%X\n%X\n%08x\n%02d/%04d\n%s\n%d mW (%d mA)\n",
sd_storage.cid.manfid,
sd_storage.cid.prod_name[0], sd_storage.cid.prod_name[1], sd_storage.cid.prod_name[2],
sd_storage.cid.prod_name[3], sd_storage.cid.prod_name[4],
(sd_storage.cid.oemid >> 8) & 0xFF, sd_storage.cid.oemid & 0xFF, sd_storage.cid.oemid,
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
sd_storage.cid.month, sd_storage.cid.year,
secret_bits ? "#FF8000 Contact me#" : "",
max_power_nominal * 3600 / 1000, sd_storage.max_power);
switch (nyx_str->info.sd_init)
@@ -2467,10 +2658,11 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
"Capacity (LBA):\n"
"Bus Width:\n"
"Current Rate:\n"
"Max Bus Speed:\n"
"Speed Class:\n"
"UHS Classes:\n"
"Max Bus Speed:\n\n"
"Write Protect:"
"Write Protect:\n"
"Vendor Info:"
);
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 5 * 3, 0);
@@ -2483,15 +2675,15 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
char *wp_info;
switch (sd_storage.csd.write_protect)
{
case 0:
wp_info = "Inactive";
break;
case 1:
wp_info = "Temporary";
break;
case 2:
case 3:
wp_info = "Permanent";
break;
case 2 ... 3:
default:
wp_info = "None";
wp_info = "Permanent";
break;
}
@@ -2507,7 +2699,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
sd_storage_get_fmodes(&sd_storage, NULL, &fmodes);
char *bus_speed;
if (fmodes.cmd_system & SD_MODE_UHS_DDR200)
if (sd_storage_get_ddr200_support(&sd_storage))
bus_speed = "DDR200";
else if (fmodes.access_mode & SD_MODE_UHS_SDR104)
bus_speed = "SDR104";
@@ -2563,10 +2755,11 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
"%X (CP %X)\n"
"%d\n"
"%d MB/s (%d MHz)\n"
"%s%s\n"
"%d (AU: %d %s\n"
"U%d V%d %sA%d%s\n"
"%s\n\n"
"%s",
"%s\n"
"%X %08X",
sd_storage.csd.structure + 1,
sd_storage.csd.cmdclass,
sd_storage.sec_cnt >> 11,
@@ -2574,10 +2767,11 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
sd_storage.ssr.bus_width,
sd_storage.csd.busspeed,
(sd_storage.csd.busspeed > 10) ? (sd_storage.csd.busspeed * 2) : 50,
bus_speed, sd_storage.has_pcie ? " | SDE985" : "", // PCIe G3L1 (985 MB/s).
sd_storage.ssr.speed_class, uhs_au_size, uhs_au_mb ? "MiB)" : "KiB)",
sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class, cpe ? cpe : "", sd_storage.ssr.app_class, cpe ? "#" : "",
bus_speed,
wp_info);
wp_info,
sd_storage.cid.rsvd, sd_storage.scr.vendor);
lv_label_set_text(lb_val2, txt_buf);
@@ -2767,28 +2961,33 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
value = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);
u32 main_pmic_version = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID3) & 0xF;
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d%s\n",
main_pmic_version, main_pmic_version == 11 ? "" : "#FF8000 "SYMBOL_WARNING"#");
if (value == 0x35)
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d\nErista OTP\n", main_pmic_version);
strcat(txt_buf, "Erista OTP\n");
else if (value == 0x53)
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d\nMariko OTP\n", main_pmic_version);
strcat(txt_buf, "Mariko OTP\n");
else
s_printf(txt_buf + strlen(txt_buf), "max77620 v%d\n#FF8000 Unknown OTP# (%02X)\n", main_pmic_version, value);
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Unknown OTP# (%02X)\n", value);
// CPU/GPU/DRAM Pmic IC info.
u32 cpu_gpu_pmic_type = h_cfg.t210b01 ? (FUSE(FUSE_RESERVED_ODM28_B01) & 1) + 1 : 0;
u8 version;
switch (cpu_gpu_pmic_type)
{
case 0:
s_printf(txt_buf + strlen(txt_buf), "max77621 v%d",
i2c_recv_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_REG_CHIPID1));
version = i2c_recv_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_REG_CHIPID1);
s_printf(txt_buf + strlen(txt_buf), "max77621 v%d%s",
version , version == 18 ? "" : "#FF8000 "SYMBOL_WARNING"#");
break;
case 1:
s_printf(txt_buf + strlen(txt_buf), "max77812-2 v%d", // High power GPU. 2 Outputs, phases 3 1.
s_printf(txt_buf + strlen(txt_buf), "max77812-2 v%d", // High power GPU. 2 Outputs, phases 3 1.
i2c_recv_byte(I2C_5, MAX77812_PHASE31_CPU_I2C_ADDR, MAX77812_REG_VERSION) & 7);
break;
case 2:
s_printf(txt_buf + strlen(txt_buf), "max77812-3 v%d.0", // Low power GPU. 3 Outputs, phases 2 1 1.
i2c_recv_byte(I2C_5, MAX77812_PHASE211_CPU_I2C_ADDR, MAX77812_REG_VERSION) & 7);
version = i2c_recv_byte(I2C_5, MAX77812_PHASE211_CPU_I2C_ADDR, MAX77812_REG_VERSION) & 7;
s_printf(txt_buf + strlen(txt_buf), "max77812-3 v%d%s", // Low power GPU. 3 Outputs, phases 2 1 1.
version, version == 5 ? "" : "#FF8000 "SYMBOL_WARNING"#");
break;
}

View File

@@ -968,7 +968,7 @@ static u32 _get_available_l4t_partition()
// Search for a suitable partition.
u32 size_sct = 0;
if (!memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128)
if (!memcmp(&gpt->header.signature, "EFI PART", 8) && gpt->header.num_part_ents <= 128)
{
for (u32 i = 0; i < gpt->header.num_part_ents; i++)
{