⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jnand.c

📁 QUALCOMM JNAND DRIVER
💻 C
📖 第 1 页 / 共 4 页
字号:
     * 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



/*===========================================================================

FUNCTION flash_dump

DESCRIPTION
  This function will dump blcok in the flash

DEPENDENCIES
  

RETURN VALUE
  If success, return FLASH_SUCCESS else FLASH_FAIL

SIDE EFFECTS

===========================================================================*/
int
flash_dump (void)
{
	int blockno, i;

	KICK_WATCHDOG();
	DPRINTF (("\n\n------ Dump block ----------------------\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(i=0; i<jtag_flash_param.size; i+=page_size)
	{
		if ((nand_device->read_page( nand_device, (jtag_flash_param.flashaddr+i)/page_size, (unsigned char *)(jtag_flash_param.addr + i))) != FS_DEVICE_DONE )
		{
			TPRINTF (0, ("verify_boot_block: read fail\n"));
			SET_ERR (ERR_READ_FAIL);
			return FLASH_FAIL;
		}
	}

	return FLASH_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -