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

📄 fdi_spll.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 5 页
字号:
  ###   limit expired or if an error occurred during programming, the function
  ###   returns HW_ERR_WRITE.  Finally, if the command was successfully issued,
  ###   the function returns HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevProtectReg(FLASH_DATA_PTR factory_reg_ptr,
                            FLASH_DATA_PTR user_reg_ptr,
                            FLASH_DATA_PTR lock_reg_ptr,
                            HW_CMD command,
                            BYTE register_num,
                            BYTE lock_flag)
{
   FLASH_DATA pr_lock_vals[] =
   {
      FLASH_PR_LOCK0_VALUE,  FLASH_PR_LOCK1_VALUE,  FLASH_PR_LOCK2_VALUE,
      FLASH_PR_LOCK3_VALUE,  FLASH_PR_LOCK4_VALUE,  FLASH_PR_LOCK5_VALUE,
      FLASH_PR_LOCK6_VALUE,  FLASH_PR_LOCK7_VALUE,  FLASH_PR_LOCK8_VALUE,
      FLASH_PR_LOCK9_VALUE,  FLASH_PR_LOCK10_VALUE, FLASH_PR_LOCK11_VALUE,
      FLASH_PR_LOCK12_VALUE, FLASH_PR_LOCK13_VALUE, FLASH_PR_LOCK14_VALUE,
      FLASH_PR_LOCK15_VALUE, FLASH_PR_LOCK16_VALUE
   };

   volatile FLASH_DATA_PTR flash_ptr =
      (FLASH_DATA_PTR) PARAMETER_PARTITION_START_ADDRESS;
   FLASH_DATA data;
   HW_ERROR retval = HW_ERR_NONE;
   DWORD key0, key1;
   DWORD data_amt, i;


   DISABLE_INTERRUPTS(key0, key1);
   data = PtrLowLvlReadStat(flash_ptr);
   ENABLE_INTERRUPTS(key0, key1);

   /* check to see if flash is suspended */
/* Begin E.5.1.867 */
   if ((data &
      (FLASH_STATUS_WRITE_SUSPENDED | FLASH_STATUS_ERASE_SUSPENDED)) &&
      ((command == HW_CMD_WRITE_PR) || (command == HW_CMD_WRITE_PR_LOCK)))
   {
      retval = HW_ERR_SUSPEND;
   }
/* End E.5.1.867 */

   /* check to see if flash is ready for protection register operation */
   else if ((data & FLASH_STATUS_READY) != FLASH_STATUS_READY)
   {
      retval = HW_ERR_NOTRDY;
   }

   /* OK to perform operation */
   else
   {
      /* set pointer to appropriate lock register */
      flash_ptr += GET_PR_LOCK_REG(register_num);

      switch (command)
      {
         case HW_CMD_WRITE_PR:
            /*
             * need to set flash pointer to appropriate block and the
             * appropriate size for the protection register bank
             */
            flash_ptr++;

            if (!register_num)
            {
               flash_ptr += FLASH_PR_64BIT_SIZE;
               data_amt = FLASH_PR_64BIT_SIZE;
            }
            else
            {
               flash_ptr += (FLASH_PR_128BIT_SIZE * (register_num - 1));
               data_amt = FLASH_PR_128BIT_SIZE;
            }

            /* write data to protection register */
            for (i = 0; i < data_amt; i++, flash_ptr++)
            {
               HARDWARE_PRECONDITION;
               DISABLE_INTERRUPTS(key0, key1);
               retval = PtrLowLvlProtectReg(flash_ptr, user_reg_ptr + i,
                                            command);
               ENABLE_INTERRUPTS(key0, key1);
               HARDWARE_POSTCONDITION;
               if (retval != HW_ERR_NONE)
               {
                  break;
               }
            }

            if ((lock_flag) && (retval == HW_ERR_NONE))
            {
               flash_ptr = (FLASH_DATA_PTR) PARAMETER_PARTITION_START_ADDRESS;
               flash_ptr += GET_PR_LOCK_REG(register_num);
               data = pr_lock_vals[register_num];
               HARDWARE_PRECONDITION;
               DISABLE_INTERRUPTS(key0, key1);
               retval = PtrLowLvlProtectReg(flash_ptr, &data,
                                            HW_CMD_WRITE_PR_LOCK);
               ENABLE_INTERRUPTS(key0, key1);
               HARDWARE_POSTCONDITION;
            }
            break;


         case HW_CMD_READ_PR:
            flash_ptr++;

            /*
             * if protection register bank #0 is specified, read both
             * user and factory values
             */
            if (!register_num)
            {
               data_amt = FLASH_PR_64BIT_SIZE;
               for (i = 0; i < data_amt; i++, flash_ptr++)
               {
                  DISABLE_INTERRUPTS(key0, key1);
                  retval = PtrLowLvlProtectReg(flash_ptr, factory_reg_ptr + i,
                                               command);
                  retval =
                     PtrLowLvlProtectReg((flash_ptr +FLASH_PR_64BIT_SIZE),
                                         user_reg_ptr + i, command);
                  ENABLE_INTERRUPTS(key0, key1);
               }
            }

            /* otherwise, all data goes into the user registers */
            else
            {
               flash_ptr += (FLASH_PR_128BIT_SIZE * (register_num - 1));
               data_amt = FLASH_PR_128BIT_SIZE;
               for (i = 0; i < data_amt; i++, flash_ptr++)
               {
                  DISABLE_INTERRUPTS(key0, key1);
                  retval = PtrLowLvlProtectReg(flash_ptr, user_reg_ptr + i,
                                             command);
                  ENABLE_INTERRUPTS(key0, key1);
               }
            }
            break;


         case HW_CMD_WRITE_PR_LOCK:
            data = pr_lock_vals[register_num];
            HARDWARE_PRECONDITION;
            DISABLE_INTERRUPTS(key0, key1);
            retval = PtrLowLvlProtectReg(flash_ptr, &data, command);
            ENABLE_INTERRUPTS(key0, key1);
            HARDWARE_POSTCONDITION;
            break;


         case HW_CMD_READ_PR_LOCK:
            DISABLE_INTERRUPTS(key0, key1);
            retval = PtrLowLvlProtectReg(flash_ptr, &data, command);
            ENABLE_INTERRUPTS(key0, key1);
            *lock_reg_ptr = data;
            break;

         default:
            retval = HW_ERR_PARAM;
      }
   }

   return retval;
}
#endif /* ENABLE_PR */



