todo高通Android UEFI中的LCD分析(1):启动流程分析

# 高通Android UEFI中的LCD分析(1):启动流程

背景

之前学习的lk阶段点亮LCD的流程算是比较经典,但是高通已经推出了很多种基于UEFI方案的启动架构。

所以需要对这块比较新的技术进行学习。

同事遇到了一个UEFI阶段LCD显示异常,而kernel正常的问题;但我解决不了。

分析

在高通UEFI架构中,通过Protocol来调用对应的功能。因此实际上的函数调用并不是显式的,而是包裹在Protocol中进行。

高通UEFI显示有关的文件有:

BOOT.XF.4.1/boot_images/QcomPkg/Drivers/DisplayDxe/DisplayDxe.c
BOOT.XF.4.1/boot_images/QcomPkg/Application/QcomChargerApp/QcomChargerAppDisplay.c
BOOT.XF.4.1/boot_images/QcomPkg/Application/QcomChargerApp/QcomChargerAppDisplay.h
BOOT.XF.4.1/boot_images/QcomPkg/Drivers/DisplayDxe/DisplayDxe.c
BOOT.XF.4.1/boot_images/QcomPkg/Drivers/DisplayDxe/DisplayDxe.h
BOOT.XF.4.1/boot_images/QcomPkg/Drivers/DisplayDxe/DisplayDxe.inf
BOOT.XF.4.1/boot_images/QcomPkg/Drivers/DisplayDxe/DisplayPwrCtrlProtocol.c
BOOT.XF.4.1/boot_images/QcomPkg/Drivers/DisplayDxe/DisplayPwrProtocol.c
    
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/BootDisplay.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/DisplayLib.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/DisplayUtils.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/ExternalDisplayDriver.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayPwr.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayPwrCtrl.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayUtils.h
    
BOOT.XF.4.1/boot_images/QcomPkg/Library/BootDisplayLib/BootDisplay.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/BootDisplayLib/BootDisplayLib.inf
BOOT.XF.4.1/boot_images/QcomPkg/Library/DisplayLib/DisplayLib.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/DisplayLib/DisplayLib.inf
BOOT.XF.4.1/boot_images/QcomPkg/Library/ExternalDisplayLib/ExtDisplay_driver.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/ExternalDisplayLib/ExternalDisplayLib.dec
BOOT.XF.4.1/boot_images/QcomPkg/Library/ExternalDisplayLib/ExternalDisplayLib.inf
BOOT.XF.4.1/boot_images/QcomPkg/Library/ExternalDisplayLib/ExternalDisplayLibStub.inf

BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/HALMDPLib.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/MDPLib.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/MDPPeripherals.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/MDPPlatformLib.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/MDPSystem.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Library/MDPTypes.h
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/DisplayUtils.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPClocks.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPClocksBoot.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPConfig.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPEDID.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPLib.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPLib.inf
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPLibBoot.inf
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPLib_i.h
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPPanel.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPPeripherals.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPSystem.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPSystemBoot.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/MDPVersion.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/NullLibs/MDPPlatformLibNull/MDPPlatformLibNull.c
BOOT.XF.4.1/boot_images/QcomPkg/Library/NullLibs/MDPPlatformLibNull/MDPPlatformLibNull.inf
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/AgattiPkg/Library/MDPPlatformLib/MDPPlatformLib.c
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/AgattiPkg/Library/MDPPlatformLib/MDPPlatformLib.inf
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/AgattiPkg/Library/MDPPlatformLib/MDPPlatformLibPanelCommon.c
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/AgattiPkg/Library/MDPPlatformLib/MDPPlatformLibPanelCommon.h
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/AgattiPkg/Library/MDPPlatformLib/MDPPlatformLibPanelConfig.h
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/AgattiPkg/Library/MDPPlatformLibBoot/MDPPlatformLib.c
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/AgattiPkg/Library/MDPPlatformLibBoot/MDPPlatformLibBoot.inf
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/KamortaPkg/Library/MDPPlatformLib/MDPPlatformLib.c
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/KamortaPkg/Library/MDPPlatformLib/MDPPlatformLib.inf
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/KamortaPkg/Library/MDPPlatformLib/MDPPlatformLibPanelCommon.c
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/KamortaPkg/Library/MDPPlatformLib/MDPPlatformLibPanelCommon.h
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/KamortaPkg/Library/MDPPlatformLib/MDPPlatformLibPanelConfig.h
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/KamortaPkg/Library/MDPPlatformLibBoot/MDPPlatformLib.c
BOOT.XF.4.1/boot_images/QcomPkg/SocPkg/KamortaPkg/Library/MDPPlatformLibBoot/MDPPlatformLibBoot.inf

