MQX TWRMCF54418 Boot Loader Bug

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

MQX TWRMCF54418 Boot Loader Bug

跳至解决方案
1,116 次查看
dwarkentin
Contributor II

The NAND FLASH boot loader code in the TWRMCF54418 bsp has a bug that prevents bit errors from being corrected when firmware images are transferred from FLASH to RAM.

 

In the file mqx/source/bsp/twrmcf54418/bootstrap.c the page transfers are configured for 2kb plus the full spare data length (2kb + 64 bytes) but this overloads the ECC engine and causes it to always report 32-bit errors and prevents it from correcting actual bit errors. The correct transfer length is 2kb + 60 bytes which includes the exact number of ECC bytes and no extra bytes.

 

nfc_ptr->SECSZ = BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE;

 

needs to be changed to

 

nfc_ptr->SECSZ = BSP_PHYSICAL_PAGE_SIZE + 60;

 

I've checked MQX 4.0 to 4.2 and all versions were affected.

标签 (1)
0 项奖励
回复
1 解答
1,033 次查看
dwarkentin
Contributor II

I was mistaken about the exact cause of the ECC engine failure. The actual cause was the even number being written to the SECSZ register. The MCF54418 TWR board uses 16-bit NAND FLASH memory and the NFC in the MCF54418 requires an odd number in the SECZ register for 16-bit devices. See section 22.3.13 in the MCF54418 Reference Manual.

The corrected line of code is:

nfc_ptr->SECSZ = NANDFLASH_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE + 1;

and here is the entire bootstrap_sram_read_data function including the ECC engine result.

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name : bootstrap_sram_read_data
* Returned Value : void
* Comments : Read data from the NAND Flash memory. Block# and page#
* must be specified.
* This code must be linked to Internal SRAM memory.
*
*END*----------------------------------------------------------------------*/
__declspec(bootstrap_sram_code)
static void bootstrap_sram_read_data(uint32_t block,uint32_t page)
{
 NFC_MemMapPtr nfc_ptr;
 uint32_t i;

/* Get the pointer to nfc registers structure */
 nfc_ptr = (&((VMCF5441_STRUCT_PTR)_PSP_GET_IPSBAR())->NFC);

/* Clearing interrupts bits */
 nfc_ptr->ISR |= (NFC_ISR_DONECLR_MASK |
 NFC_ISR_DONEEN_MASK |
 NFC_ISR_IDLECLR_MASK |
 NFC_ISR_IDLEEN_MASK);

/* Clearing buf in use */
 //for(i=0;i<NANDFLASH_PHYSICAL_PAGE_SIZE;i++)
 // NFC_SRAM_B0_REG(nfc_ptr, i) = 0;


 /* setting ROW and COLUMN address */
 page &= 0x3F;
 block &= 0x7FF;
 nfc_ptr->RAR = 0x11000000 + page + (block<<6);
 nfc_ptr->CAR = 0x00000000;

nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_READ_CYCLE2);
 nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_READ_CYCLE1) |
 NFC_CMD2_CODE(0x7EE0) |
 NFC_CMD2_BUFNO(0);

/* configuring Sector size */
 nfc_ptr->SECSZ = NANDFLASH_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE + 1;

/* 32bit ECC, 16bit data bus, 1 page cnt */
 nfc_ptr->CFG = ( NFC_CFG_ECCAD((BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE)>>3) |
 NFC_CFG_ECCSRAM_MASK |
 NFC_CFG_ECCMODE(7) |
 NFC_CFG_IDCNT(5) |
 NFC_CFG_TIMEOUT(6) |
 NFC_CFG_BITWIDTH_MASK |
 NFC_CFG_PAGECNT(1));

/* Sending START */
 nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

/* Polling for cmd done IRQ*/
 while(!(nfc_ptr->ISR & NFC_ISR_IDLE_MASK))
 {
 }

 _bit_error_count = NFC_SRAM_B0_REG( nfc_ptr, BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE + 7);

}

