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

📄 jnand.c.bak

📁 QUALCOMM JNAND DRIVER
💻 BAK
📖 第 1 页 / 共 4 页
字号:
    
    input_gap_size += gap_size;
  } /* there is a gap in code addresses */
  
  KICK_WATCHDOG();

  /* Now write the data */

  while (size > 0)
  {
    partial_bytes_avail = page_size - partial_page_index;

    if (partial_bytes_avail > size)
    {
      /* fill partial page partially and we are done, do not write page,
       * no need to update data ptr as we are out of data */
      memcpy(&partial_page_buffer[partial_page_index], data, size);
      partial_page_index += size;
      break;
    }
    else if ((partial_bytes_avail == size) && (partial_page_index != 0))
    {
      /* fill partial page completely, ready for writing, none left over */
      memcpy(&partial_page_buffer[partial_page_index], data, size);
      wbuf = partial_page_buffer;
      data += partial_bytes_avail;
      size -= partial_bytes_avail;
      partial_page_index = 0;
    }
    else if ((partial_bytes_avail < size) && (partial_page_index != 0))
    {
      /* fill partial page completely, ready for writing, some left over */
      memcpy(&partial_page_buffer[partial_page_index], data, partial_bytes_avail);
      wbuf = partial_page_buffer;
      data += partial_bytes_avail;
      size -= partial_bytes_avail;
      partial_page_index = 0;
    }
    else /* partial_page_index == 0 && size >= page_size */
    {
      /* write a full page from where it is */
      wbuf = data;
      data += page_size;
      size -= page_size;
    }
    
    KICK_WATCHDOG();

    /* Write a full page.  If we do not break out of the while early,
     * and we reach here, there is a full page to be written. */
    if (write_current_page (wbuf, addr, UPDATE_CRC) == FALSE)
    {
      return FLASH_FAIL;
    }
    KICK_WATCHDOG();

    /* We only get here when we have a full page to write, so the
     * increment of the address in the code image is always by a page. */
    addr += page_size;
  }

  /* Save the RAM address of the last byte of the image written, so
   * that when we get called next, we can see if there are any gaps */
  last_code_addr = new_last_code_addr;
  
  if (partial_page_index > page_size)
  {
    return FLASH_FAIL;
  }
  
  return FLASH_SUCCESS;

} // flash_program_boot




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

FUNCTION flash_finalize

DESCRIPTION
  This function will write any remaining data that is still buffered.
  It will then write the BIB including checksum.


DEPENDENCIES
  Assumes jtag_flash_param (global variable) has valid parameters.

RETURN VALUE
  If success, return FLASH_SUCCESS else FLASH_FAIL

SIDE EFFECTS

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

uint32 flash_finalize()
{
  unsigned int num_fill_bytes;
  unsigned char *dst;
  int spans_remaining;
  int total_len;
  int bib_size;



  KICK_WATCHDOG();
  
  DPRINTF (("\n----- FINALIZE ------\n"));
  
  /* Maybe fill last page of code with fill character and write the
   * page.  Don't include these fill bytes in total fill bytes used
   * as that is keeping track only of wasted bytes internal
   * to the image.  */
  if (partial_page_index > 0)
  {
    num_fill_bytes = page_size - partial_page_index;
    while (num_fill_bytes > 0)
    {
      partial_page_buffer[partial_page_index++] = 
      (unsigned char)NAND_FILL_CHAR;
      num_fill_bytes--;
    }
    if ((write_partial_page ((dword)0, UPDATE_CRC) == FALSE))
    {
      return FLASH_FAIL;
    }
  }
  
  KICK_WATCHDOG();

  /* Erase and do housekeeping for writing BIB block */
  if (prepare_bib_block() == FALSE)
  {
    return FLASH_FAIL;
  }
  KICK_WATCHDOG();

  DPRINTF (("finalize:Putting crc 0x%08X into BIB\n", (unsigned int)crc));

  /* Fill and write the BIB.  */
  bib1.crc = crc;
  bib1.length = image_size;
  bib_size = sizeof(struct boot_info_block);
  dst = partial_page_buffer;
  memcpy (dst, &bib1, bib_size);

  KICK_WATCHDOG();

  /* Fill the first page with the Boot Information Block and fill remainder
  * of page with fill char */
  total_len = bib_size;
  dst += bib_size;
  num_fill_bytes = page_size - total_len;
  while (num_fill_bytes > 0)
  {
    *dst++ = (unsigned char)NAND_FILL_CHAR;
    num_fill_bytes--;
  }

  KICK_WATCHDOG();

  if (write_current_page ((unsigned char *)partial_page_buffer, 
                          (dword)0, NO_UPDATE_CRC) == FALSE)
  {
    return FLASH_FAIL;
  }
  spans_remaining = 0;


#ifdef DEBUG_LOGIC
#error code not present
#endif

  return FLASH_SUCCESS;

} // flash_finalize




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

FUNCTION flash_finalize_boot

DESCRIPTION
  This function will write any remaining data that is still buffered and
  enough extra pages to exactly fill the 8K boot block.  If all 8K of the
  boot block is not written, we will get an ECC error on read.


DEPENDENCIES
  Assumes jtag_flash_param (global variable) has valid parameters.

RETURN VALUE
  If success, return FLASH_SUCCESS else FLASH_FAIL

SIDE EFFECTS

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

uint32 
flash_finalize_boot()
{
  unsigned int num_fill_bytes;
  int i, j;

  KICK_WATCHDOG();
  
  DPRINTF (("\n----- BOOT FINALIZE ------\n"));
  /*  DPRINTF (("1:Putting crc 0x%08X into BIB\n", (unsigned int)crc)); */

  if (partial_page_index > page_size)
  {
    return FLASH_FAIL;
  }
  
  /* Maybe fill last page of code with fill character and write the
   * page.  Don't include these fill bytes in total fill bytes used
   * as that is keeping track only of wasted bytes internal
   * to the image.  */
  if (partial_page_index > 0)
  {
    num_fill_bytes = page_size - partial_page_index;
    while (num_fill_bytes > 0)
    {
      partial_page_buffer[partial_page_index++] = 
      (unsigned char)NAND_FILL_CHAR;
      num_fill_bytes--;
    }
    KICK_WATCHDOG();
    if ((write_partial_page ((dword)0, UPDATE_CRC) == FALSE))
    {
      return FLASH_FAIL;
    }
  }
  
  /* Fill rest of 8k of pages (16 pages) with 0x00 and write */
  for (i=boot_block_pages; i<16; i++)
  {
    for (j=0; j<page_size; j++)
    {
      partial_page_buffer[j] = (unsigned char)0;
    }
    KICK_WATCHDOG();
    if ((write_partial_page ((dword)0, UPDATE_CRC) == FALSE))
    {
      return FLASH_FAIL;
    }
  }
  
    KICK_WATCHDOG();

  return FLASH_SUCCESS;

} // flash_finalize_boot



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

FUNCTION prepare_next_block

DESCRIPTION
  This function will erase the next available non-bad block in the flash 
  and update all global variables to point to it and its pages as the 
  next available for use.  It will also close the current span and open the
  next available span if any bad block was encountered.

DEPENDENCIES
  None

RETURN VALUE
  If success, return TRUE else FALSE

SIDE EFFECTS

