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

📄 fdi_mpll.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Copyright(R) 2001-2002 Intel Corporation */
/* ############################################################################
 ### Object: Low Level Driver
 ###
 ### Module: FDI_Mpll.c - Dual/Multi Partition Low-Level Driver
 ###   $Archive: /FDI/SRC/LOWLVL/fdi_mpll.c $
 ###   $Revision: 42 $
 ###   $Date: 10/14/04 2:08p $
 ###   $Author: Wtiso $
 ###
 ###$NoKeywords: $
 ########################################################################### */

/*                                                               
 *****************************************************************
 * NOTICE OF LICENSE AGREEMENT                                    
 *                                                                
 * This code is provided by Intel Corp., and the use is governed  
 * under the terms of a license agreement. See license agreement  
 * for complete terms of license.                                 
 *                                                                
 * YOU MAY ONLY USE THE SOFTWARE WITH INTEL FLASH PRODUCTS.  YOUR 
 * USE OF THE SOFTWARE WITH ANY OTHER FLASH PRODUCTS IS EXPRESSLY 
 * PROHIBITED UNLESS AND UNTIL YOU APPLY FOR, AND ARE GRANTED IN  
 * INTEL'S SOLE DISCRETION, A SEPARATE WRITTEN SOFTWARE LICENSE   
 * FROM INTEL LICENSING ANY SUCH USE.                             
 *****************************************************************
 */
 

#ifdef CURRENT_FILE_BEING_COMPILED
#undef CURRENT_FILE_BEING_COMPILED
#endif

#define CURRENT_FILE_BEING_COMPILED FDI_MPLL


/*
 *### Include Files
 *#########################
 */

#include "fdi_lowl.h"

#if (PARTITIONS != SINGLE)
#include "fdi_int.h"

#ifdef CUSTOM_SEM_MTX 
#include "fdi_mutx.h"
#endif

#if (PACKET_DATA == TRUE)
#include "fdi_pckt.h"
#endif



/*
 *### Local Declarations
 *#########################
 */

/* Absolute physical starting address of flash */
#define LOWLVL_FLASH_START_ADDRESS           FLASH_START_ADDRESS

/* The start and end addresses of the data-managed area within flash */
#define LOWLVL_DATA_START_ADDRESS            FDV_START_ADDRESS
#if (ADDRESS_VALIDATION == TRUE)
#define LOWLVL_DATA_END_ADDRESS \
   (FDV_START_ADDRESS + (FDV_BLOCKCOUNT * FDV_BLOCK_SIZE) - 1)

/* The start and end addresses of the code-managed area within flash */
#if (DIRECT_ACCESS_VOLUME == TRUE)
#define LOWLVL_CODE_START_ADDRESS            DAV_START_ADDRESS
#define LOWLVL_CODE_END_ADDRESS \
   (DAV_START_ADDRESS + (DAV_BLOCKCOUNT * DAV_BLOCK_SIZE) - 1)
#endif /* DIRECT_ACCESS_VOLUME */
#endif /* ADDRESS_VALIDATION */


/* Used as a temporary byte buffer during a copy */
#if (BUFFER_SIZE > 0)
#define COPY_BUFFER_SIZE                     BUFFER_SIZE
#else /* BUFFER_SIZE == 0 */
#define COPY_BUFFER_SIZE                     32
#endif /* BUFFER_SIZE */

/* A flash data value with all its bits set */
#define ALL_F                                ((FLASH_DATA) (-1))


/*
 * Validates that the address and length of the buffer lie entirely within
 * the data managed blocks (or code managed blocks if DAV is enabled).
 */
#if (ADDRESS_VALIDATION == TRUE)
#if (DIRECT_ACCESS_VOLUME != TRUE)
#define VALIDATE_ADDRESS(addr, len) \
   if (((addr) < LOWLVL_DATA_START_ADDRESS) || \
      (((addr) + (len) - 1) > LOWLVL_DATA_END_ADDRESS)) \
   { \
      return HW_ERR_PARAM; \
   }
