/** Signals the event. Queues the event to be notified if needed. @param UserEvent The event to signal . @retval EFI_INVALID_PARAMETER Parameters are not valid. @retval EFI_SUCCESS The event was signaled. **/ EFI_STATUS EFIAPI CoreSignalEvent ( IN EFI_EVENT UserEvent ) { IEVENT *Event; Event = UserEvent; if (Event == NULL) { return EFI_INVALID_PARAMETER; } if (Event->Signature != EVENT_SIGNATURE) { return EFI_INVALID_PARAMETER; } CoreAcquireEventLock (); // // If the event is not already signalled, do so // if (Event->SignalCount == 0x00000000) { Event->SignalCount++; // // If signalling type is a notify function, queue it // if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) { if (Event->ExFlag) { // // The CreateEventEx() style requires all members of the Event Group // to be signaled. // CoreReleaseEventLock (); CoreNotifySignalList (&Event->EventGroup); CoreAcquireEventLock (); } else { CoreNotifyEvent (Event); } } } CoreReleaseEventLock (); return EFI_SUCCESS; }
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; }
/** Internal function. Adds a ranges to the memory map. The range must not already exist in the map. @param Type The type of memory range to add @param Start The starting address in the memory range Must be paged aligned @param End The last address in the range Must be the last byte of a page @param Attribute The attributes of the memory range to add **/ VOID CoreAddRange ( IN EFI_MEMORY_TYPE Type, IN EFI_PHYSICAL_ADDRESS Start, IN EFI_PHYSICAL_ADDRESS End, IN UINT64 Attribute ) { LIST_ENTRY *Link; MEMORY_MAP *Entry; ASSERT ((Start & EFI_PAGE_MASK) == 0); ASSERT (End > Start) ; ASSERT_LOCKED (&gMemoryLock); DEBUG ((DEBUG_PAGE, "AddRange: %lx-%lx to %d\n", Start, End, Type)); // // Memory map being altered so updated key // mMemoryMapKey += 1; // // UEFI 2.0 added an event group for notificaiton on memory map changes. // So we need to signal this Event Group every time the memory map changes. // If we are in EFI 1.10 compatability mode no event groups will be // found and nothing will happen we we call this function. These events // will get signaled but since a lock is held around the call to this // function the notificaiton events will only be called after this funciton // returns and the lock is released. // CoreNotifySignalList (&gEfiEventMemoryMapChangeGuid); // // Look for adjoining memory descriptor // // Two memory descriptors can only be merged if they have the same Type // and the same Attribute // Link = gMemoryMap.ForwardLink; while (Link != &gMemoryMap) { Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); Link = Link->ForwardLink; if (Entry->Type != Type) { continue; } if (Entry->Attribute != Attribute) { continue; } if (Entry->End + 1 == Start) { Start = Entry->Start; RemoveMemoryMapEntry (Entry); } else if (Entry->Start == End + 1) { End = Entry->End; RemoveMemoryMapEntry (Entry); } } // // Add descriptor // mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE; mMapStack[mMapDepth].FromPages = FALSE; mMapStack[mMapDepth].Type = Type; mMapStack[mMapDepth].Start = Start; mMapStack[mMapDepth].End = End; mMapStack[mMapDepth].VirtualStart = 0; mMapStack[mMapDepth].Attribute = Attribute; InsertTailList (&gMemoryMap, &mMapStack[mMapDepth].Link); mMapDepth += 1; ASSERT (mMapDepth < MAX_MAP_DEPTH); return ; }
/** 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; }
EFI_BOOTSERVICE EFI_STATUS EFIAPI CoreSignalEvent ( IN EFI_EVENT UserEvent ) /*++ Routine Description: Signals the event. Queues the event to be notified if needed Arguments: UserEvent - The event to signal Returns: EFI_INVALID_PARAMETER - Parameters are not valid. EFI_SUCCESS - The event was signaled. --*/ { IEVENT *Event; Event = UserEvent; if (Event == NULL) { return EFI_INVALID_PARAMETER; } if (Event->Signature != EVENT_SIGNATURE) { return EFI_INVALID_PARAMETER; } CoreAcquireEventLock (); // // If the event is not already signalled, do so // if (Event->SignalCount == 0x00000000) { Event->SignalCount ++; // // If signalling type is a notify function, queue it // if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) { if (Event->ExFlag) { // // The CreateEventEx() style requires all members of the Event Group // to be signaled. // CoreReleaseEventLock (); CoreNotifySignalList (&Event->EventGroup); CoreAcquireEventLock (); } else { CoreNotifyEvent (Event); } } } CoreReleaseEventLock (); return EFI_SUCCESS; }