必威体育Betway必威体育官网
当前位置:首页 > IT技术

Qcom 8909 sbl1流程

时间:2019-08-07 14:12:08来源:IT技术作者:seo实验室小编阅读:77次「手机版」
 

SBL

最近踩的坑,记录一下,QFILE无法烧录程序,卡在烧录,后来发现是硬件的boot config配置问题

串口打印:

Format: Log Type - Time(microsec) - message - optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.BF.3.1.2.C2-00052
S - IMAGE_VARIANT_STRING=DAADANAZA
S - OEM_IMAGE_VERSION_STRING=titus-Gen9
S - Boot Config, 0x000000e1
B -      1567 - PBL, Start
B -      4546 - bootable_media_detect_entry, Start
B -  34490768 - bootable_media_detect_success, Start
B -  34490772 - elf_loader_entry, Start
B -  41428806 - auth_hash_seg_entry, Start
B -  41429054 - auth_hash_seg_exit, Start
B -  44022147 - elf_segs_hash_verify_entry, Start
B -  44090943 - PBL, End
B -  34835300 - SBL1, Start
B -  34881264 - boot_flash_init, Start
D -         0 - boot_flash_init, Delta
B -  34886540 - boot_config_data_table_init, Start
D -        30 - boot_config_data_table_init, Delta - (0 Bytes)
B -  34894592 - CDT version:3,Platform ID:8,Major ID:1,Minor ID:0,Subtype:0
B -  34900082 - zyk->
B -  34901394 - enter sbl1_hw_init---zyk
B -  34904291 - build_type:2
B -  34906304 - sbl1_ddr_set_params, Start
B -  34909415 - cpr_init, Start
D -         0 - cpr_init, Delta
B -  34913868 - Pre_DDR_clock_init, Start
D -       183 - Pre_DDR_clock_init, Delta
D -         0 - sbl1_ddr_set_params, Delta

sbl1与lk共同够成高通平台bootloader功能,现在主要记录一下高通平台sbl1启动的流程与相关烧录部分

sbl1_main_ctl

boot_config_process_bl-》boot_config_process_entry

从flash中下载代码到ram
 /*------------------------------------------------------------------
186    Image Loading and Authentication
187   ------------------------------------------------------------------*/
188   /* Reset boot statistics flash byte counter. */
189   boot_statistics_reset_flash_byte_counter();
190 
191   if (boot_config_entry->load == TRUE)

sbl1_config_table

load_qsee_pre_procs

boot_hand_control_to_deviceprogrammer_ddr_main

boot_deviceprogrammer_ddr_main

deviceprogrammer_entry

deviceprogrammer_init_hw

initFirehoseStorage

sdcc_handle_open

sdcc_handle_find_card

sdcc_find_mmc_device

sdcc_command

开始部分为sbl1.s

sbl1_entry

    ;Change to supervisor Mode
    msr     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit

    ; Save the passing parameter from PBL 将PBL中的数据传给sbl1,这里暂时存储在r7中
    mov     r7, r0

    ; Set VBAR (vector Base Address Register) to SBL vector table
    ldr     r0, =SCL_SBL1_VECTOR_BASE
    MCR     p15, 0, r0, c12, c0, 0

    ; Setup the supervisor mode stack
    ldr     r0, =|Image$$SBL1_SVC_STACK$$ZI$$limit|
    mov     r13, r0

    ; Switch to IRQ
    msr     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
    mov     r13, r0

    ; Switch to FIQ
    msr     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
    mov     r13, r0 

    ; Switch to undefined mode and setup the undefined mode stack
    msr     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
    ldr     r0, =|Image$$SBL1_UND_STACK$$ZI$$Limit|
    mov     r13, r0

    ; Switch to abort mode and setup the abort mode stack
    msr     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
    ldr     r0, =|Image$$SBL1_ABT_STACK$$ZI$$Limit|
    mov     r13, r0

    ; Return to supervisor mode
    msr     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit

    ; Restore the passing parameter 将pbl的数据传给r0一起作为函数参数给sbl1
    mov     r0, r7

    ; ------------------------------------------------------------------
    ; Call functions external to perform SBL1 function.
    ; It should never return.
    ; ------------------------------------------------------------------
    ldr    r5, =sbl1_main_ctl c语言的主要入口
    blx    r5

    ; For safety
    bl loophere  ; never returns, keep lr in r14 for debug