#else /* DIRECT_ACCESS_VOLUME == TRUE */
#define VALIDATE_ADDRESS(addr, len) \
   if ((((addr) < LOWLVL_DATA_START_ADDRESS) || \
      (((addr) + (len) - 1) > LOWLVL_DATA_END_ADDRESS)) && \
      ((((addr) < LOWLVL_CODE_START_ADDRESS) || \
      (((addr) + (len) - 1) > LOWLVL_CODE_END_ADDRESS)))) \
   { \
      return HW_ERR_PARAM; \
   }
#endif /* DIRECT_ACCESS_VOLUME */
#else  /* ADDRESS_VALIDATION != TRUE */
#define VALIDATE_ADDRESS(addr, len)
#endif /* ADDRESS_VALIDATION */


/* Returns the previously aligned address */
#define ALIGN_ADDRESS(addr) \
   ((DWORD) ((addr) & ((DWORD) ~(sizeof(FLASH_DATA) - 1))))


/*
 * Determines the number of bytes the address is off from being aligned.
 * This macro will return the number of bytes unaligned from the previously
 * aligned address.
 */
#define UNALIGNED_BYTES(addr) \
   ((DWORD) ((addr) & ((DWORD) (sizeof(FLASH_DATA) - 1))))


/* For packet data only: check to see if the argument is properly aligned */
#if (PACKET_DATA == TRUE)
#if (PARAM_CHECK == TRUE)
#define CHECK_ALIGNMENT(addr) \
   if (UNALIGNED_BYTES((DWORD) (addr))) \
   { \
      return HW_ERR_PARAM; \
   }
#else  /* (PARAM_CHECK != TRUE) */
#define CHECK_ALIGNMENT(addr)
#endif /* PARAM_CHECK */
#endif /* PACKET_DATE */


/*
 * If FDI block-locking support is enabled, this macro will lock/unlock the
 * block pointed to by its argument
 */
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
#define LOCK_BLOCK(addr_ptr) \
   *(addr_ptr) = FLASH_COMMAND_LOCK; \
   *(addr_ptr) = FLASH_COMMAND_LOCK_CONFIRM
#define UNLOCK_BLOCK(addr_ptr) \
   *(addr_ptr) = FLASH_COMMAND_LOCK; \
   *(addr_ptr) = FLASH_COMMAND_UNLOCK_CONFIRM
#else  /* !BLOCK_LOCK_SUPPORT || !ENABLE_FDI_BLOCKLOCKING */
/* #define LOCK_BLOCK(addr_ptr) */
#define UNLOCK_BLOCK(addr_ptr)
#endif /* (BLOCK_LOCK_SUPPORT) && (ENABLE_FDI_BLOCKLOCKING) */


/*
 * When using the hardware buffer on flash components, the user must
 * specify the number of bytes/words being written to the buffer after
 * issuing the write-to-buffer command
 */
#if (BUFFER_SIZE > 0)
#define BUFFER_SIZE_TO_WRITE(s)     CREATE_COMMAND((s) - 1)
#endif /* BUFFER_SIZE */


/* Returns the lesser of the two values passed */
#define GET_MIN(a, b)               (((a) < (b)) ? (a) : (b))


/*
 * To support protection registers, the following values are used to set
 * lock bits, obtain protection register sizes, and obtain lock registers.
 */
#if (ENABLE_PR != FDI_NONE)
#define FLASH_PR_LOCK_REG0          0x80
#define FLASH_PR_LOCK_REG1          0x89

#if (FLASH_PAIRED != TRUE)
#define FLASH_PR_64BIT_SIZE   ((64 >> 3) >> (sizeof(FLASH_DATA) >> 1))
#define FLASH_PR_128BIT_SIZE  ((128 >> 3) >> (sizeof(FLASH_DATA) >> 1))
#else /* FLASH_PAIRED == TRUE */
#define FLASH_PR_64BIT_SIZE   (((64 >> 3) >> (sizeof(FLASH_DATA) >> 1)) << 1)
#define FLASH_PR_128BIT_SIZE  (((128 >> 3) >> (sizeof(FLASH_DATA) >> 1)) << 1)
#endif /* FLASH_PAIRED */

