diff options
Diffstat (limited to 'arch/arm/mach-mvebu/spl.c')
-rw-r--r-- | arch/arm/mach-mvebu/spl.c | 133 |
1 files changed, 93 insertions, 40 deletions
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c index aada83f..273ecb8 100644 --- a/arch/arm/mach-mvebu/spl.c +++ b/arch/arm/mach-mvebu/spl.c @@ -46,7 +46,8 @@ #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR) && CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR != 0 #error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR must be set to 0 #endif -#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET) && CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET != 0 +#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET) && \ + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET != 0 #error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET must be set to 0 #endif #endif @@ -57,7 +58,8 @@ * set to 1. Otherwise U-Boot SPL would not be able to load U-Boot proper. */ #ifdef CONFIG_SPL_SATA -#if !defined(CONFIG_SPL_SATA_RAW_U_BOOT_USE_SECTOR) || !defined(CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR) || CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR != 1 +#if !defined(CONFIG_SPL_SATA_RAW_U_BOOT_USE_SECTOR) || \ + !defined(CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR) || CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR != 1 #error CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR must be set to 1 #endif #endif @@ -73,23 +75,23 @@ /* Structure of the main header, version 1 (Armada 370/XP/375/38x/39x) */ struct kwbimage_main_hdr_v1 { - uint8_t blockid; /* 0x0 */ - uint8_t flags; /* 0x1 */ - uint16_t nandpagesize; /* 0x2-0x3 */ - uint32_t blocksize; /* 0x4-0x7 */ - uint8_t version; /* 0x8 */ - uint8_t headersz_msb; /* 0x9 */ - uint16_t headersz_lsb; /* 0xA-0xB */ - uint32_t srcaddr; /* 0xC-0xF */ - uint32_t destaddr; /* 0x10-0x13 */ - uint32_t execaddr; /* 0x14-0x17 */ - uint8_t options; /* 0x18 */ - uint8_t nandblocksize; /* 0x19 */ - uint8_t nandbadblklocation; /* 0x1A */ - uint8_t reserved4; /* 0x1B */ - uint16_t reserved5; /* 0x1C-0x1D */ - uint8_t ext; /* 0x1E */ - uint8_t checksum; /* 0x1F */ + u8 blockid; /* 0x0 */ + u8 flags; /* 0x1 */ + u16 nandpagesize; /* 0x2-0x3 */ + u32 blocksize; /* 0x4-0x7 */ + u8 version; /* 0x8 */ + u8 headersz_msb; /* 0x9 */ + u16 headersz_lsb; /* 0xA-0xB */ + u32 srcaddr; /* 0xC-0xF */ + u32 destaddr; /* 0x10-0x13 */ + u32 execaddr; /* 0x14-0x17 */ + u8 options; /* 0x18 */ + u8 nandblocksize; /* 0x19 */ + u8 nandbadblklocation; /* 0x1A */ + u8 reserved4; /* 0x1B */ + u16 reserved5; /* 0x1C-0x1D */ + u8 ext; /* 0x1E */ + u8 checksum; /* 0x1F */ } __packed; #ifdef CONFIG_SPL_MMC @@ -99,7 +101,35 @@ u32 spl_mmc_boot_mode(const u32 boot_device) } #endif +static u32 checksum32(void *start, u32 len) +{ + u32 csum = 0; + u32 *p = start; + + while (len > 0) { + csum += *p++; + len -= sizeof(u32); + }; + + return csum; +} + +int spl_check_board_image(struct spl_image_info *spl_image, + const struct spl_boot_device *bootdev) +{ + u32 csum = *(u32 *)(spl_image->load_addr + spl_image->size - 4); + + if (checksum32((void *)spl_image->load_addr, + spl_image->size - 4) != csum) { + printf("ERROR: Invalid data checksum in kwbimage\n"); + return -EINVAL; + } + + return 0; +} + int spl_parse_board_header(struct spl_image_info *spl_image, + const struct spl_boot_device *bootdev, const void *image_header, size_t size) { const struct kwbimage_main_hdr_v1 *mhdr = image_header; @@ -116,51 +146,74 @@ int spl_parse_board_header(struct spl_image_info *spl_image, * (including SPL content) which is not included in U-Boot image_header. */ if (mhdr->version != 1 || - ((mhdr->headersz_msb << 16) | mhdr->headersz_lsb) < sizeof(*mhdr) || - ( -#ifdef CONFIG_SPL_SPI_FLASH_SUPPORT - mhdr->blockid != IBR_HDR_SPI_ID && -#endif -#ifdef CONFIG_SPL_SATA - mhdr->blockid != IBR_HDR_SATA_ID && -#endif -#ifdef CONFIG_SPL_MMC - mhdr->blockid != IBR_HDR_SDIO_ID && -#endif - 1 - )) { - printf("ERROR: Not valid SPI/NAND/SATA/SDIO kwbimage v1\n"); + ((mhdr->headersz_msb << 16) | mhdr->headersz_lsb) < sizeof(*mhdr)) { + printf("ERROR: Invalid kwbimage v1\n"); + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_SPL_SPI_FLASH_SUPPORT) && + bootdev->boot_device == BOOT_DEVICE_SPI && + mhdr->blockid != IBR_HDR_SPI_ID) { + printf("ERROR: Wrong blockid (0x%x) in SPI kwbimage\n", + mhdr->blockid); + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_SPL_SATA) && + bootdev->boot_device == BOOT_DEVICE_SATA && + mhdr->blockid != IBR_HDR_SATA_ID) { + printf("ERROR: Wrong blockid (0x%x) in SATA kwbimage\n", + mhdr->blockid); + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_SPL_MMC) && + (bootdev->boot_device == BOOT_DEVICE_MMC1 || + bootdev->boot_device == BOOT_DEVICE_MMC2 || + bootdev->boot_device == BOOT_DEVICE_MMC2_2) && + mhdr->blockid != IBR_HDR_SDIO_ID) { + printf("ERROR: Wrong blockid (0x%x) in SDIO kwbimage\n", + mhdr->blockid); return -EINVAL; } spl_image->offset = mhdr->srcaddr; -#ifdef CONFIG_SPL_SATA /* * For SATA srcaddr is specified in number of sectors. * The main header is must be stored at sector number 1. * This expects that sector size is 512 bytes and recalculates * data offset to bytes relative to the main header. */ - if (mhdr->blockid == IBR_HDR_SATA_ID) { + if (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID) { if (spl_image->offset < 1) { - printf("ERROR: Wrong SATA srcaddr in kwbimage\n"); + printf("ERROR: Wrong srcaddr (0x%08x) in SATA kwbimage\n", + spl_image->offset); return -EINVAL; } spl_image->offset -= 1; spl_image->offset *= 512; } -#endif -#ifdef CONFIG_SPL_MMC /* * For SDIO (eMMC) srcaddr is specified in number of sectors. * This expects that sector size is 512 bytes and recalculates * data offset to bytes. */ - if (mhdr->blockid == IBR_HDR_SDIO_ID) + if (IS_ENABLED(CONFIG_SPL_MMC) && mhdr->blockid == IBR_HDR_SDIO_ID) spl_image->offset *= 512; -#endif + + if (spl_image->offset % 4 != 0) { + printf("ERROR: Wrong srcaddr (0x%08x) in kwbimage\n", + spl_image->offset); + return -EINVAL; + } + + if (mhdr->blocksize <= 4 || mhdr->blocksize % 4 != 0) { + printf("ERROR: Wrong blocksize (0x%08x) in kwbimage\n", + mhdr->blocksize); + return -EINVAL; + } spl_image->size = mhdr->blocksize; spl_image->entry_point = mhdr->execaddr; |