fdi_mpll.c

来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 1,983 行 · 第 1/5 页

C
1,983
字号
      {
         /* determine the size of the buffer */
         size_to_write = GET_MIN(size, BUFFER_SIZE / sizeof(FLASH_DATA));
         buffer_size = BUFFER_SIZE_TO_WRITE(size_to_write);

         /* wait until buffer is ready */
         DISABLE_INTERRUPTS(key0, key1);
         UNLOCK_BLOCK(flash_ptr);
         do
         {
            *flash_ptr = FLASH_COMMAND_WRITE_BUFFER;
         } while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY);

         /* send size of data and fill buffer */
         *flash_ptr = buffer_size;
         for (i = 0; i < size_to_write; i++)
         {
            *flash_ptr = *ram_ptr;
            flash_ptr++;
            ram_ptr++;
         }

         /* make sure pointer is in the same block and commit buffer */
         flash_ptr--;
         *flash_ptr = FLASH_COMMAND_CONFIRM;
/*E.5.4.940 START*/
         /*mDEBUG_RESET_WRITE();*/
/*E.5.4.940 END*/
         ENABLE_INTERRUPTS(key0, key1);

         /* decrement size */
         size -= size_to_write;
      }

      /* wait until flash is done */
      while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
      {
      }

      /* Lock the block */
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
      DISABLE_INTERRUPTS(key0, key1);
      LOCK_BLOCK(flash_ptr);
      ENABLE_INTERRUPTS(key0, key1);
#endif

      /* check for errors */
      if (*flash_ptr & FLASH_STATUS_ERROR)
      {
         *flash_ptr = FLASH_COMMAND_CLEAR;
         status = HW_ERR_WRITE;
         break;
      }

      /*
       * if a write is allowed to span blocks, uncomment the following
       * line of code to guarantee that the data, not status, will be read
       * on future reads
       */
      /* *flash_ptr = FLASH_COMMAND_READ; */

      /* increment flash pointer */
      flash_ptr++;
   }

   return status;
}



#else /* BUFFER_SIZE == 0 */
/*#############################################################################
  ### WriteToFlash (Non-Buffered Version)
  ###
  ### DESCRIPTION:
  ###   Writes data to flash and performs error checking before returning.
  ###
  ### PARAMETERS:
  ###    IN:  dst_ptr (FLASH_DATA_PTR) - A pointer to the data destination.
  ###         src_ptr (FLASH_DATA_PTR) - A pointer to the data source.
  ###         size (DWORD) - The number of FLASH_DATA units to write.
  ###    OUT:
  ###
  ### RETURNS:
  ###   If any portion of the data is not written successfully, the function
  ###   returns HW_ERR_WRITE; otherwise, the function returns HW_ERR_NONE.
  ###
 */

/* E.5.0.652 Begin */
static HW_ERROR WriteToFlash(volatile FLASH_DATA *flash_ptr,
                             FLASH_DATA *ram_ptr,
                             DWORD size)
/* E.5.0.652 End */
{
   DWORD key0, key1;
   HW_ERROR status = HW_ERR_NONE;


   while (size > 0)
   {
      /* program flash */
      DISABLE_INTERRUPTS(key0, key1);
      UNLOCK_BLOCK(flash_ptr);
      *flash_ptr = FLASH_COMMAND_WRITE;
      *flash_ptr = *ram_ptr;
/*E.5.4.940 START*/
      /*mDEBUG_RESET_WRITE();*/
/*E.5.4.940 END*/
      ENABLE_INTERRUPTS(key0, key1);

      /* wait until flash is done */
      while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
      {
      }

      /* lock the block */
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
      DISABLE_INTERRUPTS(key0, key1);
      LOCK_BLOCK(flash_ptr);
      ENABLE_INTERRUPTS(key0, key1);
#endif

      /* check for errors */
      if (*flash_ptr & FLASH_STATUS_ERROR)
      {
         *flash_ptr = FLASH_COMMAND_CLEAR;
         status = HW_ERR_WRITE;
         break;
      }

      /*
       * if a write is allowed to span blocks, uncomment the following
       * line of code to guarantee that the data, not status, will be read
       * on future reads
       */
      /* *flash_ptr = FLASH_COMMAND_READ; */

      /* update pointers */
      flash_ptr++;
      ram_ptr++;
      size--;
   }

   return status;
}
#endif /* BUFFER_SIZE */



