mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-25 14:25:44 +00:00
feat(drivers/mmc): boot partition read support
Added a public function to read blocks from a current boot partition. switch between partitions has to respect eMMC partition switch timing. Signed-off-by: Vyacheslav Yurkov <uvv.mail@gmail.com> Change-Id: I55b0c910314253e5647486609583fd290dadd30a
This commit is contained in:
parent
0ef419b145
commit
5014b52dec
2 changed files with 84 additions and 3 deletions
|
@ -105,6 +105,36 @@ static int mmc_device_state(void)
|
|||
return MMC_GET_STATE(resp_data[0]);
|
||||
}
|
||||
|
||||
static int mmc_send_part_switch_cmd(unsigned int part_config)
|
||||
{
|
||||
int ret;
|
||||
unsigned int part_time = 0;
|
||||
|
||||
ret = mmc_send_cmd(MMC_CMD(6),
|
||||
EXTCSD_WRITE_BYTES |
|
||||
EXTCSD_CMD(CMD_EXTCSD_PARTITION_CONFIG) |
|
||||
EXTCSD_VALUE(part_config) |
|
||||
EXTCSD_CMD_SET_NORMAL,
|
||||
MMC_RESPONSE_R1B, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Partition switch timing is in 10ms units */
|
||||
part_time = mmc_ext_csd[CMD_EXTCSD_PART_SWITCH_TIME] * 10;
|
||||
|
||||
mdelay(part_time);
|
||||
|
||||
do {
|
||||
ret = mmc_device_state();
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
} while (ret == MMC_STATE_PRG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
|
||||
{
|
||||
int ret;
|
||||
|
@ -668,7 +698,7 @@ static inline void mmc_rpmb_enable(void)
|
|||
{
|
||||
mmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
|
||||
PART_CFG_BOOT_PARTITION1_ENABLE |
|
||||
PART_CFG_PARTITION1_ACCESS);
|
||||
PART_CFG_BOOT_PARTITION1_ACCESS);
|
||||
}
|
||||
|
||||
static inline void mmc_rpmb_disable(void)
|
||||
|
@ -710,6 +740,50 @@ size_t mmc_rpmb_erase_blocks(int lba, size_t size)
|
|||
return size_erased;
|
||||
}
|
||||
|
||||
static int mmc_part_switch(unsigned int part_type)
|
||||
{
|
||||
uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
|
||||
|
||||
part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
|
||||
part_config |= part_type;
|
||||
|
||||
return mmc_send_part_switch_cmd(part_config);
|
||||
}
|
||||
|
||||
static unsigned char mmc_current_boot_part(void)
|
||||
{
|
||||
return PART_CFG_CURRENT_BOOT_PARTITION(mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG]);
|
||||
}
|
||||
|
||||
size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size)
|
||||
{
|
||||
size_t size_read;
|
||||
int ret;
|
||||
unsigned char current_boot_part = mmc_current_boot_part();
|
||||
|
||||
if (current_boot_part != 1U &&
|
||||
current_boot_part != 2U) {
|
||||
ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = mmc_part_switch(current_boot_part);
|
||||
if (ret < 0) {
|
||||
ERROR("Failed to switch to boot partition, %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_read = mmc_read_blocks(lba, buf, size);
|
||||
|
||||
ret = mmc_part_switch(0);
|
||||
if (ret < 0) {
|
||||
ERROR("Failed to switch back to user partition, %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return size_read;
|
||||
}
|
||||
|
||||
int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
|
||||
unsigned int width, unsigned int flags,
|
||||
struct mmc_device_info *device_info)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -60,10 +60,16 @@
|
|||
#define CMD_EXTCSD_PARTITION_CONFIG 179
|
||||
#define CMD_EXTCSD_BUS_WIDTH 183
|
||||
#define CMD_EXTCSD_HS_TIMING 185
|
||||
#define CMD_EXTCSD_PART_SWITCH_TIME 199
|
||||
#define CMD_EXTCSD_SEC_CNT 212
|
||||
|
||||
#define EXT_CSD_PART_CONFIG_ACC_MASK GENMASK(2, 0)
|
||||
#define PART_CFG_BOOT_PARTITION1_ENABLE (U(1) << 3)
|
||||
#define PART_CFG_PARTITION1_ACCESS (U(1) << 0)
|
||||
#define PART_CFG_BOOT_PARTITION1_ACCESS (U(1) << 0)
|
||||
#define PART_CFG_BOOT_PART_EN_MASK GENMASK(5, 3)
|
||||
#define PART_CFG_BOOT_PART_EN_SHIFT 3
|
||||
#define PART_CFG_CURRENT_BOOT_PARTITION(x) (((x) & PART_CFG_BOOT_PART_EN_MASK) >> \
|
||||
PART_CFG_BOOT_PART_EN_SHIFT)
|
||||
|
||||
/* Values in EXT CSD register */
|
||||
#define MMC_BUS_WIDTH_1 U(0)
|
||||
|
@ -230,6 +236,7 @@ size_t mmc_erase_blocks(int lba, size_t size);
|
|||
size_t mmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size);
|
||||
size_t mmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size);
|
||||
size_t mmc_rpmb_erase_blocks(int lba, size_t size);
|
||||
size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size);
|
||||
int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
|
||||
unsigned int width, unsigned int flags,
|
||||
struct mmc_device_info *device_info);
|
||||
|
|
Loading…
Add table
Reference in a new issue