init.c

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

C
791
字号
#ifdef EFI_BOOTSHELL    
//
// Global Data
//
STATIC BOOLEAN  ShellToolsLoaded = FALSE;


VOID
PlStartShell (
    VOID
    )
{
    if (ShellToolsLoaded == FALSE) {
        PlLoadShellTools();
        PlLoadShellDebugTools();
        PlLoadShellAdditionalTools();
        ShellToolsLoaded = TRUE;
    }
    PlLoadShell();
}
#endif

STATIC
VOID
PlInitializeTables (
    IN  UINTN   FunctionId
    )
/*++

Routine Description:

    Initialization function called to obtain and update any 
    global table information or entry points that are in:

        SystemTable
        SystemTable->BootServices
        SystemTAble->RuntimeServices

Arguments:

    None

Returns:

    Tables set and updated

--*/
{    
    //
    // Initialize the platform table
    //

    PlTable.EmulateLoad          = NULL;
    PlTable.IdleLoop             = PlIdleLoop;
    PlTable.SetInterruptState    = PlSetInterruptState;
    PlTable.FlushCache           = RtPlCacheFlush;
    PlTable.SetVirtualAddressMap = RtPlSetVirtualAddressMap;
    PlTable.SI_HandoffState      = NULL;
    PlTable.EI_ReturnState       = NULL;

    //
    // Call the EFI FW's entry point and get back the initial
    // Firwmare and SystemTable
    //

    EFIEntryPoint (&PlTable, &FW, &ST);  
    BS = ST->BootServices;
    RT = ST->RuntimeServices;

    //
    // Update / provide any entries in the boot services table
    // The core EFI firmware does not provide the following
    // entries in the boot services table:
    //          Stal
    //

    BS->Stall            = RtPlStall;
    BS->SetWatchdogTimer = PlSetWatchdogTimer;

    //
    // Update / provide any entries in the runtime service table.
    // The core EFI firmware does not provide the following
    // entries in the runtime services table:

    RT->ResetSystem     = RtPlResetSystem;
    RT->GetTime         = RtPlGetTime;
    RT->SetTime         = RtPlSetTime;
    RT->GetWakeupTime   = RtPlGetWakeupTime;
    RT->SetWakeupTime   = RtPlSetWakeupTime;
   
    ST->NumberOfTableEntries = 0;
    ST->ConfigurationTable   = NULL;

    //
    // Done with table initializations
    //
}

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

Routine Description:

    Called to initialize the memory map descriptors for
    the system's memory map.   

    N.B. The FW requires that the first call be of type
    "ConventialMemory". 

    N.B. The FW requires that page 0 in the map is not 
    not ConventialMemory.  (Note the emulator can work
    around this by reporting page 0 as BootServicesData
    memory if needed.  The page is then not used at 
    Boot Services time, but it available in the memory
    map for later use)

Arguments:

    NoDesc      - Number of desc in Desc

    Desc        - The passed in memory map

Returns:

    Memory map descriptors added

--*/
{
    UINTN   Index;
    UINTN   Index1;
    UINTN   BestIndex;
    UINT64  End;
    UINT64  BestSize;

    for (Index=0; Index < NoDesc; Index++) {
        if (Desc[Index].Type == EfiACPIReclaimMemory || 
            Desc[Index].Type == EfiACPIMemoryNVS     || 
            (Desc[Index].Attribute & EFI_MEMORY_RUNTIME) ) {

            if (Desc[Index].PhysicalStart & 0x1fff) {
                for (Index1=0; Index1 < NoDesc; Index1++) {
                    if (Desc[Index1].Type == EfiConventionalMemory && Desc[Index1].NumberOfPages > 0) {
                        End = Desc[Index1].PhysicalStart + LShiftU64 (Desc[Index1].NumberOfPages, EFI_PAGE_SHIFT);
                        if (End == Desc[Index].PhysicalStart) {
                            Desc[Index1].NumberOfPages--;
                            Desc[Index].PhysicalStart -= EFI_PAGE_SIZE;
                            Desc[Index].NumberOfPages++;
                        }
                    }
                }
            }

            if (Desc[Index].NumberOfPages & 1) {
                End = Desc[Index].PhysicalStart + LShiftU64 (Desc[Index].NumberOfPages, EFI_PAGE_SHIFT);
                for (Index1=0; Index1 < NoDesc; Index1++) {
                    if (Desc[Index1].Type == EfiConventionalMemory && Desc[Index1].NumberOfPages > 0) {
                        if (End == Desc[Index1].PhysicalStart) {
                            Desc[Index].NumberOfPages++;
                            Desc[Index1].NumberOfPages--;
                            Desc[Index1].PhysicalStart += EFI_PAGE_SIZE;
                        }
                    }
                }
            }
        }
    }

    //
    // Find the largest available free memory descriptor
    // and add it first
    //
    BestIndex = NoDesc;
    BestSize = 0;
    for (Index=0; Index < NoDesc; Index += 1) {
        if (Desc[Index].Type == EfiConventionalMemory  &&
            Desc[Index].NumberOfPages > BestSize) {
            
            BestIndex = Index;
            BestSize = Desc[Index].NumberOfPages;
        }
    }

    ASSERT (BestIndex < NoDesc);
    FW->AddMemoryDescriptor (
            Desc[BestIndex].Type,
            Desc[BestIndex].PhysicalStart,
            Desc[BestIndex].NumberOfPages,
            Desc[BestIndex].Attribute
            );

    //
    // Now add all remaining information to the memory map
    //

    for (Index=0; Index < NoDesc; Index++) {
        if (Index != BestIndex && Desc[Index].NumberOfPages > 0) {
            FW->AddMemoryDescriptor (
                Desc[Index].Type, 
                Desc[Index].PhysicalStart,   
                Desc[Index].NumberOfPages,
                Desc[Index].Attribute
                );
        }
    }
}

STATIC
VOID
PlInstallBaseDevices (                      
    IN  UINTN   FunctionId,
    IN  UINTN   NvramBanks,
    IN  UINTN   NvramSize
    )
/*++

Routine Description:

    Add handles to the base devices here. In particular
    the console devices, internal nvram device(s), and
    the timer tick handler.

    Variable store support is not enabled at this time. 
    (The firware needs the nvram & system volume devices
    to enable such support)

Arguments:

    None

Returns:

    Base device handles added

--*/
{
    EFI_DEVICE_PATH                 *DevicePath;
    EFI_HANDLE                      Handle;
    EFI_STATUS                      Status;
    UINT64                          IoPortBase;

    //
    //
    // First add a device(s) to handle device_io request
    // (this is done since the next devices may need to access
    // their IO space)
    //

    if (LibGetSalIoPortMapping (&IoPortBase) != EFI_SUCCESS) {
        //
        // BugBug: If you can't find it in the SAL System Table take a guess.
        //          If this guess is wrong you will plant in the ASSERT in the stall 
        //          routine. It will look like the timer is not ticking since IOs are
        //          not working.
        //
        IoPortBase = 0x0000ffffc000000;
    }  

    //
    // EFI is defined to be in physical mode. Thus we must flip bit 63 to
    //  make the IO cycles be uncacheable.
    //
    IoPortBase |= 0x8000000000000000;

    PlInstallDefaultIoDevice (
                        BiosRootDevicePath, 
                        0x8000000000000000, // Force non cachable access
                        IoPortBase
                        );

    
    
    //
    // Set up the GlobalIoFncs global to point to global memory/io/pci space
    //
    DevicePath = BiosRootDevicePath;
    Status = BS->LocateDevicePath (&DeviceIoProtocol, &DevicePath, &Handle);
    if (!EFI_ERROR(Status)) {
        Status = BS->HandleProtocol (Handle, &DeviceIoProtocol, (VOID *)&GlobalIoFncs);
    }
    ASSERT (!EFI_ERROR(Status));

    //
    // Initialize to PCI Root Bus List
    //

    InitializePciRootBusList (&PciRootBusList);    


    //
    // Add SAL callback NVRAM store.
    //

    PlInitNvVarStoreFlash ( 
        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
        NvramSize, NvramBanks
        );
    
    //
    // Install the Unicode string device.  This device supports
    // case insensitive comparisons of Unicode strings.
    //

    PlInitializeUnicodeStringDevice();
}

STATIC
VOID
PlIdleLoop (
    IN BOOLEAN  Polling
    )
{
}

STATIC
VOID
PlExitBootServices (
    IN EFI_EVENT        Event,
    IN VOID             *Context
    )
/*++

Routine Description:

    Signal handlers for ExitBootServices event

Arguments:

    Event type
    Context fo the event

Returns:
   

--*/
{
    //
    // Clear non-runtime pointer
    //

    PlTable.EmulateLoad = NULL;
    PlTable.IdleLoop = NULL;
    PlTable.SetInterruptState = NULL;

    // EFI f/w takes care of boot service's table

    //
    // Cancel Timer
    //

    PlTimer(ID_SALCB_TIMER_CANCEL, 0, NULL);
}

VOID    
TimerCallBack (
    IN UINTN ElapsedTime
    )
/*++

Routine Description:

    Timer callback . Called by SAL whenever the timer period expires


Arguments:

    ElapsedTime in msec

Returns:

    None

--*/
{
    EFI_TPL     OldTpl; 

    OldTpl = BS->RaiseTPL(TPL_HIGH_LEVEL);

    //
    // Inform the firmware of an "timer interrupt".  The time expired
    // since the last call is 10,000 times the number of ms.  (or 100ns units)
    //

    FW->TickHandler(ElapsedTime*10000);

    BS->RestoreTPL(OldTpl); 

    return;
}

⌨️ 快捷键说明

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