/*===========================================================================
**  Function :  sbl1_main_ctl
** ==========================================================================
*/
/*!
* 
* @brief
*   The  Main controller performs the following functions:
*       - Initializes ram
*       - And so on...
* 
* @param[in] pbl_shared Pointer to shared data
*  
* @par Dependencies
*   None
* 
* @retval
*   None
* 
* @par Side Effects
*   This function never returns.
* 
*/
void sbl1_main_ctl(boot_pbl_shared_data_type *pbl_shared)
{
  bl_ERROR_type status = BL_ERR_OTHERS;
  /* Calculate the SBL start time for use during boot logger initialization. */
  sbl_start_time = CALCULATE_TIMESTAMP(HWIO_IN(TIMETICK_CLK));

#ifdef SBL1_disable_D_cache
  mmu_flush_cache_and_disable();
  mmu_enable_instruction_cache();
#endif

  /* Enabling external abort */
  sbl1_external_abort_enable(CPSR_EA_BIT);

  /*configure Domain access control register */
  mmu_set_dacr(DACR_ALL_DOMAIN_CLIENTS);

  /* Enable qdss workaround*/
  boot_clock_debug_init();

  /* Enter debug mode if debug cookie is set */
  sbl1_debug_mode_enter();

  /* Initialize the stack protection canary */
  boot_init_stack_chk_canary();

  /* Initialize boot shared imem */
  boot_shared_imem_init(&bl_shared_data);

  /* Initialize busywait module
     Note: This is required to be done before logger init due to uart driver
     dependency on busywait */
  BL_VERIFY(boot_busywait_init() == DAL_SUCCESS,BL_ERR_SBL);

  /* Initialize boot logger and start the log timer */
  sbl1_boot_logger_init(&boot_log_data,
                        pbl_shared);
  boot_log_set_meta_info(boot_log_data.meta_info_start);

  /* Retrieve info passed from PBL*/
  sbl1_retrieve_shared_info_from_pbl(pbl_shared);

  /* Initialize the QSEE interface */
  sbl1_init_sbl_qsee_interface(&bl_shared_data,
                               &sbl_verified_info);

  /* Initialize SBL memory map.
     Initializing early because drivers could be located in RPM Code RAM. */
  sbl1_populate_initial_mem_map(&bl_shared_data);

  /* Initialize the secboot functions */
  BL_VERIFY(boot_secboot_ftbl_init(&bl_shared_data) == BL_ERR_NONE,
            BL_ERR_IMG_SECURITY_FAIL);

  /* set hash algorithm */
  BL_VERIFY((status = boot_set_hash_algo(SBL_HASH_SHA256)) == BL_ERR_NONE,
            status);

  /* Initialize dal heap using internal memory */
  boot_DALSYS_HeapInit(boot_internal_heap,
                       BOOT_INTERNAL_HEAP_SIZE,
                       FALSE);

  /*Initialize DAL, needs to be called before modules that uses DAL */  
  boot_DALSYS_InitMod(NULL); 

  /* Store the sbl1 hash to shared imem */
  boot_store_tpm_hash_block(&bl_shared_data,
                            &sbl_verified_info);

   /* Initialize roll back protection image table */
  boot_rollback_init_img_set_table(&bl_shared_data,
                                   &boot_rollback_version_img_set_table[0],
                                   boot_rollback_version_img_set_num);

#if (!defined(FEATURE_RUMI_BOOT))
  /* calling here to ensure eeprom init goes fine for CDT read */
   boot_pre_i2c_clock_init();
#endif 

  /* Check L2 error flag, if it has been set then set dload cookie and reboot */
  if(L2_parity_error_in_sbl)
  {
    boot_dload_set_cookie();
    boot_hw_reset(BOOT_WARM_RESET_TYPE);
  }


  /*-----------------------------------------------------------------------
   Add the SBL1, System Debug, SMEM, and OCIMEM address ranges
   to the memory protection. 
  -----------------------------------------------------------------------*/
  boot_clobber_add_global_protection_region((void *)SBL1_CODE_BASE,
                                            SBL1_MAX_IMAGE_SIZE );

  boot_clobber_add_global_protection_region((void *)SCL_SBL1_DDR_DATA_BASE,
                                            SCL_SBL1_DDR_DATA_SIZE);

  boot_clobber_add_global_protection_region((void *)SCL_SYSTEM_DEBUG_BASE,
                                            SCL_SYSTEM_DEBUG_SIZE);

  boot_clobber_add_global_protection_region((void *)SCL_SHARED_RAM_BASE,
                                            SCL_SHARED_RAM_SIZE);

  boot_clobber_add_global_protection_region((void *)SCL_IMEM_BASE,
                                            SCL_IMEM_SIZE);

  /*----------------------------------------------------------------------
   In SBL builds the function below is stubbed out (does nothing).
   When building Deviceprogrammer the function below never returns.
   The function below becomes active by defining the feature
   FEATURE_BOOT_EXTERN_DEVICEPROGRAMMER_LITE_COMPLETED.
  ----------------------------------------------------------------------*/
  boot_hand_control_to_deviceprogrammer_lite_main (pbl_shared);

  /*-----------------------------------------------------------------------
    Process the target-dependent SBL1 procedures
  -----------------------------------------------------------------------*/
  boot_config_process_bl(&bl_shared_data,
                         SBL1_IMG,
                         sbl1_config_table);

} /* sbl1_main_ctl() */
559 /*==========================================================================
560                       DEFINE TARGET BOOT CONFIG TABLE
561 ===========================================================================*/
562 boot_configuration_table_entry sbl1_config_table[] =
563 {
564 
565  /* SBL1 -> QSEE */
566   {
567     SBL1_IMG,                   /* host_img_id */
568     CONFIG_IMG_QC,              /* host_img_type */
569     GEN_IMG,                    /* target_img_id */
570     CONFIG_IMG_ELF,             /* target_img_type */
571     SECBOOT_QSEE_SW_TYPE,       /* target_img_sec_type */
572     TRUE,                       /* load */
573     TRUE,                       /* auth */
574     FALSE,                      /* exec */
575     FALSE,                      /* jump */
576     NULL,                       /* exec_func */
577     NULL,                       /* jump_func */
578     load_qsee_pre_procs,        /* pre_procs */
579     load_qsee_post_procs,       /* post_procs */
580     NULL,                       /* load_cancel */
581     qsee_partition_name,        /* target_img_partition_id */
582     QSEE_BOOT_LOG_STR,          /* target_img_str */
583     sbl1_table,                       /* whitelist table */
584     FALSE,                      /* boot_ssa_enabled */
585     TRUE,                       /* enable_rollback_protection*/
586     FALSE,                      /* enable_xpu */
587     0x0                         /* xpu_proc_id*/
588   },
589 
590   /* SBL1 -> RPM */
591   {
592     SBL1_IMG,                   /* host_img_id */
593     CONFIG_IMG_QC,              /* host_img_type */
594     GEN_IMG,                    /* target_img_id */
595     CONFIG_IMG_ELF,             /* target_img_type */
596     SECBOOT_RPM_FW_SW_TYPE,     /* target_img_sec_type */
597     TRUE,                       /* load */
598     TRUE,                       /* auth */
599     FALSE,                      /* exec */
245 /*==========================================================================
246                   FUNCTIONS TO EXECUTE BEFORE TZ LOADING
247 ===========================================================================*/
248 boot_procedure_func_type load_qsee_pre_procs[] =
249 {   
250   /* Save reset register logs */
251   boot_save_reset_register_log, 
252     
253   /*----------------------------------------------------------------------
254    Update the partition IDs to be used for GUID based boot targets
255   ----------------------------------------------------------------------*/
256   sbl1_update_partition_ids,    
257     
258 #ifdef FEATURE_BOOT_SDCC_BOOT   
259   /* Initialize the flash device */
260   boot_flash_init,
261 #endif  
262   /* Copy the configure data table from eeprom */
263   boot_config_data_table_init,  
264     
265   /* Store platform id */             
266   sbl1_hw_platform_pre_ddr,     
267     
268   (boot_procedure_func_type)sbl1_hw_init, 
269     
270   /* Configure ddr parameters based on eeprom CDT table data. */
271   sbl1_ddr_set_params,
272   
273   /* Initialize DDR */
274   (boot_procedure_func_type)sbl1_ddr_init,
275     
276   /*----------------------------------------------------------------------
277    In SBL builds the function below is stubbed out (does nothing).
278    When building Deviceprogrammer the function below never returns.
279    The function below becomes active by defining the feature
280    FEATURE_BOOT_EXTERN_DEVICEPROGRAMMER_DDR_COMPLETED.
281   ----------------------------------------------------------------------*/
282   boot_hand_control_to_deviceprogrammer_ddr_main,
283 
284   /*Set ddr parameters in CDB2&CDB3, enhance set*/
285   sbl1_ddr_set_params_enhance,
286 
287   /* Initialize SBL1 DDR ZI region, relocate boot log to DDR */
288   sbl1_post_ddr_init,
289 
290   sbl1_hw_init_secondary,
291 
292   /* DDR training */
293   (boot_procedure_func_type)sbl1_wait_for_ddr_training,
294 
 40 /*===========================================================================
 41                       FUNCTION DECLARATIONS
 42 ===========================================================================*/
 43 
 44 /*===========================================================================
 45 
 46 **  Function :  boot_deviceprogrammer_ddr_main
 47   
 48 ** ==========================================================================
 49 */
 50 /*!
 51  * Run deviceprogrammer after ddr has been initialized.
 52  *
 53  * @param bl_shared_data
 54  *    The shared bootloader information.
 55  *
 56  * @return
 57  *    This function never returns.
 58  *
 59 *****************************************************************************/
 60 void boot_hand_control_to_deviceprogrammer_ddr_main
 61 (
 62   bl_shared_data_type *bl_shared_data
 63 )
 64 {
 65   deviceprogrammer_entry(bl_shared_data->sbl_shared_data->pbl_shared_data);
 66   for (;;);
 67 }
128 // The entry point from SBL.
129 void deviceprogrammer_entry(boot_pbl_shared_data_type *pbl_shared)
130 {
131     pbl_shared_global = pbl_shared;
132 
133     deviceprogrammer_zi_buffers ();
134     deviceprogrammer_init_hw();
135     main_firehose();
136 }
 70 void deviceprogrammer_init_hw() {
 71     char err_log[256] = {0};
 72          printLog("%s %d----zyk",__FUNCTION__,__LINE__);
 73         printLog("deviceprogrammer_init_hw");
 74     initFirehoseProtocol(); // initializes default values for fh structure
 75 
 76 #ifndef FEATURE_FIREHOSE_SKIP_CLOCK
 77 #ifndef FEATURE_BOOT_EXTERN_DEVICEPROGRAMMER_DDR_COMPLETED
 78     // This needs to be called before calling Clock_Init()         
 79     if (TRUE != Clock_PreDDRInitEx(DDR_TYPE_LPDDR2))                     { strlcat(err_log, "clock pre ddr:fail ", sizeof(err_log)); }
 80 #endif
 81     
 82     // Lowering clock frequencies because otherwise eMMC card initialization sometimes fails
 83     // if the clock '' is set too high
 84     if (FALSE == Clock_Init(CLOCK_BOOT_PERF_MIN, CLOCK_BOOT_PERF_MIN)) { strlcat(err_log, "init clock:fail ", sizeof(err_log)); }
 85 #endif
 86     
 87     // Call setlocale to set the locale to the default values
 88     // for string functions such as strncasecmp to work properly
 89     setlocale(LC_ALL, "C");
 90     
 91     if(PM_ERR_FLAG__SUCCESS != pm_pon_channel_config())            { strlcat(err_log, "init pmic:fail ", sizeof(err_log)); }
 92          printLog("%s %d----zyk",__FUNCTION__,__LINE__);
 93 
 94     // Initialize eMMC storage device, open up handles
 95     if (FALSE == initFirehoseStorage())                                { strlcat(err_log, "init storage:fail ", sizeof(err_log));        printLog("%s %d---initFirehoseStorage fail-zyk
    ",__FUNCTION__,__LINE__);}
 96     
 97 #ifndef FEATURE_FIREHOSE_SKIP_CLOCK
 98     // This calls the Clock API to bump up clocks.
 99     // Before doing this, we need support for it in the Clock SCons
100     // env.AddLibsToImage(['CLOCK_BOOT_DRIVER', 'EMMCBLD_IMAGE'],
101     // ClockChipsetSBL_lib)
102     // in file core\systemdrivers\clock\hw\msm8974\build\clock_sbl.scons
103     if (FALSE == Clock_Init(CLOCK_BOOT_PERF_MAX, CLOCK_BOOT_PERF_MAX)) { strlcat(err_log, "init clock:fail ", sizeof(err_log)); }
104 #endif
105 
106 #ifndef SKIP_SECBOOT_CHECK_NOT_recommended_BY_QUALCOMM 
107     // This check below is to ensure that only VIP programmer is run on secure boot devices
108     // In otherwords, signing the non VIP programmer is highly not recommended
109     if (FALSE == isvalidationMode() && TRUE == isAuthenticationEnabled()) { strlcat(err_log, "Secure boot detected. VIP not enabled:fail ", sizeof(err_log)); }
110 #endif      
111         
112     // These PMIC calls were added to have long key power off to be
113     // working from flash programmer so that device can be powered off in
114     // factory for devices that do not have removable BATtery
115     pm_pon_reset_source_cfg(0,PM_PON_RESET_SOURCE_KPDPWR,904,500,
116     PM_PON_RESET_CFG_NORMAL_SHUTDOWN);
117     pm_pon_reset_source_ctl(0, PM_PON_RESET_SOURCE_KPDPWR,PM_ON);
118     
119     initFirehoseTransport();    // Initialize USB transport
120     if (strlen(err_log) > 0) {
121         while (1) {
 246 boolean initFirehoseStorage() {
 247          printLog("%s %d----zyk",__FUNCTION__,__LINE__);              
 248  printLog("initFirehoseStorage");
 249     return init_storage_device_hw(&(fh.emmc_storage));
 250 }
 73 boolean init_storage_device_hw(storage_device_t *storedev) {
 74     SDCC_STATUS rc;
 75     int i;
 76     sdcc_mem_info_type mem_info;
 77 
 78     for (i = PARTITION_EMMC_USER; i < PARTITION_EMMC_NONE; i++) {
 79         if (i != PARTITION_EMMC_RPMB) {
 80             //FREEZE_watchdog();
 81                         printLog("init_storage_device_hw 1");
 82                          printLog("%s %d----zyk",__FUNCTION__,__LINE__);
 83 
 84             storedev->hsdev_partition_handles[i] = sdcc_handle_open (
 85                                                        storedev->drivenum,
 86                                                        i);
 87             if (i == PARTITION_EMMC_USER) {
 88                 if (storedev->hsdev_partition_handles[i] == NULL) {
 89                                                 printLog("init_storage_device_hw 2");
 90                          printLog("%s %d----zyk",__FUNCTION__,__LINE__);
 91                     storedev->hsdev_partition_handles[i] = sdcc_handle_open (
 92                                                                 storedev->drivenum,
 93                                                                 i);
 94                     if (storedev->hsdev_partition_handles[i] == NULL)
 95                         return false;
 96                 }
 97 
 98                 rc = sdcc_handle_mem_get_device_info(storedev->hsdev_partition_handles[i], &mem_info);
 99                 if (rc != SDCC_NO_ERROR)
100                     return FALSE;
101                 if (mem_info.card_size_in_sectors > 0)
102                     storedev->sector_size = mem_info.block_len;
103             }
104 
105         }
106     }
107 
108     //FREEZE_WATCHDOG();
109     // TODO: Can we ignore the return value of this call ?
110     rc = sdcc_handle_set_active_bootable_partition(
111             storedev->hsdev_partition_handles[PARTITION_EMMC_USER]);
112     if (rc != SDCC_NO_ERROR) {
113 
114     }
115     return TRUE;
116 }

core/storage/sdcc/src/sdcc_Mini_api.c

/*lint -save -e641 Suppress 'Converting enum to int' warning */
/******************************************************************************
* Name: sdcc_handle_open
*
* Description:
*    This function first initializes the SDCC controller such as turning on the
*    clock, configuring the GPiOS, and turning on the power supply to the
*    device.  It returns NULL if there is no memory device attached.  If there
*    is a memory device, it will initialize the device and take it out of the
*    identification state.  It then sets up the device for data transfer.
*    A non-null pointer to the SDCC device is returned.
*
* arguments:
*    driveno           [IN] : a valid drive number between 0 and the total
*                            number of card slots - 1
*    phy_partition_num [IN] : physical partition number.  Use
*                             \ref SDCC_HANDLE_PHY_PARTITION_ENTIRE_MEM_DEVICE
*                             to get a handle representing the entire memory
*                             device.  For eMMC v4.3, the valid boot partition
*                             numbers are 1 and 2.  User area partition number
*                             is 0.
*
* Returns:
*    A pointer to the SDCC device if successful.  NULL if failed.
*
* Note:
*    sdcc_init() is called in sdcc_handle_open().
*
******************************************************************************/
struct sdcc_device *
sdcc_handle_open( int16 driveno, uint32 phy_partition_num )
{
   SDCC_STATUS         rc         = SDCC_NO_ERROR;
   sdcc_slot_type     *sdcc_pdata = NULL;
   sdcc_dev_type      *sdcc_pdev  = NULL;
   boolean             ret        = TRUE;
   struct sdcc_device *ret_handle = NULL;
   boolean             still_in_use = TRUE;


    printLog("enter---k min api sdcc_handle_open");
   if ( !SDCC_DRIVENO_IS_VALID(driveno) )
   {
      DPRINTF(("Invalid Drive Number: %d", driveno));
      return NULL;
   }

   /* PBL uses legacy Qualcomm mode, so partial enumeration is supported in */
   /* Qualcomm legacy mode only. However, if we switch to SDHCi mode now, */
   /* we need to do a full re-init */
   if ((FALSE == SDCCSdhciEnable) && 
       (TRUE == sdcc_is_partial_enumeration (driveno)))
   {
      ret_handle = sdcc_handle_optimized_open (phy_partition_num);
      return ret_handle;
   }

   /* This is the only place we get config flag from a UEFI variable 
    * to determine if the driver supports SDHCi or Qualcomm interface.
    * After this, we'll use the p_device->sdhci_mode as flag */
   if (TRUE == SDCCSdhciEnable)
   {
      ret = sdcc_init_sdhci_mode(driveno);
   }
   else
   {
      ret = sdcc_init_qc_mode(driveno); 
   }

   if ( FALSE == ret )
   {
      DPRINTF(("Failed to initialize drive number %d", driveno));
      return NULL;
   }

   sdcc_pdata = sdcc_get_slot_handle (driveno);
   if (NULL == sdcc_pdata)
   {  
      DPRINTF(("sdcc_handle_open: can't get slot handle\n"));
      return NULL;
   }

   sdcc_pdev = &(sdcc_pdata->dev);

   do
   {
      /* register the client handle first */
      ret_handle = sdcc_register_client_handle( (uint32)driveno,
                                                phy_partition_num );
      if ( NULL == ret_handle )
      {
         /* check if memory device in driveno is still in use */
         still_in_use = sdcc_is_device_still_in_use( sdcc_pdev );
         if ( !still_in_use )
         {
            /* client handle list is full */
            (void) sdcc_deinit( sdcc_pdev );
         }
         break;
      }

      /* return if this is a SDIO device */
      if ( SDCC_CARD_SDIO == sdcc_pdev->card_type )
      {
         /* client handle registration will be initiated in SDIO API */
         /* deregister the client handle */
         sdcc_deregister_client_handle( &ret_handle );
         break;
      }

      /* return if it has been initialized */
      if (( SDCC_CARD_SD  == sdcc_pdev->card_type ) ||
          ( SDCC_CARD_SDHC == sdcc_pdev->card_type ) ||
          ( SDCC_CARD_MMC == sdcc_pdev->card_type ) ||
          ( SDCC_CARD_MMCHC == sdcc_pdev->card_type ))
      {
         /* no need to select the partition region on the device as it is */
         /* already in use */
         /* will return a new handle to client */
         break;
      }
     printLog("194 zyk min api sdcc_handle_open");
      /* find the attached device */
      sdcc_pdev->card_type = sdcc_handle_find_card( ret_handle );
      /* update card_type field in sdcc_mem_info struct */
      sdcc_pdev->mem.mem_info.card_type = sdcc_pdev->card_type;

      /* return and close controller if none attached */
      if ( SDCC_CARD_UNKNOWN == sdcc_pdev->card_type )
      {
         (void) sdcc_handle_close(ret_handle);
         ret_handle = NULL;
         break;
      }

      /* return if SDIO device attached */
      if ( SDCC_CARD_SDIO == sdcc_pdev->card_type )
      {
         /* client handle registration will be initiated in SDIO API */
         /* deregister the client handle */
         sdcc_deregister_client_handle( &ret_handle );
         DPRINTF(("Found SDIO device.\n"));
         break;
      }

      /* proceed if this is SD/MMC device */
      /* finish identification mode */
      rc = sdcc_init_memory_device(sdcc_pdev);
      if (SDCC_NO_ERROR != rc)
      {
         DPRINTF(("Failed to initialize the card.\n"));
         sdcc_pdev->errno = rc;

         (void) sdcc_handle_close(ret_handle);
         ret_handle = NULL;
         break;
      }

      if (FALSE == sdcc_pdev->sdhci_mode)
      {
         HAL_sdcc_flowcontrol (driveno, TRUE);
      }

      /* get memory device info  */
      rc = sdcc_get_memory_info(sdcc_pdev);
      if (SDCC_NO_ERROR != rc)
      {
         DPRINTF(("Failed to get memory card info.\n"));
         sdcc_pdev->errno = rc;

         (void) sdcc_handle_close(ret_handle);
         ret_handle = NULL;
         break;
      }

      /* re-program the clock for data transfer */
      sdcc_config_clk(sdcc_pdev, SDCC_DATA_TRANSFER_MODE);

      /* config device for data transfer */
      rc = sdcc_config_memory_device(sdcc_pdev);
      if (SDCC_NO_ERROR == rc)
      {
         sdcc_pdev->host_state = SDCC_HOST_TRAN;
         // set to true if card is removed / reinserted
         sdcc_pdata->slot_state_changed = FALSE;
      }
      else
      {
         sdcc_pdev->errno     = rc;
         sdcc_pdev->card_type = SDCC_CARD_UNKNOWN;
         (void) sdcc_handle_close(ret_handle);
         ret_handle = NULL;
      }
   }
   while (0);

   return ret_handle;
}
/******************************************************************************
* Name: sdcc_handle_find_card
*
* Description: 
*    This function finds out the card type specified in handle parameter. 
*
* Arguments:
*    handle [IN] : a pointer to the SDCC device that was returned from
*                  sdcc_handle_open()
*
* Returns:
*    card type that indicates if device is SD, MMC, SDIO, or unknown
*
******************************************************************************/
SDCC_CARD_TYPE sdcc_handle_find_card( struct sdcc_device *handle )
{
   SDCC_CARD_TYPE card_type = SDCC_CARD_UNKNOWN;
   uint32 driveno = 0;

   printLog("sdcc_handle_find_card --zyk");
   driveno = SDCC_HANDLE_GET_DRIVENO( handle );
   if (!SDCC_DRIVENO_IS_VALID( driveno ))
   {
      DPRINTF(("Invalid Drive Number:%d", driveno));
      return SDCC_CARD_UNKNOWN;
   }
printLog("sdcc_handle_find_card --zyk 167");
   /* set the power mode to 'power on' */
   HAL_sdcc_SetPowerState( driveno, HAL_SDCC_POWER_ON );

   if (FALSE == handle->hdev->sdhci_mode)  
   {
     /* enable the clock */
     HAL_sdcc_BusClockEnable( driveno, TRUE );
     /* disable powersave on bus clock while supply voltage ramps up */
     HAL_sdcc_PowerSave( driveno, FALSE );
     sdcc_osal_sleep( SDCC_SUPPLY_RAMP_UP_TIME_MS );
     HAL_sdcc_PowerSave( driveno, TRUE );

     /* Enable Feedback Clock */      
     sdcc_osal_sleep( SDCC_SUPPLY_RAMP_UP_TIME_MS );
     HAL_sdcc_SetClockEdge( driveno, HAL_SDCC_CLOCK_EDGE_FEEDBACK );
   }
   else
   {
     HAL_sdhci_PowerSave( driveno, FALSE);
     sdcc_osal_sleep( SDCC_SUPPLY_RAMP_UP_TIME_MS );
     HAL_sdhci_PowerSave( driveno, TRUE);
   }

   /* lower the clock to < 400KHz for card identification */
   sdcc_config_clk( handle->hdev, SDCC_IDENTIFICATION_MODE );
   /* look for memory card */
printLog("sdcc_handle_find_card --zyk 194");

   if (sdcc_bsp_get_slot_type(driveno) & SDCC_BSP_EMBEDDED_MEM_SLOT)
   {
      /* look for MMC device */
      card_type = sdcc_find_mmc_device( handle );
   }
   else
   {
      /* look for SD device */
      card_type = sdcc_find_sd_device( handle );
   }
printLog("sdcc_handle_find_card --zyk %d",card_type);
   return card_type;
}
/******************************************************************************
* Name: sdcc_find_mmc_device
*
* Description: 
*    This function looks for the MMC device of the specified driveno.
*
* Parameters:
*    handle [IN] : a pointer to the SDCC device 
* 
* Returns:
*    card type that indicates if device is MMC or unknown
*
******************************************************************************/
SDCC_CARD_TYPE
sdcc_find_mmc_device ( struct sdcc_device *handle )
{
   SDCC_CARD_TYPE card_type = SDCC_CARD_UNKNOWN;
   sdcc_dev_type *sdcc_pdev = handle->hdev;
   SDCC_STATUS rc = SDCC_ERR_UNKNOWN;
   sdcc_cmd_type sdcc_cmd;
   uint32 i;
   printLog("sdcc_find_mmc_device --zyk");
   /* CMD0: reset card first */
   sdcc_cmd.cmd       = SD_CMD0_GO_IDLE_STATE;
   sdcc_cmd.cmd_arg   = SDCC_CMD_ARGU_NULL;
   sdcc_cmd.resp_type = SDCC_RESP_NONE;
   sdcc_cmd.prog_scan = 0;
   sdcc_cmd.flags     = SDCC_TRANSFER_FLAG_IS_CMD_ONLY;

   (void) sdcc_command (sdcc_pdev, &sdcc_cmd);

   /* continue on to look for MMC card */
   for ( i = 0; i < SDCC_MMC_DETECT_MAX_RETRIES; i++ )
   {
      /* CMD1: sent voltage to be used */
      sdcc_cmd.cmd       = SD_CMD1_SEND_OP_COND;
      sdcc_cmd.cmd_arg   = SDCC_MMC_HCS_NEGOTIATE_OCR;
      sdcc_cmd.resp_type = SDCC_RESP_SHORT;
      sdcc_cmd.prog_scan = 0;
      sdcc_cmd.flags     = SDCC_TRANSFER_FLAG_IS_CMD_ONLY;

      rc = sdcc_command( sdcc_pdev, &sdcc_cmd );

      if ( SDCC_NO_ERROR != rc )
      {
         /* exit the for-loop for MMC card detection if there is issue in */
         /* sending the command to the card */
         break;
      }
      else if ( sdcc_cmd.resp[0] & SDCC_DEVICE_RDY )
      {
         /* access mode validation: */
         /* byte access mode represents <= 2GB card size */
         /* sector access mode represents > 2GB card size, however */
         /* this needs to be reconfirmed by reading SEC_COUNT */
         /* in EXT_CSD */
         /* >2GB: [30:29] = 1,0 */
         if ( ((sdcc_cmd.resp[0] >> 30) & 1) &&
               !((sdcc_cmd.resp[0] >> 29) & 1) )
         {
            card_type = SDCC_CARD_MMCHC;
            DPRINTF(("Found MMCHC card after %dth retry\n", i));
         }
         else
         {
            card_type = SDCC_CARD_MMC;
            DPRINTF(("Found MMC card after %dth retry\n", i));
         }
         return card_type;
      }

      sdcc_osal_sleep( SDCC_MMC_DETECT_BUSY_RETRY_Interval );
   }

   return card_type;
}
/******************************************************************************
* Name: sdcc_command
*
* Description:
*    This is a wrAPPer function for sending the command and poll 
*    the status. It decides whether to use the Qualcomm or standard 
*    Host Controller interface to communicate with the memory device.
*
* Arguments:
*    sdcc_pdev         [IN] : pointer to device type 
*    sdcc_cmd          [IN] : pointer to command data structure
*
* Returns:
*    Returns error code
*
******************************************************************************/
SDCC_STATUS
sdcc_command(sdcc_dev_type *sdcc_pdev, sdcc_cmd_type *sdcc_cmd)
{

     printLog("sdcc_command _entry cmd:%d",(uint32)sdcc_cmd->cmd); 
   if ((NULL == sdcc_pdev) || (NULL == sdcc_cmd))
   {
      //printLog("SDCC_ERR_INVALID_PARAM return"); 
      return SDCC_ERR_INVALID_PARAM;
   }

   if (TRUE == sdcc_pdev->sdhci_mode)
   {
       printLog("eMMC cmd sdhci_mode"); 
      return sdcc_command_sdhci_mode(sdcc_pdev, sdcc_cmd);
   }
   else
   {
       printLog("eMMC cmd qc_mode"); 
      return sdcc_command_qc_mode(sdcc_pdev, sdcc_cmd);
   }
}

相关阅读

淘宝天天特卖特价王活动报名流程!

现在我们要知道我们的店铺参加活动不容易,所以我们在参加一个活动之前一定要做好万全的准备,其中包括对活动流程的安排,一起来看一下

iOS 299美元企业账号申请流程及注意事项

iOS开发者众多,但并不是所有的开发者都对账号申请,证书配置这些问题都清楚,毕竟不是所有开发者都能够经历这个环节,多数情况下是进公

关于银行授信,了解流程/额度/审批

笔者之前讲了很多金融知识以及金融软件产品的设计要点,今天接着来聊一聊“银行授信”,笔者将通过银行授信流程的剖析、额度申请、审

实用流程图模板分享

流程图的制作可以套用模板,这样对框架结构的搭建就节约了很多时间,那在今天小编要给大家分享最新绘制的流程图模板,希望大家喜欢。

淘宝潮电街是什么?入驻流程有哪些?

潮电街,可能有不少商家对此都是比较不熟悉的。其简单来说,就是一个主要销售智能类商品的网上商城,现阶段的淘宝的新的核心市场。那么

分享到:

栏目导航

推荐阅读

热门阅读