/*### Global Declarations
 *######################### */



/*### Global Functions
 *######################### */

#if (RELOCATE_CODE == TRUE)
/*#############################################################################
  ### FlashDevInit (Relocate Version)
  ###
  ### DESCRIPTION:
  ###   Initializes the pointers used by the flash device functions.  Though
  ###   the flash device functions do not check, this function must be
  ###   called before any of the flash device functions can be called.
  ###
  ### PARAMETERS:
  ###    IN:  address (DWORD) - The physical address to where the low-level
  ###          functions will be relocated.
  ###    OUT:
  ###
  ### RETURNS:
  ###   HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevInit(DWORD address)
{
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
    || (ENABLE_PR != FDI_NONE))
   BYTE_PTR dst_ptr = (BYTE_PTR) address;
   BYTE_PTR src_ptr;
   WORD size;
#endif /* OPTIONAL_FEATURES */


   HARDWARE_INITIALIZE;
   /*E5.0.733 Start */ 
   CurrentFlashState = 
   SET_PARTITION_STATE(LOWLVL_DATA_START_ADDRESS, HW_STATE_READ);
    /*E5.0.733 End */

   /* Relocated functions based on configuration */
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
    || (ENABLE_PR != FDI_NONE))
   src_ptr = (BYTE_PTR) LowLvlReadStat;
   size = (WORD) ((DWORD) LowLvlEnd - (DWORD) LowLvlReadStat);

   MemoryMove(dst_ptr, src_ptr, size);
   PtrLowLvlReadStat = (LLREADSTAT_FUNCPTR) (address);

#if (BLOCK_LOCK_SUPPORT == TRUE)
   PtrLowLvlLock = (LLLOCK_FUNCPTR) (address +
                   ((DWORD) LowLvlLock - (DWORD) LowLvlReadStat));
#endif /* BLOCK_LOCK_SUPPORT */

#if (ENABLE_PR != FDI_NONE)
   PtrLowLvlProtectReg = (LLPR_FUNCPTR) (address +
                         ((DWORD) LowLvlProtectReg - (DWORD) LowLvlReadStat));
#endif /* ENABLE_PR */

#elif (BLOCK_LOCK_SUPPORT == TRUE)
   PtrLowLvlLock = (LLLOCK_FUNCPTR) LowLvlLock;
#endif /* OPTIONAL_FEATURES */

   return HW_ERR_NONE;
}



#else /* RELOCATE_CODE != TRUE */
/*#############################################################################
  ### FlashDevInit (Non-Relocate Version)
  ###
  ### DESCRIPTION:
  ###   Initializes the pointers used by the flash device functions.  Though
  ###   the flash device functions do not check, this function must be
  ###   called before any of the flash device functions can be called.
  ###
  ### PARAMETERS:
  ###    IN:  address (DWORD) - The physical address to where the low-level
  ###          functions will be relocated.  For debugging purposes, it is
  ###          ignored.
  ###    OUT:
  ###
  ### RETURNS:
  ###   HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevInit()
{
   HARDWARE_INITIALIZE;

   /*E5.0.733 Start */ 
   CurrentFlashState = 
   SET_PARTITION_STATE(LOWLVL_DATA_START_ADDRESS, HW_STATE_READ);
    /*E5.0.733 End */

   /* Assign based on configuration */
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
    || (ENABLE_PR != FDI_NONE))
   PtrLowLvlReadStat = (LLREADSTAT_FUNCPTR) LowLvlReadStat;
#endif /* (BLOCK_LOCK_SUPPORT && ENABLE_NONFDI_BLOCKLOCKING) || ENABLE_PR */

#if (BLOCK_LOCK_SUPPORT == TRUE)
   PtrLowLvlLock = (LLLOCK_FUNCPTR) LowLvlLock;
#endif /* BLOCK_LOCK_SUPPORT */

#if (ENABLE_PR != FDI_NONE)
   PtrLowLvlProtectReg = (LLPR_FUNCPTR) LowLvlProtectReg;
