/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int sunxi_sprite_download_mbr(void *buffer, uint buffer_size) { int ret; if(buffer_size != (SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM)) { printf("the mbr size is bad\n"); return -1; } if(sunxi_sprite_init(0)) { printf("sunxi sprite init fail when downlaod mbr\n"); return -1; } if(sunxi_sprite_write(0, buffer_size/512, buffer) == (buffer_size/512)) { debug("mbr write ok\n"); ret = 0; } else { debug("mbr write fail\n"); ret = -1; } if(uboot_spare_head.boot_data.storage_type == 2) { printf("begin to write standard mbr\n"); if(card_download_standard_mbr(buffer)) { printf("write standard mbr err\n"); return -1; } printf("successed to write standard mbr\n"); } if(sunxi_sprite_exit(0)) { printf("sunxi sprite exit fail when downlaod mbr\n"); return -1; } return ret; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int sunxi_sprite_force_erase_key(void) { char buf[SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM]; if(sunxi_sprite_init(1)) { printf("sunxi sprite pre init fail\n"); return -1; } //读出量产介质上的MBR if(!sunxi_sprite_read(0, (SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM)/512, buf)) { printf("read local mbr on flash failed\n"); sunxi_sprite_exit(1); return -1; } //校验MBR if(sunxi_sprite_verify_mbr(buf)) { printf("the mbr on flash is bad\n"); sunxi_sprite_exit(1); return -1; } if(sunxi_sprite_erase_private_key(buf)) { printf("erase key fail \n"); return -1; } #ifdef CONFIG_SUNXI_SECURE_STORAGE if(sunxi_secure_storage_init()) return -1; if(sunxi_secure_storage_erase("key_burned_flag") == -1) return -1; #endif printf("erase key success \n"); return 0; }
int sunxi_flash_handle_init(void) { int workmode; int storage_type; int card_no; // long long flash_size; // uboot_spare_head.boot_data.storage_type = 0; // if(uboot_spare_head.boot_data.storage_type) // uboot_spare_head.boot_data.work_mode = WORK_MODE_CARD_PRODUCT;//WORK_MODE_CARD_PRODUCT; workmode = uboot_spare_head.boot_data.work_mode; #if 1 printf("workmode = %d\n", workmode); debug("storage type = %d\n", uboot_spare_head.boot_data.storage_type); #endif if(workmode == WORK_MODE_BOOT || workmode == WORK_MODE_SPRITE_RECOVERY) { int nand_used, sdc0_used, sdc2_used, sdc_detmode=3; storage_type = uboot_spare_head.boot_data.storage_type; debug("storage type = %d\n", storage_type); if((storage_type == 1) || (storage_type == 2)) { if(2 == storage_type) { nand_used = 0; sdc2_used = 1; script_parser_patch("nand0_para", "nand0_used", &nand_used, 1); script_parser_patch("nand1_para", "nand1_used", &nand_used, 1); script_parser_patch("mmc2_para", "sdc_used", &sdc2_used, 1); script_parser_patch("mmc2_para", "sdc_detmode", &sdc_detmode, 1); } else { //nand_used = 0; sdc0_used = 1; //sdc2_used = 0; //script_parser_patch("nand0_para", "nand0_used", &nand_used, 1); //script_parser_patch("nand1_para", "nand1_used", &nand_used, 1); script_parser_patch("mmc0_para", "sdc_used", &sdc0_used, 1); script_parser_patch("mmc0_para", "sdc_detmode", &sdc_detmode, 1); //script_parser_patch("mmc2_para", "sdc_used", &sdc2_used, 1); } card_no = (storage_type == 1)?0:2; printf("MMC: %d\n", card_no); board_mmc_set_num(card_no); debug("set card number\n"); board_mmc_pre_init(card_no); debug("begin to find mmc\n"); mmc_boot = find_mmc_device(card_no); if(!mmc_boot){ printf("fail to find one useful mmc card\n"); return -1; } debug("try to init mmc\n"); if (mmc_init(mmc_boot)) { puts("MMC init failed\n"); return -1; } debug("mmc %d init ok\n", card_no); sunxi_flash_read_pt = sunxi_flash_mmc_read; sunxi_flash_write_pt = sunxi_flash_mmc_write; sunxi_flash_size_pt = sunxi_flash_mmc_size; sunxi_flash_exit_pt = sunxi_flash_mmc_exit; sunxi_flash_phyread_pt = sunxi_flash_mmc_phyread; sunxi_flash_phywrite_pt = sunxi_flash_mmc_phywrite; sunxi_sprite_phyread_pt = sunxi_flash_mmc_phyread; sunxi_sprite_phywrite_pt = sunxi_flash_mmc_phywrite; } else { nand_used = 1; sdc2_used = 0; script_parser_patch("nand0_para", "nand0_used", &nand_used, 1); script_parser_patch("nand1_para", "nand1_used", &nand_used, 1); script_parser_patch("mmc2_para", "sdc_used", &sdc2_used, 1); tick_printf("NAND: "); if (workmode == WORK_MODE_BOOT) { if(nand_uboot_init(1)) { tick_printf("nand init fail\n"); return -1; } } else if (workmode == WORK_MODE_SPRITE_RECOVERY) { if(nand_uboot_init(2)) { tick_printf("nand init fail\n"); return -1; } } //flash_size = nand_uboot_get_flash_size(); //flash_size <<= 9; //print_size(flash_size, "\n"); sunxi_flash_read_pt = sunxi_flash_nand_read; sunxi_flash_write_pt = sunxi_flash_nand_write; sunxi_flash_size_pt = sunxi_flash_nand_size; sunxi_flash_exit_pt = sunxi_flash_nand_exit; sunxi_flash_flush_pt = sunxi_flash_nand_flush; } sunxi_sprite_read_pt = sunxi_flash_read_pt; sunxi_sprite_write_pt = sunxi_flash_write_pt; sunxi_flash_init_uboot(0); script_parser_patch("target", "storage_type", &storage_type, 1); tick_printf("sunxi flash init ok\n"); #if defined(CONFIG_ARCH_SUN8IW1P1) if((storage_type == 0) || (storage_type == 2)) //如果是A31非卡0启动,则需要跳转检测卡0 { sunxi_card_probe_mmc0_boot(); } #endif if((storage_type == 0) ||(storage_type == 2)) { int sprite_next_work = 0; script_parser_fetch("card_boot","next_work",&sprite_next_work,1); if(sprite_next_work == SUNXI_UPDATA_NEXT_ACTION_SPRITE_TEST) sunxi_card_fill_boot0_magic(); } } else if((workmode & WORK_MODE_PRODUCT) || (workmode == 0x30)) /* 量产模式 */ { if(!nand_uboot_probe()) { printf("nand found\n"); sunxi_sprite_init_pt = sunxi_flash_nand_init; sunxi_sprite_exit_pt = sunxi_flash_nand_exit; sunxi_sprite_read_pt = sunxi_flash_nand_read; sunxi_sprite_write_pt = sunxi_flash_nand_write; sunxi_sprite_erase_pt = sunxi_flash_nand_erase; sunxi_sprite_size_pt = sunxi_flash_nand_size; sunxi_sprite_flush_pt = sunxi_flash_nand_flush; sunxi_sprite_force_erase_pt = sunxi_flash_nand_force_erase; debug("sunxi sprite has installed nand function\n"); uboot_spare_head.boot_data.storage_type = 0; if(workmode == 0x30) { if(sunxi_sprite_init(1)) { tick_printf("nand init fail\n"); return -1; } } } #ifdef CONFIG_SUNXI_SPINOR else if(!try_spi_nor(0)) //burn nor { printf("try nor successed \n"); sunxi_sprite_init_pt = sunxi_flash_spinor_init; sunxi_sprite_exit_pt = sunxi_flash_spinor_exit; sunxi_sprite_read_pt = sunxi_flash_spinor_read; sunxi_sprite_write_pt = sunxi_sprite_spinor_write; sunxi_sprite_erase_pt = sunxi_flash_spinor_erase; sunxi_sprite_size_pt = sunxi_flash_spinor_size; sunxi_sprite_flush_pt = sunxi_flash_spinor_flush; sunxi_sprite_datafinish_pt = sunxi_flash_spinor_datafinish; printf("sunxi sprite has installed spi function\n"); uboot_spare_head.boot_data.storage_type = 3; } #endif else /* burn sdcard 2 */ { printf("try nand fail\n"); board_mmc_pre_init(2); mmc_sprite = find_mmc_device(2); if(!mmc_sprite){ printf("fail to find one useful mmc card\n"); return -1; } if (mmc_init(mmc_sprite)) { puts("MMC init failed\n"); return -1; } sunxi_sprite_init_pt = sunxi_sprite_mmc_init; sunxi_sprite_exit_pt = sunxi_sprite_mmc_exit; sunxi_sprite_read_pt = sunxi_sprite_mmc_read; sunxi_sprite_write_pt = sunxi_sprite_mmc_write; sunxi_sprite_erase_pt = sunxi_sprite_mmc_erase; sunxi_sprite_size_pt = sunxi_sprite_mmc_size; sunxi_sprite_phyread_pt = sunxi_sprite_mmc_phyread; sunxi_sprite_phywrite_pt = sunxi_sprite_mmc_phywrite; sunxi_sprite_force_erase_pt = sunxi_sprite_mmc_force_erase; debug("sunxi sprite has installed sdcard2 function\n"); uboot_spare_head.boot_data.storage_type = 2; } if((workmode == WORK_MODE_CARD_PRODUCT) || (workmode == 0x30)) //sdcard burn mode { board_mmc_pre_init(0); mmc_boot = find_mmc_device(0); if(!mmc_boot) { printf("fail to find one useful mmc card\n"); return -1; } if (mmc_init(mmc_boot)) { puts("MMC sprite init failed\n"); return -1; } else { puts("mmc init ok\n"); } sunxi_flash_init_pt = sunxi_flash_mmc_init; sunxi_flash_read_pt = sunxi_flash_mmc_read; sunxi_flash_write_pt = sunxi_flash_mmc_write; sunxi_flash_size_pt = sunxi_flash_mmc_size; sunxi_flash_phyread_pt = sunxi_flash_mmc_phyread; sunxi_flash_phywrite_pt = sunxi_flash_mmc_phywrite; sunxi_flash_exit_pt = sunxi_flash_mmc_exit; } sunxi_flash_init_uboot(0); } else if(workmode & WORK_MODE_UPDATE) /* 升级模式 */ { } else /* undefined mode */ { } return 0; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int sunxi_sprite_erase_flash(void *img_mbr_buffer) { uint32_t need_erase_flag = 0; char buf[SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM]; //int ret; int nodeoffset; if(sunxi_sprite_erase(0, img_mbr_buffer) > 0) { printf("flash already erased\n"); return 0; } //获取擦除信息,查看是否需要擦除flash //ret = script_parser_fetch("platform", "eraseflag", &need_erase_flag, 1); nodeoffset = fdt_path_offset(working_fdt,FDT_PATH_PLATFORM); if(nodeoffset > 0) { fdt_getprop_u32(working_fdt,nodeoffset,"eraseflag",&need_erase_flag); } if(need_erase_flag) { printf("do need erase flash\n"); } else { printf("not need erase flash\n"); } //当要求强制擦除,不处理私有数据 if(need_erase_flag == 0x11) { printf("force erase flash\n"); sunxi_sprite_erase(1, img_mbr_buffer); return 0; } //检测不到private分区,即不用保护用户数据 if(!sunxi_sprite_probe_prvt(img_mbr_buffer)) { printf("no part need to protect user data\n"); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } //当初始化失败的时候,直接擦除,不处理私有数据 if(sunxi_sprite_init(1)) { debug("sunxi sprite pre init fail, we have to erase it\n"); sunxi_sprite_exit(1); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } debug("nand pre init ok\n"); //读出量产介质上的MBR if(!sunxi_sprite_read(0, (SUNXI_MBR_SIZE * SUNXI_MBR_COPY_NUM)/512, buf)) { printf("read local mbr on flash failed\n"); sunxi_sprite_exit(1); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } //校验MBR if(sunxi_sprite_verify_mbr(buf)) { printf("the mbr on flash is bad\n"); sunxi_sprite_exit(1); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); return 0; } printf("begin to store data\n"); if(sunxi_sprite_store_part_data(buf) < 0) { sunxi_sprite_exit(1); return -1; } sunxi_sprite_exit(1); printf("need_erase_flag = %d\n", need_erase_flag); //开始擦除 printf("begin to erase\n"); sunxi_sprite_erase(need_erase_flag, img_mbr_buffer); //开始回写private printf("finish erase\n"); sunxi_sprite_init(0); printf("rewrite\n"); if(sunxi_sprite_restore_part_data(img_mbr_buffer)) { sunxi_sprite_exit(0); return -1; } printf("flash exit\n"); sunxi_sprite_exit(0); return 0; }