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

📄 varinit.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c)  1999 - 2002 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:

Abstract:




Revision History

--*/

#include "ivar.h"

//
// This code is coded to the least common dominator which is
// runtime access of non-volatile variables. (Which is also
// the most interesting variable type).  Since there's no
// dynamic memory allocation at runtime, the algorithm is
// slow.   No special code for boot time optimizations
// (e.g., indexing the stores) is performed
//

//
// Prototypes
//

STATIC
BOOLEAN
VarCheckBank (
    IN STORAGE_BANK         *Bank
    );

VOID
STATIC RUNTIMEFUNCTION
RtVarStoreSetVirtualMapping (
    IN EFI_EVENT            Event,
    IN VOID                 *Context
    );

//
// Declare runtime code
//


//
//
//

VOID
InitializeVariableStore (
    VOID
    )
{
    UINT32                  Attributes;
    VARIABLE_STORE          *VarStore;
    EFI_EVENT               Event;
    EFI_STATUS              Status;

    //
    // Initialize a variable store driver for BS + RT
    //

    InitNvVarStoreVirtual (
        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
        0x4000, 2
        );

    //
    // Initialize globals for variable stores
    //

    InitializeLock (&VariableStoreLock, TPL_CALLBACK);
    RtAcquireStoreLock ();

    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
    VariableStoreType[Attributes] = &VariableStore[0];
    VariableStore[0].Attributes = Attributes;
    VariableStore[0].MemoryType = EfiBootServicesData;
    VariableStore[0].Type = "BS";
    VariableStore[0].Next = &VariableStore[1];

    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE;
    VariableStoreType[Attributes] = &VariableStore[1];
    VariableStore[1].Attributes = Attributes;
    VariableStore[1].MemoryType = EfiBootServicesData;
    VariableStore[1].Type = "NV+BS";
    VariableStore[1].Next = &VariableStore[2];

    Attributes = EFI_VARIABLE_RUNTIME_ACCESS;
    VariableStoreType[Attributes] = &VariableStore[2];
    Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
    VariableStoreType[Attributes] = &VariableStore[2];
    VariableStore[2].Attributes = Attributes;
    VariableStore[2].MemoryType = EfiRuntimeServicesData;
    VariableStore[2].Type = "BS+RT";
    VariableStore[2].Next = &VariableStore[3];

    Attributes = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
    VariableStoreType[Attributes] = &VariableStore[3];
    Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
    VariableStoreType[Attributes] = &VariableStore[3];
    VariableStore[3].Attributes = Attributes;
    VariableStore[3].MemoryType = EfiRuntimeServicesData;
    VariableStore[3].Type = "NV+BS+RT";
    VariableStore[3].RuntimeUpdate = TRUE;

    for (VarStore=VariableStore; VarStore; VarStore=VarStore->Next) {
        InitializeListHead (&VarStore->Active);
    }

    RtReleaseStoreLock ();

    //
    // Notify when SetVirtualAddressMap occurs
    //

    Status = CreateEvent (
                EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
                TPL_NOTIFY,
                RtVarStoreSetVirtualMapping,
                NULL,
                &Event
                );

    ASSERT (!EFI_ERROR(Status));
}

#pragma RUNTIME_CODE(RtVarStoreSetVirtualMapping)
VOID
STATIC RUNTIMEFUNCTION
RtVarStoreSetVirtualMapping (
    IN EFI_EVENT            Event,
    IN VOID                 *Context
    )
{
    EFI_CONVERT_POINTER     ConvertPointer;
    VARIABLE_STORE          *VarStore;
    STORAGE_BANK            *Bank;
    UINTN                   Index;
    LIST_ENTRY              *Link;
    
    
    ConvertPointer = RT->ConvertPointer;

    for (Index=0; Index < MAX_VARIABLE_STORAGE_TYPE; Index++) {
        VarStore = &VariableStore[Index];

        ConvertPointer (EFI_OPTIONAL_PTR|EFI_INTERNAL_PTR, &VarStore->Next);

        //
        // If this is a runtime variable store, update it
        //

        if (VarStore->MemoryType == EfiRuntimeServicesData) {

            //
            // Update all the banks for this store
            //

            for (Link=VarStore->Active.Flink; Link != &VarStore->Active; Link=Link->Flink) {
                Bank = CR(Link, STORAGE_BANK, Link, STORAGE_BANK_SIGNATURE);
                ConvertPointer (EFI_INTERNAL_PTR, &Bank->VarStore);
                ConvertPointer (EFI_INTERNAL_PTR, &Bank->TSize);
                ConvertPointer (0, &Bank->Device);
                ConvertPointer (0, &Bank->u.Data);
            }

            //
            // If there's a tbank, update it as well
            //

            if (VarStore->TBank) {
                Bank = VarStore->TBank;
                ConvertPointer (EFI_INTERNAL_PTR, &Bank->VarStore);
                ConvertPointer (EFI_INTERNAL_PTR, &Bank->TSize);
                ConvertPointer (0, &VarStore->TBank);
                ConvertPointer (0, &Bank->Device);
                ConvertPointer (0, &Bank->u.Data);
            }

            //
            // Fix the active bank list & other pointers in this store
            //

            RtConvertList (EFI_INTERNAL_PTR, &VarStore->Active);
            VarStore->Type = NULL;
        }
    }
    //
    // fix variablestoretype contents as well
    //

    for (Index=0; Index < (VAR_ATTRIBUTE_TYPE+1); Index++) {
        if (VariableStoreType[Index]) {
            ConvertPointer (EFI_INTERNAL_PTR, &VariableStoreType[Index]);
        }
    }

}


