/** Notification event handler registered by CoreNotifyOnArchProtocolInstallation (). This notify function is registered for every architectural protocol. This handler updates mArchProtocol[] array entry with protocol instance data and sets it's present flag to TRUE. If any constructor is required it is executed. The EFI System Table headers are updated. @param Event The Event that is being processed, not used. @param Context Event Context, not used. **/ VOID EFIAPI GenericProtocolNotify ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry; VOID *Protocol; LIST_ENTRY *Link; LIST_ENTRY TempLinkNode; Protocol = NULL; // // Get Entry from Context // Entry = (EFI_CORE_PROTOCOL_NOTIFY_ENTRY *)Context; // // See if the expected protocol is present in the handle database // Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol); if (EFI_ERROR (Status)) { return; } // // Mark the protocol as present // Entry->Present = TRUE; // // Update protocol global variable if one exists. Entry->Protocol points to a global variable // if one exists in the DXE core for this Architectural Protocol // if (Entry->Protocol != NULL) { *(Entry->Protocol) = Protocol; } // // Do special operations for Architectural Protocols // if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) { // // Register the Core timer tick handler with the Timer AP // gTimer->RegisterHandler (gTimer, CoreTimerTick); } if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) { // // When runtime architectural protocol is available, updates CRC32 in the Debug Table // CoreUpdateDebugTableCrc32 (); // // Update the Runtime Architectural protocol with the template that the core was // using so there would not need to be a dependency on the Runtime AP // // // Copy all the registered Image to new gRuntime protocol // for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) { CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY)); InsertTailList (&gRuntime->ImageHead, Link); } // // Copy all the registered Event to new gRuntime protocol // for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) { CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY)); InsertTailList (&gRuntime->EventHead, Link); } // // Clean up gRuntimeTemplate // gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead; gRuntimeTemplate.ImageHead.BackLink = &gRuntimeTemplate.ImageHead; gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead; gRuntimeTemplate.EventHead.BackLink = &gRuntimeTemplate.EventHead; } // // It's over kill to do them all every time, but it saves a lot of code. // CalculateEfiHdrCrc (&gDxeCoreRT->Hdr); CalculateEfiHdrCrc (&gBS->Hdr); CalculateEfiHdrCrc (&gDxeCoreST->Hdr); CalculateEfiHdrCrc (&gDxeCoreDS->Hdr); }
EFI_BOOTSERVICE EFI_STATUS EFIAPI CoreInstallConfigurationTable ( IN EFI_GUID *Guid, IN VOID *Table ) /*++ Routine Description: Boot Service called to add, modify, or remove a system configuration table from the EFI System Table. Arguments: Guid - Pointer to the GUID for the entry to add, update, or remove Table - Pointer to the configuration table for the entry to add, update, or remove, may be NULL. Returns: EFI_SUCCESS Guid, Table pair added, updated, or removed. EFI_INVALID_PARAMETER Input GUID not valid. EFI_NOT_FOUND Attempted to delete non-existant entry EFI_OUT_OF_RESOURCES Not enough memory available --*/ { UINTN Index; EFI_CONFIGURATION_TABLE *EfiConfigurationTable; // // If Guid is NULL, then this operation cannot be performed // if (Guid == NULL) { return EFI_INVALID_PARAMETER; } EfiConfigurationTable = gST->ConfigurationTable; // // Search all the table for an entry that matches Guid // for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { if (EfiCompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) { break; } } if (Index < gST->NumberOfTableEntries) { // // A match was found, so this is either a modify or a delete operation // if (Table != NULL) { // // If Table is not NULL, then this is a modify operation. // Modify the table enty and return. // gST->ConfigurationTable[Index].VendorTable = Table; #if (EFI_SPECIFICATION_VERSION >= 0x0002000A) // // Signal Configuration Table change // CoreNotifySignalList (Guid); #endif return EFI_SUCCESS; } // // A match was found and Table is NULL, so this is a delete operation. // gST->NumberOfTableEntries--; // // Copy over deleted entry // EfiCommonLibCopyMem ( &(EfiConfigurationTable[Index]), &(gST->ConfigurationTable[Index + 1]), (gST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE) ); } else { // // No matching GUIDs were found, so this is an add operation. // if (Table == NULL) { // // If Table is NULL on an add operation, then return an error. // return EFI_NOT_FOUND; } // // Assume that Index == gST->NumberOfTableEntries // if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) { // // Allocate a table with one additional entry. // mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE)); EfiConfigurationTable = CoreAllocateRuntimePool (mSystemTableAllocateSize); if (EfiConfigurationTable == NULL) { // // If a new table could not be allocated, then return an error. // return EFI_OUT_OF_RESOURCES; } if (gST->ConfigurationTable != NULL) { // // Copy the old table to the new table. // EfiCommonLibCopyMem ( EfiConfigurationTable, gST->ConfigurationTable, Index * sizeof (EFI_CONFIGURATION_TABLE) ); // // Free Old Table // CoreFreePool (gST->ConfigurationTable); } // // Update System Table // gST->ConfigurationTable = EfiConfigurationTable; } // // Fill in the new entry // EfiConfigurationTable[Index].VendorGuid = *Guid; EfiConfigurationTable[Index].VendorTable = Table; // // This is an add operation, so increment the number of table entries // gST->NumberOfTableEntries++; } // // Fix up the CRC-32 in the EFI System Table // CalculateEfiHdrCrc (&gST->Hdr); #if (EFI_SPECIFICATION_VERSION >= 0x0002000A) // // Signal Configuration Table change // CoreNotifySignalList (Guid); #endif return EFI_SUCCESS; }
/** Terminates all boot services. @param ImageHandle Handle that identifies the exiting image. @param MapKey Key to the latest memory map. @retval EFI_SUCCESS Boot Services terminated @retval EFI_INVALID_PARAMETER MapKey is incorrect. **/ EFI_STATUS EFIAPI CoreExitBootServices ( IN EFI_HANDLE ImageHandle, IN UINTN MapKey ) { EFI_STATUS Status; // // Disable Timer // gTimer->SetTimerPeriod (gTimer, 0); // // Terminate memory services if the MapKey matches // Status = CoreTerminateMemoryMap (MapKey); if (EFI_ERROR (Status)) { // // Notify other drivers that ExitBootServices fail // CoreNotifySignalList (&gEventExitBootServicesFailedGuid); return Status; } gMemoryMapTerminated = TRUE; // // Notify other drivers that we are exiting boot services. // CoreNotifySignalList (&gEfiEventExitBootServicesGuid); // // Report that ExitBootServices() has been called // REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES) ); // // Disable interrupt of Debug timer. // SaveAndSetDebugTimerInterrupt (FALSE); // // Disable CPU Interrupts // gCpu->DisableInterrupt (gCpu); // // Clear the non-runtime values of the EFI System Table // gDxeCoreST->BootServices = NULL; gDxeCoreST->ConIn = NULL; gDxeCoreST->ConsoleInHandle = NULL; gDxeCoreST->ConOut = NULL; gDxeCoreST->ConsoleOutHandle = NULL; gDxeCoreST->StdErr = NULL; gDxeCoreST->StandardErrorHandle = NULL; // // Recompute the 32-bit CRC of the EFI System Table // CalculateEfiHdrCrc (&gDxeCoreST->Hdr); // // Zero out the Boot Service Table // ZeroMem (gBS, sizeof (EFI_BOOT_SERVICES)); gBS = NULL; // // Update the AtRuntime field in Runtiem AP. // gRuntime->AtRuntime = TRUE; return Status; }