MQX TWRMCF54418 Boot Loader Bug

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MQX TWRMCF54418 Boot Loader Bug

Jump to solution
1,113 Views
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.

Labels (1)
0 Kudos
Reply
1 Solution
1,030 Views
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.

View solution in original post

0 Kudos
Reply
2 Replies
1,031 Views
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 Kudos
Reply
1,030 Views
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 Kudos
Reply