VOID
FwNvStoreInstalled (
    VOID
    )
{
    EFI_STATUS              Status;
    UINTN                   HandleIndex;
    UINTN                   NoHandles;
    EFI_HANDLE              *Buffer, Handle;
    EFI_VARIABLE_STORE      *Device;

    RtAcquireStoreLock ();

    //
    // Get all the variable store device handles
    //

    LibLocateHandle (ByProtocol, &VariableStoreProtocol, NULL, &NoHandles, &Buffer);

    //
    // Add all the variable store banks for all the handles
    //

    for(HandleIndex = 0; HandleIndex < NoHandles; HandleIndex += 1) {
        Handle = Buffer[HandleIndex];

        //
        // Get the variable store device
        //

        Status = BS->HandleProtocol (Handle, &VariableStoreProtocol, &Device);
        if (EFI_ERROR(Status)) {
            continue;
        }

        VarAddDevice (Device);
    }

    //
    // Done with the handle buffer
    //

    FreePool (Buffer);

    //
    // Now that all the banks are added, check their states and
    // correct any partial updates
    //

    VarCheckBanks ();
        
    //
    // Done
    //

    RtReleaseStoreLock ();

    //
    // Initialize the monotonic counter
    //

    InitializeMonotonicCount();
}


VOID
INTERNAL
VarAddDevice (
    EFI_VARIABLE_STORE  *Device
    )
{
    UINTN                   BankIndex;
    VARIABLE_STORE          *VarStore;


    ASSERT_LOCKED (&VariableStoreLock);

    //
    // Determine which store based on the device's attributes
    //

    VarStore = VariableStoreType[Device->Attributes & VAR_ATTRIBUTE_TYPE];

    //
    // Must have at least two banks in the device
    //

    if (Device->SizeStore) {
        if (Device->NoBanks < 1) {
            Device->SizeStore (Device, 1);
        }

        if (Device->NoBanks < 2) {
            Device->SizeStore (Device, 2);
        }
    }

    //
    // Add each bank
    //

    for (BankIndex=0; BankIndex < Device->NoBanks; BankIndex += 1) {
        VarStoreAddBank (VarStore, Device, BankIndex);
    }
}

VOID
INTERNAL
VarCheckBanks (
    VOID
    )
{
    VARIABLE_STORE          *VarStore;
    LIST_ENTRY              *Link;
    STORAGE_BANK            *Bank, *InUseTransition, *ObsoleteTransition;
    BOOLEAN                 Restart;


    ASSERT_LOCKED (&VariableStoreLock);

    //
    // Now that all the banks in the system have been added, get a 
    // transaction bank and detect & fix partial bank updates for each 
    // variable store.
    //

    for (VarStore=VariableStore; VarStore; VarStore=VarStore->Next) {

        //
        // Allocate a transaction bank for this store
        //

        if (VarStore->TBankRequired  && !VarStore->TBank) {
            RtVarGetTransactionBank (VarStore);
        }

        //
        // See if there is are any banks transition that were in progress,
        // and complete them.  Find any Obsolete transition
        // or InUse transition banks.  (there should only be a max of
        // 1 each since we never allow more then one, and on startup
        // we fix any that are outstanding)
        //

        InUseTransition = NULL;
        ObsoleteTransition = NULL;

        for (Link = VarStore->Active.Flink; Link != &VarStore->Active; Link=Link->Flink) {
            Bank = CR(Link, STORAGE_BANK, Link, STORAGE_BANK_SIGNATURE);

            // 
            if (Bank->State & VARH_OBSOLETE_TRANSITION) {
                ASSERT (!ObsoleteTransition);
                ObsoleteTransition = Bank;
            }

            if ((Bank->State & VARH_INUSE_TRANSITION) && !(Bank->State & VARH_INUSE)) {
                ASSERT (!InUseTransition);
                InUseTransition = Bank;
            }
        }

        //
        // There are 4 possibile conditions here:
        //      1 There are no obsolete or inuse banks in transition
        //      2 There is an obsolete transition bank, and no inuse transition bank
        //      3 There is an obsolete transition bank and an inuse transition bank
        //      4 There is an inuse transition bank and no obsolete transition bank
        //
        // 1. There is no outstanding operation - nothing to do.
        //

⌨️ 快捷键说明

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