===========================================================================*/
int
prepare_next_block (dword addr)
{
  int result;

  /* Advance to next non-bad block */
  while (nand_device->bad_block_check(nand_device, ++current_block) == 
         FS_DEVICE_BAD_BLOCK)
  {
    TPRINTF (2, ("pnb: skipping block %d   \n", (current_block - 1)));
    bad_block_gap_size += eu_size;
  }

  /* Make sure we did not go past the end of the flash */
  if (current_block >= block_count)
  {
    DPRINTF (("Error: Attempted to program beyond end of device\n"));
    SET_ERR (ERR_PAST_NAND_END);
    return FALSE;
  }

  TPRINTF (3, ("pnb:  erasing block 0x%x\n", current_block));

  /* erase the block */
  result=nand_device->erase_block( nand_device, current_block );
  if ( result != FS_DEVICE_DONE )
  {
    DPRINTF (("Error: device failed during erase\n"));
    SET_ERR (ERR_ERASE_FAIL);
    return FALSE;
  }

  /* do housekeeping to set up to use block just erased */
  current_page = current_block * pages_in_block;
  avail_pages_in_block = pages_in_block; 

  TPRINTF (3, ("pnb:  new block at  0x%x\n", current_block));

  return TRUE;
}


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

FUNCTION prepare_first_block

DESCRIPTION
  This function will erase the first available non-bad block in the flash 
  past the Boot Information Block and update all global variables to point 
  to it and its pages as the next available for use.  
  It is called once at init time with current block pointing one block
  past the BIB block.  

DEPENDENCIES
  None

RETURN VALUE
  If success, return TRUE else FALSE

SIDE EFFECTS

===========================================================================*/
int
prepare_first_block (void)
{
  int result;

  /* Advance to next non-bad block */
  while (nand_device->bad_block_check(nand_device, current_block) == 
         FS_DEVICE_BAD_BLOCK)
  {
    TPRINTF (1, ("pfb: skipping block %d   \n", current_block));
    bad_block_gap_size += eu_size;
    current_block++;
  }

  /* Make sure we did not go past the end of the flash */
  if (current_block >= block_count)
  {
    DPRINTF (("Error: Attempted to program beyond end of device\n"));
    SET_ERR (ERR_PAST_NAND_END);
    return FALSE;
  }

  /* erase the block */
  result=nand_device->erase_block( nand_device, current_block );
  if ( result != FS_DEVICE_DONE )
  {
    DPRINTF (("Error: device failed during erase\n"));
    SET_ERR (ERR_ERASE_FAIL);
    return FALSE;
  }

  /* do housekeeping to set up to use block just erased */
  current_page = current_block * pages_in_block;
  avail_pages_in_block = pages_in_block; 

  return TRUE;
}



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

FUNCTION prepare_bib_block

DESCRIPTION
  This function will erase the block that will contain the BIB
  and update all global variables to point to it and its pages as the 
  next available for use.  

DEPENDENCIES
  None

RETURN VALUE
  If success, return TRUE else FALSE

SIDE EFFECTS

===========================================================================*/
int
prepare_bib_block (void)
{
  int result;

  /* Check and erase block that contains BIB */
  current_block = bib_block;
  result = nand_device->bad_block_check(nand_device, current_block);
  if (result != FS_DEVICE_OK)
  {
    DPRINTF (("Error: BIB block is bad\n"));
    SET_ERR (ERR_BIB_BAD);
    return FALSE;
  }

  /* erase the block */
  result=nand_device->erase_block(nand_device, current_block);
  if (result != FS_DEVICE_DONE)
  {
    DPRINTF (("Error: device failed during erase\n"));
    SET_ERR (ERR_ERASE_FAIL);
    return FALSE;
  }

  /* do housekeeping to set up to use block just erased */
  current_page = current_block * pages_in_block;
  avail_pages_in_block = pages_in_block; 

  return TRUE;
}


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

FUNCTION write_partial_page

DESCRIPTION
  This function will write the currently full partial page out and 
  update any housekeeping variables as necessary

DEPENDENCIES
  None

RETURN VALUE
  If success, return TRUE else FALSE

SIDE EFFECTS

===========================================================================*/
int
write_partial_page (dword addr, int update_crc)
{
  if ( (write_current_page ((unsigned char *)partial_page_buffer, 
                            addr, update_crc) == FALSE) )
  {
    return FALSE;
  }
  partial_page_index = 0;

  return TRUE;
}



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

FUNCTION write_current_page

DESCRIPTION

⌨️ 快捷键说明

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