对外的Protocol

有关文件:

BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayPwr.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayPwrCtrl.h
BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayUtils.h

Protocol接口

学习UEFI,比较关键的是:

0、了解UEFI是如何实现的

1、了解XXX_PROTOCOL定义中有什么接口可以使用:方便我们找到实现的原型

2、找到对应的XXX_PROTOCOL_GUID是多少:方便我们找到哪里调用了对应的接口

EFIDisplayPwr.h

路径:BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayPwr.h

声明了对应的EFI_DISPLAY_POWER_PROTOCOL_GUID,但没有调用。

/*  Protocol GUID definition */
/** @ingroup efi_displayPwr_protocol */
#define EFI_DISPLAY_POWER_PROTOCOL_GUID  \
    {0xf352021d, 0x9593, 0x4432, {0xbf, 0x4, 0x67, 0xb9, 0xf3, 0xb7, 0x60, 0x8}}

/*===========================================================================
  PROTOCOL INTERFACE
===========================================================================*/
/** @ingroup efi_displayUtils_protocol
  @par Summary
  Qualcomm Display Utils Protocol interface.

  @par Parameters
  @inputprotoparams{} 
*/
struct _EFI_QCOM_DISPLAY_UTILS_PROTOCOL
{
  UINT64                                           Revision;
  EFI_DISPLAY_UTILS_SET_PROPERTY                   DisplayUtilsSetProperty; 
  EFI_DISPLAY_UTILS_GET_PROPERTY                   DisplayUtilsGetProperty;
  EFI_DISPLAY_UTILS_RENDER_LOGO                    DisplayUtilsRenderLogo;
  EFI_DISPLAY_UTILS_SET_MODE                       DisplayUtilsSetMode;
  EFI_DISPLAY_UTILS_SET_VARIABLE                   DisplayUtilsSetVariable;
  EFI_DISPLAY_UTILS_GET_VARIABLE                   DisplayUtilsGetVariable;
};
EFIDisplayPwrCtrl.h

路径:BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayPwrCtrl.h

这里的接口并没有被AP侧调用,甚至都没有声明。

/*  Protocol GUID definition */
/** @ingroup efi_displayPwrCtrl_protocol */
#define EFI_DISPLAYPWRCTRL_PROTOCOL_GUID \
    {0x7bfa4293, 0x7aa4, 0x4375, {0xb6, 0x3c, 0xb6, 0xaa, 0xb7, 0x86, 0xc4, 0x3c}}

// {68C3B70D-0F96-4006-99F6-0FD211F5F2B2}
#define EFI_UI_ACTIVE_EVENT_GUID \
    { 0x68c3b70d, 0xf96, 0x4006, { 0x99, 0xf6, 0xf, 0xd2, 0x11, 0xf5, 0xf2, 0xb2 } };

// {30D39942-9556-4887-A943-BC63805D9D43}
#define EFI_UI_IDLE_EVENT_GUID \
    {0x30d39942, 0x9556, 0x4887, { 0xa9, 0x43, 0xbc, 0x63, 0x80, 0x5d, 0x9d, 0x43 }};

/*===========================================================================
  PROTOCOL INTERFACE
===========================================================================*/
/** @ingroup efi_displayPwrCtrl_protocol
  @par Summary
  Qualcomm Display Power Control Protocol interface.

  @par Parameters
  @inputprotoparams{} 
*/
struct _EFI_QCOM_DISPLAY_PWR_CTRL_PROTOCOL
{
  UINT64                                           Revision;
  EFI_DISPLAY_PANEL_POWER_CONTROL                  DisplayPanelPowerControl; 
  EFI_DISPLAY_PANEL_POWER_STATUS                   DisplayPanelPowerStatus;
  EFI_DISPLAY_BACKLIGHT_BRIGHTNESS_LEVEL_CONTROL   DisplayBacklightBrightnessLevelControl;
  EFI_DISPLAY_BACKLIGHT_BRIGHTNESS_LEVEL_STATUS    DisplayBacklightBrightnessLevelStatus;
};
EFIDisplayUtils.h

路径:BOOT.XF.4.1/boot_images/QcomPkg/Include/Protocol/EFIDisplayUtils.h

/*  Protocol GUID definition */
/** @ingroup efi_displayUtils_protocol */