_bit_error_count is a global variable instead of a return value which was necessary to reduce code size due to the very limited amount of boot code memory.

在原帖中查看解决方案

0 项奖励
回复
2 回复数
1,034 次查看
dwarkentin
Contributor II

I was mistaken about the exact cause of the ECC engine failure. The actual cause was the even number being written to the SECSZ register. The MCF54418 TWR board uses 16-bit NAND FLASH memory and the NFC in the MCF54418 requires an odd number in the SECZ register for 16-bit devices. See section 22.3.13 in the MCF54418 Reference Manual.

The corrected line of code is:

nfc_ptr->SECSZ = NANDFLASH_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE + 1;

and here is the entire bootstrap_sram_read_data function including the ECC engine result.

/*FUNCTION*-------------------------------------------------------------------
*
* Function Name : bootstrap_sram_read_data
* Returned Value : void
* Comments : Read data from the NAND Flash memory. Block# and page#
* must be specified.
* This code must be linked to Internal SRAM memory.
*
*END*----------------------------------------------------------------------*/
__declspec(bootstrap_sram_code)
static void bootstrap_sram_read_data(uint32_t block,uint32_t page)
{
 NFC_MemMapPtr nfc_ptr;
 uint32_t i;

/* Get the pointer to nfc registers structure */
 nfc_ptr = (&((VMCF5441_STRUCT_PTR)_PSP_GET_IPSBAR())->NFC);

/* Clearing interrupts bits */
 nfc_ptr->ISR |= (NFC_ISR_DONECLR_MASK |
 NFC_ISR_DONEEN_MASK |
 NFC_ISR_IDLECLR_MASK |
 NFC_ISR_IDLEEN_MASK);

/* Clearing buf in use */
 //for(i=0;i<NANDFLASH_PHYSICAL_PAGE_SIZE;i++)
 // NFC_SRAM_B0_REG(nfc_ptr, i) = 0;


 /* setting ROW and COLUMN address */
 page &= 0x3F;
 block &= 0x7FF;
 nfc_ptr->RAR = 0x11000000 + page + (block<<6);
 nfc_ptr->CAR = 0x00000000;

nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_READ_CYCLE2);
 nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_READ_CYCLE1) |
 NFC_CMD2_CODE(0x7EE0) |
 NFC_CMD2_BUFNO(0);

/* configuring Sector size */
 nfc_ptr->SECSZ = NANDFLASH_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE + 1;

/* 32bit ECC, 16bit data bus, 1 page cnt */
 nfc_ptr->CFG = ( NFC_CFG_ECCAD((BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE)>>3) |
 NFC_CFG_ECCSRAM_MASK |
 NFC_CFG_ECCMODE(7) |
 NFC_CFG_IDCNT(5) |
 NFC_CFG_TIMEOUT(6) |
 NFC_CFG_BITWIDTH_MASK |
 NFC_CFG_PAGECNT(1));

/* Sending START */
 nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

/* Polling for cmd done IRQ*/
 while(!(nfc_ptr->ISR & NFC_ISR_IDLE_MASK))
 {
 }

 _bit_error_count = NFC_SRAM_B0_REG( nfc_ptr, BSP_PHYSICAL_PAGE_SIZE + NANDFLASH_SPARE_AREA_SIZE + 7);

}

_bit_error_count is a global variable instead of a return value which was necessary to reduce code size due to the very limited amount of boot code memory.

0 项奖励
回复
1,033 次查看
miduo
NXP Employee
NXP Employee

Hi,

Yes, we had awared this already. We have examined and compared the sources of the BSP driver and the NFC driver included in the FFS/MFS-driver. There are several differences between the two, most of it due to the FFS/MFS-driver also reading some meta-data with every read. The two drivers appear to use different definitions of the ECC status word. It therefore seem to us that we are missing some information.

0 项奖励
回复