#define FLASH_PR_LOCK0_VALUE        CREATE_COMMAND(0xFFFD)
#define FLASH_PR_LOCK1_VALUE        CREATE_COMMAND(0xFFFE)
#define FLASH_PR_LOCK2_VALUE        CREATE_COMMAND(0xFFFD)
#define FLASH_PR_LOCK3_VALUE        CREATE_COMMAND(0xFFFB)
#define FLASH_PR_LOCK4_VALUE        CREATE_COMMAND(0xFFF7)
#define FLASH_PR_LOCK5_VALUE        CREATE_COMMAND(0xFFEF)
#define FLASH_PR_LOCK6_VALUE        CREATE_COMMAND(0xFFDF)
#define FLASH_PR_LOCK7_VALUE        CREATE_COMMAND(0xFFBF)
#define FLASH_PR_LOCK8_VALUE        CREATE_COMMAND(0xFF7F)
#define FLASH_PR_LOCK9_VALUE        CREATE_COMMAND(0xFEFF)
#define FLASH_PR_LOCK10_VALUE       CREATE_COMMAND(0xFDFF)
#define FLASH_PR_LOCK11_VALUE       CREATE_COMMAND(0xFBFF)
#define FLASH_PR_LOCK12_VALUE       CREATE_COMMAND(0xF7FF)
#define FLASH_PR_LOCK13_VALUE       CREATE_COMMAND(0xEFFF)
#define FLASH_PR_LOCK14_VALUE       CREATE_COMMAND(0xDFFF)
#define FLASH_PR_LOCK15_VALUE       CREATE_COMMAND(0xBFFF)
#define FLASH_PR_LOCK16_VALUE       CREATE_COMMAND(0x7FFF)

#define GET_PR_LOCK_REG(reg)  ((reg) ? FLASH_PR_LOCK_REG1 : FLASH_PR_LOCK_REG0)
#endif /* ENABLE_PR */


/*#############################################################################
 *# Function Pointers
 *###########################################################################*/

#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
    || (ENABLE_PR != FDI_NONE))
typedef FLASH_DATA (*LLREADSTAT_FUNCPTR)(volatile FLASH_DATA_PTR);
extern FLASH_DATA LowLvlReadStat(volatile FLASH_DATA_PTR);
static LLREADSTAT_FUNCPTR PtrLowLvlReadStat;
#endif /* (BLOCK_LOCK_SUPPORT && ENABLE_NONFDI_BLOCKLOCKING) || ENABLE_PR */

#if (BLOCK_LOCK_SUPPORT == TRUE)
typedef HW_ERROR (*LLLOCK_FUNCPTR)(volatile FLASH_DATA_PTR, FLASH_DATA_PTR,
                                   HW_CMD);
extern HW_ERROR LowLvlLock(volatile FLASH_DATA_PTR, FLASH_DATA_PTR, HW_CMD);
static LLLOCK_FUNCPTR PtrLowLvlLock;
#endif /* BLOCK_LOCK_SUPPORT */

#if (ENABLE_PR != FDI_NONE)
typedef HW_ERROR (*LLPR_FUNCPTR)(volatile FLASH_DATA_PTR, FLASH_DATA_PTR,
                                 HW_CMD);
extern HW_ERROR LowLvlProtectReg(volatile FLASH_DATA_PTR, FLASH_DATA_PTR,
                                 HW_CMD);
static LLPR_FUNCPTR PtrLowLvlProtectReg;
#endif /* ENABLE_PR */

#if (RELOCATE_CODE == TRUE)
extern HW_ERROR LowLvlEnd(void);
#endif /* RELOCATE_CODE */
/* Flash Device Semaphores */
extern SEM_MTX_ID SEM_FlashWrite;
/* E5.3.875 START */
/*#if (DIRECT_ACCESS_VOLUME == TRUE)*/
extern SEM_MTX_ID SEM_FlashErase;
/*#endif /DIRECT_ACCESS_VOLUME */
/* E5.3.875 END */

#if (CONSISTENT_ACCESS_TIME == TRUE)
extern DATA_LOOKUP_PTR FDI_DataLookupPtrTable[];
#endif /* CONSISTENT_ACCESS_TIME */
/* extern SEM_MTX_ID  SEM_LookupTable; */
extern LOGICAL_BLOCK FDI_LogicalBlockTable[];
extern SEM_MTX_ID  SEM_BlockTable;



