2 #include "normal_mode.h"
3 #include "../disk/part_uefi.h"
4 #include "../disk/part_efi.h"
5 #include "../drivers/mmc/card_sdio.h"
6 #include "asm/arch/sci_types.h"
7 #include <ext_common.h>
9 #ifdef CONFIG_SECURE_BOOT
10 #include <asm/arch/secure_boot.h>
11 #include "secure_verify.h"
13 #include <asm/arch/sprd_reg.h>
14 #ifdef CONFIG_ARCH_SCX35L //only for sharkL branch modem boot process
15 #include <asm/arch/cp_boot.h>
20 #define KERNL_PAGE_SIZE 2048
22 long long load_image_time = 0;
24 #if BOOT_NATIVE_LINUX_MODEM
25 extern void sipc_addr_reset(void);
27 extern unsigned char _chkNVEcc(uint8_t * buf, uint32_t size, uint32_t checksum);
29 #ifdef CONFIG_RAMDISK_BOOT
30 extern int load_ramdisk(char *name, unsigned int base_addr, unsigned int size);
34 #ifdef CONFIG_SUPPORT_TDLTE
35 static boot_image_required_t const s_boot_image_tl_table[] = {
36 {L"tl_fixnv1", L"tl_fixnv2", LTE_FIXNV_SIZE, LTE_FIXNV_ADDR},
37 {L"tl_runtimenv1", L"tl_runtimenv2", LTE_RUNNV_SIZE, LTE_RUNNV_ADDR},
38 {L"tl_modem", NULL, LTE_MODEM_SIZE, LTE_MODEM_ADDR},
39 {L"tl_ldsp", NULL, LTE_LDSP_SIZE, LTE_LDSP_ADDR}, //ltedsp
40 {L"tl_tgdsp", NULL, LTE_GDSP_SIZE, LTE_GDSP_ADDR},
45 #ifdef CONFIG_SUPPORT_WLTE
46 static boot_image_required_t const s_boot_image_wl_table[] = {
47 {L"wl_fixnv1", L"wl_fixnv2", LTE_FIXNV_SIZE, LTE_FIXNV_ADDR},
48 {L"wl_runtimenv1", L"wl_runtimenv2", LTE_RUNNV_SIZE, LTE_RUNNV_ADDR},
49 {L"wl_modem", NULL, LTE_MODEM_SIZE, LTE_MODEM_ADDR},
50 {L"wl_ldsp", NULL, LTE_LDSP_SIZE, LTE_LDSP_ADDR},
51 {L"wl_gdsp", NULL, LTE_GDSP_SIZE, LTE_GDSP_ADDR},
52 {L"wl_warm", NULL, WL_WARM_SIZE, WL_WARM_ADDR},
57 #ifdef CONFIG_SUPPORT_LTE
58 static boot_image_required_t const s_boot_image_lte_table[] = {
59 {L"l_fixnv1", L"l_fixnv2", LTE_FIXNV_SIZE, LTE_FIXNV_ADDR},
60 {L"l_runtimenv1", L"l_runtimenv2", LTE_RUNNV_SIZE, LTE_RUNNV_ADDR},
61 {L"l_modem", NULL, LTE_MODEM_SIZE, LTE_MODEM_ADDR},
62 {L"l_ldsp", NULL, LTE_LDSP_SIZE, LTE_LDSP_ADDR},
63 {L"l_gdsp", NULL, LTE_GDSP_SIZE, LTE_GDSP_ADDR},
64 {L"l_warm", NULL, WL_WARM_SIZE, WL_WARM_ADDR},
69 #ifdef CONFIG_SUPPORT_TD
70 static boot_image_required_t const s_boot_image_TD_table[] = {
71 {L"tdfixnv1", L"tdfixnv2", FIXNV_SIZE, TDFIXNV_ADR},
72 {L"tdruntimenv1", L"tdruntimenv2", RUNTIMENV_SIZE, TDRUNTIMENV_ADR},
73 {L"tdmodem", NULL, TDMODEM_SIZE, TDMODEM_ADR},
74 {L"tddsp", NULL, TDDSP_SIZE, TDDSP_ADR},
79 #ifdef CONFIG_SUPPORT_GSM
80 static boot_image_required_t const s_boot_image_gsm_table[] = {
81 {L"g_fixnv1", L"g_fixnv2", GSM_FIXNV_SIZE, GSM_FIXNV_ADDR},
82 {L"g_runtimenv1", L"g_runtimenv2", GSM_RUNNV_SIZE, GSM_RUNNV_ADDR},
83 {L"g_modem", NULL, GSM_MODEM_SIZE, GSM_MODEM_ADDR},
84 {L"g_dsp", NULL, GSM_DSP_SIZE, GSM_DSP_ADDR},
90 #ifdef CONFIG_SUPPORT_W
91 static boot_image_required_t const s_boot_image_W_table[] = {
92 {L"wfixnv1", L"wfixnv2", FIXNV_SIZE, WFIXNV_ADR},
93 {L"wruntimenv1", L"wruntimenv2", RUNTIMENV_SIZE, WRUNTIMENV_ADR},
94 {L"wmodem", NULL, WMODEM_SIZE, WMODEM_ADR},
95 {L"wdsp", NULL, WDSP_SIZE, WDSP_ADR},
100 #ifdef CONFIG_SUPPORT_WIFI
101 static boot_image_required_t const s_boot_image_WIFI_table[] = {
102 {L"wcnfixnv1", L"wcnfixnv2", FIXNV_SIZE, WCNFIXNV_ADR},
103 {L"wcnruntimenv1", L"wcnruntimenv2", RUNTIMENV_SIZE, WCNRUNTIMENV_ADR},
104 {L"wcnmodem", NULL, WCNMODEM_SIZE, WCNMODEM_ADR},
110 static boot_image_required_t const s_boot_image_COMMON_table[] = {
111 #if !BOOT_NATIVE_LINUX
112 {L"vm", NULL, VMJALUNA_SIZE, VMJALUNA_ADR},
114 #ifdef CONFIG_SIMLOCK_ENABLE
115 {L"simlock", NULL, SIMLOCK_SIZE, SIMLOCK_ADR},
117 #ifdef CONFIG_DFS_ENABLE
118 {L"pm_sys", NULL, DFS_SIZE, DFS_ADDR},
124 static boot_image_required_t const *s_boot_image_table[] = {
125 #ifdef CONFIG_SUPPORT_TDLTE
126 s_boot_image_tl_table,
129 #ifdef CONFIG_SUPPORT_WLTE
130 s_boot_image_wl_table,
133 #ifdef CONFIG_SUPPORT_LTE
134 s_boot_image_lte_table,
137 #ifdef CONFIG_SUPPORT_GSM
138 s_boot_image_gsm_table,
141 #ifdef CONFIG_SUPPORT_TD
142 s_boot_image_TD_table,
146 #ifdef CONFIG_SUPPORT_W
147 s_boot_image_W_table,
152 #ifdef CONFIG_SUPPORT_WIFI
153 s_boot_image_WIFI_table,
156 s_boot_image_COMMON_table,
161 #ifdef CONFIG_SECURE_BOOT
162 uint8 header_buf[SEC_HEADER_MAX_SIZE];
165 int read_logoimg(char *bmp_img, size_t size)
167 block_dev_desc_t *p_block_dev = NULL;
168 disk_partition_t info;
170 p_block_dev = get_dev("mmc", 1);
171 if (NULL == p_block_dev) {
174 if (!get_partition_info_by_name(p_block_dev, L"logo", &info)) {
175 if (TRUE != Emmc_Read(PARTITION_USER, info.start, size / EMMC_SECTOR_SIZE, (uint8 *)bmp_img)) {
176 debugf("function: %s nand read error\n", __FUNCTION__);
186 int size = CONFIG_SPL_LOAD_LEN;
187 if (TRUE != Emmc_Read(PARTITION_BOOT1, 0, size / EMMC_SECTOR_SIZE, (uint8 *) spl_data)) {
188 debugf("vmjaluna nand read error \n");
195 #ifdef CONFIG_SECURE_BOOT
197 int get_spl_hash(void *hash_data)
203 //int size = CONFIG_SPL_LOAD_LEN;
204 int size = CONFIG_SPL_HASH_LEN;
206 spl_data = malloc(size);
211 if (TRUE != Emmc_Read(PARTITION_BOOT1, 0, size / EMMC_SECTOR_SIZE, (uint8 *) spl_data)) {
212 debugf("PARTITION_BOOT1 read error \n");
216 header = (NBLHeader *) ((unsigned char *)spl_data + BOOTLOADER_HEADER_OFFSET);
217 len = header->mHashLen;
219 memset(header, 0, sizeof(NBLHeader));
220 header->mHashLen = len;
221 debugf("cal spl hash len=%d\n", header->mHashLen * 4);
223 ret = cal_sha1(spl_data, (header->mHashLen) << 2, hash_data);
233 just convert partition name wchar to char with violent.
235 LOCAL __inline char *w2c(wchar_t * wchar)
237 static char buf[72] = { 0 };
239 while ((!wchar[i]) && (i < 72)) {
240 buf[i] = wchar[i] & 0xFF;
249 LOCAL void _boot_secure_check(void)
251 #ifdef CONFIG_SECURE_BOOT
253 vlr_info_t *vlr_info;
255 #ifdef CONFIG_SUPPORT_W
256 puk_adr = CONFIG_SYS_NAND_U_BOOT_DST + CONFIG_SYS_NAND_U_BOOT_SIZE - KEY_INFO_SIZ - VLR_INFO_SIZ;
257 vlr_info = (vlr_info_t *) (WDSP_ADR + WDSP_SIZE - VLR_INFO_SIZ);
258 secure_check(WDSP_ADR, vlr_info->length, vlr_info, puk_adr);
260 puk_adr = CONFIG_SYS_NAND_U_BOOT_DST + CONFIG_SYS_NAND_U_BOOT_SIZE - KEY_INFO_SIZ - VLR_INFO_SIZ;
261 vlr_info = (vlr_info_t *) (WMODEM_ADR + WMODEM_SIZE - VLR_INFO_SIZ);
262 secure_check(WMODEM_ADR, vlr_info->length, vlr_info, puk_adr);
265 #ifdef CONFIG_SUPPORT_WIFI
266 puk_adr = CONFIG_SYS_NAND_U_BOOT_DST + CONFIG_SYS_NAND_U_BOOT_SIZE - KEY_INFO_SIZ - VLR_INFO_SIZ;
267 vlr_info = (vlr_info_t *) (WCNMODEM_ADR + WCNMODEM_SIZE - VLR_INFO_SIZ);
268 secure_check(WCNMODEM_ADR, vlr_info->length, vlr_info, puk_adr);
271 #if !BOOT_NATIVE_LINUX
272 secure_check(VMJALUNA_ADR, 0, VMJALUNA_ADR + VMJALUNA_SIZE - VLR_INFO_OFF,
273 CONFIG_SYS_NAND_U_BOOT_DST + CONFIG_SYS_NAND_U_BOOT_SIZE - KEY_INFO_SIZ - VLR_INFO_OFF);
276 #ifdef CONFIG_SIMLOCK
277 secure_check(SIMLOCK_ADR, 0, SIMLOCK_ADR + SIMLOCK_SIZE - VLR_INFO_OFF,
278 CONFIG_SYS_NAND_U_BOOT_DST + CONFIG_SYS_NAND_U_BOOT_SIZE - KEY_INFO_SIZ - VLR_INFO_OFF);
286 Function for reading user partition.
288 PUBLIC int _boot_partition_read(block_dev_desc_t * dev, wchar_t * partition_name, u32 offsetsector, u32 size, u8 * buf)
294 disk_partition_t info;
297 debugf("%s:buf is NULL!\n", __func__);
300 nsct = size / EMMC_SECTOR_SIZE;
301 left = size % EMMC_SECTOR_SIZE;
303 if (get_partition_info_by_name(dev, partition_name, &info)) {
304 debugf("get partition %s info failed!\n", w2c(partition_name));
308 if (TRUE != Emmc_Read(PARTITION_USER, info.start + offsetsector, nsct, (uint8 *)buf))
312 sctbuf = malloc(EMMC_SECTOR_SIZE);
313 if (NULL != sctbuf) {
314 if (TRUE == Emmc_Read(PARTITION_USER, info.start + offsetsector + nsct, 1, (uint8 *)sctbuf)) {
315 memcpy(buf + (nsct * EMMC_SECTOR_SIZE), sctbuf, left);
325 debugf("%s: partition %s read %s!\n", __func__, w2c(partition_name), ret ? "success" : "failed");
329 PUBLIC int blk_data_read(u32 offset, u32 size, u8 *buf)
333 u32 start_sec, nsct, left;
336 debugf("NULL BUF\n");
340 start_sec = offset / EMMC_SECTOR_SIZE;
341 nsct = size / EMMC_SECTOR_SIZE;
342 left = size % EMMC_SECTOR_SIZE;
344 if (nsct && !Emmc_Read(PARTITION_USER, start_sec, nsct, (uint8 *)buf)) {
345 debugf("Failed to read mmc\n");
350 sctbuf = malloc(EMMC_SECTOR_SIZE);
352 if (!Emmc_Read(PARTITION_USER, start_sec + nsct, 1, (uint8 *)sctbuf)) {
353 debugf("Failed to read mmc\n");
357 memcpy(buf + (nsct * EMMC_SECTOR_SIZE), sctbuf, left);
370 Function for writing user partition.
372 PUBLIC int _boot_partition_write(block_dev_desc_t * dev, wchar_t * partition_name, u32 size, u8 * buf)
374 disk_partition_t info;
377 debugf("%s:buf is NULL!\n", __FUNCTION__);
380 size = (size + (EMMC_SECTOR_SIZE - 1)) & (~(EMMC_SECTOR_SIZE - 1));
381 size = size / EMMC_SECTOR_SIZE;
382 if (0 == get_partition_info_by_name(dev, partition_name, &info)) {
383 if (TRUE != Emmc_Write(PARTITION_USER, info.start, size, buf)) {
384 debugf("%s: partition:%s read error!\n", __FUNCTION__, w2c(partition_name));
388 debugf("%s: partition:%s >>>get partition info failed!\n", __FUNCTION__, w2c(partition_name));
391 debugf("%s: partition:%s write success!\n", __FUNCTION__, w2c(partition_name));
396 Function for displaying logo.
398 LOCAL __inline void _boot_display_logo(block_dev_desc_t * dev, int backlight_set)
402 #if defined(CONFIG_LCD_720P) || defined(CONFIG_LCD_HD) || CONFIG_LCD_PAD_WXGA //LiWei add CONFIG_LCD_HD
407 uint8 *bmp_img = malloc(size);
409 debugf("%s: malloc for splash image failed!\n", __FUNCTION__);
412 if (!_boot_partition_read(dev, L"logo", 0, size, bmp_img)) {
413 debugf("%s: read logo partition failed!\n", __FUNCTION__);
416 lcd_display_logo(backlight_set, (ulong) bmp_img, size);
423 we assume partition with backup must check ecc.
425 LOCAL __inline int _boot_read_partition_with_backup(block_dev_desc_t * dev, boot_image_required_t info)
427 uint8 *bakbuf = NULL;
428 uint8 *oribuf = NULL;
430 uint8 header[EMMC_SECTOR_SIZE];
432 nv_header_t *header_p = NULL;
433 uint32 bufsize = info.size + EMMC_SECTOR_SIZE;
435 header_p = (void *)header;
436 bakbuf = malloc(bufsize);
439 memset(bakbuf, 0xff, bufsize);
440 oribuf = malloc(bufsize);
441 if (NULL == oribuf) {
445 memset(oribuf, 0xff, bufsize);
447 if (_boot_partition_read(dev, info.partition, 0, info.size + EMMC_SECTOR_SIZE, oribuf)) {
448 memset(header, 0, EMMC_SECTOR_SIZE);
449 memcpy(header, oribuf, EMMC_SECTOR_SIZE);
450 checksum = header_p->checksum;
451 debugf("_boot_read_partition_with_backup origin checksum 0x%lx\n", checksum);
452 if (_chkNVEcc(oribuf + EMMC_SECTOR_SIZE, info.size, checksum)) {
453 memcpy((void *)info.mem_addr, oribuf + EMMC_SECTOR_SIZE, info.size);
457 if (_boot_partition_read(dev, info.bak_partition, 0, info.size + EMMC_SECTOR_SIZE, bakbuf)) {
458 memset(header, 0, EMMC_SECTOR_SIZE);
459 memcpy(header, bakbuf, EMMC_SECTOR_SIZE);
460 checksum = header_p->checksum;
461 debugf("_boot_read_partition_with_backup backup checksum 0x%lx\n", checksum);
462 if (_chkNVEcc(bakbuf + EMMC_SECTOR_SIZE, info.size, checksum))
468 debugf("%s:(%s)both org and bak partition are damaged!\n", __FUNCTION__, w2c(info.partition));
469 memset((void *)info.mem_addr, 0, info.size);
474 debugf("%s:(%s)bak partition is damaged!\n", __FUNCTION__, w2c(info.bak_partition));
475 _boot_partition_write(dev, info.bak_partition, info.size + EMMC_SECTOR_SIZE, oribuf);
478 debugf("%s:(%s)org partition is damaged!\n!", __FUNCTION__, w2c(info.partition));
479 memcpy((void *)info.mem_addr, bakbuf + EMMC_SECTOR_SIZE, info.size);
480 _boot_partition_write(dev, info.partition, info.size + EMMC_SECTOR_SIZE, bakbuf);
483 debugf("%s:(%s)both org and bak partition are ok!\n", __FUNCTION__, w2c(info.partition));
486 debugf("%s: status error!\n", __FUNCTION__);
497 Function for reading image which is needed when power on.
500 int _boot_load_required_image(block_dev_desc_t * dev, boot_image_required_t img_info)
502 #ifdef CONFIG_SECURE_BOOT
503 uint32 secure_boot_offset = 0;
506 debugf("%s: load %s to addr 0x%08lx\n", __FUNCTION__, w2c(img_info.partition), img_info.mem_addr);
508 if (NULL != img_info.bak_partition) {
509 _boot_read_partition_with_backup(dev, img_info);
511 #ifdef CONFIG_SECURE_BOOT
512 if (!_boot_partition_read(dev, img_info.partition, 0, SEC_HEADER_MAX_SIZE, header_buf)) {
513 debugf("%s:%s read error!\n", __FUNCTION__, w2c(img_info.partition));
516 //if(header_parser(header_buf) )
517 secure_boot_offset = get_code_offset(header_buf);
518 _boot_partition_read(dev, img_info.partition, 0 + secure_boot_offset, img_info.size, (u8 *) img_info.mem_addr);
520 secure_verify(L"uboot", header_buf, img_info.mem_addr);
522 _boot_partition_read(dev, img_info.partition, 0, img_info.size, (u8 *) img_info.mem_addr);
530 Function for checking and loading kernel/ramdisk image.
532 LOCAL int _boot_load_kernel_ramdisk_image(block_dev_desc_t * dev, char *bootmode, boot_img_hdr * hdr)
534 wchar_t *partition = NULL;
537 disk_partition_t info;
539 if (0 == memcmp(bootmode, RECOVERY_PART, strlen(RECOVERY_PART))) {
540 partition = L"recovery";
541 debugf("enter recovery mode!\n");
542 set_recovery_mode(1);
544 partition = L""BOOT_PART;
545 debugf("Enter boot mode (partition name: %s)\n", w2c(partition));
548 if (get_partition_info_by_name(dev, partition, &info)) {
549 debugf("get partition %s info failed!\n", w2c(partition));
553 offset = info.start * info.blksz;
555 if (!blk_data_read(offset, sizeof(*hdr), (u8 *)hdr)) {
556 debugf("%s:%s read error!\n", __FUNCTION__, w2c(partition));
561 if (hdr->magic_num != MAGIC_NUM) {
562 debugf("BAD BOOT IMAGE HEADER: %x\n", hdr->magic_num);
565 debugf("BOOT IMAGE HEADER: %x\n", hdr->magic_num);
568 size = roundup(sizeof(*hdr), ALIGN_SIZE) +
569 roundup(hdr->kernel_size, ALIGN_SIZE) +
570 roundup(hdr->dt_size, ALIGN_SIZE);
572 debugf("bzImage size: %lx\n", size);
574 if (!blk_data_read(offset, size, (u8 *)(KERNEL_ADR - roundup(sizeof(*hdr), ALIGN_SIZE)))) {
575 debugf("%s:%s kernel read error!\n", __FUNCTION__, w2c(partition));
580 dt_img_adr = KERNEL_ADR + roundup(hdr->kernel_size, ALIGN_SIZE);
581 debugf("dt_img_adr: %lx\n", dt_img_adr);
582 if (load_dtb((int)DT_ADR, (void *)dt_img_adr)) {
583 debugf("%s:dt load error!\n", __FUNCTION__);
589 #ifdef CONFIG_RAMDISK_BOOT
592 if (0 == memcmp(bootmode, RECOVERY_PART, strlen(RECOVERY_PART)))
593 ramdisk_part = PARTS_RAMDISK2;
595 ramdisk_part = PARTS_RAMDISK;
596 load_ramdisk(ramdisk_part, RAMDISK_ADR, RAMDISK_SIZE_MB * 1024 * 1024);
598 #endif /* CONFIG_RAMDISK_BOOT */
599 #else /* CONFIG_TIZEN */
600 #ifdef CONFIG_SDRAMDISK
602 int sd_ramdisk_size = 0;
604 size = WDSP_ADR - RAMDISK_ADR;
606 size = TDDSP_ADR - RAMDISK_ADR;
609 sd_ramdisk_size = load_sd_ramdisk((uint8 *) RAMDISK_ADR, size);
610 if (sd_ramdisk_size > 0)
611 hdr->ramdisk_size = sd_ramdisk_size;
614 #endif /* CONFIG_TIZEN */
618 #ifdef CONFIG_SECURE_BOOT
619 PUBLIC int secure_verify_partition(block_dev_desc_t * dev, wchar_t * partition_name, int ram_addr)
623 disk_partition_t info;
625 if (get_partition_info_by_name(dev, partition_name, &info)) {
626 debugf("verify get partition %s info failed!\n", w2c(partition_name));
629 size = info.size * GPT_BLOCK_SIZE;
630 debugf("%s=%x =%x\n", w2c(partition_name), info.size, size);
632 _boot_partition_read(dev, partition_name, 0, size, (u8 *) ram_addr);
633 secure_verify(L"uboot", ram_addr, 0);
638 void vlx_nand_boot(char *kernel_pname, char *cmdline, int backlight_set)
640 boot_img_hdr *hdr = (void *)raw_header;
641 block_dev_desc_t *dev = NULL;
642 #ifdef CONFIG_SECURE_BOOT
643 wchar_t *partition = NULL;
646 long long start = get_ticks();
648 dev = get_dev("mmc", 1);
650 debugf("Fatal Error,get_dev mmc failed!\n");
654 pmic_arm7_RAM_active();
658 #ifdef CONFIG_SPLASH_SCREEN
659 _boot_display_logo(dev, backlight_set);
660 performance_debug("7:");
665 #if ((!BOOT_NATIVE_LINUX)||(BOOT_NATIVE_LINUX_MODEM))
666 //load required image which config in table
668 while (s_boot_image_table[i]) {
670 while (s_boot_image_table[i][j].partition) {
671 _boot_load_required_image(dev, s_boot_image_table[i][j]);
676 performance_debug("8:");
679 #ifdef CONFIG_SECURE_BOOT
680 if (0 == memcmp(kernel_pname, RECOVERY_PART, strlen(RECOVERY_PART))) {
681 partition = L"recovery";
685 secure_verify_partition(dev, partition, KERNEL_ADR);
687 //loader kernel and ramdisk
688 if (!_boot_load_kernel_ramdisk_image(dev, kernel_pname, hdr))
690 performance_debug("9:");
691 load_image_time = get_ticks() - start;
692 //secure check for secure boot
693 //_boot_secure_check();
695 if (creat_cmdline(cmdline, hdr)) {
696 debugf("creat_cmdline failed\n");
699 #if BOOT_NATIVE_LINUX_MODEM
703 #if defined CONFIG_SC9630