📄 jnand.c.bak
字号:
This function will write the current page out and update any housekeeping
variables as necessary.
The parameter "addr" is used in a strange way. It is only passed on to
prepare_next_block so that if prepare_next_block has to skip a bad block,
it can initialize the next span after closing out the current span.
DEPENDENCIES
None
RETURN VALUE
If success, return TRUE else FALSE
SIDE EFFECTS
===========================================================================*/
int
write_current_page (unsigned char *src, dword addr, int update_crc)
{
int i;
unsigned char *vsrc1, *vsrc2;
unsigned char *origsrc = src;
/* If the previous write used the last page in NAND, we should fail here.
* However, this will probably be caught earlier, as once we write
* the last page, we will then try to erase the next block of pages
* and that should fail before we ever get here. Just being extra safe. */
if (current_page > max_pages)
{
DPRINTF (("Error: Write beyond end of NAND flash\n"));
SET_ERR (ERR_PAST_NAND_END);
return FALSE;
}
/* If we have no pages available, erase the next block of pages,
* skipping any bad blocks and failing if we have an erase failure
* on a supposedly good block, or if we run out of blocks. */
if (avail_pages_in_block == 0)
{
/* if we are programming the boot block and run out of pages in the
* first block, we are well and truly hosed. */
if (boot_block_mode == TRUE)
{
TPRINTF (3, ("wcp: ran out of boot pages\n"));
return FLASH_FAIL;
}
if (prepare_next_block (addr) == FALSE)
{
return FLASH_FAIL;
}
}
TPRINTF (3, ("wcp: writing page 0x%x\n", current_page));
if (nand_device->write_page (nand_device, current_page, src)
!= FS_DEVICE_DONE )
{
DPRINTF (("Error: device failed during write\n"));
SET_ERR (ERR_WRITE_FAIL);
return FALSE;
}
/* zero out readback buffer */
vsrc1 = readback_buffer;
for (i=0; i<page_size; i++)
{
*vsrc1++ = 0;
}
/* read back data and verify it against source */
if (nand_device->read_page (nand_device, current_page, readback_buffer)
!= FS_DEVICE_DONE )
{
DPRINTF (("Error: read fail\n"));
SET_ERR (ERR_READ_FAIL);
return FALSE;
}
vsrc1 = origsrc;
vsrc2 = readback_buffer;
for (i=0; i<page_size; i++)
{
if (*vsrc1++ != *vsrc2++)
{
DPRINTF (("Verify failed at index %d\n", i));
DPRINTF (("src at 0x%08X readback at 0x%08X\n",
(unsigned int)src, (unsigned int)readback_buffer));
DPRINTF (("Error: verify failure\n"));
SET_ERR (ERR_VERIFY_FAIL);
return FALSE;
}
}
if (update_crc == UPDATE_CRC)
{
/* The variable crc was already init'ed to CRC_30_STEP_SEED
* so calling the step wise function can replace an
* initial test for the first invocation. The CRC is calculated
* over the number of bits, so must multiply by 8 */
crc = crc_30_step (crc, src, (page_size * 8));
image_size += page_size;
TPRINTF (3, ("interim CRC 0x%08X page = 0x%08x\n",
crc, current_page));
}
/* Every page we write while in boot block mode is actually a
* code page we need to read back and verify */
if (boot_block_mode == TRUE)
{
boot_block_pages++;
}
current_page++;
avail_pages_in_block--;
return TRUE;
}
/*===========================================================================
FUNCTION flash_report
DESCRIPTION
This function stores the calculated programming statistics in the parameter
block using a slightly different struct as an overlay. These statistics
will be read by the CMM program running on T32.
RETURN VALUE
FLASH_SUCCESS
===========================================================================*/
uint32
flash_report (void)
{
report_ptr = (struct type_jtag_report *)&jtag_flash_param;
DPRINTF (("\n----- REPORT ------\n"));
// TPRINTF (0, ("flash_report: boot_block_pages = %d\n", boot_block_pages));
report_ptr->input_gap_size = input_gap_size;
report_ptr->bad_block_gap_size = bad_block_gap_size;
report_ptr->image_size = image_size;
return FLASH_SUCCESS;
}
/*===========================================================================
FUNCTION verify_boot_info
DESCRIPTION
This function will read in the boot info block, make sure it is indeed a
valid boot info block by checking two magic numbers, then use that to read
in all the code and compute a running checksum
After all code has been read and checksummed, this function will
determine if the checksum matches the checksum stored in the boot info
block.
DEPENDENCIES
RETURN VALUE
If success, return FLASH_SUCCESS else FLASH_FAIL
SIDE EFFECTS
===========================================================================*/
int
verify_boot_info (void)
{
struct boot_info_block *bib;
int page;
uint32 image_len;
uint32 bib_crc;
int i;
DPRINTF (("\n----- VERIFY ------\n"));
KICK_WATCHDOG();
/* Find first non-bad block past boot block which is the BIB */
current_block = FIRST_POSSIBLE_BLOCK;
while (nand_device->bad_block_check(nand_device, current_block) ==
FS_DEVICE_BAD_BLOCK)
{
TPRINTF (1, ("verify_boot_info: skipping block %d \n", current_block));
current_block++;
}
/* Make sure we did not go past the end of the flash */
if (current_block >= block_count)
{
DPRINTF (("Error: Attempted to read beyond end of device\n"));
SET_ERR (ERR_PAST_NAND_END);
return FLASH_FAIL;
}
/* point to first page in found block where boot info block is */
page = current_block * pages_in_block;
/* read back boot info block and some number of spans */
if ((nand_device->read_page( nand_device, page, span_rb_buf ))
!= FS_DEVICE_DONE )
{
TPRINTF (0, ("verify_boot_info: read fail\n"));
SET_ERR (ERR_READ_FAIL);
return FLASH_FAIL;
}
KICK_WATCHDOG();
bib = (struct boot_info_block *)span_rb_buf;
if (bib->magic1 != MAGIC1)
{
TPRINTF (0, ("verify_boot_info: MAGIC1 bad\n"));
SET_ERR (ERR_MAGIC1_FAIL);
return FLASH_FAIL;
}
if (bib->magic2 != MAGIC2)
{
TPRINTF (0, ("verify_boot_info: MAGIC2 bad\n"));
SET_ERR (ERR_MAGIC2_FAIL);
return FLASH_FAIL;
}
if (bib->version != BIB_VERSION)
{
TPRINTF (0, ("verify_boot_info: BIB_VERSION bad\n"));
SET_ERR (ERR_BIBVER_FAIL);
return FLASH_FAIL;
}
/* save away bib info before using buffer again */
bib_crc = bib->crc;
image_len = bib->length;
TPRINTF (2, ("verify_boot_info: image length is 0x%x\n", image_len));
/* Must initialize the CRC variable as it contains the CRC
* from when we were writing the image. */
crc = CRC_30_STEP_SEED;
/* Find first non-bad block past BIB which is the image data.
* In this case, current_block is pointing to BIB, so just increment. */
current_block++;
while (nand_device->bad_block_check(nand_device, current_block) ==
FS_DEVICE_BAD_BLOCK)
{
TPRINTF (2, ("verify_boot_info: skipping block 0x%x \n", current_block));
current_block++;
}
/* Make sure we did not go past the end of the flash */
if (current_block >= block_count)
{
DPRINTF (("Error: Attempted to read beyond end of device\n"));
SET_ERR (ERR_PAST_NAND_END);
return FLASH_FAIL;
}
TPRINTF (3, ("vbi: orig image_len 0x%x\n", image_len));
/* Read and CRC pages skipping bad blocks. When we enter this loop,
* we already are pointing to the first block of the image data. */
while (image_len > 0)
{
TPRINTF (3, ("vbi: reading block 0x%x\n", current_block));
/* Point to first page in current block. */
page = current_block * pages_in_block;
for (i=0; i<pages_in_block; i++)
{
/* Read back next page in image data */
if ((nand_device->read_page( nand_device, page, image_rb_buf ))
!= FS_DEVICE_DONE )
{
TPRINTF (0, ("verify_boot_info: read fail\n"));
SET_ERR (ERR_READ_FAIL);
return FLASH_FAIL;
}
TPRINTF (3, ("vbi: reading page 0x%x\n", page));
/* calculate CRC - always done on whole pages including fill chars */
crc = crc_30_step (crc, image_rb_buf, (page_size * 8));
TPRINTF (3, ("vbi: CRC = 0x%08X at page 0x%x\n", crc, page));
KICK_WATCHDOG();
/* Update length remaining to read and bail out if done */
image_len -= page_size;
TPRINTF (3, ("vbi: image_len after decr 0x%x\n", image_len));
if (!(image_len > 0))
{
TPRINTF (5, ("vbi: breaking out of for\n"));
break;
}
page++;
}
current_block++;
/* Have read all pages in block, advance to next non-bad block */
while (nand_device->bad_block_check(nand_device, current_block) ==
FS_DEVICE_BAD_BLOCK)
{
TPRINTF (1, ("verify_boot_info: skipping block %d \n", current_block));
current_block++;
}
}// while
if (bib_crc != crc)
{
TPRINTF (0, ("Calculated CRC 0x%08X != stored CRC 0x%08X\n",
crc, bib_crc));
SET_ERR (ERR_READ_FAIL);
return FLASH_FAIL;
}
return FLASH_SUCCESS;
}
/*===========================================================================
FUNCTION verify_boot_block
DESCRIPTION
This function will read in the boot block and checksum it.
DEPENDENCIES
RETURN VALUE
If success, return FLASH_SUCCESS else FLASH_FAIL
SIDE EFFECTS
===========================================================================*/
int
verify_boot_block (unsigned int boot_crc, int boot_pages)
{
int i;
KICK_WATCHDOG();
TPRINTF (0, ("verify_boot_block: boot_pages = %d\n", boot_pages));
/* Must initialize the CRC variable as it contains the CRC
* from when we were writing the image. */
crc = CRC_30_STEP_SEED;
for (i=0; i<boot_pages; i++)
{
/* read back boot info block and some number of spans */
if ((nand_device->read_page( nand_device, i, image_rb_buf ))
!= FS_DEVICE_DONE )
{
TPRINTF (0, ("verify_boot_block: read fail\n"));
SET_ERR (ERR_READ_FAIL);
return FLASH_FAIL;
}
/* calculate CRC - always done on whole pages including fill chars */
crc = crc_30_step (crc, image_rb_buf, (page_size * 8));
TPRINTF (3, ("verify_boot_block: CRC = 0x%08X at page 0x%x\n",
crc, i));
KICK_WATCHDOG();
}
if (boot_crc != crc)
{
TPRINTF (0, ("Calculated CRC 0x%08X != stored CRC 0x%08X\n",
crc, boot_crc));
SET_ERR (ERR_READ_FAIL);
return FLASH_FAIL;
}
DPRINTF(("verify_boot_block returning FLASH_SUCCESS"));
return FLASH_SUCCESS;
} // verify_boot_block
/*===========================================================================
FUNCTION flash_erase_chip
DESCRIPTION
This function will erase every blcok in the flash
DEPENDENCIES
RETURN VALUE
If success, return FLASH_SUCCESS else FLASH_FAIL
SIDE EFFECTS
===========================================================================*/
int
flash_erase_chip (void)
{
int blockno;
KICK_WATCHDOG();
DPRINTF (("\n\n------ Erase Chip ----------------------\n"));
DPRINTF (("Probing flash device: "));
nand_device=fs_nand_device_probe();
if (nand_device == (struct fs_device_data *)FS_NO_DEVICE)
{
DPRINTF (("Error: no nand_device found \n"));
SET_ERR (ERR_DEV_MISSING);
return FLASH_FAIL;
}
/* get some information about the device */
block_count = nand_device->block_count(nand_device);
pages_in_block = nand_device->block_size(nand_device);
page_size = nand_device->page_size(nand_device);
flash_name = nand_device->device_name(nand_device);
DPRINTF (("Found %s\n", flash_name));
DPRINTF (("Block count is %d \n", block_count));
DPRINTF (("Pages/Block is %d \n", pages_in_block));
DPRINTF (("Page size is %d \n", page_size));
DPRINTF (("Pages Avail is %d \n", max_pages));
for (blockno=0; blockno<block_count; blockno++)
{
KICK_WATCHDOG();
if (nand_device->bad_block_check(nand_device, blockno) ==
FS_DEVICE_BAD_BLOCK)
{
TPRINTF (3, ("\n--- Skipping: bad block %d\n", blockno));
continue;
}
else
{
TPRINTF (3, ("\nErasing good block %d\n", blockno));
}
/* erase the block */
if (nand_device->erase_block(nand_device, blockno) != FS_DEVICE_DONE)
{
DPRINTF (("--- Error: device failed during erase of block %d\n",
blockno));
return FLASH_FAIL;
}
}
return FLASH_SUCCESS;
} // flash_erase_chip
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -