diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 5786dd38495f69323dd3ff6ee4a9ee5c9a8c4ce3..97ed1fa43a107667702765a2070010c2ffd77fd3 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -546,6 +546,13 @@ optionally be defined: PLAT_PARTITION_MAX_ENTRIES := 12 $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES)) +- **PLAT_PARTITION_BLOCK_SIZE** + The size of partition block. It could be either 512 bytes or 4096 bytes. + The default value is 512. + `For example, define the build flag in platform.mk`_: + PLAT_PARTITION_BLOCK_SIZE := 4096 + $(eval $(call add_define,PLAT_PARTITION_BLOCK_SIZE)) + The following constant is optional. It should be defined to override the default behaviour of the ``assert()`` function (for example, to save memory). diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c index 4577f06a20bf468e359e9eba31fe4bde9b9eb32c..1b804deef6d8e2b43d7dff874f4620a4d08e5717 100644 --- a/drivers/partition/gpt.c +++ b/drivers/partition/gpt.c @@ -52,9 +52,10 @@ int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry) if (result != 0) { return result; } - entry->start = (uint64_t)gpt_entry->first_lba * PARTITION_BLOCK_SIZE; + entry->start = (uint64_t)gpt_entry->first_lba * + PLAT_PARTITION_BLOCK_SIZE; entry->length = (uint64_t)(gpt_entry->last_lba - gpt_entry->first_lba + 1) * - PARTITION_BLOCK_SIZE; + PLAT_PARTITION_BLOCK_SIZE; return 0; } diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c index 7fdbf5385aa7fe10ea62422133094d6abdf26ffc..68133eaf4f1b7951c33e11b4c23ebfdc79598ec0 100644 --- a/drivers/partition/partition.c +++ b/drivers/partition/partition.c @@ -15,7 +15,7 @@ #include <drivers/partition/mbr.h> #include <plat/common/platform.h> -static uint8_t mbr_sector[PARTITION_BLOCK_SIZE]; +static uint8_t mbr_sector[PLAT_PARTITION_BLOCK_SIZE]; static partition_entry_list_t list; #if LOG_LEVEL >= LOG_LEVEL_VERBOSE @@ -57,15 +57,15 @@ static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry) return result; } result = io_read(image_handle, (uintptr_t)&mbr_sector, - PARTITION_BLOCK_SIZE, &bytes_read); + PLAT_PARTITION_BLOCK_SIZE, &bytes_read); if (result != 0) { WARN("Failed to read data (%i)\n", result); return result; } /* Check MBR boot signature. */ - if ((mbr_sector[PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) || - (mbr_sector[PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) { + if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) || + (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) { return -ENOENT; } offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET; @@ -120,15 +120,15 @@ static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry, return result; } result = io_read(image_handle, (uintptr_t)&mbr_sector, - PARTITION_BLOCK_SIZE, &bytes_read); + PLAT_PARTITION_BLOCK_SIZE, &bytes_read); if (result != 0) { WARN("Failed to read data (%i)\n", result); return result; } /* Check MBR boot signature. */ - if ((mbr_sector[PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) || - (mbr_sector[PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) { + if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) || + (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) { return -ENOENT; } offset = (uintptr_t)&mbr_sector + diff --git a/include/drivers/partition/gpt.h b/include/drivers/partition/gpt.h index 3ae160fdc1e1bd28465c0f072c13748bd67d6b0f..d923e9535f3771de647256368fc3c86d3db3e3b2 100644 --- a/include/drivers/partition/gpt.h +++ b/include/drivers/partition/gpt.h @@ -10,9 +10,9 @@ #include <drivers/partition/partition.h> #define PARTITION_TYPE_GPT 0xee -#define GPT_HEADER_OFFSET PARTITION_BLOCK_SIZE +#define GPT_HEADER_OFFSET PLAT_PARTITION_BLOCK_SIZE #define GPT_ENTRY_OFFSET (GPT_HEADER_OFFSET + \ - PARTITION_BLOCK_SIZE) + PLAT_PARTITION_BLOCK_SIZE) #define GUID_LEN 16 #define GPT_SIGNATURE "EFI PART" diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h index d94c7824a63f6cba6c233e7195c736be982566fa..5f6483373f3da2ab55b7ed5cc00e6e01952a4172 100644 --- a/include/drivers/partition/partition.h +++ b/include/drivers/partition/partition.h @@ -17,7 +17,15 @@ CASSERT(PLAT_PARTITION_MAX_ENTRIES <= 128, assert_plat_partition_max_entries); -#define PARTITION_BLOCK_SIZE 512 +#if !PLAT_PARTITION_BLOCK_SIZE +# define PLAT_PARTITION_BLOCK_SIZE 512 +#endif /* PLAT_PARTITION_BLOCK_SIZE */ + +CASSERT((PLAT_PARTITION_BLOCK_SIZE == 512) || + (PLAT_PARTITION_BLOCK_SIZE == 4096), + assert_plat_partition_block_size); + +#define LEGACY_PARTITION_BLOCK_SIZE 512 #define EFI_NAMELEN 36 diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index 2f96efcdb3853591201005facc5ecaf4c25d6970..96136ec126f0f822df1dc684d6c3dc17b0edf74e 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -114,6 +114,11 @@ uint32_t hikey_get_spsr_for_bl33_entry(void) } #endif /* __aarch64__ */ +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + return hikey_set_fip_addr(image_id, "fastboot"); +} + int hikey_bl2_handle_post_image_load(unsigned int image_id) { int err = 0; diff --git a/plat/hisilicon/hikey/hikey_io_storage.c b/plat/hisilicon/hikey/hikey_io_storage.c index 11dd97334c4e54022b8a7214cf75a7932b9e0063..fd610d8c0c667a24451bbbcc8b164aa8e89875f7 100644 --- a/plat/hisilicon/hikey/hikey_io_storage.c +++ b/plat/hisilicon/hikey/hikey_io_storage.c @@ -18,6 +18,7 @@ #include <drivers/io/io_memmap.h> #include <drivers/io/io_storage.h> #include <drivers/mmc.h> +#include <drivers/partition/partition.h> #include <lib/mmio.h> #include <lib/semihosting.h> #include <tools_share/firmware_image_package.h> @@ -43,9 +44,12 @@ static uintptr_t fip_dev_handle; static int check_emmc(const uintptr_t spec); static int check_fip(const uintptr_t spec); -static const io_block_spec_t emmc_fip_spec = { - .offset = HIKEY_FIP_BASE, - .length = HIKEY_FIP_MAX_SIZE, +static io_block_spec_t emmc_fip_spec; + +static const io_block_spec_t emmc_gpt_spec = { + .offset = 0, + .length = PLAT_PARTITION_BLOCK_SIZE * + (PLAT_PARTITION_MAX_ENTRIES / 4 + 2), }; static const io_block_dev_spec_t emmc_dev_spec = { @@ -213,6 +217,11 @@ static const struct plat_io_policy policies[] = { check_fip }, #endif /* TRUSTED_BOARD_BOOT */ + [GPT_IMAGE_ID] = { + &emmc_dev_handle, + (uintptr_t)&emmc_gpt_spec, + check_emmc + }, }; static int check_emmc(const uintptr_t spec) @@ -267,6 +276,23 @@ void hikey_io_setup(void) (void)result; } +int hikey_set_fip_addr(unsigned int image_id, const char *name) +{ + const partition_entry_t *entry; + + if (emmc_fip_spec.length == 0) { + partition_init(GPT_IMAGE_ID); + entry = get_partition_entry(name); + if (entry == NULL) { + ERROR("Could NOT find the %s partition!\n", name); + return -ENOENT; + } + emmc_fip_spec.offset = entry->start; + emmc_fip_spec.length = entry->length; + } + return 0; +} + /* Return an IO device handle and specification which can be used to access * an image. Use this to enforce platform load policy */ diff --git a/plat/hisilicon/hikey/hikey_private.h b/plat/hisilicon/hikey/hikey_private.h index d82a0794a0c5d6e850a74a89ede6cd9bbc6b022c..b75bc723d7f3cb95fd2eb3572728fd9e68ba32b5 100644 --- a/plat/hisilicon/hikey/hikey_private.h +++ b/plat/hisilicon/hikey/hikey_private.h @@ -72,4 +72,6 @@ int hikey_write_serialno(struct random_serial_num *serialno); void init_acpu_dvfs(void); +int hikey_set_fip_addr(unsigned int image_id, const char *name); + #endif /* HIKEY_PRIVATE_H */ diff --git a/plat/hisilicon/hikey/include/hikey_def.h b/plat/hisilicon/hikey/include/hikey_def.h index 4fb3e56a17b01636111023ffa19e3bad91365d85..590700daf91540400826e2757bded6dcf631a966 100644 --- a/plat/hisilicon/hikey/include/hikey_def.h +++ b/plat/hisilicon/hikey/include/hikey_def.h @@ -84,8 +84,6 @@ #define HIKEY_BL1_MMC_DATA_SIZE 0x0000B000 #define EMMC_BASE 0 -#define HIKEY_FIP_BASE (EMMC_BASE + (4 << 20)) -#define HIKEY_FIP_MAX_SIZE (8 << 20) #define HIKEY_EMMC_RPMB_BASE (EMMC_BASE + 0) #define HIKEY_EMMC_RPMB_MAX_SIZE (128 << 10) #define HIKEY_EMMC_USERDATA_BASE (EMMC_BASE + 0) diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk index 7fd897cdab134be222c6e9d54de27d0e6b7e6be6..fbf743292753b478cf4c348f415b971d87a2813d 100644 --- a/plat/hisilicon/hikey/platform.mk +++ b/plat/hisilicon/hikey/platform.mk @@ -76,6 +76,8 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_fip.c \ drivers/io/io_storage.c \ drivers/mmc/mmc.c \ + drivers/partition/gpt.c \ + drivers/partition/partition.c \ drivers/synopsys/emmc/dw_mmc.c \ lib/cpus/aarch64/cortex_a53.S \ plat/hisilicon/hikey/aarch64/hikey_helpers.S \ diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c index fc9ddab0dfc2c01a304cb15ca015bbbe661b420b..35d76921dc7dbdd253d1da30e9c1cab930b1df8d 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c @@ -18,6 +18,7 @@ #include <drivers/delay_timer.h> #include <drivers/dw_ufs.h> #include <drivers/generic_delay_timer.h> +#include <drivers/partition/partition.h> #include <drivers/ufs.h> #include <lib/mmio.h> #ifdef SPD_opteed @@ -263,6 +264,11 @@ int hikey960_bl2_handle_post_image_load(unsigned int image_id) * This function can be used by the platforms to update/use image * information for given `image_id`. ******************************************************************************/ +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + return hikey960_set_fip_addr(image_id, "fip"); +} + int bl2_plat_handle_post_image_load(unsigned int image_id) { return hikey960_bl2_handle_post_image_load(image_id); diff --git a/plat/hisilicon/hikey960/hikey960_def.h b/plat/hisilicon/hikey960/hikey960_def.h index 4ea3acd5100f3e763795962823b21de9273410a9..9651d78919e0c50507ad7fc41c02182a16264532 100644 --- a/plat/hisilicon/hikey960/hikey960_def.h +++ b/plat/hisilicon/hikey960/hikey960_def.h @@ -44,9 +44,6 @@ #define PL011_UART_CLK_IN_HZ 19200000 #define UFS_BASE 0 -/* FIP partition */ -#define HIKEY960_FIP_BASE (UFS_BASE + 0x1400000) -#define HIKEY960_FIP_MAX_SIZE (12 << 20) #define HIKEY960_UFS_DESC_BASE 0x20000000 #define HIKEY960_UFS_DESC_SIZE 0x00200000 /* 2MB */ diff --git a/plat/hisilicon/hikey960/hikey960_io_storage.c b/plat/hisilicon/hikey960/hikey960_io_storage.c index a4e83897ededa327860d681aad29c4e0885ef584..e1c5845fbdb1e7f8bc7f69ed50dc88195d9fd097 100644 --- a/plat/hisilicon/hikey960/hikey960_io_storage.c +++ b/plat/hisilicon/hikey960/hikey960_io_storage.c @@ -18,6 +18,7 @@ #include <drivers/io/io_fip.h> #include <drivers/io/io_memmap.h> #include <drivers/io/io_storage.h> +#include <drivers/partition/partition.h> #include <lib/mmio.h> #include <lib/semihosting.h> #include <tools_share/firmware_image_package.h> @@ -36,9 +37,12 @@ static int check_fip(const uintptr_t spec); size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size); size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size); -static const io_block_spec_t ufs_fip_spec = { - .offset = HIKEY960_FIP_BASE, - .length = HIKEY960_FIP_MAX_SIZE, +static io_block_spec_t ufs_fip_spec; + +static const io_block_spec_t ufs_gpt_spec = { + .offset = 0, + .length = PLAT_PARTITION_BLOCK_SIZE * + (PLAT_PARTITION_MAX_ENTRIES / 4 + 2), }; static const io_block_dev_spec_t ufs_dev_spec = { @@ -199,6 +203,11 @@ static const struct plat_io_policy policies[] = { check_fip }, #endif /* TRUSTED_BOARD_BOOT */ + [GPT_IMAGE_ID] = { + &ufs_dev_handle, + (uintptr_t)&ufs_gpt_spec, + check_ufs + }, }; static int check_ufs(const uintptr_t spec) @@ -253,6 +262,23 @@ void hikey960_io_setup(void) (void)result; } +int hikey960_set_fip_addr(unsigned int image_id, const char *name) +{ + const partition_entry_t *entry; + + if (ufs_fip_spec.length == 0) { + partition_init(GPT_IMAGE_ID); + entry = get_partition_entry(name); + if (entry == NULL) { + ERROR("Could NOT find the %s partition!\n", name); + return -ENOENT; + } + ufs_fip_spec.offset = entry->start; + ufs_fip_spec.length = entry->length; + } + return 0; +} + /* Return an IO device handle and specification which can be used to access * an image. Use this to enforce platform load policy */ diff --git a/plat/hisilicon/hikey960/hikey960_private.h b/plat/hisilicon/hikey960/hikey960_private.h index 9a18dd620c5c0ff31f8cf7b72c3cc54021f40dfd..54bf501341083573850cba91e77ffec9f78c1943 100644 --- a/plat/hisilicon/hikey960/hikey960_private.h +++ b/plat/hisilicon/hikey960/hikey960_private.h @@ -26,6 +26,7 @@ void hikey960_init_mmu_el3(unsigned long total_base, unsigned long coh_limit); void hikey960_io_setup(void); int hikey960_read_boardid(unsigned int *id); +int hikey960_set_fip_addr(unsigned int image_id, const char *name); void hikey960_clk_init(void); void hikey960_pmu_init(void); void hikey960_regulator_enable(void); diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk index 4f2c3c699fef0afee85b8418d13e15490ab26d31..6cb53c7b6cb18f3de3287596a44cdee62daf4b53 100644 --- a/plat/hisilicon/hikey960/platform.mk +++ b/plat/hisilicon/hikey960/platform.mk @@ -22,11 +22,13 @@ COLD_BOOT_SINGLE_CPU := 1 PLAT_PL061_MAX_GPIOS := 176 PROGRAMMABLE_RESET_ADDRESS := 1 ENABLE_SVE_FOR_NS := 0 +PLAT_PARTITION_BLOCK_SIZE := 4096 # Process flags $(eval $(call add_define,HIKEY960_TSP_RAM_LOCATION_ID)) $(eval $(call add_define,CRASH_CONSOLE_BASE)) $(eval $(call add_define,PLAT_PL061_MAX_GPIOS)) +$(eval $(call add_define,PLAT_PARTITION_BLOCK_SIZE)) # Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images # in the FIP if the platform requires. @@ -75,6 +77,8 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_block.c \ drivers/io/io_fip.c \ drivers/io/io_storage.c \ + drivers/partition/gpt.c \ + drivers/partition/partition.c \ drivers/synopsys/ufs/dw_ufs.c \ drivers/ufs/ufs.c \ lib/cpus/aarch64/cortex_a53.S \