diff --git a/bsp/qemu-virt64-aarch64/.config b/bsp/qemu-virt64-aarch64/.config index a0bd1c61320c..230eee8a3951 100644 --- a/bsp/qemu-virt64-aarch64/.config +++ b/bsp/qemu-virt64-aarch64/.config @@ -272,7 +272,7 @@ CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y CONFIG_RT_DFS_ELM_LFN_UNICODE=0 CONFIG_RT_DFS_ELM_MAX_LFN=255 CONFIG_RT_DFS_ELM_DRIVES=2 -CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 # CONFIG_RT_DFS_ELM_USE_ERASE is not set CONFIG_RT_DFS_ELM_REENTRANT=y CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 @@ -311,12 +311,13 @@ CONFIG_RT_SERIAL_8250=y CONFIG_RT_SERIAL_8250_PCI=y # CONFIG_RT_SERIAL_VIRTUAL is not set # CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_ADC is not set CONFIG_RT_USING_CLOCK_TIME=y +# CONFIG_RT_USING_CLOCK_TIMER_TRIGGER is not set CONFIG_RT_CLOCK_TIME_ARM_ARCH=y # CONFIG_RT_USING_I2C is not set # CONFIG_RT_USING_PHY is not set # CONFIG_RT_USING_PHY_V2 is not set -# CONFIG_RT_USING_ADC is not set # CONFIG_RT_USING_DAC is not set CONFIG_RT_USING_NULL=y CONFIG_RT_USING_ZERO=y @@ -384,6 +385,7 @@ CONFIG_RT_HWCRYPTO_USING_RNG=y # CONFIG_RT_HWCRYPTO_USING_CRC is not set # CONFIG_RT_HWCRYPTO_USING_BIGNUM is not set # CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_PTP is not set # CONFIG_RT_USING_LED is not set CONFIG_RT_USING_INPUT=y CONFIG_RT_INPUT_POWER=y @@ -425,6 +427,7 @@ CONFIG_RT_USING_FIRMWARE=y CONFIG_RT_FIRMWARE_QEMU_FW_CFG=y # CONFIG_RT_FIRMWARE_ARM_SCMI is not set # CONFIG_RT_USING_HWCACHE is not set +# CONFIG_RT_USING_DVFS is not set CONFIG_RT_USING_REGULATOR=y # CONFIG_RT_REGULATOR_GPIO is not set CONFIG_RT_USING_RESET=y @@ -614,7 +617,7 @@ CONFIG_RT_INIT_MEMORY_REGIONS=128 # end of Using USB legacy version # CONFIG_RT_USING_FDT is not set -# CONFIG_BSP_USING_VIRTIO is not set +# CONFIG_RT_USING_LEGACY_VIRTIO is not set # CONFIG_RT_USING_RUST is not set # end of RT-Thread Components diff --git a/bsp/qemu-virt64-aarch64/rtconfig.h b/bsp/qemu-virt64-aarch64/rtconfig.h index 2cdc28737297..986a95341fd6 100644 --- a/bsp/qemu-virt64-aarch64/rtconfig.h +++ b/bsp/qemu-virt64-aarch64/rtconfig.h @@ -183,7 +183,7 @@ #define RT_DFS_ELM_LFN_UNICODE 0 #define RT_DFS_ELM_MAX_LFN 255 #define RT_DFS_ELM_DRIVES 2 -#define RT_DFS_ELM_MAX_SECTOR_SIZE 512 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 #define RT_DFS_ELM_REENTRANT #define RT_DFS_ELM_MUTEX_TIMEOUT 3000 /* end of elm-chan's FatFs, Generic FAT Filesystem Module */ diff --git a/components/drivers/block/partitions/efi.c b/components/drivers/block/partitions/efi.c index 22f6ba165910..58c68cc98b9c 100644 --- a/components/drivers/block/partitions/efi.c +++ b/components/drivers/block/partitions/efi.c @@ -93,8 +93,8 @@ rt_inline int pmbr_part_valid(gpt_mbr_record *part) */ static int is_pmbr_valid(legacy_mbr *mbr, rt_size_t total_sectors) { - rt_uint32_t sz = 0; - int part = 0, ret = 0; /* invalid by default */ + rt_uint32_t sz = 0; + int part = 0, ret = 0; /* invalid by default */ if (!mbr || rt_le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) { @@ -151,7 +151,7 @@ static int is_pmbr_valid(legacy_mbr *mbr, rt_size_t total_sectors) if (sz != (rt_uint32_t)total_sectors - 1 && sz != 0xffffffff) { LOG_W("GPT: mbr size in lba (%u) different than whole disk (%u)", - sz, rt_min_t(rt_uint32_t, total_sectors - 1, 0xffffffff)); + sz, rt_min_t(rt_uint32_t, total_sectors - 1, 0xffffffff)); } } @@ -169,31 +169,108 @@ static int is_pmbr_valid(legacy_mbr *mbr, rt_size_t total_sectors) * @return number of bytes read on success, 0 on error. */ static rt_size_t read_lba(struct rt_blk_disk *disk, - rt_uint64_t lba, rt_uint8_t *buffer, rt_size_t count) + rt_uint64_t lba, rt_uint8_t *buffer, rt_size_t count) { - rt_size_t totalreadcount = 0; + rt_uint32_t lbs; + rt_ssize_t cap_ss, lbs_ss; + rt_size_t totalreadcount = 0; + rt_uint8_t *secbuf = RT_NULL; + rt_uint64_t capacity, disk_bytes, n512; - if (!buffer || lba > last_lba(disk)) + if (!buffer || count == 0) { return 0; } - for (rt_uint64_t n = lba; count; ++n) + cap_ss = rt_blk_disk_get_capacity(disk); + lbs_ss = rt_blk_disk_get_logical_block_size(disk); + if (cap_ss < 0 || lbs_ss < 0) { - int copied = 512; + return 0; + } + + lbs = (rt_uint32_t)lbs_ss; + capacity = (rt_uint64_t)cap_ss; + + if (lbs < 512 || (lbs % 512) != 0) + { + return 0; + } + + if (lba >= capacity) + { + return 0; + } - disk->ops->read(disk, n, buffer, 1); + disk_bytes = capacity * (rt_uint64_t)lbs; + n512 = lba * ((rt_uint64_t)lbs / 512); - if (copied > count) + secbuf = rt_malloc(lbs); + if (!secbuf) + { + return 0; + } + + while (count > 0) + { + int copied = 512; + rt_ssize_t rd; + rt_uint32_t off; + rt_uint64_t log_sec, byte_off = n512 * 512; + + if (byte_off >= disk_bytes) { - copied = count; + break; } - buffer += copied; + if (copied > (int)count) + { + copied = (int)count; + } + + if ((rt_uint64_t)copied > disk_bytes - byte_off) + { + copied = (int)(disk_bytes - byte_off); + } + + log_sec = byte_off / lbs; + off = (rt_uint32_t)(byte_off % lbs); + + if (off + (rt_uint32_t)copied <= lbs) + { + rd = disk->ops->read(disk, (rt_off_t)log_sec, secbuf, 1); + if (rd != 1) + { + break; + } + rt_memcpy(buffer, secbuf + off, copied); + } + else + { + rt_uint32_t first = lbs - off; + + rd = disk->ops->read(disk, (rt_off_t)log_sec, secbuf, 1); + if (rd != 1) + { + break; + } + rt_memcpy(buffer, secbuf + off, first); + + rd = disk->ops->read(disk, (rt_off_t)(log_sec + 1), secbuf, 1); + if (rd != 1) + { + break; + } + rt_memcpy(buffer + first, secbuf, copied - first); + } + + buffer += copied; totalreadcount += copied; - count -= copied; + count -= copied; + ++n512; } + rt_free(secbuf); return totalreadcount; } @@ -205,10 +282,10 @@ static rt_size_t read_lba(struct rt_blk_disk *disk, * @return ptes on success, null on error. */ static gpt_entry *alloc_read_gpt_entries(struct rt_blk_disk *disk, - gpt_header *gpt) + gpt_header *gpt) { - rt_size_t count; - gpt_entry *pte; + rt_size_t count; + gpt_entry *pte; rt_uint64_t entry_lba; if (!gpt) @@ -255,7 +332,14 @@ static gpt_entry *alloc_read_gpt_entries(struct rt_blk_disk *disk, static gpt_header *alloc_read_gpt_header(struct rt_blk_disk *disk, rt_uint64_t lba) { gpt_header *gpt; - rt_uint32_t ssz = rt_blk_disk_get_logical_block_size(disk); + rt_uint32_t ssz; + rt_ssize_t lbs_ss = rt_blk_disk_get_logical_block_size(disk); + + if (lbs_ss <= 0) + { + return RT_NULL; + } + ssz = (rt_uint32_t)lbs_ss; gpt = rt_malloc(ssz); @@ -287,11 +371,11 @@ static gpt_header *alloc_read_gpt_header(struct rt_blk_disk *disk, rt_uint64_t l * If valid, returns pointers to newly allocated GPT header and PTEs. */ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, - rt_uint64_t lba, gpt_header **gpt, gpt_entry **ptes) + rt_uint64_t lba, gpt_header **gpt, gpt_entry **ptes) { rt_uint32_t crc, origcrc; rt_uint64_t lastlba, pt_size; - rt_ssize_t logical_block_size; + rt_ssize_t logical_block_size; if (!ptes) { @@ -307,22 +391,26 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, if (rt_le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) { LOG_D("%s: GUID Partition Table Header signature is wrong: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->signature), - (rt_uint64_t)GPT_HEADER_SIGNATURE); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu((*gpt)->signature), + (rt_uint64_t)GPT_HEADER_SIGNATURE); goto _fail; } /* Check the GUID Partition Table header size is too big */ logical_block_size = rt_blk_disk_get_logical_block_size(disk); + if (logical_block_size <= 0) + { + goto _fail; + } - if (rt_le32_to_cpu((*gpt)->header_size) > logical_block_size) + if (rt_le32_to_cpu((*gpt)->header_size) > (rt_uint32_t)logical_block_size) { LOG_D("%s: GUID Partition Table Header size is too large: %u > %u", - to_disk_name(disk), - rt_le32_to_cpu((*gpt)->header_size), - logical_block_size); + to_disk_name(disk), + rt_le32_to_cpu((*gpt)->header_size), + (rt_uint32_t)logical_block_size); goto _fail; } @@ -331,22 +419,22 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, if (rt_le32_to_cpu((*gpt)->header_size) < sizeof(gpt_header)) { LOG_D("%s: GUID Partition Table Header size is too small: %u < %u", - to_disk_name(disk), - rt_le32_to_cpu((*gpt)->header_size), - sizeof(gpt_header)); + to_disk_name(disk), + rt_le32_to_cpu((*gpt)->header_size), + sizeof(gpt_header)); goto _fail; } /* Check the GUID Partition Table CRC */ - origcrc = rt_le32_to_cpu((*gpt)->header_crc32); + origcrc = rt_le32_to_cpu((*gpt)->header_crc32); (*gpt)->header_crc32 = 0; - crc = efi_crc32((const rt_uint8_t *)(*gpt), rt_le32_to_cpu((*gpt)->header_size)); + crc = efi_crc32((const rt_uint8_t *)(*gpt), rt_le32_to_cpu((*gpt)->header_size)); if (crc != origcrc) { LOG_D("%s: GUID Partition Table Header CRC is wrong: %x != %x", - to_disk_name(disk), crc, origcrc); + to_disk_name(disk), crc, origcrc); goto _fail; } @@ -360,9 +448,9 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, if (rt_le64_to_cpu((*gpt)->start_lba) != lba) { LOG_D("%s: GPT start_lba incorrect: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->start_lba), - (rt_uint64_t)lba); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu((*gpt)->start_lba), + (rt_uint64_t)lba); goto _fail; } @@ -373,9 +461,9 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, if (rt_le64_to_cpu((*gpt)->first_usable_lba) > lastlba) { LOG_D("%s: GPT: first_usable_lba incorrect: %lld > %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba), - (rt_uint64_t)lastlba); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba), + (rt_uint64_t)lastlba); goto _fail; } @@ -383,18 +471,18 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, if (rt_le64_to_cpu((*gpt)->last_usable_lba) > lastlba) { LOG_D("%s: GPT: last_usable_lba incorrect: %lld > %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba), - (rt_uint64_t)lastlba); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba), + (rt_uint64_t)lastlba); goto _fail; } if (rt_le64_to_cpu((*gpt)->last_usable_lba) < rt_le64_to_cpu((*gpt)->first_usable_lba)) { LOG_D("%s: GPT: last_usable_lba incorrect: %lld > %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba)); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba), + (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba)); goto _fail; } @@ -409,7 +497,7 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, /* Sanity check partition table size */ pt_size = (rt_uint64_t)rt_le32_to_cpu((*gpt)->num_partition_entries) * - rt_le32_to_cpu((*gpt)->sizeof_partition_entry); + rt_le32_to_cpu((*gpt)->sizeof_partition_entry); if (pt_size > (rt_uint64_t)RT_UINT32_MAX) { @@ -473,7 +561,7 @@ rt_inline rt_bool_t is_pte_valid(const gpt_entry *pte, const rt_size_t lastlba) * @param lastlba the last LBA number. */ static void compare_gpts(struct rt_blk_disk *disk, - gpt_header *pgpt, gpt_header *agpt, rt_uint64_t lastlba) + gpt_header *pgpt, gpt_header *agpt, rt_uint64_t lastlba) { int error_found = 0; @@ -485,9 +573,9 @@ static void compare_gpts(struct rt_blk_disk *disk, if (rt_le64_to_cpu(pgpt->start_lba) != rt_le64_to_cpu(agpt->alternate_lba)) { LOG_W("%s: GPT:Primary header LBA(%lld) != Alt(%lld), header alternate_lba", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->start_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->alternate_lba)); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu(pgpt->start_lba), + (rt_uint64_t)rt_le64_to_cpu(agpt->alternate_lba)); ++error_found; } @@ -495,9 +583,9 @@ static void compare_gpts(struct rt_blk_disk *disk, if (rt_le64_to_cpu(pgpt->alternate_lba) != rt_le64_to_cpu(agpt->start_lba)) { LOG_W("%s: GPT:Primary header alternate_lba(%lld) != Alt(%lld), header start_lba", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba)); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba), + (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba)); ++error_found; } @@ -505,9 +593,9 @@ static void compare_gpts(struct rt_blk_disk *disk, if (rt_le64_to_cpu(pgpt->first_usable_lba) != rt_le64_to_cpu(agpt->first_usable_lba)) { LOG_W("%s: GPT:first_usable_lbas don't match %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->first_usable_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->first_usable_lba)); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu(pgpt->first_usable_lba), + (rt_uint64_t)rt_le64_to_cpu(agpt->first_usable_lba)); ++error_found; } @@ -515,9 +603,9 @@ static void compare_gpts(struct rt_blk_disk *disk, if (rt_le64_to_cpu(pgpt->last_usable_lba) != rt_le64_to_cpu(agpt->last_usable_lba)) { LOG_W("%s: GPT:last_usable_lbas don't match %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->last_usable_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->last_usable_lba)); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu(pgpt->last_usable_lba), + (rt_uint64_t)rt_le64_to_cpu(agpt->last_usable_lba)); ++error_found; } @@ -530,34 +618,34 @@ static void compare_gpts(struct rt_blk_disk *disk, } if (rt_le32_to_cpu(pgpt->num_partition_entries) != - rt_le32_to_cpu(agpt->num_partition_entries)) + rt_le32_to_cpu(agpt->num_partition_entries)) { LOG_W("%s: GPT:num_partition_entries don't match: 0x%x != 0x%x", - to_disk_name(disk), - rt_le32_to_cpu(pgpt->num_partition_entries), - rt_le32_to_cpu(agpt->num_partition_entries)); + to_disk_name(disk), + rt_le32_to_cpu(pgpt->num_partition_entries), + rt_le32_to_cpu(agpt->num_partition_entries)); ++error_found; } if (rt_le32_to_cpu(pgpt->sizeof_partition_entry) != - rt_le32_to_cpu(agpt->sizeof_partition_entry)) + rt_le32_to_cpu(agpt->sizeof_partition_entry)) { LOG_W("%s: GPT:sizeof_partition_entry values don't match: 0x%x != 0x%x", - to_disk_name(disk), - rt_le32_to_cpu(pgpt->sizeof_partition_entry), - rt_le32_to_cpu(agpt->sizeof_partition_entry)); + to_disk_name(disk), + rt_le32_to_cpu(pgpt->sizeof_partition_entry), + rt_le32_to_cpu(agpt->sizeof_partition_entry)); ++error_found; } if (rt_le32_to_cpu(pgpt->partition_entry_array_crc32) != - rt_le32_to_cpu(agpt->partition_entry_array_crc32)) + rt_le32_to_cpu(agpt->partition_entry_array_crc32)) { LOG_W("%s: GPT:partition_entry_array_crc32 values don't match: 0x%x != 0x%x", - to_disk_name(disk), - rt_le32_to_cpu(pgpt->partition_entry_array_crc32), - rt_le32_to_cpu(agpt->partition_entry_array_crc32)); + to_disk_name(disk), + rt_le32_to_cpu(pgpt->partition_entry_array_crc32), + rt_le32_to_cpu(agpt->partition_entry_array_crc32)); ++error_found; } @@ -565,9 +653,9 @@ static void compare_gpts(struct rt_blk_disk *disk, if (rt_le64_to_cpu(pgpt->alternate_lba) != lastlba) { LOG_W("%s: GPT:Primary header thinks Alt. header is not at the end of the disk: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba), - (rt_uint64_t)lastlba); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba), + (rt_uint64_t)lastlba); ++error_found; } @@ -575,9 +663,9 @@ static void compare_gpts(struct rt_blk_disk *disk, if (rt_le64_to_cpu(agpt->start_lba) != lastlba) { LOG_W("%s: GPT:Alternate GPT header not at the end of the disk: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba), - (rt_uint64_t)lastlba); + to_disk_name(disk), + (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba), + (rt_uint64_t)lastlba); ++error_found; } @@ -605,20 +693,27 @@ static void compare_gpts(struct rt_blk_disk *disk, * the user to decide to use the Alternate GPT. */ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, - gpt_header **gpt, gpt_entry **ptes) + gpt_header **gpt, gpt_entry **ptes) { - int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; + int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; gpt_header *pgpt = RT_NULL, *agpt = RT_NULL; - gpt_entry *pptes = RT_NULL, *aptes = RT_NULL; + gpt_entry *pptes = RT_NULL, *aptes = RT_NULL; legacy_mbr *legacymbr; - rt_size_t total_sectors = rt_blk_disk_get_capacity(disk); - rt_size_t lastlba; + rt_ssize_t cap_ss = rt_blk_disk_get_capacity(disk); + rt_size_t total_sectors; + rt_size_t lastlba; if (!ptes) { return RT_FALSE; } + if (cap_ss < 0) + { + return RT_FALSE; + } + total_sectors = (rt_size_t)cap_ss; + lastlba = last_lba(disk); if (!force_gpt) @@ -631,7 +726,11 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, return RT_FALSE; } - read_lba(disk, 0, (rt_uint8_t *)legacymbr, sizeof(*legacymbr)); + if (read_lba(disk, 0, (rt_uint8_t *)legacymbr, sizeof(*legacymbr)) < sizeof(*legacymbr)) + { + rt_free(legacymbr); + return RT_FALSE; + } good_pmbr = is_pmbr_valid(legacymbr, total_sectors); rt_free(legacymbr); @@ -641,7 +740,7 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, } LOG_D("%s: Device has a %s MBR", to_disk_name(disk), - good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : "hybrid"); + good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : "hybrid"); } good_pgpt = is_gpt_valid(disk, GPT_PRIMARY_PARTITION_TABLE_LBA, &pgpt, &pptes); @@ -667,7 +766,7 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, /* The good cases */ if (good_pgpt) { - *gpt = pgpt; + *gpt = pgpt; *ptes = pptes; rt_free(agpt); rt_free(aptes); @@ -681,7 +780,7 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, } else if (good_agpt) { - *gpt = agpt; + *gpt = agpt; *ptes = aptes; rt_free(pgpt); rt_free(pptes); @@ -697,7 +796,7 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, rt_free(pptes); rt_free(aptes); - *gpt = RT_NULL; + *gpt = RT_NULL; *ptes = RT_NULL; return RT_FALSE; @@ -706,8 +805,8 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, rt_err_t efi_partition(struct rt_blk_disk *disk) { rt_uint32_t entries_nr; - gpt_header *gpt = RT_NULL; - gpt_entry *ptes = RT_NULL; + gpt_header *gpt = RT_NULL; + gpt_entry *ptes = RT_NULL; if (!find_valid_gpt(disk, &gpt, &ptes) || !gpt || !ptes) { @@ -722,8 +821,8 @@ rt_err_t efi_partition(struct rt_blk_disk *disk) for (int i = 0; i < entries_nr && i < disk->max_partitions; ++i) { rt_uint64_t start = rt_le64_to_cpu(ptes[i].starting_lba); - rt_uint64_t size = rt_le64_to_cpu(ptes[i].ending_lba) - - rt_le64_to_cpu(ptes[i].starting_lba) + 1ULL; + rt_uint64_t size = rt_le64_to_cpu(ptes[i].ending_lba) - + rt_le64_to_cpu(ptes[i].starting_lba) + 1ULL; if (!is_pte_valid(&ptes[i], last_lba(disk))) { diff --git a/components/drivers/include/drivers/ufs.h b/components/drivers/include/drivers/ufs.h index c38de94e4ab8..f954dabfebb7 100755 --- a/components/drivers/include/drivers/ufs.h +++ b/components/drivers/include/drivers/ufs.h @@ -18,293 +18,293 @@ #include #include -#define __BIT_FIELD(v, h, l) ((v & RT_GENMASK(h, l)) >> l) +#define __BIT_FIELD(v, h, l) ((v & RT_GENMASK(h, l)) >> l) /* Host Capabilities */ -#define RT_UFS_REG_CAP 0x00 /* Host Controller Capabiities */ -#define RT_UFS_REG_CAP_NUTRS(v) __BIT_FIELD(v, 4, 0) /* Number of UTP Transfer Request Slots */ -#define RT_UFS_REG_CAP_NORTT(v) __BIT_FIELD(v, 15, 8) /* Number of outstanding READY TO TRANSFER requests supported */ -#define RT_UFS_REG_CAP_NUTMRS(v) __BIT_FIELD(v, 18, 16) /* Number of UTP Task Management Request Slots */ -#define RT_UFS_REG_CAP_AUTOH8 RT_BIT(23) /* Auto-Hibernation Support */ -#define RT_UFS_REG_CAP_64AS RT_BIT(24) /* 64-bit addressing supported */ -#define RT_UFS_REG_CAP_OODDS RT_BIT(25) /* Out of order data delivery supported */ -#define RT_UFS_REG_CAP_UICDMETMS RT_BIT(26) /* UIC DME_TEST_MODE command supported */ -#define RT_UFS_REG_CAP_UME RT_BIT(27) /* Reserved for Unified Memory Extension */ -#define RT_UFS_REG_VER 0x08 /* UFS Version */ -#define RT_UFS_REG_VER_VS(v) __BIT_FIELD(v, 03, 0) /* Version Suffix (VS) */ -#define RT_UFS_REG_VER_MNR(v) __BIT_FIELD(v, 07, 4) /* Minor Version Number (MNR) */ -#define RT_UFS_REG_VER_MJR(v) __BIT_FIELD(v, 15, 8) /* Major Version Number (MJR) */ -#define RT_UFS_REG_HCPID 0x10 /* Host Controller Identification Descriptor – Product ID */ -#define RT_UFS_REG_HCMID 0x14 /* Host Controller Identification Descriptor – Manufacturer ID */ -#define RT_UFS_REG_HCMID_MIC(v) __BIT_FIELD(v, 7, 0) /* Manufacturer Identification Code */ -#define RT_UFS_REG_HCMID_BI(v) __BIT_FIELD(v, 15, 8) /* Bank Index */ -#define RT_UFS_REG_AHIT 0x18 /* Auto-Hibernate Idle Timer */ -#define RT_UFS_REG_AHIT_AH8ITV(v) __BIT_FIELD(v, 9, 0) /* Auto-Hibern8 Idle Timer Value */ -#define RT_UFS_REG_AHIT_TS(v) __BIT_FIELD(v, 12, 10) /* Timer scale */ +#define RT_UFS_REG_CAP 0x00 /* Host Controller Capabiities */ +#define RT_UFS_REG_CAP_NUTRS(v) __BIT_FIELD(v, 4, 0) /* Number of UTP Transfer Request Slots */ +#define RT_UFS_REG_CAP_NORTT(v) __BIT_FIELD(v, 15, 8) /* Number of outstanding READY TO TRANSFER requests supported */ +#define RT_UFS_REG_CAP_NUTMRS(v) __BIT_FIELD(v, 18, 16) /* Number of UTP Task Management Request Slots */ +#define RT_UFS_REG_CAP_AUTOH8 RT_BIT(23) /* Auto-Hibernation Support */ +#define RT_UFS_REG_CAP_64AS RT_BIT(24) /* 64-bit addressing supported */ +#define RT_UFS_REG_CAP_OODDS RT_BIT(25) /* Out of order data delivery supported */ +#define RT_UFS_REG_CAP_UICDMETMS RT_BIT(26) /* UIC DME_TEST_MODE command supported */ +#define RT_UFS_REG_CAP_UME RT_BIT(27) /* Reserved for Unified Memory Extension */ +#define RT_UFS_REG_VER 0x08 /* UFS Version */ +#define RT_UFS_REG_VER_VS(v) __BIT_FIELD(v, 03, 0) /* Version Suffix (VS) */ +#define RT_UFS_REG_VER_MNR(v) __BIT_FIELD(v, 07, 4) /* Minor Version Number (MNR) */ +#define RT_UFS_REG_VER_MJR(v) __BIT_FIELD(v, 15, 8) /* Major Version Number (MJR) */ +#define RT_UFS_REG_HCPID 0x10 /* Host Controller Identification Descriptor – Product ID */ +#define RT_UFS_REG_HCMID 0x14 /* Host Controller Identification Descriptor – Manufacturer ID */ +#define RT_UFS_REG_HCMID_MIC(v) __BIT_FIELD(v, 7, 0) /* Manufacturer Identification Code */ +#define RT_UFS_REG_HCMID_BI(v) __BIT_FIELD(v, 15, 8) /* Bank Index */ +#define RT_UFS_REG_AHIT 0x18 /* Auto-Hibernate Idle Timer */ +#define RT_UFS_REG_AHIT_AH8ITV(v) __BIT_FIELD(v, 9, 0) /* Auto-Hibern8 Idle Timer Value */ +#define RT_UFS_REG_AHIT_TS(v) __BIT_FIELD(v, 12, 10) /* Timer scale */ /* Operation and Runtime */ -#define RT_UFS_REG_IS 0x20 /* Interrupt Status */ -#define RT_UFS_REG_IS_UTRCS RT_BIT(0) /* UTP Transfer Request Completion Status */ -#define RT_UFS_REG_IS_UDEPRI RT_BIT(1) /* UIC DME_ENDPOINTRESET Indication */ -#define RT_UFS_REG_IS_UE RT_BIT(2) /* UIC Error */ -#define RT_UFS_REG_IS_UTMS RT_BIT(3) /* UIC Test Mode Status */ -#define RT_UFS_REG_IS_UPMS RT_BIT(4) /* UIC Power Mode Status */ -#define RT_UFS_REG_IS_UHXS RT_BIT(5) /* UIC Hibernate Exit Status */ -#define RT_UFS_REG_IS_UHES RT_BIT(6) /* UIC Hibernate Enter Status */ -#define RT_UFS_REG_IS_ULLS RT_BIT(7) /* UIC Link Lost Status */ -#define RT_UFS_REG_IS_ULSS RT_BIT(8) /* UIC Link Startup Status */ -#define RT_UFS_REG_IS_UTMRCS RT_BIT(9) /* UTP Task Management Request Completion Status */ -#define RT_UFS_REG_IS_UCCS RT_BIT(10) /* UIC Command Completion Status */ -#define RT_UFS_REG_IS_DFES RT_BIT(11) /* Device Fatal Error Status */ -#define RT_UFS_REG_IS_UTPES RT_BIT(12) /* UTP Error Status */ -#define RT_UFS_REG_IS_HCFES RT_BIT(16) /* Host Controller Fatal Error Status */ -#define RT_UFS_REG_IS_SBFES RT_BIT(17) /* System Bus Fatal Error Status */ -#define RT_UFS_REG_IE 0x24 /* Interrupt Enable */ -#define RT_UFS_REG_IE_UTRCE RT_BIT(0) /* UTP Transfer Request Completion Enable */ -#define RT_UFS_REG_IE_UDEPRIE RT_BIT(1) /* UIC DME_ENDPOINTRESET */ -#define RT_UFS_REG_IE_UEE RT_BIT(2) /* UIC Error Enable */ -#define RT_UFS_REG_IE_UTMSE RT_BIT(3) /* UIC Test Mode Status Enable */ -#define RT_UFS_REG_IE_UPMSE RT_BIT(4) /* UIC Power Mode Status Enable */ -#define RT_UFS_REG_IE_UHXSE RT_BIT(5) /* UIC Hibernate Exit Status Enable */ -#define RT_UFS_REG_IE_UHESE RT_BIT(6) /* UIC Hibernate Enter Status Enable */ -#define RT_UFS_REG_IE_ULLSE RT_BIT(7) /* UIC Link Lost Status Enable */ -#define RT_UFS_REG_IE_ULSSE RT_BIT(8) /* UIC Link Startup Status Enable */ -#define RT_UFS_REG_IE_UTMRCE RT_BIT(9) /* UTP Task Management Request Completion Enable */ -#define RT_UFS_REG_IE_UCCE RT_BIT(10) /* UIC COMMAND Completion Enable */ -#define RT_UFS_REG_IE_DFEE RT_BIT(11) /* Device Fatal Error Enable */ -#define RT_UFS_REG_IE_UTPEE RT_BIT(12) /* UTP Error Enable */ -#define RT_UFS_REG_IE_HCFEE RT_BIT(16) /* Host Controller Fatal Error Enable */ -#define RT_UFS_REG_IE_SBFEE RT_BIT(17) /* System Bus Fatal Error Enable */ -#define RT_UFS_REG_HCS 0x30 /* Host Controller Status */ -#define RT_UFS_REG_HCS_DP RT_BIT(0) /* Device Present */ -#define RT_UFS_REG_HCS_UTRLRDY RT_BIT(1) /* UTP Transfer Request List Ready */ -#define RT_UFS_REG_HCS_UTMRLRDY RT_BIT(2) /* UTP Task Management Request List Ready */ -#define RT_UFS_REG_HCS_UCRDY RT_BIT(3) /* UIC COMMAND Ready */ -#define RT_UFS_REG_HCS_UPMCRS(v) __BIT_FIELD(v, 10, 8) /* UIC Power Mode Change Request Status */ -#define RT_UFS_REG_HCS_UTPEC(v) __BIT_FIELD(v, 15, 12) /* UTP Error Code */ -#define RT_UFS_REG_HCS_TTAGUTPE(v) __BIT_FIELD(v, 23, 16) /* Task Tag of UTP error */ -#define RT_UFS_REG_HCS_TLUNUTPE(v) __BIT_FIELD(v, 31, 24) /* Target LUN of UTP error */ -#define RT_UFS_REG_HCE 0x34 /* Host Controller Enable */ -#define RT_UFS_REG_UECPA 0x38 /* Host UIC Error Code PHY Adapter Layer */ -#define RT_UFS_REG_UECPA_EC(v) __BIT_FIELD(v, 4, 0) /* UIC PHY Adapter Layer Error Code */ -#define RT_UFS_REG_UECPA_ERR RT_BIT(31) /* UIC PHY AdapterA Layer Error */ -#define RT_UFS_REG_UECDL 0x3c /* Host UIC Error Code Data Link Layer */ -#define RT_UFS_REG_UECDL_EC(v) __BIT_FIELD(v, 14, 0) /* UIC Data Link Layer Error Code */ -#define RT_UFS_REG_UECDL_ERR RT_BIT(31) /* UIC Data Link Layer Error */ -#define RT_UFS_REG_UECN 0x40 /* Host UIC Error Code Network Layer */ -#define RT_UFS_REG_UECN_EC(v) __BIT_FIELD(v, 2, 0) /* UIC Network Layer Error Code */ -#define RT_UFS_REG_UECN_ERR RT_BIT(31) /* UIC Network Layer Error */ -#define RT_UFS_REG_UECT 0x44 /* Host UIC Error Code Transport Layer */ -#define RT_UFS_REG_UECT_EC(v) __BIT_FIELD(v, 6, 0) /* UIC Transport Layer Error Code */ -#define RT_UFS_REG_UECT_ERR RT_BIT(31) /* UIC Transport Layer Error */ -#define RT_UFS_REG_UECDME 0x48 /* Host UIC Error Code DME */ -#define RT_UFS_REG_UECDME_EC(v) __BIT_FIELD(v, 0, 0) /* UIC DME Error Code */ -#define RT_UFS_REG_UECDME_ERR RT_BIT(31) /* UIC DME Error */ -#define RT_UFS_REG_UTRIACR 0x4c /* UTP Transfer Request Interrupt Aggregation Control Register */ -#define RT_UFS_REG_UTRIACR_IAEN RT_BIT(31) /* Interrupt Aggregation Enable/Disable */ -#define RT_UFS_REG_UTRIACR_IAPWEN RT_BIT(24) /* Interrupt aggregation parameter write enable */ -#define RT_UFS_REG_UTRIACR_IASB RT_BIT(20) /* Interrupt aggregation status bit */ -#define RT_UFS_REG_UTRIACR_CTR RT_BIT(16) /* Counter and Timer Reset */ -#define RT_UFS_REG_UTRIACR_IACTH(v) __BIT_FIELD(v, 12, 8) /* Interrupt aggregation counter threshold */ -#define RT_UFS_REG_UTRIACR_IATOVAL(v) __BIT_FIELD(v, 7, 0) /* Interrupt aggregation timeout (40us units) */ +#define RT_UFS_REG_IS 0x20 /* Interrupt Status */ +#define RT_UFS_REG_IS_UTRCS RT_BIT(0) /* UTP Transfer Request Completion Status */ +#define RT_UFS_REG_IS_UDEPRI RT_BIT(1) /* UIC DME_ENDPOINTRESET Indication */ +#define RT_UFS_REG_IS_UE RT_BIT(2) /* UIC Error */ +#define RT_UFS_REG_IS_UTMS RT_BIT(3) /* UIC Test Mode Status */ +#define RT_UFS_REG_IS_UPMS RT_BIT(4) /* UIC Power Mode Status */ +#define RT_UFS_REG_IS_UHXS RT_BIT(5) /* UIC Hibernate Exit Status */ +#define RT_UFS_REG_IS_UHES RT_BIT(6) /* UIC Hibernate Enter Status */ +#define RT_UFS_REG_IS_ULLS RT_BIT(7) /* UIC Link Lost Status */ +#define RT_UFS_REG_IS_ULSS RT_BIT(8) /* UIC Link Startup Status */ +#define RT_UFS_REG_IS_UTMRCS RT_BIT(9) /* UTP Task Management Request Completion Status */ +#define RT_UFS_REG_IS_UCCS RT_BIT(10) /* UIC Command Completion Status */ +#define RT_UFS_REG_IS_DFES RT_BIT(11) /* Device Fatal Error Status */ +#define RT_UFS_REG_IS_UTPES RT_BIT(12) /* UTP Error Status */ +#define RT_UFS_REG_IS_HCFES RT_BIT(16) /* Host Controller Fatal Error Status */ +#define RT_UFS_REG_IS_SBFES RT_BIT(17) /* System Bus Fatal Error Status */ +#define RT_UFS_REG_IE 0x24 /* Interrupt Enable */ +#define RT_UFS_REG_IE_UTRCE RT_BIT(0) /* UTP Transfer Request Completion Enable */ +#define RT_UFS_REG_IE_UDEPRIE RT_BIT(1) /* UIC DME_ENDPOINTRESET */ +#define RT_UFS_REG_IE_UEE RT_BIT(2) /* UIC Error Enable */ +#define RT_UFS_REG_IE_UTMSE RT_BIT(3) /* UIC Test Mode Status Enable */ +#define RT_UFS_REG_IE_UPMSE RT_BIT(4) /* UIC Power Mode Status Enable */ +#define RT_UFS_REG_IE_UHXSE RT_BIT(5) /* UIC Hibernate Exit Status Enable */ +#define RT_UFS_REG_IE_UHESE RT_BIT(6) /* UIC Hibernate Enter Status Enable */ +#define RT_UFS_REG_IE_ULLSE RT_BIT(7) /* UIC Link Lost Status Enable */ +#define RT_UFS_REG_IE_ULSSE RT_BIT(8) /* UIC Link Startup Status Enable */ +#define RT_UFS_REG_IE_UTMRCE RT_BIT(9) /* UTP Task Management Request Completion Enable */ +#define RT_UFS_REG_IE_UCCE RT_BIT(10) /* UIC COMMAND Completion Enable */ +#define RT_UFS_REG_IE_DFEE RT_BIT(11) /* Device Fatal Error Enable */ +#define RT_UFS_REG_IE_UTPEE RT_BIT(12) /* UTP Error Enable */ +#define RT_UFS_REG_IE_HCFEE RT_BIT(16) /* Host Controller Fatal Error Enable */ +#define RT_UFS_REG_IE_SBFEE RT_BIT(17) /* System Bus Fatal Error Enable */ +#define RT_UFS_REG_HCS 0x30 /* Host Controller Status */ +#define RT_UFS_REG_HCS_DP RT_BIT(0) /* Device Present */ +#define RT_UFS_REG_HCS_UTRLRDY RT_BIT(1) /* UTP Transfer Request List Ready */ +#define RT_UFS_REG_HCS_UTMRLRDY RT_BIT(2) /* UTP Task Management Request List Ready */ +#define RT_UFS_REG_HCS_UCRDY RT_BIT(3) /* UIC COMMAND Ready */ +#define RT_UFS_REG_HCS_UPMCRS(v) __BIT_FIELD(v, 10, 8) /* UIC Power Mode Change Request Status */ +#define RT_UFS_REG_HCS_UTPEC(v) __BIT_FIELD(v, 15, 12) /* UTP Error Code */ +#define RT_UFS_REG_HCS_TTAGUTPE(v) __BIT_FIELD(v, 23, 16) /* Task Tag of UTP error */ +#define RT_UFS_REG_HCS_TLUNUTPE(v) __BIT_FIELD(v, 31, 24) /* Target LUN of UTP error */ +#define RT_UFS_REG_HCE 0x34 /* Host Controller Enable */ +#define RT_UFS_REG_UECPA 0x38 /* Host UIC Error Code PHY Adapter Layer */ +#define RT_UFS_REG_UECPA_EC(v) __BIT_FIELD(v, 4, 0) /* UIC PHY Adapter Layer Error Code */ +#define RT_UFS_REG_UECPA_ERR RT_BIT(31) /* UIC PHY AdapterA Layer Error */ +#define RT_UFS_REG_UECDL 0x3c /* Host UIC Error Code Data Link Layer */ +#define RT_UFS_REG_UECDL_EC(v) __BIT_FIELD(v, 14, 0) /* UIC Data Link Layer Error Code */ +#define RT_UFS_REG_UECDL_ERR RT_BIT(31) /* UIC Data Link Layer Error */ +#define RT_UFS_REG_UECN 0x40 /* Host UIC Error Code Network Layer */ +#define RT_UFS_REG_UECN_EC(v) __BIT_FIELD(v, 2, 0) /* UIC Network Layer Error Code */ +#define RT_UFS_REG_UECN_ERR RT_BIT(31) /* UIC Network Layer Error */ +#define RT_UFS_REG_UECT 0x44 /* Host UIC Error Code Transport Layer */ +#define RT_UFS_REG_UECT_EC(v) __BIT_FIELD(v, 6, 0) /* UIC Transport Layer Error Code */ +#define RT_UFS_REG_UECT_ERR RT_BIT(31) /* UIC Transport Layer Error */ +#define RT_UFS_REG_UECDME 0x48 /* Host UIC Error Code DME */ +#define RT_UFS_REG_UECDME_EC(v) __BIT_FIELD(v, 0, 0) /* UIC DME Error Code */ +#define RT_UFS_REG_UECDME_ERR RT_BIT(31) /* UIC DME Error */ +#define RT_UFS_REG_UTRIACR 0x4c /* UTP Transfer Request Interrupt Aggregation Control Register */ +#define RT_UFS_REG_UTRIACR_IAEN RT_BIT(31) /* Interrupt Aggregation Enable/Disable */ +#define RT_UFS_REG_UTRIACR_IAPWEN RT_BIT(24) /* Interrupt aggregation parameter write enable */ +#define RT_UFS_REG_UTRIACR_IASB RT_BIT(20) /* Interrupt aggregation status bit */ +#define RT_UFS_REG_UTRIACR_CTR RT_BIT(16) /* Counter and Timer Reset */ +#define RT_UFS_REG_UTRIACR_IACTH(v) __BIT_FIELD(v, 12, 8) /* Interrupt aggregation counter threshold */ +#define RT_UFS_REG_UTRIACR_IATOVAL(v) __BIT_FIELD(v, 7, 0) /* Interrupt aggregation timeout (40us units) */ /* UTRIACR compose */ -#define RT_UFS_UTRIACR_TIMEOUT_MASK RT_GENMASK(7, 0) -#define RT_UFS_UTRIACR_COUNTER_THLD_MASK RT_GENMASK(12, 8) -#define RT_UFS_UTRIACR_CTR RT_BIT(16) -#define RT_UFS_UTRIACR_IASB RT_BIT(20) -#define RT_UFS_UTRIACR_IAPWEN RT_BIT(24) -#define RT_UFS_UTRIACR_IAEN RT_BIT(31) -#define RT_UFS_UTRIACR_COUNTER_THLD(c) ((((rt_uint32_t)(c)) & 0x1fu) << 8) -#define RT_UFS_UTRIACR_TIMEOUT(t) (((rt_uint32_t)(t)) & 0xffu) -#define RT_UFS_UTRIACR_ENABLE_PARAMS(cnt, to) (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_IAPWEN | \ - RT_UFS_UTRIACR_COUNTER_THLD(cnt) | RT_UFS_UTRIACR_TIMEOUT(to)) -#define RT_UFS_UTRIACR_RESET (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_CTR) +#define RT_UFS_UTRIACR_TIMEOUT_MASK RT_GENMASK(7, 0) +#define RT_UFS_UTRIACR_COUNTER_THLD_MASK RT_GENMASK(12, 8) +#define RT_UFS_UTRIACR_CTR RT_BIT(16) +#define RT_UFS_UTRIACR_IASB RT_BIT(20) +#define RT_UFS_UTRIACR_IAPWEN RT_BIT(24) +#define RT_UFS_UTRIACR_IAEN RT_BIT(31) +#define RT_UFS_UTRIACR_COUNTER_THLD(c) ((((rt_uint32_t)(c)) & 0x1fu) << 8) +#define RT_UFS_UTRIACR_TIMEOUT(t) (((rt_uint32_t)(t)) & 0xffu) +#define RT_UFS_UTRIACR_ENABLE_PARAMS(cnt, to) (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_IAPWEN | \ + RT_UFS_UTRIACR_COUNTER_THLD(cnt) | RT_UFS_UTRIACR_TIMEOUT(to)) +#define RT_UFS_UTRIACR_RESET (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_CTR) /* UTP Transfer */ -#define RT_UFS_REG_UTRLBA 0x50 /* UTP Transfer Request List Base Address */ -#define RT_UFS_REG_UTRLBA_MASK(v) __BIT_FIELD(v, 31, 10) -#define RT_UFS_REG_UTRLBAU 0x54 /* UTP Transfer Request List Base Address Upper 32-Bits */ -#define RT_UFS_REG_UTRLBAU_MASK(v) __BIT_FIELD(v, 31, 0) -#define RT_UFS_REG_UTRLDBR 0x58 /* UTP Transfer Request List Door Bell Register */ -#define RT_UFS_REG_UTRLCLR 0x5c /* UTP Transfer Request List CLear Register */ -#define RT_UFS_REG_UTRLRSR 0x60 /* UTP Transfer Request Run-Stop Register */ +#define RT_UFS_REG_UTRLBA 0x50 /* UTP Transfer Request List Base Address */ +#define RT_UFS_REG_UTRLBA_MASK(v) __BIT_FIELD(v, 31, 10) +#define RT_UFS_REG_UTRLBAU 0x54 /* UTP Transfer Request List Base Address Upper 32-Bits */ +#define RT_UFS_REG_UTRLBAU_MASK(v) __BIT_FIELD(v, 31, 0) +#define RT_UFS_REG_UTRLDBR 0x58 /* UTP Transfer Request List Door Bell Register */ +#define RT_UFS_REG_UTRLCLR 0x5c /* UTP Transfer Request List CLear Register */ +#define RT_UFS_REG_UTRLRSR 0x60 /* UTP Transfer Request Run-Stop Register */ /* UTP Task Managemeng */ -#define RT_UFS_REG_UTMRLBA 0x70 /* UTP Task Management Request List Base Address */ -#define RT_UFS_REG_UTMRLBA_MASK(v) __BIT_FIELD(v, 31, 10) -#define RT_UFS_REG_UTMRLBAU 0x74 /* UTP Task Management Request List Base Address Upper 32-Bits */ -#define RT_UFS_REG_UTMRLBAU_MASK(v) __BIT_FIELD(v, 31, 0) -#define RT_UFS_REG_UTMRLDBR 0x78 /* UTP Task Management Request List Door Bell Register */ -#define RT_UFS_REG_UTMRLCLR 0x7c /* UTP Task Management Request List CLear Register */ -#define RT_UFS_REG_UTMRLRSR 0x80 /* UTP Task Management Run-Stop Register */ +#define RT_UFS_REG_UTMRLBA 0x70 /* UTP Task Management Request List Base Address */ +#define RT_UFS_REG_UTMRLBA_MASK(v) __BIT_FIELD(v, 31, 10) +#define RT_UFS_REG_UTMRLBAU 0x74 /* UTP Task Management Request List Base Address Upper 32-Bits */ +#define RT_UFS_REG_UTMRLBAU_MASK(v) __BIT_FIELD(v, 31, 0) +#define RT_UFS_REG_UTMRLDBR 0x78 /* UTP Task Management Request List Door Bell Register */ +#define RT_UFS_REG_UTMRLCLR 0x7c /* UTP Task Management Request List CLear Register */ +#define RT_UFS_REG_UTMRLRSR 0x80 /* UTP Task Management Run-Stop Register */ /* UIC Command */ -#define RT_UFS_REG_UICCMD 0x90 /* UIC Command Register */ -#define RT_UFS_REG_UICCMD_CMDOP(v) __BIT_FIELD(v, 7, 0) /* Command Opcode */ -#define RT_UFS_REG_UCMDARG1 0x94 /* UIC Command Argument 1 */ -#define RT_UFS_REG_UCMDARG2 0x98 /* UIC Command Argument 2 */ -#define RT_UFS_REG_UCMDARG3 0x9c /* UIC Command Argument 3 */ +#define RT_UFS_REG_UICCMD 0x90 /* UIC Command Register */ +#define RT_UFS_REG_UICCMD_CMDOP(v) __BIT_FIELD(v, 7, 0) /* Command Opcode */ +#define RT_UFS_REG_UCMDARG1 0x94 /* UIC Command Argument 1 */ +#define RT_UFS_REG_UCMDARG2 0x98 /* UIC Command Argument 2 */ +#define RT_UFS_REG_UCMDARG3 0x9c /* UIC Command Argument 3 */ /* UMA */ -#define RT_UFS_REG_UMA_EXT 0xb0 /* Reserved for Unified Memory Extension */ +#define RT_UFS_REG_UMA_EXT 0xb0 /* Reserved for Unified Memory Extension */ /* Vendor Specific */ -#define RT_UFS_REG_VS 0xc0 /* Vendor Specific Registers */ +#define RT_UFS_REG_VS 0xc0 /* Vendor Specific Registers */ /* UTP Error Code */ enum { - RT_UFS_UTPEC_ERR_INV_TYPE = 1, + RT_UFS_UTPEC_ERR_INV_TYPE = 1, }; /* UIC Power Mode Change Request Status */ enum { - RT_UFS_UPMCRS_PWR_OK = 0x0, - RT_UFS_UPMCRS_PWR_LOCAL = 0x1, - RT_UFS_UPMCRS_PWR_REMOTE = 0x2, - RT_UFS_UPMCRS_PWR_BUSY = 0x3, - RT_UFS_UPMCRS_PWR_ERROR_CAP = 0x4, - RT_UFS_UPMCRS_PWR_FATAL_ERROR = 0x5, + RT_UFS_UPMCRS_PWR_OK = 0x0, + RT_UFS_UPMCRS_PWR_LOCAL = 0x1, + RT_UFS_UPMCRS_PWR_REMOTE = 0x2, + RT_UFS_UPMCRS_PWR_BUSY = 0x3, + RT_UFS_UPMCRS_PWR_ERROR_CAP = 0x4, + RT_UFS_UPMCRS_PWR_FATAL_ERROR = 0x5, }; /* UIC PHY Adapter Layer Error Code */ enum { - RT_UFS_UECPA_EC_LANE0 = RT_BIT(0), - RT_UFS_UECPA_EC_LANE1 = RT_BIT(1), - RT_UFS_UECPA_EC_LANE2 = RT_BIT(2), - RT_UFS_UECPA_EC_LANE3 = RT_BIT(3), - RT_UFS_UECPA_EC_GENERIC = RT_BIT(4), + RT_UFS_UECPA_EC_LANE0 = RT_BIT(0), + RT_UFS_UECPA_EC_LANE1 = RT_BIT(1), + RT_UFS_UECPA_EC_LANE2 = RT_BIT(2), + RT_UFS_UECPA_EC_LANE3 = RT_BIT(3), + RT_UFS_UECPA_EC_GENERIC = RT_BIT(4), }; /* UIC Data Link Layer Error Code */ enum { - RT_UFS_UECDL_EC_NAC_RECEIVED = RT_BIT(0), - RT_UFS_UECDL_EC_TCx_REPLAY_TIMER_EXPIRED = RT_BIT(1), - RT_UFS_UECDL_EC_AFCx_REQUEST_TIMER_EXPIRED = RT_BIT(2), - RT_UFS_UECDL_EC_FCx_PROTECTION_TIMER_EXPIRED = RT_BIT(3), - RT_UFS_UECDL_EC_CRC_ERROR = RT_BIT(4), - RT_UFS_UECDL_EC_RX_BUFFER_OVERFLOW = RT_BIT(5), - RT_UFS_UECDL_EC_MAX_FRAME_LENGTH_EXCEEDED = RT_BIT(6), - RT_UFS_UECDL_EC_WRONG_SEQUENCE_NUMBER = RT_BIT(7), - RT_UFS_UECDL_EC_AFC_FRAME_SYNTAX_ERROR = RT_BIT(8), - RT_UFS_UECDL_EC_NAC_FRAME_SYNTAX_ERROR = RT_BIT(9), - RT_UFS_UECDL_EC_EOF_SYNTAX_ERROR = RT_BIT(10), - RT_UFS_UECDL_EC_FRAME_SYNTAX_ERROR = RT_BIT(11), - RT_UFS_UECDL_EC_BAD_CTRL_SYMBOL_TYPE = RT_BIT(12), - RT_UFS_UECDL_EC_PA_INIT_ERROR = RT_BIT(13), - RT_UFS_UECDL_EC_PA_ERROR_IND_RECEIVED = RT_BIT(14), + RT_UFS_UECDL_EC_NAC_RECEIVED = RT_BIT(0), + RT_UFS_UECDL_EC_TCx_REPLAY_TIMER_EXPIRED = RT_BIT(1), + RT_UFS_UECDL_EC_AFCx_REQUEST_TIMER_EXPIRED = RT_BIT(2), + RT_UFS_UECDL_EC_FCx_PROTECTION_TIMER_EXPIRED = RT_BIT(3), + RT_UFS_UECDL_EC_CRC_ERROR = RT_BIT(4), + RT_UFS_UECDL_EC_RX_BUFFER_OVERFLOW = RT_BIT(5), + RT_UFS_UECDL_EC_MAX_FRAME_LENGTH_EXCEEDED = RT_BIT(6), + RT_UFS_UECDL_EC_WRONG_SEQUENCE_NUMBER = RT_BIT(7), + RT_UFS_UECDL_EC_AFC_FRAME_SYNTAX_ERROR = RT_BIT(8), + RT_UFS_UECDL_EC_NAC_FRAME_SYNTAX_ERROR = RT_BIT(9), + RT_UFS_UECDL_EC_EOF_SYNTAX_ERROR = RT_BIT(10), + RT_UFS_UECDL_EC_FRAME_SYNTAX_ERROR = RT_BIT(11), + RT_UFS_UECDL_EC_BAD_CTRL_SYMBOL_TYPE = RT_BIT(12), + RT_UFS_UECDL_EC_PA_INIT_ERROR = RT_BIT(13), + RT_UFS_UECDL_EC_PA_ERROR_IND_RECEIVED = RT_BIT(14), }; /* UIC Network Layer Error Code */ enum { - RT_UFS_UECN_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0), - RT_UFS_UECN_EC_BAD_DEVICEID_ENC = RT_BIT(1), - RT_UFS_UECN_EC_LHDR_TRAP_PACKET_DROPPING = RT_BIT(2), + RT_UFS_UECN_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0), + RT_UFS_UECN_EC_BAD_DEVICEID_ENC = RT_BIT(1), + RT_UFS_UECN_EC_LHDR_TRAP_PACKET_DROPPING = RT_BIT(2), }; /* UIC Transport Layer Error Code */ enum { - RT_UFS_UECT_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0), - RT_UFS_UECT_EC_UNKNOWN_CPORTID = RT_BIT(1), - RT_UFS_UECT_EC_NO_CONNECTION_RX = RT_BIT(2), - RT_UFS_UECT_EC_CONTROLLED_SEGMENT_DROPPING = RT_BIT(3), - RT_UFS_UECT_EC_BAD_TC = RT_BIT(4), - RT_UFS_UECT_EC_E2E_CREDIT_OVERFLOW = RT_BIT(5), - RT_UFS_UECT_EC_SAFETY_VALVE_DROPPING = RT_BIT(6), + RT_UFS_UECT_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0), + RT_UFS_UECT_EC_UNKNOWN_CPORTID = RT_BIT(1), + RT_UFS_UECT_EC_NO_CONNECTION_RX = RT_BIT(2), + RT_UFS_UECT_EC_CONTROLLED_SEGMENT_DROPPING = RT_BIT(3), + RT_UFS_UECT_EC_BAD_TC = RT_BIT(4), + RT_UFS_UECT_EC_E2E_CREDIT_OVERFLOW = RT_BIT(5), + RT_UFS_UECT_EC_SAFETY_VALVE_DROPPING = RT_BIT(6), }; /* UIC DME Error Code */ enum { - RT_UFS_UECDME_EC_GENERIC = RT_BIT(0), + RT_UFS_UECDME_EC_GENERIC = RT_BIT(0), }; /* UIC Command Opcode */ enum { /* Configuration */ - RT_UFS_CMDOP_DME_GET = 0x1, - RT_UFS_CMDOP_DME_SET = 0x2, - RT_UFS_CMDOP_DME_PEER_GET = 0x3, - RT_UFS_CMDOP_DME_PEER_SET = 0x4, + RT_UFS_CMDOP_DME_GET = 0x1, + RT_UFS_CMDOP_DME_SET = 0x2, + RT_UFS_CMDOP_DME_PEER_GET = 0x3, + RT_UFS_CMDOP_DME_PEER_SET = 0x4, /* Control */ - RT_UFS_CMDOP_DME_POWERON = 0x10, - RT_UFS_CMDOP_DME_POWEROFF = 0x11, - RT_UFS_CMDOP_DME_ENABLE = 0x12, - RT_UFS_CMDOP_DME_RESET = 0x14, - RT_UFS_CMDOP_DME_ENDPOINTRESET = 0x15, - RT_UFS_CMDOP_DME_LINKSTARTUP = 0x16, - RT_UFS_CMDOP_DME_HIBERNATE_ENTER = 0x17, - RT_UFS_CMDOP_DME_HIBERNATE_EXIT = 0x18, - RT_UFS_CMDOP_DME_TEST_MODE = 0x1a, + RT_UFS_CMDOP_DME_POWERON = 0x10, + RT_UFS_CMDOP_DME_POWEROFF = 0x11, + RT_UFS_CMDOP_DME_ENABLE = 0x12, + RT_UFS_CMDOP_DME_RESET = 0x14, + RT_UFS_CMDOP_DME_ENDPOINTRESET = 0x15, + RT_UFS_CMDOP_DME_LINKSTARTUP = 0x16, + RT_UFS_CMDOP_DME_HIBERNATE_ENTER = 0x17, + RT_UFS_CMDOP_DME_HIBERNATE_EXIT = 0x18, + RT_UFS_CMDOP_DME_TEST_MODE = 0x1a, }; /* UIC Config result code / Generic error code */ enum { - RT_UFS_CMDRES_SUCCESS = 0x0, - RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE = 0x1, - RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE_VALUE = 0x2, - RT_UFS_CMDRES_READ_ONLY_MIB_ATTRIBUTE = 0x3, - RT_UFS_CMDRES_WRITE_ONLY_MIB_ATTRIBUTE = 0x4, - RT_UFS_CMDRES_BAD_INDEX = 0x5, - RT_UFS_CMDRES_LOCKED_MIB_ATTRIBUTE = 0x6, - RT_UFS_CMDRES_BAD_TEST_FEATURE_INDEX = 0x7, - RT_UFS_CMDRES_PEER_COMMUNICATION_FAILURE = 0x8, - RT_UFS_CMDRES_BUSY = 0x9, - RT_UFS_CMDRES_DME_FAILURE = 0xa, - RT_UFS_CMDRES_MASK = 0xff, + RT_UFS_CMDRES_SUCCESS = 0x0, + RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE = 0x1, + RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE_VALUE = 0x2, + RT_UFS_CMDRES_READ_ONLY_MIB_ATTRIBUTE = 0x3, + RT_UFS_CMDRES_WRITE_ONLY_MIB_ATTRIBUTE = 0x4, + RT_UFS_CMDRES_BAD_INDEX = 0x5, + RT_UFS_CMDRES_LOCKED_MIB_ATTRIBUTE = 0x6, + RT_UFS_CMDRES_BAD_TEST_FEATURE_INDEX = 0x7, + RT_UFS_CMDRES_PEER_COMMUNICATION_FAILURE = 0x8, + RT_UFS_CMDRES_BUSY = 0x9, + RT_UFS_CMDRES_DME_FAILURE = 0xa, + RT_UFS_CMDRES_MASK = 0xff, }; /* * UIC DME attribute encoding (JEDEC UFS / UniPro PA) */ -#define RT_UFS_UIC_ARG_MIB_SEL(attr, sel) ((((rt_uint32_t)(attr) & 0xffffU) << 16) | ((rt_uint32_t)(sel) & 0xffffU)) -#define RT_UFS_UIC_ARG_MIB(attr) RT_UFS_UIC_ARG_MIB_SEL(attr, 0) +#define RT_UFS_UIC_ARG_MIB_SEL(attr, sel) ((((rt_uint32_t)(attr) & 0xffffU) << 16) | ((rt_uint32_t)(sel) & 0xffffU)) +#define RT_UFS_UIC_ARG_MIB(attr) RT_UFS_UIC_ARG_MIB_SEL(attr, 0) /* PHY Adapter — subset used for power / link configuration */ -#define RT_UFS_PA_RXGEAR 0x1583 -#define RT_UFS_PA_TXGEAR 0x1568 -#define RT_UFS_PA_ACTIVERXDATALANES 0x1580 -#define RT_UFS_PA_ACTIVETXDATALANES 0x1560 -#define RT_UFS_PA_RXTERMINATION 0x1584 -#define RT_UFS_PA_TXTERMINATION 0x1569 -#define RT_UFS_PA_HSSERIES 0x156a -#define RT_UFS_PA_PWRMODE 0x1571 -#define RT_UFS_PA_PWRMODEUSERDATA0 0x15b0 -#define RT_UFS_PA_PWRMODEUSERDATA1 0x15b1 -#define RT_UFS_PA_PWRMODEUSERDATA2 0x15b2 -#define RT_UFS_PA_PWRMODEUSERDATA3 0x15b3 -#define RT_UFS_PA_PWRMODEUSERDATA4 0x15b4 -#define RT_UFS_PA_PWRMODEUSERDATA5 0x15b5 -#define RT_UFS_DME_LOCAL_FC0_PROT_TO 0xd041 -#define RT_UFS_DME_LOCAL_TC0_REPLAY_TO 0xd042 -#define RT_UFS_DME_LOCAL_AFC0_REQ_TO 0xd043 - -#define RT_UFS_DL_FC0_PROT_TO_DEFAULT 8191U -#define RT_UFS_DL_TC0_REPLAY_TO_DEFAULT 65535U -#define RT_UFS_DL_AFC0_REQ_TO_DEFAULT 32767U -#define RT_UFS_DL_FC1_PROT_TO_DEFAULT 8191U -#define RT_UFS_DL_TC1_REPLAY_TO_DEFAULT 65535U -#define RT_UFS_DL_AFC1_REQ_TO_DEFAULT 32767U +#define RT_UFS_PA_RXGEAR 0x1583 +#define RT_UFS_PA_TXGEAR 0x1568 +#define RT_UFS_PA_ACTIVERXDATALANES 0x1580 +#define RT_UFS_PA_ACTIVETXDATALANES 0x1560 +#define RT_UFS_PA_RXTERMINATION 0x1584 +#define RT_UFS_PA_TXTERMINATION 0x1569 +#define RT_UFS_PA_HSSERIES 0x156a +#define RT_UFS_PA_PWRMODE 0x1571 +#define RT_UFS_PA_PWRMODEUSERDATA0 0x15b0 +#define RT_UFS_PA_PWRMODEUSERDATA1 0x15b1 +#define RT_UFS_PA_PWRMODEUSERDATA2 0x15b2 +#define RT_UFS_PA_PWRMODEUSERDATA3 0x15b3 +#define RT_UFS_PA_PWRMODEUSERDATA4 0x15b4 +#define RT_UFS_PA_PWRMODEUSERDATA5 0x15b5 +#define RT_UFS_DME_LOCAL_FC0_PROT_TO 0xd041 +#define RT_UFS_DME_LOCAL_TC0_REPLAY_TO 0xd042 +#define RT_UFS_DME_LOCAL_AFC0_REQ_TO 0xd043 + +#define RT_UFS_DL_FC0_PROT_TO_DEFAULT 8191U +#define RT_UFS_DL_TC0_REPLAY_TO_DEFAULT 65535U +#define RT_UFS_DL_AFC0_REQ_TO_DEFAULT 32767U +#define RT_UFS_DL_FC1_PROT_TO_DEFAULT 8191U +#define RT_UFS_DL_TC1_REPLAY_TO_DEFAULT 65535U +#define RT_UFS_DL_AFC1_REQ_TO_DEFAULT 32767U enum rt_ufs_pa_pwr_mode { - RT_UFS_PA_FAST_MODE = 1, - RT_UFS_PA_SLOW_MODE = 2, - RT_UFS_PA_FASTAUTO_MODE = 4, - RT_UFS_PA_SLOWAUTO_MODE = 5, - RT_UFS_PA_UNCHANGED_MODE = 7, + RT_UFS_PA_FAST_MODE = 1, + RT_UFS_PA_SLOW_MODE = 2, + RT_UFS_PA_FASTAUTO_MODE = 4, + RT_UFS_PA_SLOWAUTO_MODE = 5, + RT_UFS_PA_UNCHANGED_MODE = 7, }; enum rt_ufs_pa_hs_rate { - RT_UFS_PA_HS_MODE_A = 1, - RT_UFS_PA_HS_MODE_B = 2, + RT_UFS_PA_HS_MODE_A = 1, + RT_UFS_PA_HS_MODE_B = 2, }; /* Auto-Hibernate Idle Timer (AHIT) — REG 0x18 */ -#define RT_UFS_AHIT_TIMER_MASK RT_GENMASK(9, 0) -#define RT_UFS_AHIT_SCALE_MASK RT_GENMASK(12, 10) +#define RT_UFS_AHIT_TIMER_MASK RT_GENMASK(9, 0) +#define RT_UFS_AHIT_SCALE_MASK RT_GENMASK(12, 10) rt_inline rt_uint32_t rt_ufs_ahit_encode(rt_uint16_t timer, rt_uint8_t scale) { @@ -312,68 +312,67 @@ rt_inline rt_uint32_t rt_ufs_ahit_encode(rt_uint16_t timer, rt_uint8_t scale) } /* 150 * 10^3 us idle before auto-Hibernate8 */ -#define RT_UFS_AHIT_DEFAULT rt_ufs_ahit_encode(150, 3) +#define RT_UFS_AHIT_DEFAULT rt_ufs_ahit_encode(150, 3) /* * UTP / UPIU (refer to JEDEC UFS & UFSHCI) */ -#define RT_UFS_CDB_SIZE 16 -#define RT_UFS_ALIGNED_UPIU_SIZE 512 -#define RT_UFS_SENSE_SIZE 18 +#define RT_UFS_CDB_SIZE 16 +#define RT_UFS_ALIGNED_UPIU_SIZE 512 +#define RT_UFS_SENSE_SIZE 18 /* UTP Transfer Request Command Type */ -#define RT_UTP_CMD_TYPE_SCSI 0x0 -#define RT_UTP_CMD_TYPE_UFS_STORAGE 0x1 -#define RT_UTP_CMD_TYPE_DEV_MANAGE 0x2 +#define RT_UTP_CMD_TYPE_SCSI 0x0 +#define RT_UTP_CMD_TYPE_UFS_STORAGE 0x1 +#define RT_UTP_CMD_TYPE_DEV_MANAGE 0x2 /* UTP Data Direction */ -#define RT_UTP_NO_DATA_TRANSFER 0 -#define RT_UTP_HOST_TO_DEVICE 1 -#define RT_UTP_DEVICE_TO_HOST 2 +#define RT_UTP_NO_DATA_TRANSFER 0 +#define RT_UTP_HOST_TO_DEVICE 1 +#define RT_UTP_DEVICE_TO_HOST 2 /* Overall Command Status (OCS) in UTRD */ enum rt_ufs_ocs { - RT_UFS_OCS_SUCCESS = 0x0, - RT_UFS_OCS_INVALID_CMD_TABLE_ATTR = 0x1, - RT_UFS_OCS_INVALID_PRDT_ATTR = 0x2, - RT_UFS_OCS_MISMATCH_DATA_BUF_SIZE = 0x3, - RT_UFS_OCS_MISMATCH_RESP_UPIU_SIZE = 0x4, - RT_UFS_OCS_PEER_COMM_FAILURE = 0x5, - RT_UFS_OCS_ABORTED = 0x6, - RT_UFS_OCS_FATAL_ERROR = 0x7, - RT_UFS_OCS_DEVICE_FATAL_ERROR = 0x8, - RT_UFS_OCS_INVALID_COMMAND_STATUS = 0xf, + RT_UFS_OCS_SUCCESS = 0x0, + RT_UFS_OCS_INVALID_CMD_TABLE_ATTR = 0x1, + RT_UFS_OCS_INVALID_PRDT_ATTR = 0x2, + RT_UFS_OCS_MISMATCH_DATA_BUF_SIZE = 0x3, + RT_UFS_OCS_MISMATCH_RESP_UPIU_SIZE = 0x4, + RT_UFS_OCS_PEER_COMM_FAILURE = 0x5, + RT_UFS_OCS_ABORTED = 0x6, + RT_UFS_OCS_FATAL_ERROR = 0x7, + RT_UFS_OCS_DEVICE_FATAL_ERROR = 0x8, + RT_UFS_OCS_INVALID_COMMAND_STATUS = 0xf, }; /* UPIU Transaction Codes (Initiator to Target) */ -#define RT_UPIU_TRANSACTION_NOP_OUT 0x00 -#define RT_UPIU_TRANSACTION_COMMAND 0x01 -#define RT_UPIU_TRANSACTION_DATA_OUT 0x02 -#define RT_UPIU_TRANSACTION_TASK_REQ 0x04 -#define RT_UPIU_TRANSACTION_QUERY_REQ 0x16 +#define RT_UPIU_TRANSACTION_NOP_OUT 0x00 +#define RT_UPIU_TRANSACTION_COMMAND 0x01 +#define RT_UPIU_TRANSACTION_DATA_OUT 0x02 +#define RT_UPIU_TRANSACTION_TASK_REQ 0x04 +#define RT_UPIU_TRANSACTION_QUERY_REQ 0x16 /* UPIU Transaction Codes (Target to Initiator) */ -#define RT_UPIU_TRANSACTION_NOP_IN 0x20 -#define RT_UPIU_TRANSACTION_RESPONSE 0x21 -#define RT_UPIU_TRANSACTION_DATA_IN 0x22 -#define RT_UPIU_TRANSACTION_TASK_RSP 0x24 -#define RT_UPIU_TRANSACTION_QUERY_RSP 0x36 +#define RT_UPIU_TRANSACTION_NOP_IN 0x20 +#define RT_UPIU_TRANSACTION_RESPONSE 0x21 +#define RT_UPIU_TRANSACTION_DATA_IN 0x22 +#define RT_UPIU_TRANSACTION_TASK_RSP 0x24 +#define RT_UPIU_TRANSACTION_QUERY_RSP 0x36 /* UPIU Command Set Type */ -#define RT_UPIU_COMMAND_SET_TYPE_SCSI 0x0 +#define RT_UPIU_COMMAND_SET_TYPE_SCSI 0x0 /* UPIU Command flags */ -#define RT_UPIU_CMD_FLAGS_NONE 0x00 -#define RT_UPIU_CMD_FLAGS_WRITE 0x20 -#define RT_UPIU_CMD_FLAGS_READ 0x40 +#define RT_UPIU_CMD_FLAGS_NONE 0x00 +#define RT_UPIU_CMD_FLAGS_WRITE 0x20 +#define RT_UPIU_CMD_FLAGS_READ 0x40 /* PRDT: max single entry size 256KB, granularity 4 bytes */ -#define RT_UFS_PRDT_BYTE_COUNT_MAX (256 * 1024) +#define RT_UFS_PRDT_BYTE_COUNT_MAX (256 * 1024) /* UPIU header - 12 bytes, big-endian */ -rt_packed(struct rt_utp_upiu_header -{ +rt_packed(struct rt_utp_upiu_header { rt_uint8_t transaction_code; rt_uint8_t flags; rt_uint8_t lun; @@ -384,49 +383,43 @@ rt_packed(struct rt_utp_upiu_header rt_uint8_t status; rt_uint8_t ehs_length; rt_uint8_t device_information; - rt_be16_t data_segment_length; + rt_be16_t data_segment_length; }); /* Command UPIU - SCSI CDB */ -rt_packed(struct rt_utp_upiu_cmd -{ - rt_be32_t exp_data_transfer_len; +rt_packed(struct rt_utp_upiu_cmd { + rt_be32_t exp_data_transfer_len; rt_uint8_t cdb[RT_UFS_CDB_SIZE]; }); /* Request UPIU - command type */ -rt_packed(struct rt_utp_upiu_req -{ +rt_packed(struct rt_utp_upiu_req { struct rt_utp_upiu_header header; - struct rt_utp_upiu_cmd sc; + struct rt_utp_upiu_cmd sc; }); /* Response UPIU - SCSI response (cmd_rsp) */ -rt_packed(struct rt_utp_cmd_rsp -{ - rt_be32_t residual_transfer_count; - rt_be32_t reserved[4]; - rt_be16_t sense_data_len; +rt_packed(struct rt_utp_cmd_rsp { + rt_be32_t residual_transfer_count; + rt_be32_t reserved[4]; + rt_be16_t sense_data_len; rt_uint8_t sense_data[RT_UFS_SENSE_SIZE]; }); -rt_packed(struct rt_utp_upiu_rsp -{ +rt_packed(struct rt_utp_upiu_rsp { struct rt_utp_upiu_header header; - struct rt_utp_cmd_rsp sr; + struct rt_utp_cmd_rsp sr; }); /* Physical Region Descriptor Table entry (LE, used by controller) */ -rt_packed(struct rt_ufs_sg_entry -{ +rt_packed(struct rt_ufs_sg_entry { rt_uint64_t addr; /* LE in memory for UFSHCI */ rt_uint32_t reserved; rt_uint32_t size; /* LE */ }); /* Request Descriptor Header - common to UTRD/UTMRD (4DW) */ -rt_packed(struct rt_ufs_request_desc_header -{ +rt_packed(struct rt_ufs_request_desc_header { rt_uint32_t dword_0; rt_uint32_t dword_1; rt_uint32_t dword_2; @@ -438,8 +431,7 @@ rt_packed(struct rt_ufs_request_desc_header #define RT_UFS_UTP_REQ_DESC_INT_CMD 0x01000000 /* UTP Transfer Request Descriptor (UTRD) - 32 bytes, host byte order for HC (LE in spec) */ -rt_packed(struct rt_utp_transfer_req_desc -{ +rt_packed(struct rt_utp_transfer_req_desc { struct rt_ufs_request_desc_header header; /* DW 4-5: UCD base address low/high dwords */ rt_uint32_t command_desc_base_addr_lo; /* 128-byte aligned, HC reads as LE */ @@ -453,8 +445,8 @@ rt_packed(struct rt_utp_transfer_req_desc /* UTP Transfer Command Descriptor (UCD) - command_upiu + response_upiu + prd_table */ struct rt_utp_transfer_cmd_desc { - rt_uint8_t command_upiu[RT_UFS_ALIGNED_UPIU_SIZE]; - rt_uint8_t response_upiu[RT_UFS_ALIGNED_UPIU_SIZE]; + rt_uint8_t command_upiu[RT_UFS_ALIGNED_UPIU_SIZE]; + rt_uint8_t response_upiu[RT_UFS_ALIGNED_UPIU_SIZE]; struct rt_ufs_sg_entry prd_table[]; }; @@ -464,8 +456,8 @@ struct rt_utp_transfer_cmd_desc * Partition probing may read multiple blocks with buffers not page-aligned, * so we keep a generous entry count to safely split by page boundaries. */ -#define RT_UFS_PRDT_ENTRIES_PER_SLOT 32 -#define RT_UFS_UCD_SIZE (RT_UFS_ALIGNED_UPIU_SIZE * 2 + sizeof(struct rt_ufs_sg_entry) * RT_UFS_PRDT_ENTRIES_PER_SLOT) +#define RT_UFS_PRDT_ENTRIES_PER_SLOT 32 +#define RT_UFS_UCD_SIZE (RT_UFS_ALIGNED_UPIU_SIZE * 2 + sizeof(struct rt_ufs_sg_entry) * RT_UFS_PRDT_ENTRIES_PER_SLOT) struct rt_ufs_ops; struct rt_ufs_host; @@ -493,7 +485,7 @@ struct rt_ufs_host struct rt_scsi_host parent; void *regs; - int irq; + int irq; rt_uint32_t cap; rt_uint32_t nutrs; /* Number of UTP transfer request slots, 1..32 */ @@ -502,34 +494,34 @@ struct rt_ufs_host /* UTRL (UTRD list) base (must be 1KB aligned); we use slot0 only */ struct rt_utp_transfer_req_desc *utrd; /* Points to utrl_base[0] */ - void *utrl_base; /* Full UTRL base */ - rt_size_t utrl_size; /* Bytes */ - rt_ubase_t utrl_handle; + void *utrl_base; /* Full UTRL base */ + rt_size_t utrl_size; /* Bytes */ + rt_ubase_t utrl_handle; /* UTMRL (UTMRD list) base (must be 1KB aligned); placeholder for now */ - void *utmrl_base; - rt_size_t utmrl_size; + void *utmrl_base; + rt_size_t utmrl_size; rt_ubase_t utmrl_handle; rt_uint8_t utmrl_coherent; rt_uint8_t *ucd_base; /* One UCD: command_upiu + response_upiu + prd_table */ - rt_size_t ucd_size; /* RT_UFS_UCD_SIZE or platform value */ - rt_ubase_t ucd_handle; - rt_uint8_t ucd_coherent; + rt_size_t ucd_size; /* RT_UFS_UCD_SIZE or platform value */ + rt_ubase_t ucd_handle; + rt_uint8_t ucd_coherent; /* Bounce buffer for small DMA I/O (avoid stack/unmapped buffers) */ rt_uint8_t *bounce; - rt_size_t bounce_size; - rt_ubase_t bounce_handle; + rt_size_t bounce_size; + rt_ubase_t bounce_handle; /* IRQ status snapshot (written by ISR, read by transfer thread) */ volatile rt_uint32_t irq_status; struct rt_completion done; - struct rt_spinlock lock; + struct rt_spinlock lock; struct rt_ufs_pa_layer_attr pwr_active; - rt_uint8_t pwr_active_valid; + rt_uint8_t pwr_active_valid; /** * Raw AHIT register value. 0 = use RT_UFS_AHIT_DEFAULT when CAP reports Auto-H8 support. * Write 0 via rt_ufs_auto_hibern8_set() to turn off auto-hibernate. @@ -542,6 +534,7 @@ struct rt_ufs_ops rt_err_t (*init)(struct rt_ufs_host *ufs); rt_err_t (*exit)(struct rt_ufs_host *ufs); rt_err_t (*reset)(struct rt_ufs_host *ufs); + rt_err_t (*hce_enable_notify)(struct rt_ufs_host *ufs, enum rt_ufs_notify_change_status status); rt_err_t (*link_startup_notify)(struct rt_ufs_host *ufs, enum rt_ufs_notify_change_status status); }; @@ -563,7 +556,7 @@ rt_err_t rt_ufs_host_unregister(struct rt_ufs_host *ufs); * @return RT_EOK on success, -RT_ETIMEOUT on timeout, -RT_ERROR on failure */ rt_err_t rt_ufs_uic_cmd_send(struct rt_ufs_host *ufs, rt_uint32_t cmd, - rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3); + rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3); /** * @brief Apply default power/performance settings after the link is up @@ -587,6 +580,16 @@ void rt_ufs_pm_post_linkup(struct rt_ufs_host *ufs); */ rt_err_t rt_ufs_dme_set(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32_t value); +/** + * @brief UIC DME_RESET + */ +rt_err_t rt_ufs_dme_reset(struct rt_ufs_host *ufs); + +/** + * @brief UIC DME_ENABLE + */ +rt_err_t rt_ufs_dme_enable(struct rt_ufs_host *ufs); + /** * @brief UIC DME_GET * diff --git a/components/drivers/ufs/ufs.c b/components/drivers/ufs/ufs.c index 9c35e32f9edb..73f39c208af1 100755 --- a/components/drivers/ufs/ufs.c +++ b/components/drivers/ufs/ufs.c @@ -20,20 +20,110 @@ #include /* UTP slot index used for all SCSI commands (single-threaded transfer) */ -#define RT_UFS_SLOT_ID 0 +#define RT_UFS_SLOT_ID 0 /* Timeout for UTP transfer completion (ms) */ -#define RT_UFS_UTP_TIMEOUT_MS 5000 +#define RT_UFS_UTP_TIMEOUT_MS 5000 /* UIC command timeout (ms) */ -#define RT_UFS_UIC_TIMEOUT_MS 500 +#define RT_UFS_UIC_TIMEOUT_MS 500 /* UTRL/UTMRL base address must be 1KB aligned (UTRLBA/UTMRLBA bits[31:10]). */ -#define RT_UFS_UTR_LIST_ALIGN 1024 -#define RT_UFS_UTR_LIST_BYTES(n) ((rt_size_t)(n) * sizeof(struct rt_utp_transfer_req_desc)) +#define RT_UFS_UTR_LIST_ALIGN 1024 +#define RT_UFS_UTR_LIST_BYTES(n) ((rt_size_t)(n) * sizeof(struct rt_utp_transfer_req_desc)) /* UTRD dword_0 data direction bits */ -#define RT_UFS_UTRD_DD_NONE 0x00000000U -#define RT_UFS_UTRD_DD_HOST_TO_DEVICE 0x02000000U -#define RT_UFS_UTRD_DD_DEVICE_TO_HOST 0x04000000U +#define RT_UFS_UTRD_DD_NONE 0x00000000U +#define RT_UFS_UTRD_DD_HOST_TO_DEVICE 0x02000000U +#define RT_UFS_UTRD_DD_DEVICE_TO_HOST 0x04000000U /* UTRD dword_0 command type bits */ -#define RT_UFS_UTRD_CMD_TYPE_SCSI (1U << RT_UFS_UPIU_COMMAND_TYPE_OFFSET) +#define RT_UFS_UTRD_CMD_TYPE_SCSI (1U << RT_UFS_UPIU_COMMAND_TYPE_OFFSET) + +static rt_err_t ufs_wait_hce(struct rt_ufs_host *ufs) +{ + rt_tick_t deadline = rt_tick_get() + rt_tick_from_millisecond(1000); + + while (!(HWREG32(ufs->regs + RT_UFS_REG_HCE) & 0x1)) + { + if (rt_tick_get() >= deadline) + { + LOG_E("%s: UFS HCE enable timeout", rt_dm_dev_get_name(ufs->parent.dev)); + return -RT_ETIMEOUT; + } + + rt_thread_mdelay(1); + } + + return RT_EOK; +} + +static rt_err_t ufs_link_startup(struct rt_ufs_host *ufs) +{ + rt_err_t err; + rt_uint32_t value = 0; + + if (ufs->ops->link_startup_notify) + { + ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_PRE); + } + + err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_LINKSTARTUP, 0, &value, 0); + + if (ufs->ops->link_startup_notify) + { + ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_POST); + } + + return err; +} + +static rt_err_t ufs_wait_utrd_complete(struct rt_ufs_host *ufs, rt_tick_t timeout) +{ + rt_tick_t deadline = rt_tick_get() + timeout; + rt_bool_t db_seen = RT_FALSE; + + while (rt_tick_get() < deadline) + { + rt_base_t level; + rt_uint32_t irq_status; + rt_uint32_t is = HWREG32(ufs->regs + RT_UFS_REG_IS); + rt_uint32_t db = HWREG32(ufs->regs + RT_UFS_REG_UTRLDBR); + + if (db & RT_BIT(RT_UFS_SLOT_ID)) + { + db_seen = RT_TRUE; + } + + level = rt_spin_lock_irqsave(&ufs->lock); + irq_status = ufs->irq_status; + + if ((irq_status | is) & RT_UFS_REG_IS_UTRCS) + { + ufs->irq_status &= ~RT_UFS_REG_IS_UTRCS; + rt_spin_unlock_irqrestore(&ufs->lock, level); + HWREG32(ufs->regs + RT_UFS_REG_IS) = RT_UFS_REG_IS_UTRCS; + return RT_EOK; + } + + rt_spin_unlock_irqrestore(&ufs->lock, level); + + if (db_seen && !(db & RT_BIT(RT_UFS_SLOT_ID))) + { + return RT_EOK; + } + + if ((irq_status | is) & (RT_UFS_REG_IS_UTPES | RT_UFS_REG_IS_DFES | RT_UFS_REG_IS_UE)) + { + return -RT_ERROR; + } + + rt_thread_mdelay(1); + } + + return -RT_ETIMEOUT; +} + +static rt_uint8_t ufs_utrd_ocs(struct rt_ufs_host *ufs) +{ + rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, ufs->utrd, sizeof(*ufs->utrd)); + return rt_le32_to_cpu(ufs->utrd->header.dword_2) & 0xf; +} static rt_uint8_t ufs_scsi_cmd_data_dir(struct rt_scsi_cmd *cmd) { @@ -57,11 +147,11 @@ static rt_uint8_t ufs_scsi_cmd_data_dir(struct rt_scsi_cmd *cmd) } static void ufs_prepare_upiu_cmd(struct rt_ufs_host *ufs, struct rt_utp_upiu_req *req, struct rt_utp_upiu_rsp *rsp, - struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd) + struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd) { rt_uint16_t cdb_len; - rt_size_t data_len = cmd->data.size; - rt_uint8_t flags = RT_UPIU_CMD_FLAGS_NONE; + rt_size_t data_len = cmd->data.size; + rt_uint8_t flags = RT_UPIU_CMD_FLAGS_NONE; if (ufs_scsi_cmd_data_dir(cmd) == RT_UTP_DEVICE_TO_HOST) { @@ -73,15 +163,15 @@ static void ufs_prepare_upiu_cmd(struct rt_ufs_host *ufs, struct rt_utp_upiu_req } rt_memset(req, 0, sizeof(*req)); - req->header.transaction_code = RT_UPIU_TRANSACTION_COMMAND; - req->header.flags = flags; - req->header.lun = (rt_uint8_t)(sdev->lun & 0x7f); - req->header.task_tag = RT_UFS_SLOT_ID; - req->header.command_set_type = RT_UPIU_COMMAND_SET_TYPE_SCSI; + req->header.transaction_code = RT_UPIU_TRANSACTION_COMMAND; + req->header.flags = flags; + req->header.lun = (rt_uint8_t)(sdev->lun & 0x7f); + req->header.task_tag = RT_UFS_SLOT_ID; + req->header.command_set_type = RT_UPIU_COMMAND_SET_TYPE_SCSI; req->header.data_segment_length = rt_cpu_to_be16((rt_uint16_t)data_len); req->sc.exp_data_transfer_len = rt_cpu_to_be32((rt_uint32_t)data_len); - cdb_len = cmd->op_size < RT_UFS_CDB_SIZE ? (rt_uint16_t)cmd->op_size : RT_UFS_CDB_SIZE; + cdb_len = cmd->op_size < RT_UFS_CDB_SIZE ? (rt_uint16_t)cmd->op_size : RT_UFS_CDB_SIZE; rt_memcpy(req->sc.cdb, &cmd->op, cdb_len); rt_memset(rsp, 0, sizeof(*rsp)); @@ -90,18 +180,18 @@ static void ufs_prepare_upiu_cmd(struct rt_ufs_host *ufs, struct rt_utp_upiu_req /* Fill UTRD header and link to UCD; PRDT filled separately. */ static rt_err_t ufs_prepare_utrd(struct rt_ufs_host *ufs, rt_uint8_t data_dir, rt_size_t data_len) { - rt_uint64_t ucd_phys = ufs->ucd_handle; - rt_uint32_t utp_dd_dword = RT_UFS_UTRD_DD_NONE; - rt_uint16_t resp_off_dw, resp_len_dw, prdt_off_dw, prdt_len_entries; + rt_uint64_t ucd_phys = ufs->ucd_handle; + rt_uint32_t utp_dd_dword = RT_UFS_UTRD_DD_NONE; + rt_uint16_t resp_off_dw, resp_len_dw, prdt_off_dw, prdt_len_entries; struct rt_utp_transfer_req_desc *utrd = ufs->utrd; /* Clear whole descriptor to avoid any leftover fields */ rt_memset(utrd, 0, sizeof(*utrd)); /* UFSHCI: offset/length in DWORDs (4 bytes) */ - resp_off_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2); - prdt_off_dw = (rt_uint16_t)((RT_UFS_ALIGNED_UPIU_SIZE * 2) >> 2); - resp_len_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2); + resp_off_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2); + prdt_off_dw = (rt_uint16_t)((RT_UFS_ALIGNED_UPIU_SIZE * 2) >> 2); + resp_len_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2); prdt_len_entries = (data_len > 0) ? 1 : 0; /* RequestDescHeader.dword_0..dword_3 */ @@ -123,10 +213,10 @@ static rt_err_t ufs_prepare_utrd(struct rt_ufs_host *ufs, rt_uint8_t data_dir, r /* UFSHCI expects LE for descriptor fields */ utrd->command_desc_base_addr_lo = rt_cpu_to_le32(rt_lower_32_bits(ucd_phys)); utrd->command_desc_base_addr_hi = rt_cpu_to_le32(rt_upper_32_bits(ucd_phys)); - utrd->response_upiu_offset = rt_cpu_to_le16(resp_off_dw); - utrd->response_upiu_length = rt_cpu_to_le16(resp_len_dw); - utrd->prd_table_offset = rt_cpu_to_le16(prdt_off_dw); - utrd->prd_table_length = rt_cpu_to_le16(prdt_len_entries); + utrd->response_upiu_offset = rt_cpu_to_le16(resp_off_dw); + utrd->response_upiu_length = rt_cpu_to_le16(resp_len_dw); + utrd->prd_table_offset = rt_cpu_to_le16(prdt_off_dw); + utrd->prd_table_length = rt_cpu_to_le16(prdt_len_entries); return RT_EOK; } @@ -134,11 +224,11 @@ static rt_err_t ufs_prepare_utrd(struct rt_ufs_host *ufs, rt_uint8_t data_dir, r /* Fill PRDT with entries for cmd->data.ptr (split by page boundary). */ static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr, rt_size_t len, rt_uint16_t *out_entries) { - rt_size_t left; - rt_uint8_t *ptr; - rt_uint16_t n = 0; + rt_size_t left; + rt_uint8_t *ptr; + rt_uint16_t n = 0; struct rt_utp_transfer_cmd_desc *ucd = (struct rt_utp_transfer_cmd_desc *)ufs->ucd_base; - struct rt_ufs_sg_entry *prd = ucd->prd_table; + struct rt_ufs_sg_entry *prd = ucd->prd_table; if (out_entries) { @@ -151,22 +241,22 @@ static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr, } left = len; - ptr = (rt_uint8_t *)(rt_ubase_t)data_ptr; + ptr = (rt_uint8_t *)(rt_ubase_t)data_ptr; while (left) { rt_uint64_t addr; - rt_size_t chunk, page_off; + rt_size_t chunk, page_off; if (n >= RT_UFS_PRDT_ENTRIES_PER_SLOT) { LOG_E("%s: UFS: PRDT entries overflow (len=%u left=%u n=%u)", rt_dm_dev_get_name(ufs->parent.dev), - len, left, n); + len, left, n); return -RT_EIO; } page_off = ((rt_ubase_t)ptr) & (ARCH_PAGE_SIZE - 1); - chunk = ARCH_PAGE_SIZE - page_off; + chunk = ARCH_PAGE_SIZE - page_off; if (chunk > left) { chunk = left; @@ -181,11 +271,11 @@ static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr, addr = (rt_uint64_t)rt_kmem_v2p(ptr); } - prd[n].addr = rt_cpu_to_le64(addr); + prd[n].addr = rt_cpu_to_le64(addr); prd[n].reserved = 0; - prd[n].size = rt_cpu_to_le32((rt_uint32_t)(chunk - 1)); /* 0-based byte count */ + prd[n].size = rt_cpu_to_le32((rt_uint32_t)(chunk - 1)); /* 0-based byte count */ - ptr += chunk; + ptr += chunk; left -= chunk; ++n; } @@ -200,22 +290,24 @@ static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr, static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd) { - struct rt_utp_transfer_cmd_desc *ucd = (struct rt_utp_transfer_cmd_desc *)ufs->ucd_base; - struct rt_utp_upiu_req *req = (struct rt_utp_upiu_req *)ucd->command_upiu; - struct rt_utp_upiu_rsp *rsp = (struct rt_utp_upiu_rsp *)ucd->response_upiu; + struct rt_utp_transfer_cmd_desc *ucd = (struct rt_utp_transfer_cmd_desc *)ufs->ucd_base; + struct rt_utp_upiu_req *req = (struct rt_utp_upiu_req *)ucd->command_upiu; + struct rt_utp_upiu_rsp *rsp = (struct rt_utp_upiu_rsp *)ucd->response_upiu; struct rt_utp_transfer_req_desc *utrd = ufs->utrd; - void *regs = ufs->regs; - rt_uint8_t data_dir; - rt_uint32_t is; - rt_err_t err = RT_EOK; - rt_uint16_t prdt_entries = 0; - rt_uint8_t ocs; - rt_bool_t use_bounce = RT_FALSE; - void *orig_ptr = cmd->data.ptr, *resp_buf; - rt_size_t orig_size = cmd->data.size; - void *dma_ptr = cmd->data.ptr; - rt_size_t dma_size = cmd->data.size; - rt_bool_t bounce_copied = RT_FALSE; + void *regs = ufs->regs; + rt_uint8_t data_dir; + rt_base_t level; + rt_uint32_t is; + rt_uint32_t irq_status; + rt_err_t err = RT_EOK; + rt_uint16_t prdt_entries = 0; + rt_uint8_t ocs; + rt_bool_t use_bounce = RT_FALSE; + void *orig_ptr = cmd->data.ptr, *resp_buf; + rt_size_t orig_size = cmd->data.size; + void *dma_ptr = cmd->data.ptr; + rt_size_t dma_size = cmd->data.size; + rt_bool_t bounce_copied = RT_FALSE; data_dir = ufs_scsi_cmd_data_dir(cmd); /* Basic controller readiness checks to avoid hard timeouts */ @@ -250,7 +342,7 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device { rt_memcpy(ufs->bounce, orig_ptr, orig_size); } - dma_ptr = ufs->bounce; + dma_ptr = ufs->bounce; dma_size = orig_size; } @@ -268,31 +360,31 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device /* Basic debug information before submitting UTP */ LOG_D("%s: UTP submit: opcode=%#02x dir=%u data_len=%u slot=%u", - rt_dm_dev_get_name(ufs->parent.dev), - cmd->op.unknow.opcode, data_dir, - cmd->data.size, RT_UFS_SLOT_ID); + rt_dm_dev_get_name(ufs->parent.dev), + cmd->op.unknow.opcode, data_dir, + cmd->data.size, RT_UFS_SLOT_ID); LOG_D("%s: UTP ctrl regs: HCS=%#08x IE=%#08x HCE=%#08x", - rt_dm_dev_get_name(ufs->parent.dev), - HWREG32(regs + RT_UFS_REG_HCS), - HWREG32(regs + RT_UFS_REG_IE), - HWREG32(regs + RT_UFS_REG_HCE)); + rt_dm_dev_get_name(ufs->parent.dev), + HWREG32(regs + RT_UFS_REG_HCS), + HWREG32(regs + RT_UFS_REG_IE), + HWREG32(regs + RT_UFS_REG_HCE)); LOG_D("%s: UTP ctrl ready bits: UTRLRDY=%u UTMRLRDY=%u UICRDY=%u", - rt_dm_dev_get_name(ufs->parent.dev), - (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTRLRDY) ? 1 : 0, - (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTMRLRDY) ? 1 : 0, - (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UCRDY) ? 1 : 0); + rt_dm_dev_get_name(ufs->parent.dev), + (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTRLRDY) ? 1 : 0, + (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTMRLRDY) ? 1 : 0, + (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UCRDY) ? 1 : 0); LOG_D("%s: UTP UTRD: dword_0=%#08x dword_2(ocs)=%#08x", - rt_dm_dev_get_name(ufs->parent.dev), - rt_le32_to_cpu(utrd->header.dword_0), - rt_le32_to_cpu(utrd->header.dword_2)); + rt_dm_dev_get_name(ufs->parent.dev), + rt_le32_to_cpu(utrd->header.dword_0), + rt_le32_to_cpu(utrd->header.dword_2)); LOG_D("%s: UTP UTRD: ucd_base_lo=%#08x ucd_base_hi=%#08x resp_off_dw=%u resp_len_dw=%u prd_off_dw=%u prd_len=%u", - rt_dm_dev_get_name(ufs->parent.dev), - rt_le32_to_cpu(utrd->command_desc_base_addr_lo), - rt_le32_to_cpu(utrd->command_desc_base_addr_hi), - rt_le16_to_cpu(utrd->response_upiu_offset), - rt_le16_to_cpu(utrd->response_upiu_length), - rt_le16_to_cpu(utrd->prd_table_offset), - rt_le16_to_cpu(utrd->prd_table_length)); + rt_dm_dev_get_name(ufs->parent.dev), + rt_le32_to_cpu(utrd->command_desc_base_addr_lo), + rt_le32_to_cpu(utrd->command_desc_base_addr_hi), + rt_le16_to_cpu(utrd->response_upiu_offset), + rt_le16_to_cpu(utrd->response_upiu_length), + rt_le16_to_cpu(utrd->prd_table_offset), + rt_le16_to_cpu(utrd->prd_table_length)); /* * DMA descriptors/data must be visible to controller. @@ -307,7 +399,9 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device } /* Clear interrupt status for transfer complete */ + level = rt_spin_lock_irqsave(&ufs->lock); ufs->irq_status = 0; + rt_spin_unlock_irqrestore(&ufs->lock, level); /* Ack any stale pending IRQ bits before kicking */ HWREG32(regs + RT_UFS_REG_IS) = RT_UINT32_MAX; /* Enable UTP completion/error interrupts */ @@ -318,32 +412,42 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device HWREG32(regs + RT_UFS_REG_UTRLDBR) = RT_BIT(RT_UFS_SLOT_ID); rt_spin_unlock(&ufs->lock); - /* Interrupt mode: wait for completion signaled by ISR */ - if ((err = rt_completion_wait(&ufs->done, rt_tick_from_millisecond(RT_UFS_UTP_TIMEOUT_MS)))) + /* + * Poll UTRCS directly. QEMU and some PCI hosts may complete the transfer + * before the INTx/MSI handler is wired up during early probe. + */ + if ((err = ufs_wait_utrd_complete(ufs, rt_tick_from_millisecond(RT_UFS_UTP_TIMEOUT_MS)))) { - LOG_E("%s: UFS UTP wait timeout: IS=%#08x irq_status=%#08x", - rt_dm_dev_get_name(ufs->parent.dev), - HWREG32(regs + RT_UFS_REG_IS), ufs->irq_status); + level = rt_spin_lock_irqsave(&ufs->lock); + irq_status = ufs->irq_status; + rt_spin_unlock_irqrestore(&ufs->lock, level); + + LOG_E("%s: UFS UTP wait failed: err=%d IS=%#08x irq_status=%#08x UTRLDBR=%#08x OCS=%#x", + rt_dm_dev_get_name(ufs->parent.dev), + err, HWREG32(regs + RT_UFS_REG_IS), irq_status, + HWREG32(regs + RT_UFS_REG_UTRLDBR), ufs_utrd_ocs(ufs)); /* Dump UPIU header and PRDT entry for post-mortem */ LOG_E("%s: UTP UPIU: tx=%u flags=%#02x lun=%u tag=%u seg_len(be16)=%u", - rt_dm_dev_get_name(ufs->parent.dev), - req->header.transaction_code, req->header.flags, - req->header.lun, req->header.task_tag, - rt_be16_to_cpu(req->header.data_segment_length)); + rt_dm_dev_get_name(ufs->parent.dev), + req->header.transaction_code, req->header.flags, + req->header.lun, req->header.task_tag, + rt_be16_to_cpu(req->header.data_segment_length)); if (cmd->data.size > 0) { + struct rt_ufs_sg_entry *prd = ((struct rt_utp_transfer_cmd_desc *)ufs->ucd_base)->prd_table; + LOG_E("%s: UTP PRDT[0]: addr=%#llx size(le32)=%#08x", - rt_dm_dev_get_name(ufs->parent.dev), - (rt_uint64_t)(&((struct rt_utp_transfer_cmd_desc *)ufs->ucd_base)->prd_table[0])->addr, - (&((struct rt_utp_transfer_cmd_desc *)ufs->ucd_base)->prd_table[0])->size); + rt_dm_dev_get_name(ufs->parent.dev), + (unsigned long long)rt_le64_to_cpu(prd[0].addr), + rt_le32_to_cpu(prd[0].size)); } goto _end; } - is = ufs->irq_status | HWREG32(regs + RT_UFS_REG_IS); + is = HWREG32(regs + RT_UFS_REG_IS); if (is & (RT_UFS_REG_IS_UTPES | RT_UFS_REG_IS_DFES | RT_UFS_REG_IS_UE)) { err = -RT_ERROR; @@ -372,9 +476,9 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device } LOG_D("%s: UFS UTRD complete: dword_2=%#08x (ocs=%#x)", - rt_dm_dev_get_name(ufs->parent.dev), - rt_le32_to_cpu(utrd->header.dword_2), - (rt_le32_to_cpu(utrd->header.dword_2) & 0x0f)); + rt_dm_dev_get_name(ufs->parent.dev), + rt_le32_to_cpu(utrd->header.dword_2), + (rt_le32_to_cpu(utrd->header.dword_2) & 0x0f)); /* * Post-process SCSI response in resp_buf (INQUIRY etc.). @@ -395,8 +499,8 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device /* Align with AHCI behavior: always expose direct-access block device */ inq->devtype = SCSI_DEVICE_TYPE_DIRECT; - inq->rmb = 0; - inq->length = 95 - 4; + inq->rmb = 0; + inq->length = 95 - 4; } _no_resp_buf: @@ -423,8 +527,16 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device goto _end; } - if (rsp->header.status != 0) + /* + * SCSI status lives in the response UPIU header. CHECK CONDITION (0x02) + * may still carry valid data; sense is handled by the SCSI core if needed. + */ + if (rsp->header.status != 0 && rsp->header.status != 0x02) { + LOG_E("%s: UFS SCSI status=%#02x sense_len=%u", + rt_dm_dev_get_name(ufs->parent.dev), + rsp->header.status, + rt_be16_to_cpu(rsp->sr.sense_data_len)); err = -RT_ERROR; goto _end; } @@ -461,7 +573,7 @@ static rt_err_t ufs_host_reset(struct rt_scsi_device *sdev) static rt_err_t ufs_host_transfer(struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd) { - rt_err_t err; + rt_err_t err; struct rt_ufs_host *ufs = rt_container_of(sdev->host, struct rt_ufs_host, parent); switch (cmd->op.unknow.opcode) @@ -499,15 +611,14 @@ static rt_err_t ufs_host_transfer(struct rt_scsi_device *sdev, struct rt_scsi_cm return err; } -static struct rt_scsi_ops ufs_host_ops = -{ - .reset = ufs_host_reset, +static struct rt_scsi_ops ufs_host_ops = { + .reset = ufs_host_reset, .transfer = ufs_host_transfer, }; static void ufs_isr(int irqno, void *param) { - rt_uint32_t is; + rt_uint32_t is; struct rt_ufs_host *ufs = param; if (!(is = HWREG32(ufs->regs + RT_UFS_REG_IS))) @@ -515,7 +626,9 @@ static void ufs_isr(int irqno, void *param) return; } + rt_spin_lock(&ufs->lock); ufs->irq_status |= is; + rt_spin_unlock(&ufs->lock); HWREG32(ufs->regs + RT_UFS_REG_IS) = is; if (is & (RT_UFS_REG_IS_UTRCS | RT_UFS_REG_IS_UTPES | RT_UFS_REG_IS_DFES | RT_UFS_REG_IS_UE)) @@ -526,9 +639,8 @@ static void ufs_isr(int irqno, void *param) rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs) { - rt_err_t err; - rt_uint32_t value; - char dev_name[RT_NAME_MAX]; + rt_err_t err; + char dev_name[RT_NAME_MAX]; struct rt_scsi_host *scsi; if (!ufs || !ufs->ops || !ufs->regs) @@ -536,7 +648,7 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs) return -RT_EINVAL; } - ufs->cap = HWREG32(ufs->regs + RT_UFS_REG_CAP); + ufs->cap = HWREG32(ufs->regs + RT_UFS_REG_CAP); ufs->nutrs = RT_UFS_REG_CAP_NUTRS(ufs->cap) + 1; ufs->nutrs = rt_min_t(rt_uint32_t, 32, ufs->nutrs); @@ -555,7 +667,7 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs) ufs->utrd = (struct rt_utp_transfer_req_desc *)ufs->utrl_base; /* Slot0 */ /* Allocate UCD (Command Descriptor) */ - ufs->ucd_size = ufs->ucd_size ? : RT_UFS_UCD_SIZE; + ufs->ucd_size = ufs->ucd_size ?: RT_UFS_UCD_SIZE; ufs->ucd_base = rt_dma_alloc_coherent(ufs->parent.dev, ufs->ucd_size, &ufs->ucd_handle); if (!ufs->ucd_base) @@ -567,9 +679,9 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs) rt_memset(ufs->ucd_base, 0, ufs->ucd_size); /* Allocate bounce buffer for small DMA transfers (512B is enough for inquiry/sense/capacity) */ - ufs->bounce_size = 4096; + ufs->bounce_size = 4096; ufs->bounce_handle = 0; - ufs->bounce = rt_dma_alloc_coherent(ufs->parent.dev, ufs->bounce_size, &ufs->bounce_handle); + ufs->bounce = rt_dma_alloc_coherent(ufs->parent.dev, ufs->bounce_size, &ufs->bounce_handle); if (!ufs->bounce) { @@ -585,50 +697,52 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs) goto _fail; } + if (ufs->ops->hce_enable_notify && + (err = ufs->ops->hce_enable_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_PRE))) + { + goto _fail; + } + /* Enable controller (HCE 1) */ HWREG32(ufs->regs + RT_UFS_REG_HCE) = 0; rt_thread_mdelay(1); HWREG32(ufs->regs + RT_UFS_REG_HCE) = 0x1; - rt_thread_mdelay(1); + + if ((err = ufs_wait_hce(ufs))) + { + goto _fail; + } /* Program UTRD/UTMRD list base addresses */ - HWREG32(ufs->regs + RT_UFS_REG_UTRLBA) = rt_lower_32_bits(ufs->utrl_handle); + HWREG32(ufs->regs + RT_UFS_REG_UTRLBA) = rt_lower_32_bits(ufs->utrl_handle); HWREG32(ufs->regs + RT_UFS_REG_UTRLBAU) = rt_upper_32_bits(ufs->utrl_handle); /* UTMRL: allocate minimal aligned list if not provided */ - ufs->utmrl_size = RT_UFS_UTR_LIST_ALIGN; + ufs->utmrl_size = RT_UFS_UTR_LIST_ALIGN; ufs->utmrl_handle = 0; - ufs->utmrl_base = rt_dma_alloc_coherent(ufs->parent.dev, ufs->utmrl_size, &ufs->utmrl_handle); + ufs->utmrl_base = rt_dma_alloc_coherent(ufs->parent.dev, ufs->utmrl_size, &ufs->utmrl_handle); if (ufs->utmrl_base) { rt_memset(ufs->utmrl_base, 0, ufs->utmrl_size); } - HWREG32(ufs->regs + RT_UFS_REG_UTMRLBA) = rt_lower_32_bits(ufs->utmrl_handle); + HWREG32(ufs->regs + RT_UFS_REG_UTMRLBA) = rt_lower_32_bits(ufs->utmrl_handle); HWREG32(ufs->regs + RT_UFS_REG_UTMRLBAU) = rt_upper_32_bits(ufs->utmrl_handle); /* Start run/stop */ - HWREG32(ufs->regs + RT_UFS_REG_UTRLRSR) = 0x1; + HWREG32(ufs->regs + RT_UFS_REG_UTRLRSR) = 0x1; HWREG32(ufs->regs + RT_UFS_REG_UTMRLRSR) = 0x1; - /* Link startup: set UTRLRDY/UTMRLRDY */ - value = HWREG32(ufs->regs + RT_UFS_REG_HCS); - if (!(value & RT_UFS_REG_HCS_UTRLRDY) || !(value & RT_UFS_REG_HCS_UTMRLRDY) || !(value & RT_UFS_REG_HCS_UCRDY)) + if (ufs->ops->hce_enable_notify && + (err = ufs->ops->hce_enable_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_POST))) { - if (ufs->ops->link_startup_notify) - { - ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_PRE); - } - - if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_LINKSTARTUP, 0, &value, 0))) - { - goto _fail; - } + goto _fail; + } - if (ufs->ops->link_startup_notify) - { - ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_POST); - } + /* Link startup: required before the first SCSI/UTP transfer */ + if ((err = ufs_link_startup(ufs))) + { + goto _fail; } ufs->pwr_active_valid = 0; @@ -643,10 +757,10 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs) rt_hw_interrupt_install(ufs->irq, ufs_isr, ufs, dev_name); rt_hw_interrupt_umask(ufs->irq); - scsi = &ufs->parent; - scsi->ops = &ufs_host_ops; - scsi->max_id = rt_max_t(rt_size_t, scsi->max_id, 1); - scsi->max_lun = rt_max_t(rt_size_t, scsi->max_lun, 1); + scsi = &ufs->parent; + scsi->ops = &ufs_host_ops; + scsi->max_id = rt_max_t(rt_size_t, scsi->max_id, 1); + scsi->max_lun = rt_max_t(rt_size_t, scsi->max_lun, 1); scsi->parallel_io = RT_TRUE; if ((err = rt_scsi_host_register(scsi))) @@ -721,18 +835,18 @@ rt_err_t rt_ufs_host_unregister(struct rt_ufs_host *ufs) } rt_err_t rt_ufs_uic_cmd_send(struct rt_ufs_host *ufs, rt_uint32_t cmd, - rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3) + rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3) { rt_uint32_t is; - rt_int32_t timeout; - void *regs = ufs->regs; + rt_int32_t timeout; + void *regs = ufs->regs; if (!regs) { return -RT_EINVAL; } - timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS); + timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS); timeout += rt_tick_get(); while (!(HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UCRDY)) @@ -749,12 +863,13 @@ rt_err_t rt_ufs_uic_cmd_send(struct rt_ufs_host *ufs, rt_uint32_t cmd, HWREG32(regs + RT_UFS_REG_UCMDARG1) = arg1; HWREG32(regs + RT_UFS_REG_UCMDARG2) = arg2 ? *arg2 : 0; HWREG32(regs + RT_UFS_REG_UCMDARG3) = arg3; - HWREG32(regs + RT_UFS_REG_UICCMD) = cmd & 0xff; + HWREG32(regs + RT_UFS_REG_UICCMD) = cmd & 0xff; - timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS); + timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS); timeout += rt_tick_get(); - do { + do + { is = HWREG32(regs + RT_UFS_REG_IS); if (is & RT_UFS_REG_IS_UCCS) { diff --git a/components/drivers/ufs/ufs_pm.c b/components/drivers/ufs/ufs_pm.c index 86284efee024..acd0d1d0185b 100755 --- a/components/drivers/ufs/ufs_pm.c +++ b/components/drivers/ufs/ufs_pm.c @@ -18,7 +18,7 @@ #define DBG_LVL DBG_INFO #include -#define RT_UFS_DME_ATTR_SET_NOR 0 +#define RT_UFS_DME_ATTR_SET_NOR 0 rt_inline rt_uint32_t ufs_uic_arg_attr_type(rt_uint8_t t) { @@ -27,7 +27,7 @@ rt_inline rt_uint32_t ufs_uic_arg_attr_type(rt_uint8_t t) rt_err_t rt_ufs_dme_set(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32_t value) { - rt_err_t err; + rt_err_t err; rt_uint32_t arg2 = ufs_uic_arg_attr_type(RT_UFS_DME_ATTR_SET_NOR); if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_SET, attr_sel, &arg2, value))) @@ -43,10 +43,46 @@ rt_err_t rt_ufs_dme_set(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32 return RT_EOK; } +rt_err_t rt_ufs_dme_reset(struct rt_ufs_host *ufs) +{ + rt_err_t err; + rt_uint32_t arg2 = 0; + + if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_RESET, 0, &arg2, 0))) + { + return err; + } + + if ((arg2 & RT_UFS_CMDRES_MASK) != RT_UFS_CMDRES_SUCCESS) + { + return -RT_ERROR; + } + + return RT_EOK; +} + +rt_err_t rt_ufs_dme_enable(struct rt_ufs_host *ufs) +{ + rt_err_t err; + rt_uint32_t arg2 = 0; + + if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_ENABLE, 0, &arg2, 0))) + { + return err; + } + + if ((arg2 & RT_UFS_CMDRES_MASK) != RT_UFS_CMDRES_SUCCESS) + { + return -RT_ERROR; + } + + return RT_EOK; +} + rt_err_t rt_ufs_dme_get(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32_t *value) { rt_uint32_t arg2 = 0; - rt_err_t err; + rt_err_t err; if (!value) { @@ -75,7 +111,7 @@ rt_err_t rt_ufs_uic_pa_pwrmode(struct rt_ufs_host *ufs, rt_uint8_t mode) rt_err_t rt_ufs_pa_power_mode_set(struct rt_ufs_host *ufs, const struct rt_ufs_pa_layer_attr *attr, rt_bool_t force) { - rt_err_t err; + rt_err_t err; rt_uint8_t mode; if (!ufs || !attr || !ufs->regs) @@ -192,7 +228,7 @@ rt_err_t rt_ufs_pa_power_mode_set(struct rt_ufs_host *ufs, const struct rt_ufs_p return err; } - ufs->pwr_active = *attr; + ufs->pwr_active = *attr; ufs->pwr_active_valid = 1; return RT_EOK; @@ -255,7 +291,7 @@ rt_err_t rt_ufs_auto_hibern8_set(struct rt_ufs_host *ufs, rt_uint32_t reg_val) } HWREG32(ufs->regs + RT_UFS_REG_AHIT) = reg_val; - ufs->ahit = reg_val; + ufs->ahit = reg_val; return RT_EOK; }