#include "debug.h" | |
#include "load_vt.h" | |
#include "flash_wp.h" | |
#include "bootloader.h" | |
#include "apb_watchdog.h" | |
#ifdef ENABLE_EMMC | |
#include "sdmmc_api.h" | |
static int emmc_write_protect(int bootmode) | |
{ | |
ver_table_entry_t vt_entry; | |
unsigned long long wp_start_addr; | |
unsigned long long wp_size; | |
unsigned long long emmc_chip_size; | |
int i, ret, tmp; | |
int ver_table_entry_num; | |
//amend emmc erase unit size, write protect size and chip size. | |
ret = emmc_amend_sundry_size(); | |
if (ret){ | |
dbg_printf(PRN_ERR,"emmc amend sundry_size fail.\n"); | |
} | |
emmc_chip_size = emmc_get_chip_size(); | |
ret = emmc_enable_userarea_poweron_write_protect(); | |
if (ret != 0){ | |
dbg_printf(PRN_ERR,"emmc user area write protect enable fail.\n"); | |
reset_soc(); | |
} | |
//1. partition tables at header. | |
wp_start_addr = 0ULL; | |
wp_size = (16ULL << 20); | |
ret = emmc_set_userarea_write_protect(wp_start_addr, wp_size); | |
if (ret){ | |
dbg_printf(PRN_ERR,"emmc partition table write protect fail.\n"); | |
reset_soc(); | |
} | |
//2. partition tables at tail. | |
tmp = emmc_chip_size % (16ULL << 20); | |
if (tmp) | |
wp_start_addr = emmc_chip_size - tmp; | |
else | |
wp_start_addr = emmc_chip_size - (16ULL << 20); | |
wp_size = (16ULL << 20); | |
ret = emmc_set_userarea_write_protect(wp_start_addr, wp_size); | |
if (ret){ | |
dbg_printf(PRN_ERR,"emmc partition table write protect fail.\n"); | |
reset_soc(); | |
} | |
//3. partitions according boot mode. | |
ver_table_entry_num = get_version_table_entry_number(); | |
if(bootmode == BOOTMODE_RECOVERY){ | |
#if 0 | |
dbg_printf(PRN_RES,"Clear write protect of boot partition.\n"); | |
ret = emmc_disable_bootarea_poweron_write_protect(pSDMMCP); | |
if (ret != 0){ | |
dbg_printf(PRN_ERR,"emmc boot partition write protect enable fail.\n"); | |
while(1); | |
} | |
#endif | |
for (i = 0; i < ver_table_entry_num; i++) | |
{ | |
fetch_partition_info(i, &vt_entry); | |
if (vt_entry.write_protect_flag & RECOVERY_WP_MASK) | |
{ | |
wp_start_addr = vt_entry.part1_start_blkind * ((512ULL) << 10); | |
wp_size = vt_entry.part1_blks * ((512ULL) << 10); | |
ret = emmc_set_userarea_write_protect(wp_start_addr, wp_size); | |
if (ret){ | |
dbg_printf(PRN_ERR,"set user area partition %s to write protect fail.\n", vt_entry.name); | |
reset_soc(); | |
} | |
dbg_printf(PRN_RES,"Set user area partition %s to write protect.\n", vt_entry.name); | |
} | |
} | |
}else if (bootmode == BOOTMODE_NORMAL){ | |
dbg_printf(PRN_RES,"Set boot area to write protect. \n"); | |
ret = emmc_enable_bootarea_poweron_write_protect(); | |
if (ret != 0){ | |
dbg_printf(PRN_ERR,"emmc boot area write protect enable fail.\n"); | |
reset_soc(); | |
} | |
for (i = 0; i < ver_table_entry_num; i++) | |
{ | |
fetch_partition_info(i, &vt_entry); | |
//dbg_printf(PRN_RES,"vt_entry.name = %s.\t", vt_entry.name); | |
//dbg_printf(PRN_RES,"vt_entry.write_protect_flag = %d.\n", vt_entry.write_protect_flag); | |
if (vt_entry.write_protect_flag & NORMAL_WP_MASK) | |
{ | |
wp_start_addr = vt_entry.part1_start_blkind * ((512ULL) << 10); | |
wp_size = vt_entry.part1_blks * ((512ULL) << 10); | |
ret = emmc_set_userarea_write_protect(wp_start_addr, wp_size); | |
if (ret){ | |
dbg_printf(PRN_ERR,"set user area partition %s to write protect fail.\n", vt_entry.name); | |
reset_soc(); | |
} | |
dbg_printf(PRN_RES,"set user area partition %s to write protect.\n", vt_entry.name); | |
} | |
} | |
} | |
return 0; | |
} | |
#endif | |
int flash_write_protect(int bootmode) | |
{ | |
#ifdef ENABLE_EMMC | |
return emmc_write_protect(bootmode); | |
#endif | |
dbg_printf(PRN_DBG,"write protection is not supported.\n"); | |
return 0; | |
} |