// {c0dd69ac-76ba-11e6-ab24-1fc7f5575f19}
#define EFI_DISPLAYUTILS_PROTOCOL_GUID \
    {0xc0dd69ac, 0x76ba, 0x11e6, {0xab, 0x24, 0x1f, 0xc7, 0xf5, 0x57, 0x5f, 0x19}}

/**
  Protocol declaration.
*/
typedef struct _EFI_QCOM_DISPLAY_UTILS_PROTOCOL  EFI_QCOM_DISPLAY_UTILS_PROTOCOL;

/** 
  Display Utils property types
*/
typedef enum
{
    EFI_DISPLAY_UTILS_DEVICE_TREE_ADDR = 0x0,   /**< Device tree base address: (Type: VOID*) */
    EFI_DISPLAY_UTILS_PANEL_OVERRIDE,           /**< Panel override string (Type: CHAR8*) */
    EFI_DISPLAY_UTILS_SUPPORTED_PANELS,         /**< Newline separated list of supported panels (Type: CHAR16*) */
    EFI_DISPLAY_UTILS_PANEL_CONFIG,             /**< Panel raw configuration */
    EFI_DISPLAY_UTILS_DYNAMIC_REFRESH,          /**< Dynamic refresh settings (Type: UINT32*) */
}   EFI_DISPLAY_UTILS_PROPERTY_TYPE;

/*===========================================================================
  PROTOCOL INTERFACE
===========================================================================*/
/** @ingroup efi_displayUtils_protocol
  @par Summary
  Qualcomm Display Utils Protocol interface.

  @par Parameters
  @inputprotoparams{} 
*/
struct _EFI_QCOM_DISPLAY_UTILS_PROTOCOL
{
    UINT64                                           Revision;
    EFI_DISPLAY_UTILS_SET_PROPERTY                   DisplayUtilsSetProperty; 
    EFI_DISPLAY_UTILS_GET_PROPERTY                   DisplayUtilsGetProperty;
    EFI_DISPLAY_UTILS_RENDER_LOGO                    DisplayUtilsRenderLogo;
    EFI_DISPLAY_UTILS_SET_MODE                       DisplayUtilsSetMode;
    EFI_DISPLAY_UTILS_SET_VARIABLE                   DisplayUtilsSetVariable;
    EFI_DISPLAY_UTILS_GET_VARIABLE                   DisplayUtilsGetVariable;
};

EFI_DISPLAYUTILS_PROTOCOL_GUID在AP侧中的FASTBOOT模式被调用了,用于判断是否支持显示画面。

bootable/bootloader/edk2/QcomModulePkg/Library/FastbootLib/FastbootCmds.c

STATIC UINT8
is_display_supported ( VOID )
{
    EFI_STATUS Status = EFI_SUCCESS;
    EfiQcomDisplayUtilsProtocol *pDisplayUtilProtocol;
    EFI_GUID DisplayUtilGUID = EFI_DISPLAYUTILS_PROTOCOL_GUID;
    EFI_DISPLAY_UTILS_PANEL_CONFIG_PARAMS PanelConfig;
    UINT32 Index = 0;
    UINT32 ParamSize = sizeof (PanelConfig);
    PanelConfig.uPanelIndex = Index;

    if (EFI_SUCCESS == gBS->LocateProtocol (&DisplayUtilGUID,
                                            NULL,
                                            (VOID **)&pDisplayUtilProtocol)) {
        Status = pDisplayUtilProtocol->DisplayUtilsGetProperty (
            EFI_DISPLAY_UTILS_PANEL_CONFIG,
            (VOID*)&PanelConfig, &ParamSize);
        if ( Status == EFI_NOT_FOUND ) {
            DEBUG ((EFI_D_VERBOSE, "Display is not supported\n"));
            return 0;
        }
    }
    DEBUG ((EFI_D_VERBOSE, "Display is enabled\n"));
    return 1;
}

对应接口的实现

下面我们具体看看EFI_QCOM_DISPLAY_UTILS_PROTOCOL这个实现。

BOOT.XF.4.1/boot_images/QcomPkg/Library/MDPLib/DisplayUtils.c

/* Display Utils Protocol Implementation
 */
EFI_QCOM_DISPLAY_UTILS_PROTOCOL  gQcomDisplayUtilsProtocolImplementation = 
{
    DISPLAY_UTILS_REVISION,
    Display_Utils_SetProperty,
    Display_Utils_GetProperty,
    Display_Utils_RenderLogo,
    Display_Utils_SetMode,
    Display_Utils_SetVariable,
    Display_Utils_GetVariable
};

执行流程

DisplayDxeInitialize

显示驱动执环境的初始化

BOOT.XF.4.1\boot_images\QcomPkg\Drivers\DisplayDxe\DisplayDxe.c

