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

📄 m512_mtd.c

📁 M-System DOC(Disk on a Chip) Flash芯片的诊断工具, 可以从Flash芯片中获取特定的数据信息, 用于判断芯片当前的状态.
💻 C
📖 第 1 页 / 共 5 页
字号:
                                          FLDword   *dwNextAddressPtr,
                                          unsigned  *dwDOC_PhyAddress,
                                          FLBoolean fResetAll)
{
  FLFlash              *flash;
  FLDword              dwWinSize = 0x2000 ;
  volatile FLWord      wChipId,wChipIdConfirm;
  FLByte               bIF_CFG ;

  DBG_PRINT_FLOW(FLZONE_MTD,"Flow: docWindowBaseAddress Entered.\r\n");

  /* if memory range to search for DiskOnChip window is not specified      */
  /* assume the standard x86 PC architecture where DiskOnChip Plus appears */
  /* in a memory range reserved for BIOS expansions                        */
#ifndef FL_ADD_ADDRESS_0_SUPPORT
  if (dwLowAddress == 0x0L)
  {
    dwLowAddress  = M512_DEFAULT_START_ADR;
    dwHighAddress = M512_DEFAULT_STOP_ADR;
  }
  else if (dwHighAddress == 0x0L)
  {
    dwHighAddress = M512_DEFAULT_STOP_ADR;
  }
#endif

  /* Initialize socket memory access routine */
  flash = flFlashOf(bSocketNo);

  /*** Step 1 : Set all possible controllers (ASIC) to RESET MODE ***/
  for (bIF_CFG=16;bIF_CFG>=8;bIF_CFG=bIF_CFG-8)
  { 
#ifndef FL_NO_USE_FUNC
    if(M512_setBusType(flash,flBusConfig[bSocketNo],2,bIF_CFG)==FALSE)
    {
      continue ;
    }
#endif /* FL_NO_USE_FUNC */
    dwWinSize = M512_DocWindow(flash) ; 

    if(fResetAll == TRUE)
    {   
      for(*dwNextAddressPtr = dwLowAddress;*dwNextAddressPtr<=dwHighAddress;*dwNextAddressPtr+=dwWinSize)
      {
        flash->win = (NDOC2window)physicalToPointer(*dwNextAddressPtr,dwWinSize,bSocketNo);
        /*** The 1st read from the MDOC_512 is Dummy read        ***/
        M512_DirectRead8BitReg (flash,M512_NOP_REG) ; 
         /*** Exit for DPD mode into the last mode (RESET/NORMAL) ***/
        M512_deepPowerDownMode (flash,EXIT_DEEP_POWER_DOWN) ;
        /*** set controller (ASIC) to RESET MODE                 ***/
        M512_asicSetMode (flash,RESET_MODE) ;
      }
    }    
  }

  /*** Step 2 : Read chip ID while skipping alias addresses ***/
  for(*dwNextAddressPtr  = dwLowAddress ; 
      *dwNextAddressPtr <= dwHighAddress ; 
      *dwNextAddressPtr += dwWinSize)
  {
    /*** Step 2 : Read chip ID while skipping alias addresses ***/
    for (bIF_CFG=16;bIF_CFG>=8;bIF_CFG=bIF_CFG-8)
    { /*** If this bus configuration is suported reset the FLASH with it ***/
      flash->if_cfg = bIF_CFG ; 

#ifndef FL_NO_USE_FUNC
      if(M512_setBusType(flash,flBusConfig[bSocketNo],2,bIF_CFG)==FALSE)
      {
        continue ;
      }
#endif /* FL_NO_USE_FUNC */
      DBG_PRINT_WRN_PRM(FLZONE_MTD,(FLTXT("Looking for G3/P3 MDOC Devices while assuming IF_CFG=%u.\r\n"),(FLWord)bIF_CFG));

      flash->win = (NDOC2window)physicalToPointer(*dwNextAddressPtr,dwWinSize,bSocketNo);

      /* set controller (ASIC) to NORMAL MODE        */
      M512_asicSetMode (flash,NORMAL_MODE) ;
      /* Read the CHIP_ID                            */
      wChipId        = M512_ReadChipID(flash);
      wChipIdConfirm = M512_ReadChipID_Confirm(flash) ;
      
      if  (((wChipId      != M512_CHIP_ID           ) ||
          (wChipIdConfirm != M512_CHIP_ID_COMPLEMENT) ||
          (M512_Read8BitReg(flash,M512_ALIAS_RESOLUTION_REG) == M512_ALIAS_RESOLUTION)) && 
          /*** Or MDOC256 chip i.d was found          ***/
          ((wChipId       != M256_CHIP_ID           ) ||
          (wChipIdConfirm != M256_CHIP_ID_COMPLEMENT) ||
          (M512_Read8BitReg(flash,M512_ALIAS_RESOLUTION_REG) == M512_ALIAS_RESOLUTION)) &&
          /*** Or MDOC_1G chip i.d was found          ***/
          ((wChipId       != M1G_CHIP_ID) ||
          (wChipIdConfirm != M1G_CHIP_ID) ||
          (M512_Read8BitReg(flash,M512_ALIAS_RESOLUTION_REG) == M512_ALIAS_RESOLUTION))) 
          continue;

#ifndef FL_NO_USE_FUNC
      /* Now that we found the controller use the correct if_cfg and interleave */
      if(M512_setBusType(flash,flBusConfig[bSocketNo],2,(FLByte)(M512_Find_IF_CFG(flash)))==FALSE)
      {
         M512_setBusType(flash,flBusConfig[bSocketNo],2,bIF_CFG);
         continue;
      }
#endif /* FL_NO_USE_FUNC */

      /* DiskOnChip found, mark alias resolution register */
      M512_Write8BitReg(flash,M512_ALIAS_RESOLUTION_REG,M512_ALIAS_RESOLUTION);

      dwLowAddress       = *dwNextAddressPtr ; /* save DiskOnChip address */
      *dwNextAddressPtr += dwWinSize;
      DBG_PRINT_WRN(FLZONE_MTD,"G3/P3 DiskOnChip was FOUND ");
      DBG_PRINT_WRN_PRM(FLZONE_MTD,(FLTXT("on address %lx.\r\n"),dwLowAddress));

      /*** DOC was found                                                  ***/
      *dwDOC_PhyAddress = ((unsigned)(dwLowAddress >> 12)) ;
      flash->mediaType = M512_G3_TYPE; /* Prevent identification of other devices */
   /* Remember the chip id until MTD_VARS will be initialized */
      flash->unitsInFirstFloor = wChipId;
      /*** Return flOK                                                    ***/
      return flOK ;
    }    
  }

  DBG_PRINT_FLOW(FLZONE_MTD,"Flow: docWindowBaseAddress Exit (NOT FOUND).\r\n");

  /* DiskOnChip  memory window not found  */
  *dwDOC_PhyAddress = 0 ; 
  return flAdapterNotFound ;
}

/************************************************************************ 
 *  flRegisterDOCM512SOC                                                * 
 *                                                                      * 
 * The routine searches for DOC and if found it updates the noOfSockets *   
 * global variable and the socket struct with baseaddress,size,...      *
 *                                                                      * 
 * Parameters:                                                          * 
 *      dwLowAddress : Low range of search                              * 
 *      dwHighAddress: High range of search                             *        
 *                                                                      * 
 * Returns:                                                             *  
 *    FLStatus    : 0 on success, otherwise failure                     *
 ************************************************************************/
FLStatus flRegisterDOCM512SOC(FLDword dwLowAddress, FLDword dwHighAddress)
{
  int serialNo;
  FLBoolean fResetAll = TRUE;
  FLStatus status ; 

  DBG_PRINT_FLOW(FLZONE_MTD,"Flow: flRegisterDOCOM512SOC Entered.\r\n");
  if( noOfSockets >= SOCKETS )
    return flTooManyComponents;

  /* Try to register DiskOnChip using */
  for(serialNo = 0 ; noOfSockets < SOCKETS ; serialNo++ , noOfSockets++)
  {
    /*** Step 1 : Get a pointer to the last socket                            ***/
    /***          noOfSockets - Is a global variable that holds the number of ***/
    /***          sockets found.                                              ***/
    FLSocket * socket = flSocketOf(noOfSockets);

    /*** Step 2 : Set the Socket volNo field                                  ***/
    /***          Set the socket volNo field to be the current noOfSockets    ***/
    socket->volNo = noOfSockets;

    /*** Step 3 : Set the Socket fields                                       ***/
    /***          Set the socket fields by calling to docSocketInit routine   ***/
    /***          Found in DOCSOC.C and initializes the socket fields which   ***/
    /***          are not relevant for the MTD                                ***/            
    docSocketInit(socket);

    /*** Step 4 : Set the Socket.window.baseAddress field                     ***/
    /***          Search for base address of DOC that was not found yet       ***/      
    /***          dwLowAddress recieves the next address to search            ***/ 
    status = M512_docWindowBaseAddress (noOfSockets,dwLowAddress,dwHighAddress,
                       &dwLowAddress,&socket->window.baseAddress,fResetAll) ;

    fResetAll = FALSE; /* Don't change to reset mode on the next itteration */

    /*** If (socket->window.baseAddress==0 => DOC was not found => return)            ***/
    /*** else repets STEP 1..5                                                        ***/    
    if (status)   /* DiskOnChip not detected */
      break;

    /*** Step 5 : Set the Socket.window.size & vol.window.base                        ***/
    /***          Set the socket field to be 8Kbyte                                   ***/
    flSetWindowSize(socket,M512_DocWindow(flFlashOf((FLByte)flSocketNoOf(socket)))>>12L);  /* The second argument is 4k units => 8K = 2*4 KBytes */

  }
  /*** In case that no DOC was found                                                      ***/
  if( serialNo == 0 )
    return flAdapterNotFound;
  DBG_PRINT_FLOW(FLZONE_MTD,"Flow: flRegisterDOCM512SOC Entered.\r\n");
  return flOK;
}

/************************************************************************
 ***************************** Init functions ***************************
 ************************************************************************/

/***********************************************************************
 * Name: M512_checkAndFixAccessError
 * Recover from protection/Sequence error of the current asic state
 * machine.
 *
 * Parameters:
 *      flashPtr     : Pointer identifying drive
 *
 * Note : In order to exit from protection/sequance error the routine
 *        forces the flash into reset mode.
 *        The routine would check that the error status is cleared
 *
 * Returns: 
 *    flOK             - No error accured
 *    flGeneralFailure - Failed clearing error 
 *    flSequanceError  - Sequance error was fixed
 *    flHWProtection   - Protetion error was fixed 
 ***********************************************************************/
static FLStatus M512_checkAndFixAccessError(FLFlash *flashPtr)
{ 
  FLStatus status ;
  FLByte bTemp ; 

  DBG_PRINT_FLOW(FLZONE_MTD,"Flow: checkAndFixAccessError Entered.\r\n");

  /*** Check if there really is a violation and remmember it ***/
  if (M512_IsProtectionError (flashPtr))  
  {
    DBG_PRINT_ERR(FLZONE_MTD,"M512_checkAndFixAccessError:Protection error occurred.\r\n");
    status = flHWProtection; 
  }
  else if (M512_IsSequenceError (flashPtr))  
  {
    DBG_PRINT_ERR(FLZONE_MTD,"M512_checkAndFixAccessError:Sequence error occurred.\r\n");
    status = flSequenceError;
  }
  else
    return flOK ; 
  bTemp = M512_Read8BitReg (flashPtr,M512_FLASH_CONTROL_REG) ;

  /*** Remove the WP                                         ***/
  bTemp &= ~(M512_FWP_SIGNAL_ACTIVE) ;

  /*** set FCE_SIGNAL_ACTIVE                                 ***/
  bTemp |= M512_FCE_SIGNAL_ACTIVE ;

  M512_Write8BitReg (flashPtr,M512_FLASH_CONTROL_REG,bTemp) ;

  /*** Clear either protection error or sequence error       ***/
  M512_reset_Seq (flashPtr) ;  

  /*** Check if protection error was removed => if not return error ***/
  if(M512_IsSequenceOrProtectionError(flashPtr))  
  {
    DBG_PRINT_ERR(FLZONE_MTD,"checkAndFixAccessError:Can't recover from protection / sequance violation.\r\n");
    return flGeneralFailure;
  }
  DBG_PRINT_FLOW(FLZONE_MTD,"Flow: checkAndFixAccessError Exit.\r\n");
  return status;
}


#ifndef FL_NO_USE_FUNC
/************************************************************************
 *  Name:M512_setBusType                                                                            *
 *                                                                      *
 * Check validity and set the proper memory access routines for MTD.    *
 *                                                                      *
 * Parameters:                                                          *
 *     volume               : Pointer identifying drive                 *
 *     dBusConfig           : Socket access discriptor                  *
 *     bInterleave          : Interleave factor (1,2)                   *
 *     bIF_CFG              : if_cfg state:                             *
 *                            8  - 8 bit                                *
 *                            16 - 16 bit                               *
 *                                                                      *
 * Returns:                                                             *
 *      TRUE if routines are available and fit the DiskOnChip           *
 *      configuration otherwise FALSE.                                  *
 *                                                                      *
 *      The variable pointer to busConfig is added TrueFFS private      *
 *      MTD descriptors.                                                *
 ************************************************************************/
static FLBoolean M512_setBusType(FLFlash *volume,FLDword dBusConfig,FLByte bInterleave,FLByte bIF_CFG)
{

  DBG_PRINT_FLOW(FLZONE_MTD,"Flow: setBusType Entered.\r\n");

  if (bIF_CFG==16) 
    dBusConfig |= FL_16BIT_DOC_ACCESS ;
  else if (bIF_CFG==8) 
    dBusConfig |= FL_8BIT_DOC_ACCESS ; 

⌨️ 快捷键说明

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