#if (PACKET_DATA == TRUE)
#if (BUFFER_SIZE > 0)
/*#############################################################################
  ### FlashDevWritePacket
  ###
  ### DESCRIPTION:
  ###   Allows the Data Manager to write packets to flash.  Unlike
  ###   FlashDevWrite(), this function will not align the data if the data
  ###   is not aligned.  However, it will check to see if the addresses are
  ###   aligned if PARAM_CHECK (found in FDI_Type.h) is set to TRUE.
  ###
  ### PARAMETERS:
  ###    IN:  buffer_ptr (BYTE_PTR) - Source buffer of the data to be written.
  ###         address (DWORD) - Flash data fragment start address for the
  ###          write.
  ###         size (DWORD) - Size of the buffer to be written, in bytes.
  ###    OUT:
  ###
  ### RETURNS:
  ###   If PARAM_CHECK is set to TRUE and the addresses are not aligned,
  ###   the function returns HW_ERR_PARAM.  If an error occurred when writing
  ###   any data, the function returns HW_ERR_WRITE.  Otherwise, the function
  ###   returns HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevWritePacket(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
   FLASH_DATA_PTR dst_data_ptr, src_data_ptr;
   DWORD key0, key1;
   DWORD data_size;

   HW_ERROR status = HW_ERR_NONE;

   /* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
   mDEBUG_PLR_SIMULATION(size);
#endif /* TEST_PLR == BKGD_MLC or DAV_MLC */

   /**/
   CHECK_ALIGNMENT((DWORD) buffer_ptr);
   CHECK_ALIGNMENT(address);
   CHECK_ALIGNMENT(size);

   dst_data_ptr = (FLASH_DATA_PTR) address;
   src_data_ptr = (FLASH_DATA_PTR) buffer_ptr;
   size /= sizeof(FLASH_DATA);

   HARDWARE_PRECONDITION;

   /*
    * to get the best performance out of flash, all buffered writes
    * should occur on buffer boundaries.  Write the initial data that is
    * not buffer aligned so that all subsequent writes are on buffer
    * boundaries.
    */
   while ((size > 0) && (status == HW_ERR_NONE))
   {
      /**/
      data_size = GET_MIN(size, BUFFER_SIZE / sizeof(FLASH_DATA));

      /* write buffer */
      do
      {
#if (TIME_MONITOR_ENABLED == TRUE)
         TIME_MONITOR(key0, key1);
#else
         DISABLE_INTERRUPTS(key0, key1);
#endif
         status = PtrLowLvlWrite(dst_data_ptr, src_data_ptr, data_size);
         ENABLE_INTERRUPTS(key0, key1);
      } while ((status == HW_ERR_SUSPEND) || (status == HW_ERR_ABORT));

      /* update pointers/variables */
      dst_data_ptr += data_size;
      src_data_ptr += data_size;
      size -= data_size;
   }

   HARDWARE_POSTCONDITION;
   return status;
}



