📄 fdi_mpll.c
字号:
/* 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 + -