#endif /* ENABLE_PR */
   return HW_ERR_NONE;
}
#endif /* DEBUG_LOWLVL */



/*#############################################################################
  ### FlashDevCompatCheck
  ###
  ### DESCRIPTION:
  ###   Verifies compatibility with flash support by the user application.
  ###   If the function determines that the component is incompatible, it
  ###   returns an error.
  ###
  ### PARAMETERS:
  ###    IN:  address (DWORD) - The absolute address of the window in flash
  ###          to scan.
  ###    OUT:
  ###
  ### RETURNS:
  ###   If the flash type is supported, the function returns HW_ERR_NONE.  If
  ###   the flash type is not supported or if there was an error clearing
  ###   the status register, the function returns HW_ERR_COMPAT.
  ###
 */

HW_ERROR FlashDevCompatCheck(DWORD address, DWORD size)
{
   volatile FLASH_DATA_PTR flash_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
   FLASH_DATA status_reg;
   HW_ERROR compat;


   /* look for the first value that is not FLASH_STATUS_READY */
   for (*flash_ptr = FLASH_COMMAND_READ; (DWORD) flash_ptr < (address + size);
         flash_ptr++)
   {
      if (*flash_ptr != FLASH_STATUS_READY)
      {
         break;
      }
   }

   /* if at or past end of window, no compatibility issue */
   if ((DWORD) flash_ptr >= (address + size))
   {
      compat = HW_ERR_NONE;
   }

   /* otherwise, clear status register and check value */
   else
   {
      *flash_ptr = FLASH_COMMAND_CLEAR;
      *flash_ptr = FLASH_COMMAND_STATUS;
      status_reg = *flash_ptr;
      *flash_ptr = FLASH_COMMAND_READ;

      if (status_reg == FLASH_STATUS_READY)
      {
         compat = HW_ERR_NONE;
      }
      else
      {
         compat = HW_ERR_COMPAT;
      }
   }

   return compat;
}


/*#############################################################################
  ### FlashDevWrite
  ###
  ### DESCRIPTION:
  ###   This function writes 'size' bytes of data from a specified buffer to
  ###   the destination addresss within the device(s).  The Background Manager,
  ###   Reclaim Task, and Code Manager determine the relative address by
  ###   using the FDI mapping structures.  This function translates the
  ###   relative address into a physical system addres and verifies the
  ###   address range.  After aligning the source and destination buffers,
  ###   the function takes the flash write semaphore and calls the low-level
  ###   function LowLvlWrite() via its function pointer.  Upon completion
  ###   of the write, the function releases the flash write semaphore and
  ###   returns the appropriate value.
  ###
  ### PARAMETERS:
  ###    IN:  buffer_ptr (BYTE_PTR) - A pointer to the start address of the
  ###          data to be written.
  ###         address (DWORD) - The destination address within the flash
  ###          device(s).
  ###         size (DWORD) - The amount of data, in bytes, to write.
  ###
  ### RETURNS:
  ###   If any portion of the data being written does not fall within the
  ###   data managed area (or the code managed area if DAV is enabled), the
  ###   function returns HW_ERR_PARAM.  If an error occurred while writing
  ###   the data to flash, HW_ERR_WRITE is returned.  Finally, if all the
  ###   parameters are within the appropriate ranges and the data was
  ###   written successfully, the function returns HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevWrite(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
   BYTE_PTR                dst_byte_ptr, src_byte_ptr;
   /* E5.1.769 START */
   volatile FLASH_DATA_PTR dst_data_ptr;
   /* E5.1.769 END */
   FLASH_DATA              temp_buffer[COPY_BUFFER_SIZE / sizeof(FLASH_DATA)];

   DWORD dst_offset;
   DWORD byte_size, data_size;
   HW_ERROR status = HW_ERR_NONE;

   DWORD preempted_state;
   BYTE suspended = (BYTE) FALSE;


   /* power loss simulation for testing purposes */
   mDEBUG_PLR_SIMULATION(size);

   /* address validation */
   address += LOWLVL_FLASH_START_ADDRESS;
   VALIDATE_ADDRESS(address, size);


   /* if size is 0, return */
   if (size == 0)
   {
      return HW_ERR_NONE;
   }


⌨️ 快捷键说明

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