/**********************************************************************************************************************
     Public APIs
**/
/**
  Initialize the state information for the Display Dxe

  @param  ImageHandle   of the loaded driver
  @param  SystemTable   Pointer to the System Table

  @retval EFI_SUCCESS           Protocol registered
  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
  @retval EFI_DEVICE_ERROR      Hardware problems

**/
EFI_STATUS
EFIAPI
DisplayDxeInitialize (
    IN EFI_HANDLE         ImageHandle,
    IN EFI_SYSTEM_TABLE   *SystemTable
)
{
    EFI_STATUS         eStatus            = EFI_SUCCESS;
    EFI_GUID           sOutputGUID        = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
    EFI_HANDLE         hUEFIDisplayHandle = NULL;
    MDP_InitParamsType sInitParam;
    EFI_GUID           UIActiveEventGuid  = EFI_UI_ACTIVE_EVENT_GUID;
    EFI_GUID           UIIdleEventGuid    = EFI_UI_IDLE_EVENT_GUID;

    // Clear out global structures
    MDP_OSAL_MEMZERO(&gModeInfo, sizeof(DisplayDxe_ModeInfo));
    MDP_OSAL_MEMZERO(&sInitParam, sizeof(MDP_InitParamsType));

    /* Register for an ExitBootServicesEvent */
    // 创建了一些事件(略): 创建一个事件,然后设定一个条件,使得条件满足的时候就执行这个事件
    // ...

    // 初始化有关的 时钟、电源
    if (EFI_SUCCESS != DisplayPwr_InitLPMSupport(TRUE))
    {
        DEBUG((EFI_D_WARN, "DisplayDxe: Failed to register LPM CB!\n"));
    }

    // Initialize Apps BootLoader (ABL) interface
    // It checks for panel override, if any, set by ABL and sets up parameters which will be used by MDPInit
    if (MDP_STATUS_OK != MDPSetProperty(MDP_DISPLAY_PRIMARY, MDP_DISPLAY_PROPERTY_ABL_INTERFACE_INIT, NULL))
    {
        DEBUG((EFI_D_INFO, "DisplayDxe: Failed to initialize ABL!\n"));
    }

    // Initialize the MDP 
    if (MDP_STATUS_OK != MDPInit(&sInitParam, MDP_INIT_FLAG_MMU_INIT))
    {
        DEBUG ((EFI_D_INFO, "DisplayDxe: MDP init failed!\n"));      
        eStatus = EFI_DEVICE_ERROR;
    }
    else
    {
        MDP_PowerParamsType      sPowerParams;
        MDP_DetectParamType      sDetectParams;
        MDP_PropertiesParamType  sDisplayProp;

        MDP_OSAL_MEMZERO(&sDisplayProp, sizeof(MDP_PropertiesParamType));
        MDP_OSAL_MEMZERO(&sPowerParams, sizeof(MDP_PowerParamsType));

        sPowerParams.bPowerOn = TRUE;
        sDisplayProp.bDisplayPwrState = TRUE;


        //////////////////
        // Main Display //
        //////////////////

        // If the primary is supported initialize it
        if (TRUE == sInitParam.aSupportedDisplays[MDP_DISPLAY_PRIMARY])
        {
            if (MDP_STATUS_OK != MDPPower(MDP_DISPLAY_PRIMARY, &sPowerParams, 0x0))
            {
                DEBUG ((EFI_D_INFO, "DisplayDxe: Primary panel power up failed!\n"));    
            }
            else
            {
                MDP_OSAL_MEMZERO(&sDetectParams, sizeof(MDP_DetectParamType));

                // Default reporting of primary display
                if (MDP_STATUS_OK != MDPDetect(MDP_DISPLAY_PRIMARY, &sDetectParams, 0x0))
                {
                    eStatus = EFI_DEVICE_ERROR;
                }
                else if (TRUE == sDetectParams.bDisplayDetected)
                {
                    eStatus = DisplayDxeSelectMode(MDP_DISPLAY_PRIMARY, &sDetectParams);

                    // Set the primary display to on 
                    if (MDP_STATUS_OK != MDPSetProperty(MDP_DISPLAY_PRIMARY, MDP_DISPLAY_PROPERTY_POWER_STATE, &sDisplayProp))
                    {
                        eStatus = EFI_DEVICE_ERROR; 
                    }
                }
            }
        }    

        // If we not have detected a valid mode on both primary and external display report error
        if ((0 == gModeInfo.uNumModes[MDP_DISPLAY_PRIMARY]) && (0 == gModeInfo.uNumModes[MDP_DISPLAY_EXTERNAL]))
        {
            eStatus = EFI_DEVICE_ERROR;
        }
        else
        {
            // Default at some dummy mode
            gModeInfo.sCurrentModeInfo.Version                       = GRAPHICS_OUTPUT_PROTOCOL_REVISION;
            gModeInfo.sCurrentModeInfo.PixelFormat                   = DISPLAYDXE_DEFAULT_PIXEL_FORMAT;
            gModeInfo.sCurrentModeInfo.HorizontalResolution          = 0;
            gModeInfo.sCurrentModeInfo.VerticalResolution            = 0;
            gModeInfo.sCurrentModeInfo.PixelInformation.RedMask      = DISPLAYDXE_RED_MASK;
            gModeInfo.sCurrentModeInfo.PixelInformation.GreenMask    = DISPLAYDXE_GREEN_MASK;
            gModeInfo.sCurrentModeInfo.PixelInformation.BlueMask     = DISPLAYDXE_BLUE_MASK;
            gModeInfo.sCurrentModeInfo.PixelInformation.ReservedMask = DISPLAYDXE_ALPHA_MASK;
            gModeInfo.sCurrentModeInfo.PixelsPerScanLine             = 0;

            // Setup the protocol information, set the current mode to an invalid mode forcing a set mode
            gModeInfo.sProtocolInfo.MaxMode    = 1;
            gModeInfo.sProtocolInfo.Mode       = (UINT32)-1;
            gModeInfo.sProtocolInfo.SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
            gModeInfo.sProtocolInfo.Info       = &gModeInfo.sCurrentModeInfo;

            gModeInfo.bExtSupported            = sInitParam.aSupportedDisplays[MDP_DISPLAY_EXTERNAL];

            // Install display protocols only if panel is detected.
            // Make a new handle with EFI Graphics Protocol
            if (EFI_SUCCESS != (eStatus = gBS->InstallMultipleProtocolInterfaces (&hUEFIDisplayHandle,
                                                                                  &gEfiDevicePathProtocolGuid,
                                                                                  &DisplayDevicePath,
                                                                                  &sOutputGUID,
                                                                                  &gDisplayDxeOutputProtocol,
                                                                                  &gQcomDisplayPwrCtrlProtocolGuid,
                                                                                  &gDisplayPwrCtrlProtocolImplementation,
                                                                                  &gEfiDisplayPowerStateProtocolGuid,
                                                                                  &gDisplayPwrProtocolImplementation,
                                                                                  &gQcomDisplayUtilsProtocolGuid,
                                                                                  &gQcomDisplayUtilsProtocolImplementation,
                                                                                  NULL)))
            {
                DEBUG ((EFI_D_INFO, "DisplayDxe: InstallMultipleProtocolInterfaces failed!\n"));
            }
        } 
    }

    if (eStatus == EFI_SUCCESS)
    {
        if(EFI_SUCCESS != GetConfigValue ("EnableDisplayThread", &gModeInfo.uMultiThreadded))
        {
            gModeInfo.uMultiThreadded = 0;
        }

        // Spawn off thread to enable mode set if we are in a threadded environment
        if (gModeInfo.uMultiThreadded )
        {
            InitLock ("DispInit", &gModeInfo.hModeLock);
            if(InitLock == NULL)
            {
                // If single CPU core is configured, the priority of this thread should be higher than UEFI dxe thread
                if (NULL != (gModeInfo.hDispThread = ThreadCreate ("Disp", &SetModeThread, 0, UEFI_THREAD_PRIORITY + 1, DEFAULT_STACK_SIZE * 3)))
                {  
                    if (MDP_STATUS_OK != MDP_SetMultiThreadState(TRUE))
                    {
                        DEBUG ((EFI_D_WARN, "DisplayDxe: Failed to set multiThread state to be enabled!\n"));    

                        // Disable multi threadding
                        gModeInfo.uMultiThreadded = 0;
                    }
                    else
                    {
                        ThreadDetach (gModeInfo.hDispThread);
                        ThreadResume (gModeInfo.hDispThread);
                    }
                }
                else
                {
                    // Disable multi threadding
                    gModeInfo.uMultiThreadded = 0;
                }
            }
            else
            {
                // Disable multi threadding
                gModeInfo.uMultiThreadded = 0;
            }
        }
    }

    return eStatus;
}

todo

上一篇:我的联想拯救者y7000p怎么安装双系统Linux ubuntu 18.04呢?


下一篇:4.opencore引导三系统(MacOs+Windows+Linux)