#else /* BUFFER_SIZE == 0 */
/*#############################################################################
  ### FlashDevWritePacket
  ###
  ### DESCRIPTION:
  ###   Allows the Data Manager to write packets to flash.  Unlike
  ###   FlashDevWrite(), this function will not align the data if the data
  ###   is not aligned.  However, it will check to see if the addresses are
  ###   aligned if PARAM_CHECK (found in FDI_Type.h) is set to TRUE.
  ###
  ### PARAMETERS:
  ###    IN:  buffer_ptr (BYTE_PTR) - Source buffer of the data to be written.
  ###         address (DWORD) - Flash data fragment start address for the
  ###          write.
  ###         size (DWORD) - Size of the buffer to be written, in bytes.
  ###    OUT:
  ###
  ### RETURNS:
  ###   If PARAM_CHECK is set to TRUE and the addresses are not aligned,
  ###   the function returns HW_ERR_PARAM.  If an error occurred when writing
  ###   any data, the function returns HW_ERR_WRITE.  Otherwise, the function
  ###   returns HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevWritePacket(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
   DWORD dst_data_addr, src_data_addr;
   DWORD key0, key1;
   DWORD data_size;

   HW_ERROR status = HW_ERR_NONE;

   /* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
   mDEBUG_PLR_SIMULATION(size);
#endif /* TEST_PLR == BKGD_MLC or DAV_MLC */

   /**/
   CHECK_ALIGNMENT((DWORD) buffer_ptr);
   CHECK_ALIGNMENT(address);
   CHECK_ALIGNMENT(size);

   dst_data_addr = (DWORD) address;
   src_data_addr = (DWORD) buffer_ptr;
   data_size = size / sizeof(FLASH_DATA);

   HARDWARE_PRECONDITION;

   /*
    * with non-buffered components, data only needs to be written on
    * aligned addresses.
    */
   do
   {
#if (TIME_MONITOR_ENABLED == TRUE)
      TIME_MONITOR(key0, key1);
#else
      DISABLE_INTERRUPTS(key0, key1);
#endif
      status = PtrLowLvlWritePacket(&dst_data_addr, &src_data_addr,
                                    &data_size);
      ENABLE_INTERRUPTS(key0, key1);
   } while (status == HW_ERR_SUSPEND);

   HARDWARE_POSTCONDITION;
   return status;
}
#endif /* BUFFER_SIZE */
#endif /* PACKET_DATA */



/*#############################################################################
  ### FlashDevFindInstance
  ###
  ### DESCRIPTION:
  ###  Scans all unit headers in block designated by address, look for
  ###  the first empty unit header or the instance to be located.
  ###
  ### PARAMETERS:
  ###    IN:
  ###       identifier        - unique identifier of data
  ###       table_number      - number of the sequence table being searched
  ###       this_instance     - sequence table instance number for this block
  ###       type              - parameter or data stream identification
  ###       attribute         - attribute type to search for
  ###       command           - FIND_INSTANCE or FIND_LAST_HEADER
  ###       block             - sequence table block number
  ###       hdr_status        - header status value to look for
  ###    OUT:
  ###       block_addr_ptr    - first address of this block
  ###       header_offset_ptr - byte offset to the unit header
  ###       unit_offset_ptr   - byte offset to the data unit or fragment unit
  ###
  ### GLOBALS:
  ###
  ### FORMAT:
  ###  HW_ERROR FlashFindDevInstance(DWORD_PTR, DWORD_PTR, DWORD_PTR,IDTYPE,
  ###                     WORD, WORD, WORD, WORD, BYTE, BYTE, BYTE)
  ###
  ### RETURNS:
  ###  HW_ERR_SYSTEM  This instance no find
  ###  HW_ERR_NONE    function execution is successful
  ###
 */
HW_ERROR
FlashDevFindInstance(DWORD_PTR blk_addr_ptr,
                  DWORD_PTR header_offset_ptr,
                  DWORD_PTR unit_offset_ptr,
                  IDTYPE identifier,
                  WORD table_number,
                  WORD this_instance,
                  WORD block,
                  WORD hdr_status,
                  BYTE type,
                  BYTE attribute,
                  BYTE command)
{
   UNIT_HEADER header;
   UNIT_HDR_PTR pHdr;
   DWORD address;

   WORD physical_block;

   SEM_MTX_WAIT(SEM_BlockTable);
   physical_block = FDI_LogicalBlockTable[block].physical_block_number;
   SEM_MTX_POST(SEM_BlockTable);
   *blk_addr_ptr = BLOCK_ADDRESS(physical_block);
   *unit_offset_ptr = 0;

  

⌨️ 快捷键说明

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