#include "Typedef.h" #include "Errors.h" #include "bsp.h" #include "PlatformConfig.h" #include "osa.h" #include #include "UART.h" #include "qspi_host.h" #include "qspi_nor.h" #include "qspi_dma.h" #include "crane_ds_mpu.h" #include "loadTable.h" #include "qspi_nor_bp.h" #ifdef SUPPORT_FBP #define FBP_THIN #ifdef SW_HANDLE_XIP extern int spi_nor_wait(struct spi_flash_chip *chip, uint8_t *s, int pe, unsigned int *p_cpsr); #else extern int spi_nor_wait(struct spi_flash_chip *chip, uint8_t *s); #endif extern BOOL IsMiniSystem(void); extern UINT32 get_reserved_start_address(void); extern UINT32 get_reserved_end_address(void); extern UINT32 get_bootloader_end_address(void); ProtectedAreaSizeType flash_protect_area_type = PORTION_NONE; #define ALL_BP_BITS(x) ((x >> 2) & 0x1F) #define ALL_BP_BITS_CLEAR(x) ( x & 0x83) // & 10000011 #define ALL_BP_BITS_GET(x) (x & 0x7C) // &01111100 #if !(defined(CRANEL_8MRAM) || defined(CRANEL_4MRAM) || defined(LTEGSM_THIN)) ProtectAreaInfo ProtectAreaInfo_16M[PORTITION_MAX_TYPE] = { {PORTION_NONE, 0x0, 0x0}, {PORTION_UPPER_1_64, 0xFC0000, 0xFFFFFF}, {PORTION_UPPER_1_32, 0xF80000, 0xFFFFFF}, {PORTION_UPPER_1_16, 0xF00000, 0xFFFFFF}, {PORTION_UPPER_1_8, 0xE00000, 0xFFFFFF}, {PORTION_UPPER_1_4, 0xC00000, 0xFFFFFF}, {PORTION_UPPER_1_2, 0x800000, 0xFFFFFF}, {PORTION_LOWER_1_64, 0x000000, 0x03FFFF}, {PORTION_LOWER_1_32, 0x000000, 0x07FFFF}, {PORTION_LOWER_1_16, 0x000000, 0x0FFFFF}, {PORTION_LOWER_1_8, 0x000000, 0x1FFFFF}, {PORTION_LOWER_1_4, 0x000000, 0x3FFFFF}, {PORTION_LOWER_1_2, 0x000000, 0x7FFFFF}, {PORTION_TOP_4K, 0xFFF000, 0xFFFFFF}, {PORTION_TOP_8K, 0xFFE000, 0xFFFFFF}, {PORTION_TOP_16K, 0xFFC000, 0xFFFFFF}, {PORTION_TOP_32K, 0xFF8000, 0xFFFFFF}, {PORTION_BOTTOM_4K, 0x000000, 0x000FFF}, {PORTION_BOTTOM_8K, 0x000000, 0x001FFF}, {PORTION_BOTTOM_16K, 0x000000, 0x003FFF}, {PORTION_BOTTOM_32K, 0x000000, 0x007FFF}, {PORTION_LOWER_63_64, 0x000000, 0xFBFFFF}, {PORTION_LOWER_31_32, 0x000000, 0xF7FFFF}, {PORTION_LOWER_15_16, 0x000000, 0xEFFFFF}, {PORTION_LOWER_7_8, 0x000000, 0xDFFFFF}, {PORTION_LOWER_3_4, 0x000000, 0xBFFFFF}, {PORTION_UPPER_63_64, 0x040000, 0xFFFFFF}, {PORTION_UPPER_31_32, 0x080000, 0xFFFFFF}, {PORTION_UPPER_15_16, 0x100000, 0xFFFFFF}, {PORTION_UPPER_7_8, 0x200000, 0xFFFFFF}, {PORTION_UPPER_3_4, 0x400000, 0xFFFFFF}, {PORTION_UNPROTECT_TOP_4K, 0x000000, 0xFFEFFF}, {PORTION_UNPROTECT_TOP_8K, 0x000000, 0xFFDFFF}, {PORTION_UNPROTECT_TOP_16K, 0x000000, 0xFFBFFF}, {PORTION_UNPROTECT_TOP_32K, 0x000000, 0xFF7FFF}, {PORTION_UNPROTECT_BOTTOM_4K, 0x001000, 0xFFFFFF}, {PORTION_UNPROTECT_BOTTOM_8K, 0x002000, 0xFFFFFF}, {PORTION_UNPROTECT_BOTTOM_16K, 0x004000, 0xFFFFFF}, {PORTION_UNPROTECT_BOTTOM_32K, 0x008000, 0xFFFFFF}, {PORTION_ALL, 0x000000, 0xFFFFFF}, }; #endif ProtectAreaInfo ProtectAreaInfo_8M[] = { {PORTION_NONE, 0x0, 0x0}, #ifndef FBP_THIN {PORTION_UPPER_1_64, 0x7E0000, 0x7FFFFF}, {PORTION_UPPER_1_32, 0x7C0000, 0x7FFFFF}, {PORTION_UPPER_1_16, 0x780000, 0x7FFFFF}, {PORTION_UPPER_1_8, 0x700000, 0x7FFFFF}, {PORTION_UPPER_1_4, 0x600000, 0x7FFFFF}, {PORTION_UPPER_1_2, 0x400000, 0x7FFFFF}, #endif {PORTION_LOWER_1_64, 0x000000, 0x01FFFF}, {PORTION_LOWER_1_32, 0x000000, 0x03FFFF}, {PORTION_LOWER_1_16, 0x000000, 0x07FFFF}, {PORTION_LOWER_1_8, 0x000000, 0x0FFFFF}, {PORTION_LOWER_1_4, 0x000000, 0x1FFFFF}, {PORTION_LOWER_1_2, 0x000000, 0x3FFFFF}, #ifndef FBP_THIN {PORTION_TOP_4K, 0x7FF000, 0x7FFFFF}, {PORTION_TOP_8K, 0x7FE000, 0x7FFFFF}, {PORTION_TOP_16K, 0x7FC000, 0x7FFFFF}, {PORTION_TOP_32K, 0x7F8000, 0x7FFFFF}, #endif {PORTION_BOTTOM_4K, 0x000000, 0x000FFF}, {PORTION_BOTTOM_8K, 0x000000, 0x001FFF}, {PORTION_BOTTOM_16K, 0x000000, 0x003FFF}, {PORTION_BOTTOM_32K, 0x000000, 0x007FFF}, {PORTION_LOWER_63_64, 0x000000, 0x7DFFFF}, {PORTION_LOWER_31_32, 0x000000, 0x7BFFFF}, {PORTION_LOWER_15_16, 0x000000, 0x77FFFF}, {PORTION_LOWER_7_8, 0x000000, 0x6FFFFF}, {PORTION_LOWER_3_4, 0x000000, 0x5FFFFF}, #ifndef FBP_THIN {PORTION_UPPER_63_64, 0x020000, 0x7FFFFF}, {PORTION_UPPER_31_32, 0x040000, 0x7FFFFF}, {PORTION_UPPER_15_16, 0x080000, 0x7FFFFF}, {PORTION_UPPER_7_8, 0x100000, 0x7FFFFF}, {PORTION_UPPER_3_4, 0x200000, 0x7FFFFF}, {PORTION_UNPROTECT_TOP_4K, 0x000000, 0x7FEFFF}, {PORTION_UNPROTECT_TOP_8K, 0x000000, 0x7FDFFF}, {PORTION_UNPROTECT_TOP_16K, 0x000000, 0x7FBFFF}, {PORTION_UNPROTECT_TOP_32K, 0x000000, 0x7F7FFF}, {PORTION_UNPROTECT_BOTTOM_4K, 0x001000, 0x7FFFFF}, {PORTION_UNPROTECT_BOTTOM_8K, 0x002000, 0x7FFFFF}, {PORTION_UNPROTECT_BOTTOM_16K, 0x004000, 0x7FFFFF}, {PORTION_UNPROTECT_BOTTOM_32K, 0x008000, 0x7FFFFF}, #endif {PORTION_ALL, 0x000000, 0x7FFFFF}, }; ProtectAreaInfo ProtectAreaInfo_4M[] = { {PORTION_NONE, 0x0, 0x0}, #ifndef FBP_THIN {PORTION_UPPER_1_64, 0x3F0000, 0x3FFFFF}, {PORTION_UPPER_1_32, 0x3E0000, 0x3FFFFF}, {PORTION_UPPER_1_16, 0x3C0000, 0x3FFFFF}, {PORTION_UPPER_1_8, 0x380000, 0x3FFFFF}, {PORTION_UPPER_1_4, 0x300000, 0x3FFFFF}, {PORTION_UPPER_1_2, 0x200000, 0x3FFFFF}, #endif {PORTION_LOWER_1_64, 0x000000, 0x00FFFF}, {PORTION_LOWER_1_32, 0x000000, 0x01FFFF}, {PORTION_LOWER_1_16, 0x000000, 0x03FFFF}, {PORTION_LOWER_1_8, 0x000000, 0x07FFFF}, {PORTION_LOWER_1_4, 0x000000, 0x0FFFFF}, {PORTION_LOWER_1_2, 0x000000, 0x1FFFFF}, #ifndef FBP_THIN {PORTION_TOP_4K, 0x3FF000, 0x3FFFFF}, {PORTION_TOP_8K, 0x3FE000, 0x3FFFFF}, {PORTION_TOP_16K, 0x3FC000, 0x3FFFFF}, {PORTION_TOP_32K, 0x3F8000, 0x3FFFFF}, #endif {PORTION_BOTTOM_4K, 0x000000, 0x000FFF}, {PORTION_BOTTOM_8K, 0x000000, 0x001FFF}, {PORTION_BOTTOM_16K, 0x000000, 0x003FFF}, {PORTION_BOTTOM_32K, 0x000000, 0x007FFF}, {PORTION_LOWER_63_64, 0x000000, 0x3EFFFF}, {PORTION_LOWER_31_32, 0x000000, 0x3DFFFF}, {PORTION_LOWER_15_16, 0x000000, 0x3BFFFF}, {PORTION_LOWER_7_8, 0x000000, 0x37FFFF}, {PORTION_LOWER_3_4, 0x000000, 0x2FFFFF}, #ifndef FBP_THIN {PORTION_UPPER_63_64, 0x010000, 0x3FFFFF}, {PORTION_UPPER_31_32, 0x020000, 0x3FFFFF}, {PORTION_UPPER_15_16, 0x040000, 0x3FFFFF}, {PORTION_UPPER_7_8, 0x080000, 0x3FFFFF}, {PORTION_UPPER_3_4, 0x100000, 0x3FFFFF}, {PORTION_UNPROTECT_TOP_4K, 0x000000, 0x3FEFFF}, {PORTION_UNPROTECT_TOP_8K, 0x000000, 0x3FDFFF}, {PORTION_UNPROTECT_TOP_16K, 0x000000, 0x3FBFFF}, {PORTION_UNPROTECT_TOP_32K, 0x000000, 0x3F7FFF}, {PORTION_UNPROTECT_BOTTOM_4K, 0x001000, 0x3FFFFF}, {PORTION_UNPROTECT_BOTTOM_8K, 0x002000, 0x3FFFFF}, {PORTION_UNPROTECT_BOTTOM_16K, 0x004000, 0x3FFFFF}, {PORTION_UNPROTECT_BOTTOM_32K, 0x008000, 0x3FFFFF}, #endif {PORTION_ALL, 0x000000, 0x3FFFFF}, }; ProtectAreaInfo ProtectAreaInfo_2M[] = { {PORTION_NONE, 0x0, 0x0}, #ifndef FBP_THIN {PORTION_UPPER_1_64, 0xFFFFFFFF, 0xFFFFFFFF}, //this is useless type in 2M flash {PORTION_UPPER_1_32, 0x1F0000, 0x1FFFFF}, {PORTION_UPPER_1_16, 0x1E0000, 0x1FFFFF}, {PORTION_UPPER_1_8, 0x1C0000, 0x1FFFFF}, {PORTION_UPPER_1_4, 0x180000, 0x1FFFFF}, {PORTION_UPPER_1_2, 0x100000, 0x1FFFFF}, {PORTION_LOWER_1_64, 0xFFFFFFFF, 0xFFFFFFFF}, //this is useless type in 2M flash #endif {PORTION_LOWER_1_32, 0x000000, 0x00FFFF}, {PORTION_LOWER_1_16, 0x000000, 0x01FFFF}, {PORTION_LOWER_1_8, 0x000000, 0x03FFFF}, {PORTION_LOWER_1_4, 0x000000, 0x07FFFF}, {PORTION_LOWER_1_2, 0x000000, 0x0FFFFF}, #ifndef FBP_THIN {PORTION_TOP_4K, 0x1FF000, 0x1FFFFF}, {PORTION_TOP_8K, 0x1FE000, 0x1FFFFF}, {PORTION_TOP_16K, 0x1FC000, 0x1FFFFF}, {PORTION_TOP_32K, 0x1F8000, 0x1FFFFF}, #endif {PORTION_BOTTOM_4K, 0x000000, 0x000FFF}, {PORTION_BOTTOM_8K, 0x000000, 0x001FFF}, {PORTION_BOTTOM_16K, 0x000000, 0x003FFF}, {PORTION_BOTTOM_32K, 0x000000, 0x007FFF}, {PORTION_LOWER_63_64, 0xFFFFFFFF, 0xFFFFFFFF}, //this is useless type in 2M flash {PORTION_LOWER_31_32, 0x000000, 0x1EFFFF}, {PORTION_LOWER_15_16, 0x000000, 0x1DFFFF}, {PORTION_LOWER_7_8, 0x000000, 0x1BFFFF}, {PORTION_LOWER_3_4, 0x000000, 0x17FFFF}, #ifndef FBP_THIN {PORTION_UPPER_63_64, 0xFFFFFFFF, 0xFFFFFFFF}, //this is useless type in 2M flash {PORTION_UPPER_31_32, 0x010000, 0x1FFFFF}, {PORTION_UPPER_15_16, 0x020000, 0x1FFFFF}, {PORTION_UPPER_7_8, 0x040000, 0x1FFFFF}, {PORTION_UPPER_3_4, 0x080000, 0x1FFFFF}, {PORTION_UNPROTECT_TOP_4K, 0x000000, 0x1FEFFF}, {PORTION_UNPROTECT_TOP_8K, 0x000000, 0x1FDFFF}, {PORTION_UNPROTECT_TOP_16K, 0x000000, 0x1FBFFF}, {PORTION_UNPROTECT_TOP_32K, 0x000000, 0x1F7FFF}, {PORTION_UNPROTECT_BOTTOM_4K, 0x001000, 0x1FFFFF}, {PORTION_UNPROTECT_BOTTOM_8K, 0x002000, 0x1FFFFF}, {PORTION_UNPROTECT_BOTTOM_16K, 0x004000, 0x1FFFFF}, {PORTION_UNPROTECT_BOTTOM_32K, 0x008000, 0x1FFFFF}, #endif {PORTION_ALL, 0x000000, 0x1FFFFF}, }; int qspi_nor_find_fbp(uint32_t start_addr, uint32_t end_addr, struct spi_flash_chip *chip) { ProtectAreaInfo *pProtectAreaInfo = NULL, *pTempProtectAreaInfo = NULL; //struct spi_flash_chip *chip = &nor_chip; int type_num = 0; int total_type = 0; int protect_type = -1; uint32_t size = 0, temp_size = 0; int first_entry = 1; if(!chip) { CPUartLogPrintf("%s:chip is null", __func__); return protect_type; } CPUartLogPrintf("%s:flash size is 0x%llx, name is %s", __func__, chip->size, chip->name); //160x series only built-in GD and XMC flash,both of them have the same FBP setting #if !(defined(CRANEL_8MRAM) || defined(CRANEL_4MRAM) || defined(LTEGSM_THIN)) if(chip->size == 16*1024*1024){ pProtectAreaInfo = &ProtectAreaInfo_16M[0]; total_type = sizeof(ProtectAreaInfo_16M)/sizeof(ProtectAreaInfo); } else #endif if(chip->size == 8*1024*1024){ pProtectAreaInfo = &ProtectAreaInfo_8M[0]; total_type = sizeof(ProtectAreaInfo_8M)/sizeof(ProtectAreaInfo); } else if(chip->size == 4*1024*1024){ pProtectAreaInfo = &ProtectAreaInfo_4M[0]; total_type = sizeof(ProtectAreaInfo_4M)/sizeof(ProtectAreaInfo); } else if(chip->size == 2*1024*1024) { pProtectAreaInfo = &ProtectAreaInfo_2M[0]; total_type = sizeof(ProtectAreaInfo_2M)/sizeof(ProtectAreaInfo); } else { RTI_LOG("%s:unkown flash,not support fbp", __func__); return protect_type; } for(type_num = PORTION_NONE; type_num < total_type; type_num++) { pTempProtectAreaInfo = (ProtectAreaInfo *)(pProtectAreaInfo + type_num); if(pTempProtectAreaInfo->start_address == 0x0 && pTempProtectAreaInfo->end_address <= end_addr) { if(first_entry) { size = pTempProtectAreaInfo->end_address - 0x0; protect_type = pProtectAreaInfo[type_num].protect_type; first_entry = 0; } //CPUartLogPrintf("protect_type=%d,size=0x%x",protect_type,size); if(size < pTempProtectAreaInfo->end_address) { size = pTempProtectAreaInfo->end_address - 0x0; protect_type = pProtectAreaInfo[type_num].protect_type; } } } #ifdef QUEC_ADD_FALSH_TEST_SUPPORT #ifndef MIN_SYS if (!IsMiniSystem()) {//MiniSystem extern void quec_set_fbp_size(int size); quec_set_fbp_size(size); } #endif #endif RTI_LOG("%s:find type is %d, protect area=0x0~0x%lx", __func__, protect_type, size); return protect_type; } int qspi_nor_set_fbp(ProtectedAreaSizeType protect_type, struct spi_flash_chip *chip) { uint8_t status1,status2,n_status1,n_status2; uint8_t data[2]; uint8_t status; int ret = 0; int is2MFlashFlag = 0; //struct spi_flash_chip *chip = &nor_chip; if(chip->size == 2*1024*1024) { is2MFlashFlag = 1; CPUartLogPrintf("%s:set is2MFlashFlag to 1.", __func__); } ret = spi_nor_read_status1(chip, &status1); if(ret < 0) { CPUartLogPrintf("%s:spi_nor_read_status1 failed.", __func__); return ret; } if((chip->options & SPINOR_WRITE_STATUS1_1BYTE) && !(chip->options & SPINOR_HAVE_WRITE_STATUS2)) //no read SR2 if no SR2 status2 = 0; else { ret = spi_nor_read_status2(chip, &status2); if(ret < 0) { CPUartLogPrintf("%s:spi_nor_read_status2 failed.", __func__); return ret; } } RTI_LOG("%s:org status1[0x%x],status2[0x%x].", __func__, status1, status2); n_status1 = status1; n_status2 = status2; switch(protect_type) { case PORTION_NONE: { if(is2MFlashFlag) { if(status2 & (1<<6)) //CMP = 1 { status1 = status1 | (6 << 2); // 2M flash only set bp2-bp1 } else //CMP = 0 { status1 = status1 & 0xE3; //b 11100011 clear bp2-bp0 } } else { if(status2 & (1<<6)) //CMP = 1 { status1 = status1 | (7 << 2); } else //CMP = 0 { status1 = status1 & 0xE3; //b 11100011 clear bp2-bp0 } } //CPUartLogPrintf("PORTION_NONE,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_ALL: { if(is2MFlashFlag) { if(status2 & (1<<6)) //CMP = 1 { status1 = status1 & 0xE3; //b 11100011 clear bp2-bp0 } else //CMP = 0 { status1 = status1 | (6 << 2); // 2M flash only set bp2-bp1 } } else { if(status2 & (1<<6)) //CMP = 1 { status1 = status1 & 0xE3; //b 11100011 clear bp2-bp0 } else //CMP = 0 { status1 = status1 | (7 << 2); } } //CPUartLogPrintf("PORTION_ALL,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #ifndef FBP_THIN case PORTION_UPPER_1_64: { if(is2MFlashFlag) { CPUartLogPrintf("%s:2M flash not support PORTION_UPPER_1_64", __func__); return -1; } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x04; // b 00000100 } //CPUartLogPrintf("PORTION_UPPER_1_64,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_1_32: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x04; // b 00000100 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x08; // b 00001000 } //CPUartLogPrintf("PORTION_UPPER_1_32,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_1_16: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x08; // b 00001000 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x0C; // b 00001100 } //CPUartLogPrintf("PORTION_UPPER_1_16,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_1_8: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x0C; // b 00001100 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x10; // b 00010000 } //CPUartLogPrintf("PORTION_UPPER_1_8,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_1_4: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x10; // b 00010000 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x12; // b 00010100 } //CPUartLogPrintf("PORTION_UPPER_1_4,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_1_2: { if(is2MFlashFlag) { if(status2 & (1<<6)) //CMP = 1 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x34; // b 00110100 } else //CMP = 0 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x12; // b 00010100 } } else { if(status2 & (1<<6)) //CMP = 1 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x38; // b 00111000 } else //CMP = 0 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x14; // b 00011000 } } //CPUartLogPrintf("PORTION_UPPER_1_2,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #endif case PORTION_LOWER_1_64: { if(is2MFlashFlag) { CPUartLogPrintf("%s:2M flash not support PORTION_UPPER_1_64", __func__); return -1; } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x24; // b 00100100 } //CPUartLogPrintf("PORTION_LOWER_1_64,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_1_32: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x24; // b 00100100 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x28; // b 00101000 } //CPUartLogPrintf("PORTION_LOWER_1_32,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_1_16: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x28; // b 00101000 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x2C; // b 00101100 } //CPUartLogPrintf("PORTION_LOWER_1_16,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_1_8: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x2C; // b 00101100 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x30; // b 00110000 } //CPUartLogPrintf("PORTION_LOWER_1_8,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_1_4: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x30; // b 00110000 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x34; // b 00110100 } //CPUartLogPrintf("PORTION_LOWER_1_4,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_1_2: { if(is2MFlashFlag) { if(status2 & (1<<6)) //CMP = 1 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x14; // b 00010100 } else //CMP = 0 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x34; // b 00110100 } } else { if(status2 & (1<<6)) //CMP = 1 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x18; // b 00011000 } else //CMP = 0 { status1 = ALL_BP_BITS_CLEAR(status1)| 0x38; // b 00111000 } } //CPUartLogPrintf("PORTION_LOWER_1_2,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #ifndef FBP_THIN case PORTION_TOP_4K: { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x44; // b 01000100 //CPUartLogPrintf("PORTION_TOP_4K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_TOP_8K: { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x48; // b 01001000 //CPUartLogPrintf("PORTION_TOP_8K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_TOP_16K: { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x4C; // b 01001100 //CPUartLogPrintf("PORTION_TOP_16K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_TOP_32K: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x50; // b 01010x00 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x58; // b 01011000 } //CPUartLogPrintf("PORTION_TOP_32K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_BOTTOM_4K: { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x64; // b 01100100 //CPUartLogPrintf("PORTION_BOTTOM_4K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_BOTTOM_8K: { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x68; // b 01101000 //CPUartLogPrintf("PORTION_BOTTOM_8K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_BOTTOM_16K: { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x6C; // b 01101100 //CPUartLogPrintf("PORTION_BOTTOM_16K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #endif case PORTION_BOTTOM_32K: { if(is2MFlashFlag) { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x70; // b 01110X00 } else { status2 = status2 & 0xBF; // set cmp to 0; status1 = ALL_BP_BITS_CLEAR(status1)| 0x70; // b 01110000 //XMC 4MB/2MB only support 0x70 but XMC 8M/16M support both 0x78 and 0x70 } //CPUartLogPrintf("PORTION_BOTTOM_32K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_63_64: { if(is2MFlashFlag) { CPUartLogPrintf("%s:2M flash not support PORTION_LOWER_63_64", __func__); return -1; } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x04; // b 00000100 } //CPUartLogPrintf("PORTION_LOWER_63_64,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_31_32: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x04; // b 00000100 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x08; // b 00001000 } //CPUartLogPrintf("PORTION_LOWER_31_32,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_15_16: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x08; // b 00001000 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x0C; // b 00001100 } //CPUartLogPrintf("PORTION_LOWER_15_16,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_7_8: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x0C; // b 00001100 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x10; // b 00010000 } //CPUartLogPrintf("PORTION_LOWER_7_8,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_LOWER_3_4: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x10; // b 00010000 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x14; // b 00010100 } //CPUartLogPrintf("PORTION_LOWER_3_4,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #ifndef FBP_THIN case PORTION_UPPER_63_64: { if(is2MFlashFlag) { CPUartLogPrintf("%s:2M flash not support PORTION_UPPER_63_64", __func__); return -1; } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x24; // b 00100100 } //CPUartLogPrintf("PORTION_UPPER_63_64,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_31_32: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x24; // b 00100100 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x28; // b 00101000 } //CPUartLogPrintf("PORTION_UPPER_31_32,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_15_16: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x28; // b 00101000 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x2C; // b 00101100 } //CPUartLogPrintf("PORTION_UPPER_15_16,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_7_8: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x2C; // b 00101100 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x30; // b 00110000 } //CPUartLogPrintf("PORTION_UPPER_7_8,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UPPER_3_4: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x30; // b 00110000 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x34; // b 00110100 } //CPUartLogPrintf("PORTION_UPPER_3_4,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #endif case PORTION_UNPROTECT_TOP_4K: { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x44; // b 01000100 //CPUartLogPrintf("PORTION_UNPROTECT_TOP_4K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UNPROTECT_TOP_8K: { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x48; // b 01001000 //CPUartLogPrintf("PORTION_UNPROTECT_TOP_8K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UNPROTECT_TOP_16K: { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x4C; // b 01001100 //CPUartLogPrintf("PORTION_UNPROTECT_TOP_16K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UNPROTECT_TOP_32K: { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x50; // b 01010000 //CPUartLogPrintf("PORTION_UNPROTECT_TOP_32K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #ifndef FBP_THIN case PORTION_UNPROTECT_BOTTOM_4K: { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x64; // b 01100100 //CPUartLogPrintf("PORTION_UNPROTECT_BOTTOM_4K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UNPROTECT_BOTTOM_8K: { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x68; // b 01101000 //CPUartLogPrintf("PORTION_UNPROTECT_BOTTOM_8K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UNPROTECT_BOTTOM_16K: { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x6C; // b 01101100 //CPUartLogPrintf("PORTION_UNPROTECT_BOTTOM_16K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } case PORTION_UNPROTECT_BOTTOM_32K: { if(is2MFlashFlag) { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x70; // b 01110x00 } else { status2 = status2 | (1<<6); // set cmp to 1; status1 = ALL_BP_BITS_CLEAR(status1)| 0x78; // b 01111000 } //CPUartLogPrintf("PORTION_UNPROTECT_BOTTOM_32K,status1[0x%x],status2[0x%lx]", __func__, status1, status2); break; } #endif default: { CPUartLogPrintf("%s:unkown type,not support.", __func__); return -1; } } RTI_LOG("%s:new status1[0x%x],status2[0x%x].", __func__, status1, status2); data[0] = status1; data[1] = status2; if((ALL_BP_BITS_GET(n_status1) == ALL_BP_BITS_GET(status1)) && (n_status2 == status2)) { CPUartLogPrintf("%s: fbp no change.\r\n", __func__); return 0; } //spi_nor_write_enable(chip); //no need if (chip->options & SPINOR_HAVE_WRITE_STATUS2) { //CPUartLogPrintf("%s:SPINOR_HAVE_WRITE_STATUS2,data_0[0x%x],data_1[0x%x]", __func__, data[0], data[1]); spi_nor_write_volatile_status_register_enable(chip); ret = spi_nor_write_status2(chip, &data[1]); if(ret != 0) { CPUartLogPrintf("error %d spi_nor_write_status2\n", ret); } //CPUartLogPrintf("%s:SPINOR_WRITE_STATUS1_1BYTE", __func__); spi_nor_write_volatile_status_register_enable(chip); ret = spi_nor_write_status1(chip, data, 1); if(ret != 0) { CPUartLogPrintf("error %d spi_nor_write_status1 1byte\n", ret); } } else if (chip->options & SPINOR_WRITE_STATUS1_1BYTE) { //CPUartLogPrintf("%s:SPINOR_WRITE_STATUS1_1BYTE", __func__); spi_nor_write_volatile_status_register_enable(chip); ret = spi_nor_write_status1(chip, data, 1); if(ret != 0) { CPUartLogPrintf("error %d spi_nor_write_status1 1byte\n", ret); } } else { spi_nor_write_volatile_status_register_enable(chip); ret = spi_nor_write_status1(chip, data, 2); if(ret != 0) { CPUartLogPrintf("error %d spi_nor_write_status1 2byte\n", ret); } } #ifdef SW_HANDLE_XIP ret = spi_nor_wait(chip, &status, 0, NULL); #else ret = spi_nor_wait(chip, &status); #endif if (ret < 0) { CPUartLogPrintf("error %d write status register\n", ret); return ret; } spi_nor_read_status1(chip, &n_status1); if((chip->options & SPINOR_WRITE_STATUS1_1BYTE) && !(chip->options & SPINOR_HAVE_WRITE_STATUS2)) ////no read SR2 if no SR2 n_status2 = 0; else spi_nor_read_status2(chip, &n_status2); RTI_LOG("%s:read back,n_status1[0x%x],n_status2[0x%x].", __func__, n_status1, n_status2); if((ALL_BP_BITS_GET(n_status1) == ALL_BP_BITS_GET(status1)) && (n_status2 == status2)) { flash_protect_area_type = protect_type; CPUartLogPrintf("%s:fbp valid.", __func__); } return ret; } //flash hardware protect--chenjian void crane_set_fbp(void) { UINT32 reserved_start_addr = get_reserved_start_address() - 0x80000000; UINT32 reserved_end_addr = get_reserved_end_address() - 0x80000000; int protect_type = -1; struct spi_flash_chip *chip = get_spi_flash_chip(1); if(chip==NULL){ CPUartLogPrintf("%s chip is null", __func__); return; } extern UINT32 get_gpspvt_begin_addr(void); if(get_gpspvt_begin_addr() && (get_gpspvt_begin_addr() < get_reserved_start_address())) //there is gnss pvt in system { reserved_start_addr = get_gpspvt_begin_addr() - 0x80000000; reserved_end_addr = reserved_start_addr; } if(IsMiniSystem()){ reserved_start_addr = get_bootloader_end_address() - 0x80000000; reserved_end_addr = reserved_start_addr; } CPUartLogPrintf("%s:reserved_start_addr[0x%lx],reserved_end_addr[0x%lx]", __func__, reserved_start_addr, reserved_end_addr); protect_type = qspi_nor_find_fbp(reserved_start_addr, reserved_end_addr, chip); if(protect_type < 0) { CPUartLogPrintf("%s: cannt find match fbp type", __func__); return; } qspi_nor_set_fbp((ProtectedAreaSizeType)protect_type, chip); return; } #endif