init.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 791 行 · 第 1/2 页

C
791
字号
/*++

Copyright (c)  1999 - 2003 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.


Module Name:

    init.c

Abstract: 

    Main entry point on EFI 64-bit environment. This environment layers 
    on top of the SAL_A

Revision History

--*/

#include "Sal64.h"
#include "plshell.h"
#include "SalHandoff.h"
#include "intload.h"
#include "Drivers.h"
#include "PlDefio.h"
#include "PlatformLib.h"

#define EFI_STACK_SIZE_IN_PAGES           (0x20000 / EFI_PAGE_SIZE)   // 128 KB
#define EFI_BSP_SIZE_IN_PAGES             (0x4000 / EFI_PAGE_SIZE)    // 16 KB
#define EFI_INTERRUPT_STACK_SIZE_IN_PAGES (0x20000 / EFI_PAGE_SIZE)   // 128 KB
#define EFI_INTERRUPT_BSP_SIZE_IN_PAGES   (0x4000 / EFI_PAGE_SIZE)    // 16 KB

typedef struct {
    UINT64 EfiStackAddr;
    UINT64 EfiBspAddr;
    UINT64 EfiIntStackAddr;
    UINT64 EfiIntBspAddr;
} EFI_STACK_INFO;

EFI_STACK_INFO EfiStackInfo;

EFI_PCI_OPTION_ROM_TABLE PciOptionRomTable;

EFI_STATUS
BuildEfiCoreImageHandle (
  IN  VOID                 *EntryPoint,
  IN  VOID                 *BaseAddress,
  IN  UINT64               Size,
  OUT EFI_HANDLE           *CoreImageHandle
  );

STATIC
VOID
PlInitializeTables (
    IN  UINTN   FunctionId
    );

STATIC
VOID
PlInstallMemoryMap (
    IN  UINTN                   FunctionId,
    IN  UINTN                   NoDesc,
    IN  EFI_MEMORY_DESCRIPTOR   *Desc
    );

STATIC
VOID
PlInstallBaseDevices (
    IN  UINTN   FunctionId,
    IN  UINTN   NvramBanks,
    IN  UINTN   NvramSize
    );

//
//
//

STATIC
VOID
PlExitBootServices (
    IN EFI_EVENT        Event,
    IN VOID             *Context
    );

VOID    
TimerCallBack (
    IN UINTN ElapsedTime
    );

VOID
PlAddBootOptionDefaults (
    IN  UINT16  BootOptionNumber
    );

//
//
//

rArg
MainEntry (
    IN UINTN                    FunctionId,
    IN SALEFIHANDOFF            *SalEfiHandoff
    )