/*#############################################################################
 *# Dual/Multi Partition Macros
 *###########################################################################*/

/* partition states */
/*typedef enum
{
   HW_STATE_READ   = 0,
   HW_STATE_STATUS = 1
} HW_STATE;*/
enum
{
   HW_STATE_READ   = 0,
   HW_STATE_STATUS = 1
};


/* sets partition state */
#define SET_PARTITION_STATE(addr, state) \
   (((addr) & (-sizeof(FLASH_DATA))) | ((DWORD) (state)))

/* gets partition state */
#define GET_PARTITION_STATE(ps) \
   (((ps) & HW_STATE_STATUS) ? HW_STATE_STATUS : HW_STATE_READ)

/* gets partition address */
#define GET_PARTITION_ADDRESS(ps) \
   ((ps) & (-sizeof(FLASH_DATA)))


/* Checks if the partition is ready to be read from */
#if (PARTITIONS != MULTI)
#define CUI_FLASH_STATUS_PARTITION_READY        0x80
#else  /* PARTITIONS == MULTI */
#define CUI_FLASH_STATUS_PARTITION_READY        0x81
#endif /* PARTITIONS */

#define FLASH_STATUS_PARTITION_READY \
   CREATE_COMMAND(CUI_FLASH_STATUS_PARTITION_READY)

/* E5.0.480 START */
#if (FLASH_PAIRED == TRUE)
#define SHIFT_FACTOR (sizeof(FLASH_DATA) << 2)
#define DEVICE0_MASK ((FLASH_DATA) (ALL_F >> SHIFT_FACTOR))
#define DEVICE1_MASK ((FLASH_DATA) ((ALL_F >> SHIFT_FACTOR) << SHIFT_FACTOR))

#define IS_PARTITION_BUSY(fp) \
   ((((*(fp) & DEVICE0_MASK) & FLASH_STATUS_PARTITION_READY) == 0) || \
    (((*(fp) & DEVICE1_MASK) & FLASH_STATUS_PARTITION_READY) == 0))
#define RESUME_WRITE_SUSPENDED_FLASH(fp) \
   if ((*(fp) & DEVICE0_MASK) & FLASH_STATUS_WRITE_SUSPENDED) \
   { \
      *(fp) = ((FLASH_COMMAND_STATUS & DEVICE1_MASK) | \
               (FLASH_COMMAND_RESUME & DEVICE0_MASK)); \
   } \
   if ((*(fp) & DEVICE1_MASK) & FLASH_STATUS_WRITE_SUSPENDED) \
   { \
      *(fp) = ((FLASH_COMMAND_STATUS & DEVICE0_MASK) | \
               (FLASH_COMMAND_RESUME & DEVICE1_MASK)); \
   } \
   *(fp) = FLASH_COMMAND_STATUS

#else  /* FLASH_PAIRED != TRUE */
#define IS_PARTITION_BUSY(fp) \
   ((*(fp) & FLASH_STATUS_PARTITION_READY) == 0)
#define RESUME_WRITE_SUSPENDED_FLASH(fp) \
   *(fp) = FLASH_COMMAND_RESUME; \
   *(fp) = FLASH_COMMAND_STATUS
#endif /* FLASH_PAIRED */
/* E5.0.480 END */

/* Stores the current block address and the state of the partition */
/*E5.0.733 Start */ 
static DWORD CurrentFlashState;
/*E5.0.733 End */


/*
 *### Local Functions
 *#########################
 */

#if (BUFFER_SIZE > 0)
/*#############################################################################
  ### WriteToFlash (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 */
{
   FLASH_DATA buffer_size;
   DWORD size_to_write;
   DWORD i;

   DWORD key0, key1;
   HW_ERROR status = HW_ERR_NONE;


   while (size > 0)
   {
      /* not enough data, use single data program */
      if (size == 1)
      {
         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);

         /* increment ram pointer and decrement size */
         ram_ptr++;
         size--;
      }

      /* enough data is present, use hardware buffer */
      else

⌨️ 快捷键说明

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