/*++

  Routine Description:

    This is the entry point after this code has been loaded into memory. 

Arguments:
    FunctionId -    0x00 - SAL Call's just return right away
                    0x01 - SAL to EFI handoff BIOS INT 13 and INT 16 drivers loaded
                    0x11 - SAL to EFI handoff Cache Disabled same as 0x01
                    0x02 - SAL to EFI handoff Native Keyboard & IDE Drivers
    BugBug: These need to be in a common include file with the SAL. This is
            just implementation detail and not architecture.
    
    SalEfiHandoff - Info passed to EFI from Sal When it's launched.

Returns:

    Calls into EFI Firmware

--*/
{
    rArg        RetParam = {0, 0, 0, 0};
    EFI_STATUS  Status;
    EFI_EVENT   Event;
    EFI_HANDLE  EfiCoreImageHandle;


POST_CODE(0xaf);
    /* 
     *  for now stub out call with FunctionId == 0
     */
    if(FunctionId == 0) {
        //
        // This call back allows the SAL to call EFI incrementally.
        // Function ID zero is called but not used, so we just return.
        // This could be used to call EFI right after memory init, but
        // before the legacy BIOS was initialized for example...
        //

        //
        // Add the platform support to the EFI FW tables.
        //
        PlInitializeTables(FunctionId);

        //
        // Initialize the EFI FW memory map
        //
POST_CODE(0x01);
        PlInstallMemoryMap (FunctionId, SalEfiHandoff->MemDescCount, SalEfiHandoff->MemDesc);
POST_CODE(0x02);
        FW->MemoryMapInstalled();                           // Second
POST_CODE(0x03);

        Status = BS->AllocatePages (AllocateAnyPages, 
                                    EfiBootServicesData,
                                    EFI_STACK_SIZE_IN_PAGES,
                                    &EfiStackInfo.EfiStackAddr);
        EfiStackInfo.EfiStackAddr += (EFI_STACK_SIZE_IN_PAGES * EFI_PAGE_SIZE - 0x10);

        Status = BS->AllocatePages (AllocateAnyPages, 
                                    EfiBootServicesData,
                                    EFI_BSP_SIZE_IN_PAGES,
                                    &EfiStackInfo.EfiBspAddr);

        Status = BS->AllocatePages (AllocateAnyPages, 
                                    EfiBootServicesData,
                                    EFI_INTERRUPT_STACK_SIZE_IN_PAGES,
                                    &EfiStackInfo.EfiIntStackAddr);
        EfiStackInfo.EfiIntStackAddr += (EFI_INTERRUPT_STACK_SIZE_IN_PAGES * EFI_PAGE_SIZE - 0x10);

        Status = BS->AllocatePages (AllocateAnyPages, 
                                    EfiBootServicesData,
                                    EFI_INTERRUPT_BSP_SIZE_IN_PAGES,
                                    &EfiStackInfo.EfiIntBspAddr);

POST_CODE(0x04);
        RetParam.p1 = (UINT64)(&(EfiStackInfo.EfiStackAddr));

        return (RetParam);
    }
    // 
    //  Initialize the configuration tables in the EFI System Table
    //
    //  The ACPI Table added here is the ACPI 1.0 Table.  If an ACPI 2.0 table is present in the system,
    //  an additional table would have to be installed.  If the SAL passes an ACPI 2.0 table instead of
    //  an ACPI 1.0 table, then the GUID would have to be changed to the ACPI 2.0 GUID.
    //
POST_CODE(0x04);
    BS->InstallConfigurationTable(&SalSystemTableGuid, SalEfiHandoff->SalSystemTable);
    BS->InstallConfigurationTable(&AcpiTableGuid,      SalEfiHandoff->AcpiTable);
    BS->InstallConfigurationTable(&Acpi20TableGuid,    FindAcpiRsdPtr());
    BS->InstallConfigurationTable(&MpsTableGuid,       SalEfiHandoff->MpsTable);
    BS->InstallConfigurationTable(&SMBIOSTableGuid,    FindSMBIOSPtr());
    if (SalEfiHandoff->PciOptionRomCount > 0) {
      PciOptionRomTable.PciOptionRomCount       = SalEfiHandoff->PciOptionRomCount;
      PciOptionRomTable.PciOptionRomDescriptors = SalEfiHandoff->PciOptionRomDescriptors;
      BS->InstallConfigurationTable (&gEfiPciOptionRomTableGuid, &PciOptionRomTable);
    }

POST_CODE(0x05);
    PlInitSalPalProc ((UINT64)SalEfiHandoff->SALCallBack, 0x12345678abcdef0);

    // 
    //  Initialize timer interrupts
    //
POST_CODE(0x06);
    PlTimer(ID_SALCB_TIMER_START, TIMER_PERIOD, (PLABEL *)TimerCallBack);

    //
    // Once the memory map has been installed, basic EFI services
    // are now functional.   Although no devices or variable
    // store support is on line.
    //
POST_CODE(0x07);
    InitializeLib (NULL, ST);

    //
    // Build an image handle for the current executing image
    // 
    BuildEfiCoreImageHandle (
      MainEntry,
      SalEfiHandoff->EfiCoreBaseAddress,
      SalEfiHandoff->EfiCoreLength,
      &EfiCoreImageHandle
      );

POST_CODE(0x08);
    PlInitWatchdogTimer();

    //
    // Initialize support for calling BIOS functions
    //
POST_CODE(0x09);
    InitializeBiosIntCaller ();

    //
    // Install base devices.  This would at least include a 
    // global device_IO device, all NV ram store device(s), and 
    // the timer tick.  It may optionally include other device_io
    // devices.
    //
POST_CODE(0x0a);
    PlInstallBaseDevices(FunctionId, 
                         SalEfiHandoff->NVRAMBanks, 
                         SalEfiHandoff->NVRAMSize);                   
POST_CODE(0x0b);
    FW->NvStoreInstalled();                             // Third

    //
    // Say we only support English
    //
POST_CODE(0x0e);
    Status = RT->SetVariable (  
                    VarLanguageCodes, &EfiGlobalVariable,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    strlena (LanguageCodeEnglish), LanguageCodeEnglish 
                    );
    ASSERT (!EFI_ERROR(Status));

    //
    // Set supported language to English.
    //
    Status = RT->SetVariable (  
                    VarLanguage, &EfiGlobalVariable,
                    EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    strlena (LanguageCodeEnglish), LanguageCodeEnglish 
                    );
    //ASSERT (!EFI_ERROR(Status));

    //
    // Set EFIDebug based on NVRAM variable;
    //
    EFIDebugVariable ();

POST_CODE(0x0f);
    InitializeLib (NULL, ST);

    //
    // Install and connect all built in EFI 1.1 Drivers.
    //
POST_CODE(0x10);
    LOAD_INTERNAL_BS_DRIVER (L"BiosDisk",               InstallBiosBlkIoDrivers);

    LOAD_INTERNAL_BS_DRIVER (L"Ebc",                    InitializeEbcDriver);
    LOAD_INTERNAL_BS_DRIVER (L"Decompress",             DecompressDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"PcatPciRootBridge",      InitializePcatPciRootBridge);
    LOAD_INTERNAL_BS_DRIVER (L"PciBus",                 PciBusEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"PcatIsaAcpi",            PcatIsaAcpiDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"IsaBus",                 IsaBusControllerDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"IsaSerial",              SerialControllerDriverEntryPoint);

#ifdef SOFT_SDV
    LOAD_INTERNAL_BS_DRIVER (L"BiosVga",                BiosVgaDriverEntryPoint);
#else
    LOAD_INTERNAL_BS_DRIVER (L"BiosVgaMiniPort",        BiosVgaMiniPortDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"VgaClass",               VgaClassDriverEntryPoint);
#endif
//  LOAD_INTERNAL_BS_DRIVER (L"CirrusLogic5430",        CirrusLogic5430UgaDrawDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"GraphicsConsole",        InitializeGraphicsConsole);
    LOAD_INTERNAL_BS_DRIVER (L"Terminal",               InitializeTerminal);
    LOAD_INTERNAL_BS_DRIVER (L"ConPlatform",            ConPlatformDriverEntry);
    LOAD_INTERNAL_BS_DRIVER (L"ConSplitter",            ConSplitterDriverEntry);
    LOAD_INTERNAL_BS_DRIVER (L"BiosKeyboard",           BiosKeyboardDriverEntryPoint);

POST_CODE(0x11);
    ConnectAllConsoles ();

    //
    // Once consoles are installed, message may be printed
    // to the consoles
    //
POST_CODE(0x12);
    EFIFirmwareBanner();
    PlPrintLogonBanner();
    if ((FunctionId & SAL_EFI_CACHE_DISABLED) == SAL_EFI_CACHE_DISABLED) {
        Print (L"%ECache Disabled%N. ");
    } else {
        Print (L"%ECache Enabled%N. ");
    }
    Print (L"This image %HMainEntry%N is at address %016x\n",  *( UINT64 *)MainEntry);

POST_CODE(0x13);
    LOAD_INTERNAL_BS_DRIVER (L"DiskIo",                 DiskIoDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Partition",              PartitionEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Fat",                    FatEntryPoint);
    LOAD_INTERNAL_RT_DRIVER (L"Undi",                   InitializeUNDIDriver );
    LOAD_INTERNAL_BS_DRIVER (L"BiosSnp16",              BiosSnp16DriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Snp3264",                InitializeSnpNiiDriver);
    LOAD_INTERNAL_BS_DRIVER (L"PxeBc",                  InitializeBCDriver);
    LOAD_INTERNAL_BS_DRIVER (L"PxeDhcp4",               PxeDhcp4DriverEntryPoint);
//  LOAD_INTERNAL_BS_DRIVER (L"BIS",                    EFIBIS_BaseCodeModuleInit);
    LOAD_INTERNAL_BS_DRIVER (L"SerialMouse",            SerialMouseDriverEntryPoint);

    //
    // Create an event to be signalled when ExitBootServices occurs
    //
POST_CODE(0x14);
    Status = BS->CreateEvent(
                    EVT_SIGNAL_EXIT_BOOT_SERVICES, 
                    TPL_NOTIFY,
                    PlExitBootServices,
                    NULL,
                    &Event
                    );

    ASSERT (!EFI_ERROR(Status));

#ifdef EFI_BOOTSHELL    
    PlInitializeInternalLoad();
#endif

    PlInitializeLegacyBoot();

    // 
    // loop thru boot manager and boot maintenance until a boot
    // option is selected
    //
POST_CODE(0x15);
    while (TRUE) {
        //
        // The platform code is ready to boot the machine. Pass control
        // to the boot manager
        // 
        LOAD_INTERNAL_DRIVER(
            FW,
            IMAGE_SUBSYSTEM_EFI_APPLICATION,
            L"bootmgr",
            InitializeBootManager
            );

        //
        // If we return from above, means that no boot choices were found
        // or boot maintenance chosen. hence invoke boot maintenance menu
        // 
        LOAD_INTERNAL_DRIVER(
            FW,
            IMAGE_SUBSYSTEM_EFI_APPLICATION,
            L"bmaint",
            InitializeBootMaintenance
            );
    }

    RetParam.p0 = 0;
    return (RetParam);
}

⌨️ 快捷键说明

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