EFI_STATUS MD5Final ( IN MD5_CTX *Md5Ctx, OUT UINT8 *HashVal ) /*++ Routine Description: GC_TODO: Add function description Arguments: Md5Ctx - GC_TODO: add argument description HashVal - GC_TODO: add argument description Returns: EFI_SUCCESS - GC_TODO: Add description for return value --*/ { UINTN PadLength; if (Md5Ctx->Status == EFI_ALREADY_STARTED) { // // Store Hashed value & Zeroize sensitive context information. // EfiCopyMem (HashVal, (UINT8 *) Md5Ctx->States, MD5_HASHSIZE); EfiZeroMem ((UINT8 *)Md5Ctx, sizeof (*Md5Ctx)); return EFI_SUCCESS; } if (EFI_ERROR (Md5Ctx->Status)) { return Md5Ctx->Status; } PadLength = Md5Ctx->Count >= 56 ? 120 : 56; PadLength -= Md5Ctx->Count; MD5UpdateBlock (Md5Ctx, Md5HashPadding, PadLength); Md5Ctx->Length = LShiftU64 (Md5Ctx->Length, 3); MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) &Md5Ctx->Length, 8); EfiZeroMem (Md5Ctx->M, sizeof (Md5Ctx->M)); Md5Ctx->Length = 0; Md5Ctx->Status = EFI_ALREADY_STARTED; return MD5Final (Md5Ctx, HashVal); }
EFI_STATUS MD5Init ( IN MD5_CTX *Md5Ctx ) /*++ Routine Description: GC_TODO: Add function description Arguments: Md5Ctx - GC_TODO: add argument description Returns: EFI_SUCCESS - GC_TODO: Add description for return value --*/ { EfiZeroMem (Md5Ctx, sizeof (*Md5Ctx)); // // Set magic initialization constants. // Md5Ctx->States[0] = 0x67452301; Md5Ctx->States[1] = 0xefcdab89; Md5Ctx->States[2] = 0x98badcfe; Md5Ctx->States[3] = 0x10325476; return EFI_SUCCESS; }
VOID UpdateOrderPage ( IN UINT16 UpdatePageId, IN BM_MENU_OPTION *OptionMenu, IN BMM_CALLBACK_DATA *CallbackData ) { BM_MENU_ENTRY *NewMenuEntry; UINT16 Index; IFR_OPTION *IfrOptionList; CallbackData->BmmAskSaveOrNot = TRUE; UpdatePageStart (CallbackData); CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu); EfiZeroMem (CallbackData->BmmFakeNvData.OptionOrder, 100); IfrOptionList = EfiAllocateZeroPool (sizeof (IFR_OPTION) * OptionMenu->MenuNumber); if (NULL == IfrOptionList) { return ; } for (Index = 0; Index < OptionMenu->MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index); IfrOptionList[Index].StringToken = NewMenuEntry->DisplayStringToken; IfrOptionList[Index].Value.u8 = (UINT8) (NewMenuEntry->OptionNumber + 1); IfrOptionList[Index].Flags = 0; CallbackData->BmmFakeNvData.OptionOrder[Index] = IfrOptionList[Index].Value.u8; } if (OptionMenu->MenuNumber > 0) { CreateOrderedListOpCode ( OPTION_ORDER_QUESTION_ID, VARSTORE_ID_BOOT_MAINT, OPTION_ORDER_VAR_OFFSET, STRING_TOKEN (STR_CHANGE_ORDER), STRING_TOKEN (STR_CHANGE_ORDER), 0, 0, EFI_IFR_NUMERIC_SIZE_1, 100, IfrOptionList, OptionMenu->MenuNumber, &gUpdateData ); } SafeFreePool (IfrOptionList); UpdatePageEnd (CallbackData); EfiCopyMem ( CallbackData->BmmOldFakeNVData.OptionOrder, CallbackData->BmmFakeNvData.OptionOrder, 100 ); }
EFI_STATUS EfiFvbInitialize ( VOID ) /*++ Routine Description: Initialize globals and register Fvb Protocol notification function. Arguments: None Returns: EFI_SUCCESS - Fvb is successfully initialized others - Fail to initialize --*/ { UINTN Status; mFvbCount = 0; Status = gBS->AllocatePool ( EfiRuntimeServicesData, (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT, (VOID *) &mFvbEntry ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT); mFvbEvent = RtEfiLibCreateProtocolNotifyEvent ( &gEfiFirmwareVolumeBlockProtocolGuid, EFI_TPL_CALLBACK, FvbNotificationFunction, NULL, &mFvbRegistration ); // // Register SetVirtualAddressMap () notify function // // Status = gBS->CreateEvent ( // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, // EFI_TPL_NOTIFY, // EfiRuntimeLibFvbVirtualNotifyEvent, // NULL, // &mEfiFvbVirtualNotifyEvent // ); // ASSERT_EFI_ERROR (Status); // gEfiFvbInitialized = TRUE; return EFI_SUCCESS; }
VOID EFIAPI InvokeAmdInitMid ( IN EFI_EVENT Event, IN VOID *Context ) /*++ Routine Description: Installs the AmdInitMid This function gets called each time the EFI_EVENT_SIGNAL_READY_TO_BOOT gets signaled Arguments & Return Values: Standard event handling function prototype --*/ { AMD_INTERFACE_PARAMS AmdInterfaceParams; AGESA_STATUS AgesaStatus; AMD_DXE_INIT_MID_PROTOCOL AmdInitMidProtocol; EFI_HANDLE Handle; STATIC BOOLEAN InitMidInvoked = FALSE; // // Prepare for AmdInitMid // if (!InitMidInvoked) { EfiZeroMem (&AmdInterfaceParams, sizeof (AMD_INTERFACE_PARAMS)); AmdInterfaceParams.StdHeader.ImageBasePtr = 0; AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM; AmdInterfaceParams.AllocationMethod = PostMemDram; AmdInterfaceParams.AgesaFunctionName = AMD_INIT_MID; AgesaStatus = AmdCreateStruct (&AmdInterfaceParams); ((AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr)->StdHeader = AmdInterfaceParams.StdHeader; OemCustomizeInitMid (gBS, (AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr); AgesaStatus = AmdInitMid ((AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr); OemHookAfterInitMid (gBS, (AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr); if ((AgesaStatus == AGESA_CRITICAL) || (AgesaStatus == AGESA_FATAL)) { return; } AmdInitMidProtocol.Revision = AGESA_DXE_INIT_MID_REV; Handle = NULL; gBS->InstallProtocolInterface ( &Handle, &gAmdDxeInitMidProtocolGuid, EFI_NATIVE_INTERFACE, &AmdInitMidProtocol ); } InitMidInvoked = TRUE; }
EFI_STATUS CreateOneOfOpCode ( IN EFI_QUESTION_ID QuestionId, IN EFI_VARSTORE_ID VarStoreId, IN UINT16 VarOffset, IN EFI_STRING_ID Prompt, IN EFI_STRING_ID Help, IN UINT8 QuestionFlags, IN UINT8 OneOfFlags, IN IFR_OPTION *OptionsList, IN UINTN OptionCount, IN OUT EFI_HII_UPDATE_DATA *Data ) { UINTN Length; EFI_IFR_ONE_OF OneOf; UINT8 *LocalBuffer; ASSERT (Data != NULL && Data->Data != NULL); if (!IsValidNumricFlags (OneOfFlags) || !IsValidQuestionFlags (QuestionFlags) || ((OptionCount != 0) && (OptionsList == NULL))) { return EFI_INVALID_PARAMETER; } Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END); if (Data->Offset + Length > Data->BufferSize) { return EFI_BUFFER_TOO_SMALL; } OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP; OneOf.Header.Length = (UINT8) sizeof (EFI_IFR_ONE_OF); OneOf.Header.Scope = 1; OneOf.Question.Header.Prompt = Prompt; OneOf.Question.Header.Help = Help; OneOf.Question.QuestionId = QuestionId; OneOf.Question.VarStoreId = VarStoreId; OneOf.Question.VarStoreInfo.VarOffset = VarOffset; OneOf.Question.Flags = QuestionFlags; OneOf.Flags = OneOfFlags; EfiZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA)); LocalBuffer = (UINT8 *) Data->Data + Data->Offset; EfiCopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF)); Data->Offset += sizeof (EFI_IFR_ONE_OF); CreateOneOfOptionOpCode (OptionCount, OptionsList, (UINT8)(OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data); CreateEndOpCode (Data); return EFI_SUCCESS; }
VOID DgpuSpecialPostForHcfiGpu ( IN AMD_CPM_DISPLAY_FEATURE_PROTOCOL *CpmDisplayFeatureProtocolPtr, IN VOID *VBiosImage, IN UINTN VBiosImageSize ) { #ifndef AMD_CPM_EDKII EFI_STATUS Status; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; EFI_IA32_REGISTER_SET Regs; UINT32 TempDBuf; UINT8 *DSegBuffer; UINT16 Patch; CPM_DISPLAY_FEATURE_PRIVATE *DisplayFeatureDataPtr; UINT8 *SaveBufferPtr; EFI_LEGACY_REGION_PROTOCOL *LegacyRegion; DisplayFeatureDataPtr = &CpmDisplayFeatureProtocolPtr->DisplayFeatureData; //Step 00. Allocate memory to save original data Status = gBS->AllocatePool ( EfiRuntimeServicesData, 0x10000, (VOID**)&SaveBufferPtr ); if (!EFI_ERROR (Status)) { //Locate legacy region protocol Status = gBS->LocateProtocol (&gEfiLegacyRegionProtocolGuid, NULL, (VOID**)&LegacyRegion); if (!EFI_ERROR (Status)) { //Step 01. dGPUVBiosSpecialPost Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID**)&LegacyBios); if (!EFI_ERROR (Status)) { LegacyRegion->UnLock (LegacyRegion, 0xD0000, 0x10000, NULL); TempDBuf = 0x000D0000; DSegBuffer = (UINT8 *) (UINTN)TempDBuf; CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (SaveBufferPtr, DSegBuffer, 0x10000); CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (DSegBuffer, VBiosImage, VBiosImageSize); Patch = *((UINT16 *) (UINTN) (TempDBuf + 0x40)); EfiZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); Regs.X.AX = DisplayFeatureDataPtr->GfxDevicePfa[0].Raw; Status = LegacyBios->FarCall86 ( LegacyBios, 0xD000, Patch, &Regs, NULL, 0 ); ASSERT_EFI_ERROR (Status); //Step 02. CopyVBiosFromD000 CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (VBiosImage, DSegBuffer, VBiosImageSize); CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (DSegBuffer, SaveBufferPtr, 0x10000); // lock the D000:0000 after we restore it LegacyRegion->Lock (LegacyRegion, 0xD0000, 0x10000, NULL); } } } Status = gBS->FreePool (SaveBufferPtr); #endif return; }
STATIC EFI_STATUS EFIAPI WinNtSerialIoDriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) /*++ Routine Description: Arguments: Returns: None --*/ // TODO: This - add argument and description to function comment // TODO: Handle - add argument and description to function comment // TODO: RemainingDevicePath - add argument and description to function comment // TODO: EFI_SUCCESS - add return value to function comment // TODO: EFI_SUCCESS - add return value to function comment { EFI_STATUS Status; EFI_WIN_NT_IO_PROTOCOL *WinNtIo; WIN_NT_SERIAL_IO_PRIVATE_DATA *Private; HANDLE NtHandle; UART_DEVICE_PATH Node; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; UINTN EntryCount; UINTN Index; EFI_SERIAL_IO_PROTOCOL *SerialIo; Private = NULL; NtHandle = INVALID_HANDLE_VALUE; // // Grab the protocols we need // Status = gBS->OpenProtocol ( Handle, &gEfiDevicePathProtocolGuid, &ParentDevicePath, This->DriverBindingHandle, Handle, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { return Status; } // // Grab the IO abstraction we need to get any work done // Status = gBS->OpenProtocol ( Handle, &gEfiWinNtIoProtocolGuid, &WinNtIo, This->DriverBindingHandle, Handle, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { gBS->CloseProtocol ( Handle, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Handle ); return Status; } if (Status == EFI_ALREADY_STARTED) { if (RemainingDevicePath == NULL) { return EFI_SUCCESS; } // // Make sure a child handle does not already exist. This driver can only // produce one child per serial port. // Status = gBS->OpenProtocolInformation ( Handle, &gEfiWinNtIoProtocolGuid, &OpenInfoBuffer, &EntryCount ); if (EFI_ERROR (Status)) { return Status; } Status = EFI_ALREADY_STARTED; for (Index = 0; Index < EntryCount; Index++) { if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) { Status = gBS->OpenProtocol ( OpenInfoBuffer[Index].ControllerHandle, &gEfiSerialIoProtocolGuid, &SerialIo, This->DriverBindingHandle, Handle, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (!EFI_ERROR (Status)) { EfiCopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH)); Status = SerialIo->SetAttributes ( SerialIo, Node.BaudRate, SerialIo->Mode->ReceiveFifoDepth, SerialIo->Mode->Timeout, Node.Parity, Node.DataBits, Node.StopBits ); } break; } } gBS->FreePool (OpenInfoBuffer); return Status; } // // Check to see if we can access the hardware device. If it's Open in NT we // will not get access. // NtHandle = WinNtIo->WinNtThunk->CreateFile ( WinNtIo->EnvString, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); if (NtHandle == INVALID_HANDLE_VALUE) { Status = EFI_DEVICE_ERROR; goto Error; } // // Construct Private data // Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA), &Private ); if (EFI_ERROR (Status)) { goto Error; } // // This signature must be valid before any member function is called // Private->Signature = WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE; Private->NtHandle = NtHandle; Private->ControllerHandle = Handle; Private->Handle = NULL; Private->WinNtThunk = WinNtIo->WinNtThunk; Private->ParentDevicePath = ParentDevicePath; Private->ControllerNameTable = NULL; Private->SoftwareLoopbackEnable = FALSE; Private->HardwareLoopbackEnable = FALSE; Private->HardwareFlowControl = FALSE; Private->Fifo.First = 0; Private->Fifo.Last = 0; Private->Fifo.Surplus = SERIAL_MAX_BUFFER_SIZE; EfiLibAddUnicodeString ( LANGUAGE_CODE_ENGLISH, gWinNtSerialIoComponentName.SupportedLanguages, &Private->ControllerNameTable, WinNtIo->EnvString ); Private->SerialIo.Revision = SERIAL_IO_INTERFACE_REVISION; Private->SerialIo.Reset = WinNtSerialIoReset; Private->SerialIo.SetAttributes = WinNtSerialIoSetAttributes; Private->SerialIo.SetControl = WinNtSerialIoSetControl; Private->SerialIo.GetControl = WinNtSerialIoGetControl; Private->SerialIo.Write = WinNtSerialIoWrite; Private->SerialIo.Read = WinNtSerialIoRead; Private->SerialIo.Mode = &Private->SerialIoMode; if (RemainingDevicePath != NULL) { // // Match the configuration of the RemainingDevicePath. IsHandleSupported() // already checked to make sure the RemainingDevicePath contains settings // that we can support. // EfiCopyMem (&Private->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH)); } else { // // Build the device path by appending the UART node to the ParentDevicePath // from the WinNtIo handle. The Uart setings are zero here, since // SetAttribute() will update them to match the default setings. // EfiZeroMem (&Private->UartDevicePath, sizeof (UART_DEVICE_PATH)); Private->UartDevicePath.Header.Type = MESSAGING_DEVICE_PATH; Private->UartDevicePath.Header.SubType = MSG_UART_DP; SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath, sizeof (UART_DEVICE_PATH)); } // // Build the device path by appending the UART node to the ParentDevicePath // from the WinNtIo handle. The Uart setings are zero here, since // SetAttribute() will update them to match the current setings. // Private->DevicePath = EfiAppendDevicePathNode ( ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath ); if (Private->DevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error; } // // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults. // Private->SerialIoMode.ControlMask = SERIAL_CONTROL_MASK; Private->SerialIoMode.Timeout = SERIAL_TIMEOUT_DEFAULT; Private->SerialIoMode.BaudRate = Private->UartDevicePath.BaudRate; Private->SerialIoMode.ReceiveFifoDepth = SERIAL_FIFO_DEFAULT; Private->SerialIoMode.DataBits = Private->UartDevicePath.DataBits; Private->SerialIoMode.Parity = Private->UartDevicePath.Parity; Private->SerialIoMode.StopBits = Private->UartDevicePath.StopBits; // // Issue a reset to initialize the COM port // Status = Private->SerialIo.Reset (&Private->SerialIo); if (EFI_ERROR (Status)) { goto Error; } // // Create new child handle // Status = gBS->InstallMultipleProtocolInterfaces ( &Private->Handle, &gEfiSerialIoProtocolGuid, &Private->SerialIo, &gEfiDevicePathProtocolGuid, Private->DevicePath, NULL ); if (EFI_ERROR (Status)) { goto Error; } // // Open For Child Device // Status = gBS->OpenProtocol ( Handle, &gEfiWinNtIoProtocolGuid, &WinNtIo, This->DriverBindingHandle, Private->Handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); if (EFI_ERROR (Status)) { goto Error; } return EFI_SUCCESS; Error: // // Use the Stop() function to free all resources allocated in Start() // if (Private != NULL) { if (Private->Handle != NULL) { This->Stop (This, Handle, 1, &Private->Handle); } else { if (NtHandle != INVALID_HANDLE_VALUE) { Private->WinNtThunk->CloseHandle (NtHandle); } if (Private->DevicePath != NULL) { gBS->FreePool (Private->DevicePath); } EfiLibFreeUnicodeStringTable (Private->ControllerNameTable); gBS->FreePool (Private); } } This->Stop (This, Handle, 0, NULL); return Status; }
STATIC EFI_STATUS EFIAPI WinNtSerialIoSetAttributes ( IN EFI_SERIAL_IO_PROTOCOL *This, IN UINT64 BaudRate, IN UINT32 ReceiveFifoDepth, IN UINT32 Timeout, IN EFI_PARITY_TYPE Parity, IN UINT8 DataBits, IN EFI_STOP_BITS_TYPE StopBits ) /*++ Routine Description: This function is used to set the attributes. Arguments: This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue. BaudRate - The Baud rate of the serial device. ReceiveFifoDepth - The request depth of fifo on receive side. Timeout - the request timeout for a single charact. Parity - The type of parity used in serial device. DataBits - Number of deata bits used in serial device. StopBits - Number of stop bits used in serial device. Returns: Status code None --*/ // TODO: EFI_SUCCESS - add return value to function comment // TODO: EFI_DEVICE_ERROR - add return value to function comment // TODO: EFI_DEVICE_ERROR - add return value to function comment // TODO: EFI_DEVICE_ERROR - add return value to function comment // TODO: EFI_SUCCESS - add return value to function comment // TODO: EFI_DEVICE_ERROR - add return value to function comment // TODO: EFI_SUCCESS - add return value to function comment { EFI_STATUS Status; UINTN Index; WIN_NT_SERIAL_IO_PRIVATE_DATA *Private; COMMTIMEOUTS PortTimeOuts; DWORD ConvertedTime; BOOL Result; EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; EFI_TPL Tpl; // // for BaudRate, currently we support // 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200,38400,57600,115200 // UINT64 BaudRateCurrentSupport[] = {50, 75, 110, 134, 150, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 19200, 38400, 57600, 115200, SERIAL_PORT_MAX_BAUD_RATE+1}; Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This); // // Some of our arguments have defaults if a null value is passed in, and // we must set the default values if a null argument is passed in. // if (BaudRate == 0) { BaudRate = SERIAL_BAUD_DEFAULT; } if (ReceiveFifoDepth == 0) { ReceiveFifoDepth = SERIAL_FIFO_DEFAULT; } if (Timeout == 0) { Timeout = SERIAL_TIMEOUT_DEFAULT; } if (Parity == DefaultParity) { Parity = NoParity; } if (DataBits == 0) { DataBits = SERIAL_DATABITS_DEFAULT; } if (StopBits == DefaultStopBits) { StopBits = OneStopBit; } // // Make sure all parameters are valid // if ((BaudRate > SERIAL_PORT_MAX_BAUD_RATE) || (BaudRate < SERIAL_PORT_MIN_BAUD_RATE)) { return EFI_INVALID_PARAMETER; } // //The lower baud rate supported by the serial device will be selected without exceeding the unsupported BaudRate parameter // for (Index = 1; Index < (sizeof (BaudRateCurrentSupport) / sizeof (BaudRateCurrentSupport[0])); Index++) { if (BaudRate < BaudRateCurrentSupport[Index]) { BaudRate = BaudRateCurrentSupport[Index-1]; break; } } if ((ReceiveFifoDepth < 1) || (ReceiveFifoDepth > SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH)) { return EFI_INVALID_PARAMETER; } if ((Timeout < SERIAL_PORT_MIN_TIMEOUT) || (Timeout > SERIAL_PORT_MAX_TIMEOUT)) { return EFI_INVALID_PARAMETER; } if ((Parity < NoParity) || (Parity > SpaceParity)) { return EFI_INVALID_PARAMETER; } if ((StopBits < OneStopBit) || (StopBits > TwoStopBits)) { return EFI_INVALID_PARAMETER; } // // Now we only support DataBits=7,8. // if ((DataBits < 7) || (DataBits > 8)) { return EFI_INVALID_PARAMETER; } // // Now we only support DataBits=7,8. // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits. // if (StopBits == OneFiveStopBits) { return EFI_INVALID_PARAMETER; } // // See if the new attributes already match the current attributes // if (Private->UartDevicePath.BaudRate == BaudRate && Private->UartDevicePath.DataBits == DataBits && Private->UartDevicePath.Parity == Parity && Private->UartDevicePath.StopBits == StopBits && Private->SerialIoMode.ReceiveFifoDepth == ReceiveFifoDepth && Private->SerialIoMode.Timeout == Timeout ) { return EFI_SUCCESS; } Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY); // // Get current values from NT // EfiZeroMem (&Private->NtDCB, sizeof (DCB)); Private->NtDCB.DCBlength = sizeof (DCB); if (!Private->WinNtThunk->GetCommState (Private->NtHandle, &Private->NtDCB)) { Private->NtError = Private->WinNtThunk->GetLastError (); DEBUG ((EFI_D_ERROR, "SerialSetAttributes: GetCommState %d\n", Private->NtError)); gBS->RestoreTPL (Tpl); return EFI_DEVICE_ERROR; } // // Map EFI com setting to NT // Private->NtDCB.BaudRate = ConvertBaud2Nt (BaudRate); Private->NtDCB.ByteSize = ConvertData2Nt (DataBits); Private->NtDCB.Parity = ConvertParity2Nt (Parity); Private->NtDCB.StopBits = ConvertStop2Nt (StopBits); Private->NtDCB.fBinary = TRUE; Private->NtDCB.fParity = Private->NtDCB.Parity == NOPARITY ? FALSE : TRUE; Private->NtDCB.fOutxCtsFlow = FALSE; Private->NtDCB.fOutxDsrFlow = FALSE; Private->NtDCB.fDtrControl = DTR_CONTROL_ENABLE; Private->NtDCB.fDsrSensitivity = FALSE; Private->NtDCB.fOutX = FALSE; Private->NtDCB.fInX = FALSE; Private->NtDCB.fRtsControl = RTS_CONTROL_ENABLE; Private->NtDCB.fNull = FALSE; // // Set new values // Result = Private->WinNtThunk->SetCommState (Private->NtHandle, &Private->NtDCB); if (!Result) { Private->NtError = Private->WinNtThunk->GetLastError (); DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommState %d\n", Private->NtError)); gBS->RestoreTPL (Tpl); return EFI_DEVICE_ERROR; } // // Set com port read/write timeout values // ConvertedTime = ConvertTime2Nt (Timeout); PortTimeOuts.ReadIntervalTimeout = MAXDWORD; PortTimeOuts.ReadTotalTimeoutMultiplier = 0; PortTimeOuts.ReadTotalTimeoutConstant = ConvertedTime; PortTimeOuts.WriteTotalTimeoutMultiplier = ConvertedTime == 0 ? 1 : ConvertedTime; PortTimeOuts.WriteTotalTimeoutConstant = 0; if (!Private->WinNtThunk->SetCommTimeouts (Private->NtHandle, &PortTimeOuts)) { Private->NtError = Private->WinNtThunk->GetLastError (); DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommTimeouts %d\n", Private->NtError)); gBS->RestoreTPL (Tpl); return EFI_DEVICE_ERROR; } // // Update mode // Private->SerialIoMode.BaudRate = BaudRate; Private->SerialIoMode.ReceiveFifoDepth = ReceiveFifoDepth; Private->SerialIoMode.Timeout = Timeout; Private->SerialIoMode.Parity = Parity; Private->SerialIoMode.DataBits = DataBits; Private->SerialIoMode.StopBits = StopBits; // // See if Device Path Node has actually changed // if (Private->UartDevicePath.BaudRate == BaudRate && Private->UartDevicePath.DataBits == DataBits && Private->UartDevicePath.Parity == Parity && Private->UartDevicePath.StopBits == StopBits ) { gBS->RestoreTPL(Tpl); return EFI_SUCCESS; } // // Update the device path // Private->UartDevicePath.BaudRate = BaudRate; Private->UartDevicePath.DataBits = DataBits; Private->UartDevicePath.Parity = (UINT8) Parity; Private->UartDevicePath.StopBits = (UINT8) StopBits; NewDevicePath = EfiAppendDevicePathNode ( Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath ); if (NewDevicePath == NULL) { gBS->RestoreTPL (Tpl); return EFI_DEVICE_ERROR; } if (Private->Handle != NULL) { Status = gBS->ReinstallProtocolInterface ( Private->Handle, &gEfiDevicePathProtocolGuid, Private->DevicePath, NewDevicePath ); if (EFI_ERROR (Status)) { gBS->RestoreTPL (Tpl); return Status; } } if (Private->DevicePath != NULL) { gBS->FreePool (Private->DevicePath); } Private->DevicePath = NewDevicePath; gBS->RestoreTPL (Tpl); return EFI_SUCCESS; }
EFI_STATUS EFIAPI TslOpen ( EFI_TSL_INIT_INTERFACE *This, IN OUT EFI_HANDLE *LibHandle, OUT VOID **PrivateLibInterface ) /*++ Routine Description: One interface function of the TslInit to open the support library. Arguments: This - the protocol instance structure. LibHandle - a library handle to bind the TestRecoveryLibrary protocol. PrivateLibInterface - private interface of TestRecoveryLibrary protocol. Returns: EFI_SUCCESS - open the TestRecoveryLibrary successfully. EFI_INVALID_PARAMETER - invalid parameter, LibHandle is NULL. EFI_ALREADY_STARTED - the TestRecoveryLibrary has been bind on the LibHandle before. --*/ { EFI_STATUS Status; TEST_RECOVERY_PRIVATE_DATA *Private; TSL_INIT_PRIVATE_DATA *TslPrivate; // // Check parameter // if (LibHandle == NULL) { return EFI_INVALID_PARAMETER; } TslPrivate = TSL_INIT_PRIVATE_DATA_FROM_THIS (This); // // Open the TestRecoveryLibrary protocol to perform the supported test. // if (*LibHandle != NULL) { Status = gBS->OpenProtocol ( *LibHandle, &gEfiTestRecoveryLibraryGuid, NULL, TslPrivate->ImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (!EFI_ERROR (Status)) { return EFI_ALREADY_STARTED; } } // // Initialize the TestRecoveryLibrary private data // Status = gBS->AllocatePool( EfiBootServicesData, sizeof (TEST_RECOVERY_PRIVATE_DATA), (VOID **)&Private ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (Private, sizeof(TEST_RECOVERY_PRIVATE_DATA)); Private->Signature = TEST_RECOVERY_PRIVATE_DATA_SIGNATURE; Private->TestRecovery.LibraryRevision = 0x10000; Private->TestRecovery.Name = gTrlName; Private->TestRecovery.Description = gTrlDescription; Private->TestRecovery.ReadResetRecord = TrlReadResetRecord; Private->TestRecovery.WriteResetRecord = TrlWriteResetRecord; Private->PrivateInterface.SetConfig = TrlSetConfig; if (PrivateLibInterface != NULL) { *PrivateLibInterface = (VOID *)&(Private->PrivateInterface); } // // Install TestRecoveryLibrary protocol // Status = gBS->InstallProtocolInterface ( LibHandle, &gEfiTestRecoveryLibraryGuid, EFI_NATIVE_INTERFACE, &(Private->TestRecovery) ); return Status; }
EFI_STATUS EFIAPI MiscSubclassDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Description: Standard EFI driver point. This driver parses the mMiscSubclassDataTable structure and reports any generated data to the DataHub. Arguments: ImageHandle Handle for the image of this driver SystemTable Pointer to the EFI System Table Returns: EFI_SUCCESS The data was successfully reported to the Data Hub. --*/ { EFI_MISC_SUBCLASS_DRIVER_DATA RecordData; EFI_DATA_HUB_PROTOCOL *DataHub; #if (EFI_SPECIFICATION_VERSION >= 0x0002000A) EFI_HII_DATABASE_PROTOCOL *HiiDatabase; EFI_HII_PACKAGE_LIST_HEADER *PackageList; #else EFI_HII_PROTOCOL *Hii; EFI_HII_PACKAGES *PackageList; #endif EFI_HII_HANDLE HiiHandle; EFI_STATUS EfiStatus; UINTN Index; BOOLEAN LogRecordData; EFI_EVENT Event; VOID *Registration; // // // EfiInitializeDriverLib (ImageHandle, SystemTable); // // Initialize constant portion of subclass header. // RecordData.Header.Version = EFI_MISC_SUBCLASS_VERSION; RecordData.Header.HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER); RecordData.Header.Instance = 1; RecordData.Header.SubInstance = 1; // // Locate data hub protocol. // EfiStatus = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub); if (EFI_ERROR (EfiStatus)) { DEBUG ((EFI_D_ERROR, "Could not locate DataHub protocol. %r\n", EfiStatus)); return EfiStatus; } else if (DataHub == NULL) { DEBUG ((EFI_D_ERROR, "LocateProtocol(DataHub) returned NULL pointer!\n")); return EFI_DEVICE_ERROR; } // // Locate hii protocol. // #if (EFI_SPECIFICATION_VERSION >= 0x0002000A) EfiStatus = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase); if (EFI_ERROR (EfiStatus)) { DEBUG ((EFI_D_ERROR, "Could not locate HiiDatabase protocol. %r\n", EfiStatus)); return EfiStatus; } else if (HiiDatabase == NULL) { DEBUG ((EFI_D_ERROR, "LocateProtocol(HiiDatabase) returned NULL pointer!\n")); return EFI_DEVICE_ERROR; } // // Add our default strings to the HII database. They will be modified later. // PackageList = PreparePackageList (1, &gEfiMiscSubClassGuid, MiscSubclassStrings); EfiStatus = HiiDatabase->NewPackageList (HiiDatabase, PackageList, ImageHandle, &HiiHandle); #else EfiStatus = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii); if (EFI_ERROR (EfiStatus)) { DEBUG ((EFI_D_ERROR, "Could not locate Hii protocol. %r\n", EfiStatus)); return EfiStatus; } else if (Hii == NULL) { DEBUG ((EFI_D_ERROR, "LocateProtocol(Hii) returned NULL pointer!\n")); return EFI_DEVICE_ERROR; } // // Add our default strings to the HII database. They will be modified later. // PackageList = PreparePackages (1, &gEfiMiscSubClassGuid, MiscSubclassStrings); EfiStatus = Hii->NewPack (Hii, PackageList, &HiiHandle); #endif gBS->FreePool (PackageList); if (EFI_ERROR (EfiStatus)) { DEBUG ((EFI_D_ERROR, "Could not log default strings to Hii. %r\n", EfiStatus)); return EfiStatus; } // // // for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) { // // Stupidity check! Do nothing if RecordLen is zero. // %%TBD - Should this be an error or a mechanism for ignoring // records in the Data Table? // if (mMiscSubclassDataTable[Index].RecordLen == 0) { DEBUG ( (EFI_D_ERROR, "mMiscSubclassDataTable[%d].RecordLen == 0\n", Index) ); continue; } // // Initialize per-record portion of subclass header and // copy static data into data portion of subclass record. // RecordData.Header.RecordType = mMiscSubclassDataTable[Index].RecordType; if (mMiscSubclassDataTable[Index].RecordData == NULL) { EfiZeroMem ( &RecordData.Record, mMiscSubclassDataTable[Index].RecordLen ); } else { EfiCopyMem ( &RecordData.Record, mMiscSubclassDataTable[Index].RecordData, mMiscSubclassDataTable[Index].RecordLen ); } // // If the entry does not have a function pointer, just log the data. // if (mMiscSubclassDataTable[Index].Function == NULL) { // // Log RecordData to Data Hub. // EfiStatus = DataHub->LogData ( DataHub, &gEfiMiscSubClassGuid, &gEfiMiscSubClassGuid, EFI_DATA_RECORD_CLASS_DATA, &RecordData, sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen ); if (EFI_ERROR (EfiStatus)) { DEBUG ( (EFI_D_ERROR, "LogData(%d bytes) == %r\n", sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen, EfiStatus) ); } continue; } // // The entry has a valid function pointer. // Keep calling the function and logging data until there // is no more data to log. // for (;;) { // // // EfiStatus = (*mMiscSubclassDataTable[Index].Function) ( mMiscSubclassDataTable[Index].RecordType, &mMiscSubclassDataTable[Index].RecordLen, &RecordData.Record, & LogRecordData ); // // // if (EFI_ERROR (EfiStatus)) { break; } if (!LogRecordData) { break; } // // // EfiStatus = DataHub->LogData ( DataHub, &gEfiMiscSubClassGuid, &gEfiMiscSubClassGuid, EFI_DATA_RECORD_CLASS_DATA, &RecordData, sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen ); if (EFI_ERROR (EfiStatus)) { DEBUG ( (EFI_D_ERROR, "LogData(%d bytes) == %r\n", sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen, EfiStatus) ); } } } // // Install notify function to fetch memory data through WinNtIo protocol and store to data hub. // EfiStatus = gBS->CreateEvent ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_CALLBACK, WinNtIoProtocolNotifyFunction, ImageHandle, &Event ); ASSERT (!EFI_ERROR (EfiStatus)); EfiStatus = gBS->RegisterProtocolNotify ( &gEfiWinNtIoProtocolGuid, Event, &Registration ); ASSERT (!EFI_ERROR (EfiStatus)); return EFI_SUCCESS; }
EFI_STATUS AddOpCode ( IN VOID *FormBuffer, IN OUT VOID *OpCodeData ) /*++ Routine Description: Add op-code data to the FormBuffer Arguments: FormBuffer - Form buffer to be inserted to OpCodeData - Op-code data to be inserted Returns: EFI_OUT_OF_RESOURCES - No enough buffer to allocate EFI_SUCCESS - Op-code data successfully inserted --*/ { EFI_HII_PACK_HEADER *NewBuffer; UINT8 *Source; UINT8 *Destination; // // Pre-allocate a buffer sufficient for us to work on. // We will use it as a destination scratch pad to build data on // and when complete shift the data back to the original buffer // NewBuffer = EfiLibAllocateZeroPool (DEFAULT_FORM_BUFFER_SIZE); if (NewBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } Source = (UINT8 *) FormBuffer; Destination = (UINT8 *) NewBuffer; // // Copy the IFR Package header to the new buffer // EfiCopyMem (Destination, Source, sizeof (EFI_HII_PACK_HEADER)); // // Advance Source and Destination to next op-code // Source = Source + sizeof (EFI_HII_PACK_HEADER); Destination = Destination + sizeof (EFI_HII_PACK_HEADER); // // Copy data to the new buffer until we run into the end_form // for (; ((EFI_IFR_OP_HEADER *) Source)->OpCode != EFI_IFR_END_FORM_OP;) { // // If the this opcode is an end_form_set we better be creating and endform // Nonetheless, we will add data before the end_form_set. This also provides // for interesting behavior in the code we will run, but has no bad side-effects // since we will possibly do a 0 byte copy in this particular end-case. // if (((EFI_IFR_OP_HEADER *) Source)->OpCode == EFI_IFR_END_FORM_SET_OP) { break; } // // Copy data to new buffer // EfiCopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length); // // Adjust Source/Destination to next op-code location // Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length; Source = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length; } // // Prior to the end_form is where we insert the new op-code data // EfiCopyMem (Destination, OpCodeData, ((EFI_IFR_OP_HEADER *) OpCodeData)->Length); Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; NewBuffer->Length = (UINT32) (NewBuffer->Length + (UINT32) (((EFI_IFR_OP_HEADER *) OpCodeData)->Length)); // // Copy end-form data to new buffer // EfiCopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length); // // Adjust Source/Destination to next op-code location // Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length; Source = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length; // // Copy end-formset data to new buffer // EfiCopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length); // // Zero out the original buffer and copy the updated data in the new buffer to the old buffer // EfiZeroMem (FormBuffer, DEFAULT_FORM_BUFFER_SIZE); EfiCopyMem (FormBuffer, NewBuffer, DEFAULT_FORM_BUFFER_SIZE); // // Free the newly created buffer since we don't need it anymore // gBS->FreePool (NewBuffer); return EFI_SUCCESS; }
EFI_DEBUG_STATUS DebuggerInstructionBranch ( IN CHAR16 *CommandArg, IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext ) /*++ Routine Description: DebuggerCommand - InstructionBranch Arguments: CommandArg - The argument for this command DebuggerPrivate - EBC Debugger private data structure InterruptType - Interrupt type. SystemContext - EBC system context. Returns: EFI_DEBUG_CONTINUE - formal return value --*/ { UINTN Index; // // Check argument // if (CommandArg != NULL) { if (EfiStriCmp (CommandArg, L"c") == 0) { // // Clear Trace // DebuggerPrivate->TraceEntryCount = 0; EfiZeroMem (DebuggerPrivate->TraceEntry, sizeof(DebuggerPrivate->TraceEntry)); EDBPrint (L"Instruction Trace is cleared\n"); } else { EDBPrint (L"Trace argument Invalid\n"); } return EFI_DEBUG_CONTINUE; } // // Check Trace Entry Count // if (DebuggerPrivate->TraceEntryCount == 0) { EDBPrint (L"No Instruction Trace\n"); return EFI_DEBUG_CONTINUE; } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) { EDBPrint (L"Instruction Trace Crash, re-initialize!\n"); DebuggerPrivate->TraceEntryCount = 0; return EFI_DEBUG_CONTINUE; } // // Go through each Trace entry and print // EDBPrint (L"Instruction Trace (->Latest):\n"); EDBPrint (L" Source Addr Destination Addr Type\n"); EDBPrint (L" ================== ================== ========\n"); //EDBPrint (L" 0x00000000FFFFFFFF 0xFFFFFFFF00000000 (CALLEX)\n"); for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) { EDBPrint ( L" 0x%016lx 0x%016lx %s\n", DebuggerPrivate->TraceEntry[Index].SourceAddress, DebuggerPrivate->TraceEntry[Index].DestAddress, EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type) ); } // // Done // return EFI_DEBUG_CONTINUE; }
/** *--------------------------------------------------------------------------------------- * * AgesaDxeCallout * * Description: * AGESA DXE Call out dispatcher * * Parameters: * @param[in] Param1 * @param[in] Param2 * @param[in, out] *ConfigPtr * * @retval AGESA_STATUS * *--------------------------------------------------------------------------------------- **/ EFI_STATUS AgesaDxeCallout ( IN UINT32 Param1, IN UINTN Param2, IN OUT VOID *ConfigPtr ) { EFI_STATUS Status; AGESA_STATUS AgesaStatus; AGESA_BUFFER_PARAMS *BufferConfigPtr; AGESA_DXE_BUFFER_MANAGER *AgesaLocateBufferPtr; AGESA_DXE_BUFFER_MANAGER *PreviousBufferPtr; Status = EFI_UNSUPPORTED; AgesaStatus = AGESA_UNSUPPORTED; BufferConfigPtr = (AGESA_BUFFER_PARAMS *) ConfigPtr; AgesaLocateBufferPtr = NULL; PreviousBufferPtr = NULL; switch (Param1) { case AGESA_ALLOCATE_BUFFER: if (Param2 == HEAP_CALLOUT_BOOTTIME) { Status = gBS->AllocatePool ( EfiBootServicesData, BufferConfigPtr->BufferLength, &BufferConfigPtr->BufferPointer ); } else if (Param2 == HEAP_CALLOUT_RUNTIME) { Status = gBS->AllocatePool ( EfiACPIMemoryNVS, BufferConfigPtr->BufferLength, &BufferConfigPtr->BufferPointer ); } if (EFI_ERROR (Status)) { return Status; } // // Initialize the memory // EfiZeroMem (BufferConfigPtr->BufferPointer, BufferConfigPtr->BufferLength); // // Create the first buffer for AGESA_ALLOCATE_BUFFER Manager // AgesaBufferManager->BufferLength = BufferConfigPtr->BufferLength; AgesaBufferManager->BufferHandle = BufferConfigPtr->BufferHandle; AgesaBufferManager->BufferPtr = BufferConfigPtr->BufferPointer; Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (AGESA_DXE_BUFFER_MANAGER), &AgesaBufferManager->NextAgesaBufferManagerPtr ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (AgesaBufferManager->NextAgesaBufferManagerPtr, sizeof (AGESA_DXE_BUFFER_MANAGER)); AgesaBufferManager = AgesaBufferManager->NextAgesaBufferManagerPtr; AgesaBufferManager->NextAgesaBufferManagerPtr = NULL; break; case AGESA_DEALLOCATE_BUFFER: AgesaLocateBufferPtr = mAgesaDxePrivate->BufferManagerPtr; while (AgesaLocateBufferPtr->NextAgesaBufferManagerPtr != NULL) { if (AgesaLocateBufferPtr->BufferHandle == BufferConfigPtr->BufferHandle) { // // Before deleting the current buffer from the link, setup the link from // previous to next buffer pointer to maintain the continuity of the link // list. // PreviousBufferPtr->NextAgesaBufferManagerPtr = AgesaLocateBufferPtr->NextAgesaBufferManagerPtr; Status = gBS->FreePool (AgesaLocateBufferPtr); break; } PreviousBufferPtr = AgesaLocateBufferPtr; AgesaLocateBufferPtr = AgesaLocateBufferPtr->NextAgesaBufferManagerPtr; } break; case AGESA_LOCATE_BUFFER: AgesaLocateBufferPtr = mAgesaDxePrivate->BufferManagerPtr; while (AgesaLocateBufferPtr->NextAgesaBufferManagerPtr != NULL) { if (AgesaLocateBufferPtr->BufferHandle == BufferConfigPtr->BufferHandle) { BufferConfigPtr->BufferPointer = AgesaLocateBufferPtr->BufferPtr; BufferConfigPtr->BufferLength = (UINT32) AgesaLocateBufferPtr->BufferLength; Status = EFI_SUCCESS; break; } AgesaLocateBufferPtr = AgesaLocateBufferPtr->NextAgesaBufferManagerPtr; } break; default: break; } return Status; }
EFI_STATUS EFIAPI AgesaDxeDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; AMD_INTERFACE_PARAMS AmdInterfaceParams; AGESA_STATUS AgesaStatus; AMD_ENV_PARAMS AmdInitEnvParams; EFI_EVENT ReadyToBootEvent; EFI_HANDLE Handle; AMD_BUFFER_MANAGER_PROTOCOL *BufferMgr; // // Initialize Global Variable // EfiInitializeDriverLib (ImageHandle, SystemTable); // // Initialize the configuration structure and private data area // // Allocate memory for the private data Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (AGESA_DXE_PRIVATE_DATA), &mAgesaDxePrivate); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } // // Install the AMD_AGESA_MMIO_PROTOCOL // mAgesaDxePrivate->MmioMapManager.AmdMmioMapManager = AmdMmioMapManager; Handle = NULL; gBS->InstallProtocolInterface ( &Handle, &gAmdAgesaMmioProtocolGuid, EFI_NATIVE_INTERFACE, &mAgesaDxePrivate->MmioMapManager ); // // Initialize the private data structure // mAgesaDxePrivate->Signature = AGESA_DXE_PRIVATE_DATA_SIGNATURE; // // Create the first buffer for AGESA_ALLOCATE_BUFFER Manager // Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (AGESA_DXE_BUFFER_MANAGER), &mAgesaDxePrivate->BufferManagerPtr ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (mAgesaDxePrivate->BufferManagerPtr, sizeof (AGESA_DXE_BUFFER_MANAGER)); mAgesaDxePrivate->BufferManagerPtr->NextAgesaBufferManagerPtr = NULL; AgesaBufferManager = mAgesaDxePrivate->BufferManagerPtr; // // Rebuild persist heap from HOB. // Status = RebuildHeap (&mAgesaDxePrivate->HeapManagerPtr); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } // // Invoke AmdInitEnv // EfiZeroMem (&AmdInterfaceParams, sizeof (AMD_INTERFACE_PARAMS)); EfiZeroMem (&AmdInitEnvParams, sizeof (AMD_ENV_PARAMS)); AmdInterfaceParams.StdHeader.ImageBasePtr = 0; AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM; AmdInterfaceParams.AllocationMethod = ByHost; AmdInterfaceParams.AgesaFunctionName = AMD_INIT_ENV; AmdInterfaceParams.NewStructPtr = &AmdInitEnvParams; AmdInterfaceParams.NewStructSize = sizeof (AMD_ENV_PARAMS); AgesaStatus = AmdCreateStruct (&AmdInterfaceParams); AmdInitEnvParams.StdHeader = AmdInterfaceParams.StdHeader; OemCustomizeInitEnv (gBS, &AmdInitEnvParams); AgesaStatus = AmdInitEnv (&AmdInitEnvParams); OemHookAfterInitEnv (gBS, &AmdInitEnvParams); if ((AgesaStatus == AGESA_CRITICAL) || (AgesaStatus == AGESA_FATAL)) { return EFI_DEVICE_ERROR; } // // Install AmdBufferManagerProtocol which notifies other dependent drivers // Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (AMD_BUFFER_MANAGER_PROTOCOL), &BufferMgr ); ASSERT_EFI_ERROR (Status); BufferMgr->StdHeader = AmdInitEnvParams.StdHeader; BufferMgr->DxeBufferManager = mAgesaDxePrivate->BufferManagerPtr; BufferMgr->AmdBufferCallout = AgesaDxeCallout; Handle = NULL; gBS->InstallProtocolInterface ( &Handle, &gAmdBufferManagerProtocolGuid, EFI_NATIVE_INTERFACE, BufferMgr ); // // Register the event handling function for AmdInitMid to be launched after // PciIo protocol // Status = gBS->CreateEventEx ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_NOTIFY, InvokeAmdInitMid, NULL, &PciIoProtocolInstallEventGuid, &PciIoEvent ); Status = gBS->RegisterProtocolNotify ( &gEfiPciIoProtocolGuid, PciIoEvent, &mRegistrationForPciIo ); // // Set up call back for AmdInitLate after AmdInitMid has been launched. // Status = gBS->CreateEventEx ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_NOTIFY, InvokeAmdInitLate, NULL, &AmdInitMidProtocolInstallEventGuid, &AmdInitMidEvent ); Status = gBS->RegisterProtocolNotify ( &gAmdDxeInitMidProtocolGuid, AmdInitMidEvent, &(mRegistrationForAmdInitMid) ); // // Initialize AMD CPU Interface protocol // mAgesaDxePrivate->CpuInterface.CreateProcessorTables = AmdCpuCreateProcessorTables; // Invoke AmdInitRtb // Register the event handling function to do last minute configuration and // preparation for system suspend-to-RAM mode. // Status = gBS->CreateEventEx ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_NOTIFY, AgesaInitRtb, NULL, &gEfiEventReadyToBootGuid, &ReadyToBootEvent ); return EFI_SUCCESS; }
EFI_STATUS RebuildHeap ( IN OUT HEAP_MANAGER **HeapManagerPtr ) { EFI_STATUS Status; AGESA_STATUS AgesaStatus; UINTN BufferSize; UINTN AlignTo16ByteInDxeMem; UINTN TotalAlignTo16ByteInHob; EFI_PEI_HOB_POINTERS Hob; VOID *HobList; VOID *HeapBufferInHob; HEAP_MANAGER *HeapManagerInHob; BUFFER_NODE *HeapHeaderNodeInHob; BUFFER_NODE *HeapCurrentNodeInHob; BUFFER_NODE *HeapPreNodeInHob; HEAP_MANAGER *HeapManagerInDxeMem; BUFFER_NODE *HeapHeaderNodeInDxeMem; BUFFER_NODE *HeapCurrentNodeInDxeMem; BUFFER_NODE *HeapPreNodeInDxeMem; UINT32 OffsetOfHeapCurrentNodeInDxeMem; AGESA_BUFFER_PARAMS AllocParams; Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList); ASSERT_EFI_ERROR (Status); Hob.Raw = HobList; HeapBufferInHob = NULL; while (!END_OF_HOB_LIST (Hob)) { Status = GetNextGuidHob ( &HobList, &gAmdHeapHobGuid, &HeapBufferInHob, &BufferSize ); if (Status == EFI_SUCCESS ) { HeapManagerInHob = (HEAP_MANAGER *) HeapBufferInHob; HeapHeaderNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapManagerInHob + HeapManagerInHob->FirstActiveBufferOffset); HeapCurrentNodeInHob = HeapHeaderNodeInHob; // // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers // Reserve maximum pad size for each heap node. // 2. Allocate memory for heap buffers // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment // // // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers. // Reserve maximum pad size for each heap node. // TotalAlignTo16ByteInHob = 0; do { HeapPreNodeInHob = HeapCurrentNodeInHob; TotalAlignTo16ByteInHob += 0xF; HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode); } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET); // // 2. Allocate memory for heap buffers // AllocParams.BufferLength = (UINT32) (HeapManagerInHob->UsedSize + TotalAlignTo16ByteInHob + 0x0F); AllocParams.BufferHandle = AMD_HEAP_IN_MAIN_MEMORY_HANDLE; if ((AgesaStatus = AgesaAllocateBuffer (0, &AllocParams)) != AGESA_SUCCESS) { if (AGESA_ERROR > AgesaStatus) { return EFI_OUT_OF_RESOURCES; } } EfiZeroMem (AllocParams.BufferPointer, AllocParams.BufferLength); *HeapManagerPtr = AllocParams.BufferPointer; // // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment // HeapManagerInDxeMem = *HeapManagerPtr; HeapManagerInDxeMem->FirstActiveBufferOffset = sizeof (HEAP_MANAGER); HeapManagerInDxeMem->UsedSize = sizeof (HEAP_MANAGER); HeapHeaderNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapManagerInDxeMem->FirstActiveBufferOffset); OffsetOfHeapCurrentNodeInDxeMem = HeapManagerInDxeMem->FirstActiveBufferOffset; HeapCurrentNodeInDxeMem = HeapHeaderNodeInDxeMem; HeapCurrentNodeInHob = HeapHeaderNodeInHob; HeapPreNodeInHob = NULL; do { // Create BUFFER_NODE with 16-byte alignment padding considered. // The beginning of data buffer is on 16-byte boundary address. // The structure of a heap buffer would be looked like below. // // +---------------------------------------------------------------------------------+ // | BUFFER_NODE | Pad | IDS SENTINEL ("Head") | Data buffer | IDS SENTINEL ("Tail") | // +---------------------------------------------------------------------------------+ // AlignTo16ByteInDxeMem = ((0x10 - (((UINTN) (VOID *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL) & 0xF)) & 0xF); HeapCurrentNodeInDxeMem->BufferHandle = HeapCurrentNodeInHob->BufferHandle; HeapCurrentNodeInDxeMem->BufferSize = (UINT32) (HeapCurrentNodeInHob->BufferSize + AlignTo16ByteInDxeMem); HeapCurrentNodeInDxeMem->Persist = HeapCurrentNodeInHob->Persist; HeapCurrentNodeInDxeMem->PadSize = (UINT8) AlignTo16ByteInDxeMem; HeapCurrentNodeInDxeMem->OffsetOfNextNode = OffsetOfHeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + HeapCurrentNodeInDxeMem->BufferSize; // Copy buffer data gBS->CopyMem ( (UINT8 *) ((UINT8 *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + AlignTo16ByteInDxeMem), (UINT8 *) ((UINT8 *) HeapCurrentNodeInHob + sizeof (BUFFER_NODE)), HeapCurrentNodeInHob->BufferSize ); // Point to the next heap node HeapPreNodeInHob = HeapCurrentNodeInHob; HeapPreNodeInDxeMem = HeapCurrentNodeInDxeMem; HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode); HeapCurrentNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapCurrentNodeInDxeMem->OffsetOfNextNode); OffsetOfHeapCurrentNodeInDxeMem = (UINT32) ((UINTN) HeapCurrentNodeInDxeMem - (UINTN) HeapManagerInDxeMem); } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET); // // Finalize the last heap node // HeapManagerInDxeMem->UsedSize = (UINT32) HeapPreNodeInDxeMem->OffsetOfNextNode; HeapPreNodeInDxeMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET; // // Finalize Heap Manager pointer // No free buffer node is provide after heap recreation. // *HeapManagerPtr = HeapManagerInDxeMem; HeapManagerInDxeMem->FirstActiveBufferOffset = (UINT32) ((UINT8 *) HeapHeaderNodeInDxeMem - (UINT8 *) HeapManagerInDxeMem); HeapManagerInDxeMem->FirstFreeSpaceOffset = AMD_HEAP_INVALID_HEAP_OFFSET; HeapManagerInDxeMem->Signature = HeapManagerInHob->Signature; return EFI_SUCCESS; } } return EFI_NOT_FOUND; }
EFI_STATUS GetNumericInput ( IN UI_MENU_SELECTION *Selection, IN UI_MENU_OPTION *MenuOption ) /*++ Routine Description: This routine reads a numeric value from the user input. Arguments: Selection - Pointer to current selection. MenuOption - Pointer to the current input menu. Returns: EFI_SUCCESS - If numerical input is read successfully EFI_DEVICE_ERROR - If operation fails --*/ { EFI_STATUS Status; UINTN Column; UINTN Row; CHAR16 InputText[23]; CHAR16 FormattedNumber[22]; UINT64 PreviousNumber[20]; UINTN Count; UINTN Loop; BOOLEAN ManualInput; BOOLEAN HexInput; BOOLEAN DateOrTime; UINTN InputWidth; UINT64 EditValue; UINT64 Step; UINT64 Minimum; UINT64 Maximum; UINTN EraseLen; UINT8 Digital; EFI_INPUT_KEY Key; EFI_HII_VALUE *QuestionValue; FORM_BROWSER_FORM *Form; FORM_BROWSER_FORMSET *FormSet; FORM_BROWSER_STATEMENT *Question; Column = MenuOption->OptCol; Row = MenuOption->Row; PreviousNumber[0] = 0; Count = 0; InputWidth = 0; Digital = 0; FormSet = Selection->FormSet; Form = Selection->Form; Question = MenuOption->ThisTag; QuestionValue = &Question->HiiValue; Step = Question->Step; Minimum = Question->Minimum; Maximum = Question->Maximum; if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) { DateOrTime = TRUE; } else { DateOrTime = FALSE; } // // Prepare Value to be edit // EraseLen = 0; EditValue = 0; if (Question->Operand == EFI_IFR_DATE_OP) { Step = 1; Minimum = 1; switch (MenuOption->Sequence) { case 0: Maximum = 12; EraseLen = 4; EditValue = QuestionValue->Value.date.Month; break; case 1: Maximum = 31; EraseLen = 3; EditValue = QuestionValue->Value.date.Day; break; case 2: Maximum = 0xffff; EraseLen = 5; EditValue = QuestionValue->Value.date.Year; break; default: break; } } else if (Question->Operand == EFI_IFR_TIME_OP) { Step = 1; Minimum = 0; switch (MenuOption->Sequence) { case 0: Maximum = 23; EraseLen = 4; EditValue = QuestionValue->Value.time.Hour; break; case 1: Maximum = 59; EraseLen = 3; EditValue = QuestionValue->Value.time.Minute; break; case 2: Maximum = 59; EraseLen = 3; EditValue = QuestionValue->Value.time.Second; break; default: break; } } else { // // Numeric // EraseLen = gOptionBlockWidth; EditValue = QuestionValue->Value.u64; if (Maximum == 0) { Maximum = (UINT64) -1; } } if (Step == 0) { ManualInput = TRUE; } else { ManualInput = FALSE; } if ((Question->Operand == EFI_IFR_NUMERIC_OP) && ((Question->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) { HexInput = TRUE; } else { HexInput = FALSE; } if (ManualInput) { if (HexInput) { InputWidth = Question->StorageWidth * 2; } else { switch (Question->StorageWidth) { case 1: InputWidth = 3; break; case 2: InputWidth = 5; break; case 4: InputWidth = 10; break; case 8: InputWidth = 20; break; default: InputWidth = 0; break; } } InputText[0] = LEFT_NUMERIC_DELIMITER; SetUnicodeMem (InputText + 1, InputWidth, L' '); InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER; InputText[InputWidth + 2] = L'\0'; PrintAt (Column, Row, InputText); Column++; } // // First time we enter this handler, we need to check to see if // we were passed an increment or decrement directive // do { Key.UnicodeChar = CHAR_NULL; if (gDirection != 0) { Key.ScanCode = gDirection; gDirection = 0; goto TheKey2; } Status = WaitForKeyStroke (&Key); TheKey2: switch (Key.UnicodeChar) { case '+': case '-': if (Key.UnicodeChar == '+') { Key.ScanCode = SCAN_RIGHT; } else { Key.ScanCode = SCAN_LEFT; } Key.UnicodeChar = CHAR_NULL; goto TheKey2; case CHAR_NULL: switch (Key.ScanCode) { case SCAN_LEFT: case SCAN_RIGHT: if (DateOrTime) { // // By setting this value, we will return back to the caller. // We need to do this since an auto-refresh will destroy the adjustment // based on what the real-time-clock is showing. So we always commit // upon changing the value. // gDirection = SCAN_DOWN; } if (!ManualInput) { if (Key.ScanCode == SCAN_LEFT) { if (EditValue > Step) { EditValue = EditValue - Step; } else { EditValue = Minimum; } } else if (Key.ScanCode == SCAN_RIGHT) { EditValue = EditValue + Step; if (EditValue > Maximum) { EditValue = Maximum; } } EfiZeroMem (FormattedNumber, 21 * sizeof (CHAR16)); if (Question->Operand == EFI_IFR_DATE_OP) { if (MenuOption->Sequence == 2) { // // Year // SPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINTN) EditValue); } else { // // Month/Day // SPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINTN) EditValue); } if (MenuOption->Sequence == 0) { FormattedNumber[EraseLen - 2] = DATE_SEPARATOR; } else if (MenuOption->Sequence == 1) { FormattedNumber[EraseLen - 1] = DATE_SEPARATOR; } } else if (Question->Operand == EFI_IFR_TIME_OP) { SPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINTN) EditValue); if (MenuOption->Sequence == 0) { FormattedNumber[EraseLen - 2] = TIME_SEPARATOR; } else if (MenuOption->Sequence == 1) { FormattedNumber[EraseLen - 1] = TIME_SEPARATOR; } } else { QuestionValue->Value.u64 = EditValue; PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16)); } gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND); for (Loop = 0; Loop < EraseLen; Loop++) { PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" "); } gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT); if (MenuOption->Sequence == 0) { PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER); Column = MenuOption->OptCol + 1; } PrintStringAt (Column, Row, FormattedNumber); if (!DateOrTime || MenuOption->Sequence == 2) { PrintChar (RIGHT_NUMERIC_DELIMITER); } goto EnterCarriageReturn; } break; case SCAN_UP: case SCAN_DOWN: goto EnterCarriageReturn; case SCAN_ESC: return EFI_DEVICE_ERROR; default: break; } break; EnterCarriageReturn: case CHAR_CARRIAGE_RETURN: // // Store Edit value back to Question // if (Question->Operand == EFI_IFR_DATE_OP) { switch (MenuOption->Sequence) { case 0: QuestionValue->Value.date.Month = (UINT8) EditValue; break; case 1: QuestionValue->Value.date.Day = (UINT8) EditValue; break; case 2: QuestionValue->Value.date.Year = (UINT16) EditValue; break; default: break; } } else if (Question->Operand == EFI_IFR_TIME_OP) { switch (MenuOption->Sequence) { case 0: QuestionValue->Value.time.Hour = (UINT8) EditValue; break; case 1: QuestionValue->Value.time.Minute = (UINT8) EditValue; break; case 2: QuestionValue->Value.time.Second = (UINT8) EditValue; break; default: break; } } else { // // Numeric // QuestionValue->Value.u64 = EditValue; } // // Check to see if the Value is something reasonable against consistency limitations. // If not, let's kick the error specified. // Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF); if (EFI_ERROR (Status)) { // // Input value is not valid, restore Question Value // GetQuestionValue (FormSet, Form, Question, TRUE); } else { SetQuestionValue (FormSet, Form, Question, TRUE); if (!DateOrTime || (Question->Storage != NULL)) { // // NV flag is unnecessary for RTC type of Date/Time // UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); } } return Status; break; case CHAR_BACKSPACE: if (ManualInput) { if (Count == 0) { break; } // // Remove a character // EditValue = PreviousNumber[Count - 1]; UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE); Count--; Column--; PrintAt (Column, Row, L" "); } break; default: if (ManualInput) { if (HexInput) { if (!IsHexDigit (&Digital, Key.UnicodeChar)) { UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE); break; } } else { if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') { UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE); break; } } // // If Count exceed input width, there is no way more is valid // if (Count >= InputWidth) { break; } // // Someone typed something valid! // if (Count != 0) { if (HexInput) { EditValue = LShiftU64 (EditValue, 4) + Digital; } else { // // EditValue = EditValue * 10 + (Key.UnicodeChar - L'0'); // EditValue = LShiftU64 (EditValue, 3) + LShiftU64 (EditValue, 1) + (Key.UnicodeChar - L'0'); } } else { if (HexInput) { EditValue = Digital; } else { EditValue = Key.UnicodeChar - L'0'; } } if (EditValue > Maximum) { UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE); EditValue = PreviousNumber[Count]; break; } else { UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE); } Count++; PreviousNumber[Count] = EditValue; PrintCharAt (Column, Row, Key.UnicodeChar); Column++; } break; } } while (TRUE); return EFI_SUCCESS; }
// // ///////////////////////////////////////////////////////////////////// // // Udp Read Routine - called by base code - e.g. TFTP - already locked // EFI_STATUS TcpRead ( IN PXE_BASECODE_DEVICE *Private, IN UINT16 OpFlags, IN OUT EFI_IP_ADDRESS *DestIpPtr, OPTIONAL IN OUT EFI_PXE_BASE_CODE_TCP_PORT *DestPortPtr, OPTIONAL IN OUT EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL IN OUT EFI_PXE_BASE_CODE_TCP_PORT *SrcPortPtr, OPTIONAL IN UINTN *HeaderSizePtr, OPTIONAL IN VOID *HeaderPtr, IN OUT UINTN *BufferSizePtr, IN VOID *BufferPtr ) /*++ Routine description: TCP read packet. Parameters: Private := Pointer to PxeBc interface OpFlags := DestIpPtr := DestPortPtr := SrcIpPtr := SrcPortPtr := HeaderSizePtr := HeaderPtr := BufferSizePtr := BufferPtr := Returns: EFI_SUCCESS := EFI_DEVICE_ERROR := EFI_INVALID_PARAMETER := other := --*/ { EFI_IP_ADDRESS TmpSrcIp; EFI_IP_ADDRESS TmpDestIp; EFI_STATUS StatCode; UINTN BufferSize; UINTN HeaderSize; // // combination structure of pseudo header/tcp header // #pragma pack (1) struct { IPV4_HEADER Ipv4Hdr; TCPV4_PSEUDO_HEADER Tcpv4Phdr; TCPV4_HEADER Tcpv4Hdr; UINT8 ProtHdr[64]; } Hdrs; #pragma pack () HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0; // // Yes, I now require a Header Allocated // if (HeaderPtr == 0) { return EFI_DEVICE_ERROR; } HeaderSize = sizeof Hdrs.Ipv4Hdr + sizeof Hdrs.Tcpv4Hdr; EfiZeroMem (Hdrs.ProtHdr, 64); Hdrs.ProtHdr[0] = 'M'; Hdrs.ProtHdr[1] = 'A'; Hdrs.ProtHdr[2] = 'R'; Hdrs.ProtHdr[3] = 'M'; Hdrs.ProtHdr[4] = 'A'; Hdrs.ProtHdr[5] = 'R'; DEBUG ((EFI_D_NET, "\nTcpRead() BufferSize = %xh", *BufferSizePtr)); // // read [with filtering] // check parameters // if (BufferSizePtr == NULL || BufferPtr == NULL || (HeaderSize != 0 && HeaderPtr == NULL) || (OpFlags &~UDP_FILTER_MASK) // // if filtering on a particular IP/Port, need it // || (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr == NULL) || (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && SrcPortPtr == NULL) || (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && DestPortPtr == NULL) ) { DEBUG ((EFI_D_INFO, "\nTcpRead() Exit #1 Invalid Parameter")); return EFI_INVALID_PARAMETER; } BufferSize = *BufferSizePtr; // // in case we loop // // we need source and dest IPs for pseudo header // if (SrcIpPtr == NULL) { SrcIpPtr = &TmpSrcIp; } if (DestIpPtr == NULL) { DestIpPtr = &TmpDestIp; TmpDestIp = Private->EfiBc.Mode->StationIp; } for (;;) { *BufferSizePtr = BufferSize; DEBUG ((EFI_D_NET, "\nSize of Hdrs.Tcpv4Hdr = %d", sizeof Hdrs.Tcpv4Hdr)); // // Let's receive the IP and TCP header at the Hdrs.Ipv4Hdr location // and the data for the TCP will be passed back in the BufferPtr. // StatCode = IpReceive ( Private, OpFlags, SrcIpPtr, DestIpPtr, PROT_TCP, HeaderPtr, HeaderSize, BufferPtr, BufferSizePtr, 0 ); EfiCopyMem (&Hdrs.Ipv4Hdr, HeaderPtr, HeaderSize); DEBUG ( (EFI_D_NET, "\nTcpRead() BufferSize = %xh Ipv+Tcp = %d", *BufferSizePtr, sizeof Hdrs.Ipv4Hdr + sizeof Hdrs.Tcpv4Hdr) ); DEBUG ( (EFI_D_NET, "\nTcpRead() Destination IP address is: %d.%d.%d.%d\n", Hdrs.Ipv4Hdr.DestAddr.B[0], Hdrs.Ipv4Hdr.DestAddr.B[1], Hdrs.Ipv4Hdr.DestAddr.B[2], Hdrs.Ipv4Hdr.DestAddr.B[3]) ); DEBUG ( (EFI_D_NET, "\nTcpRead() Source IP address is: %d.%d.%d.%d\n", Hdrs.Ipv4Hdr.SrcAddr.B[0], Hdrs.Ipv4Hdr.SrcAddr.B[1], Hdrs.Ipv4Hdr.SrcAddr.B[2], Hdrs.Ipv4Hdr.SrcAddr.B[3]) ); if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) { UINT16 SPort; UINT16 DPort; SPort = NTOHS (Hdrs.Tcpv4Hdr.SrcPort); DPort = NTOHS (Hdrs.Tcpv4Hdr.DestPort); // // do filtering // if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && *SrcPortPtr != SPort) { continue; } if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && *DestPortPtr != DPort) { continue; } // // check checksum // if (StatCode == EFI_SUCCESS && Hdrs.Tcpv4Hdr.Checksum) { Hdrs.Tcpv4Phdr.SrcAddr.L = SrcIpPtr->Addr[0]; Hdrs.Tcpv4Phdr.DestAddr.L = DestIpPtr->Addr[0]; Hdrs.Tcpv4Phdr.Zero = 0; Hdrs.Tcpv4Phdr.Protocol = PROT_TCP; Hdrs.Tcpv4Phdr.TotalLength = (UINT16) (NTOHS (Hdrs.Ipv4Hdr.TotalLength) - sizeof Hdrs.Ipv4Hdr); Hdrs.Tcpv4Phdr.TotalLength = HTONS (Hdrs.Tcpv4Phdr.TotalLength); if (Hdrs.Tcpv4Hdr.Checksum == 0xffff) { Hdrs.Tcpv4Hdr.Checksum = 0; } // // The HeaderPtr has the IP header in it, let's skip it and start the // checksum at the TCP pseudo header. // if (IpChecksum2 ( (UINT16 *) HeaderPtr + sizeof Hdrs.Ipv4Hdr, sizeof Hdrs.Tcpv4Hdr + sizeof Hdrs.Tcpv4Phdr, (UINT16 *) BufferPtr, *BufferSizePtr )) { DEBUG ( (EFI_D_NET, "\nTcpRead() Hdrs.Ipv4hdr == %xh", &Hdrs.Ipv4Hdr) ); DEBUG ( (EFI_D_NET, "\nTcpRead() Hdrs.Tcpv4hdr == %xh", &Hdrs.Tcpv4Hdr) ); DEBUG ((EFI_D_NET, "\nTcpRead() Header size == %d", HeaderSize)); DEBUG ((EFI_D_NET, "\nTcpRead() BufferPtr == %xh", BufferPtr)); DEBUG ((EFI_D_NET, "\nTcpRead() Buffer size == %d", *BufferSizePtr)); DEBUG ((EFI_D_NET, "\nTcpRead() Exit #2 Device Error")); // // Invalid checksum for a zero lenght buffer is okay. // if (*BufferSizePtr > 0) { return EFI_DEVICE_ERROR; } } } DEBUG ((EFI_D_NET, "\nTcpRead() PASSED!!!!!!!!")); // // all passed // if (SrcPortPtr != NULL) { *SrcPortPtr = SPort; } if (DestPortPtr != NULL) { *DestPortPtr = DPort; } } if ((StatCode != EFI_SUCCESS) && (StatCode != EFI_TIMEOUT)) { DEBUG ( (EFI_D_INFO, "\nTcpRead() Exit #3 %Xh %r", StatCode, StatCode) ); } return StatCode; } }
EFI_STATUS ProcessOptions ( IN UI_MENU_SELECTION *Selection, IN UI_MENU_OPTION *MenuOption, IN BOOLEAN Selected, OUT CHAR16 **OptionString ) /*++ Routine Description: Process a Question's Option (whether selected or un-selected). Arguments: Selection - Pointer to UI_MENU_SELECTION. MenuOption - The MenuOption for this Question. Selected - TRUE: if Question is selected. OptionString - Pointer of the Option String to be displayed. Returns: EFI_SUCCESS - Question Option process success. Other - Question Option process fail. --*/ { EFI_STATUS Status; CHAR16 *StringPtr; CHAR16 *TempString; UINTN Index; FORM_BROWSER_STATEMENT *Question; CHAR16 FormattedNumber[21]; UINT16 Number; CHAR16 Character[2]; EFI_INPUT_KEY Key; UINTN BufferSize; QUESTION_OPTION *OneOfOption; EFI_LIST_ENTRY *Link; EFI_HII_VALUE HiiValue; EFI_HII_VALUE *QuestionValue; BOOLEAN Suppress; UINT16 Minimum; UINT16 Maximum; QUESTION_OPTION *Option; UINTN Index2; UINT8 *ValueArray; UINT8 ValueType; Status = EFI_SUCCESS; StringPtr = NULL; Character[1] = L'\0'; *OptionString = NULL; EfiZeroMem (FormattedNumber, 21 * sizeof (CHAR16)); BufferSize = (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow; Question = MenuOption->ThisTag; QuestionValue = &Question->HiiValue; Minimum = (UINT16) Question->Minimum; Maximum = (UINT16) Question->Maximum; ValueArray = Question->BufferValue; ValueType = Question->ValueType; switch (Question->Operand) { case EFI_IFR_ORDERED_LIST_OP: // // Check whether there are Options of this OrderedList // if (IsListEmpty (&Question->OptionListHead)) { break; } // // Initialize Option value array // if (GetArrayData (ValueArray, ValueType, 0) == 0) { GetQuestionDefault (Selection->FormSet, Selection->Form, Question, 0); } if (Selected) { // // Go ask for input // Status = GetSelectionInputPopUp (Selection, MenuOption); } else { // // We now know how many strings we will have, so we can allocate the // space required for the array or strings. // *OptionString = EfiLibAllocateZeroPool (Question->MaxContainers * BufferSize); ASSERT (*OptionString); HiiValue.Type = ValueType; HiiValue.Value.u64 = 0; for (Index = 0; Index < Question->MaxContainers; Index++) { HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index); if (HiiValue.Value.u64 == 0) { // // Values for the options in ordered lists should never be a 0 // break; } OneOfOption = ValueToOption (Question, &HiiValue); if (OneOfOption == NULL) { // // Show error message // do { CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); // // The initial value of the orderedlist is invalid, force to be valid value // Link = GetFirstNode (&Question->OptionListHead); Index2 = 0; while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) { Option = QUESTION_OPTION_FROM_LINK (Link); SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64); Index2++; Link = GetNextNode (&Question->OptionListHead, Link); } SetArrayData (ValueArray, ValueType, Index2, 0); Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); gBS->FreePool (*OptionString); *OptionString = NULL; return EFI_NOT_FOUND; } Suppress = FALSE; if ((OneOfOption->SuppressExpression != NULL) && (OneOfOption->SuppressExpression->Result.Value.b)) { // // This option is suppressed // Suppress = TRUE; } if (!Suppress) { Character[0] = LEFT_ONEOF_DELIMITER; NewStrCat (OptionString[0], Character); StringPtr = GetToken (OneOfOption->Text, Selection->Handle); NewStrCat (OptionString[0], StringPtr); Character[0] = RIGHT_ONEOF_DELIMITER; NewStrCat (OptionString[0], Character); Character[0] = CHAR_CARRIAGE_RETURN; NewStrCat (OptionString[0], Character); gBS->FreePool (StringPtr); } } } break; case EFI_IFR_ONE_OF_OP: // // Check whether there are Options of this OneOf // if (IsListEmpty (&Question->OptionListHead)) { break; } if (Selected) { // // Go ask for input // Status = GetSelectionInputPopUp (Selection, MenuOption); } else { *OptionString = EfiLibAllocateZeroPool (BufferSize); ASSERT (*OptionString); OneOfOption = ValueToOption (Question, QuestionValue); if (OneOfOption == NULL) { // // Show error message // do { CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); // // Force the Question value to be valid // Link = GetFirstNode (&Question->OptionListHead); while (!IsNull (&Question->OptionListHead, Link)) { Option = QUESTION_OPTION_FROM_LINK (Link); if ((Option->SuppressExpression == NULL) || !Option->SuppressExpression->Result.Value.b) { EfiCopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE)); SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); break; } Link = GetNextNode (&Question->OptionListHead, Link); } gBS->FreePool (*OptionString); *OptionString = NULL; return EFI_NOT_FOUND; } if ((OneOfOption->SuppressExpression != NULL) && (OneOfOption->SuppressExpression->Result.Value.b)) { // // This option is suppressed // Suppress = TRUE; } else { Suppress = FALSE; } if (Suppress) { // // Current selected option happen to be suppressed, // enforce to select on a non-suppressed option // Link = GetFirstNode (&Question->OptionListHead); while (!IsNull (&Question->OptionListHead, Link)) { OneOfOption = QUESTION_OPTION_FROM_LINK (Link); if ((OneOfOption->SuppressExpression == NULL) || !OneOfOption->SuppressExpression->Result.Value.b) { Suppress = FALSE; EfiCopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE)); SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND); break; } Link = GetNextNode (&Question->OptionListHead, Link); } } if (!Suppress) { Character[0] = LEFT_ONEOF_DELIMITER; NewStrCat (OptionString[0], Character); StringPtr = GetToken (OneOfOption->Text, Selection->Handle); NewStrCat (OptionString[0], StringPtr); Character[0] = RIGHT_ONEOF_DELIMITER; NewStrCat (OptionString[0], Character); gBS->FreePool (StringPtr); } } break; case EFI_IFR_CHECKBOX_OP: *OptionString = EfiLibAllocateZeroPool (BufferSize); ASSERT (*OptionString); *OptionString[0] = LEFT_CHECKBOX_DELIMITER; if (Selected) { // // Since this is a BOOLEAN operation, flip it upon selection // QuestionValue->Value.b = QuestionValue->Value.b ? FALSE : TRUE; // // Perform inconsistent check // Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF); if (EFI_ERROR (Status)) { // // Inconsistent check fail, restore Question Value // QuestionValue->Value.b = QuestionValue->Value.b ? FALSE : TRUE; gBS->FreePool (*OptionString); *OptionString = NULL; return Status; } // // Save Question value // Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); } if (QuestionValue->Value.b) { *(OptionString[0] + 1) = CHECK_ON; } else { *(OptionString[0] + 1) = CHECK_OFF; } *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER; break; case EFI_IFR_NUMERIC_OP: if (Selected) { // // Go ask for input // Status = GetNumericInput (Selection, MenuOption); } else { *OptionString = EfiLibAllocateZeroPool (BufferSize); ASSERT (*OptionString); *OptionString[0] = LEFT_NUMERIC_DELIMITER; // // Formatted print // PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16)); Number = (UINT16) GetStringWidth (FormattedNumber); EfiCopyMem (OptionString[0] + 1, FormattedNumber, Number); *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER; } break; case EFI_IFR_DATE_OP: if (Selected) { // // This is similar to numerics // Status = GetNumericInput (Selection, MenuOption); } else { *OptionString = EfiLibAllocateZeroPool (BufferSize); ASSERT (*OptionString); switch (MenuOption->Sequence) { case 0: *OptionString[0] = LEFT_NUMERIC_DELIMITER; SPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.date.Month); *(OptionString[0] + 3) = DATE_SEPARATOR; break; case 1: SetUnicodeMem (OptionString[0], 4, L' '); SPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.date.Day); *(OptionString[0] + 6) = DATE_SEPARATOR; break; case 2: SetUnicodeMem (OptionString[0], 7, L' '); SPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%4d", (UINTN) QuestionValue->Value.date.Year); *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER; break; } } break; case EFI_IFR_TIME_OP: if (Selected) { // // This is similar to numerics // Status = GetNumericInput (Selection, MenuOption); } else { *OptionString = EfiLibAllocateZeroPool (BufferSize); ASSERT (*OptionString); switch (MenuOption->Sequence) { case 0: *OptionString[0] = LEFT_NUMERIC_DELIMITER; SPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Hour); *(OptionString[0] + 3) = TIME_SEPARATOR; break; case 1: SetUnicodeMem (OptionString[0], 4, L' '); SPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Minute); *(OptionString[0] + 6) = TIME_SEPARATOR; break; case 2: SetUnicodeMem (OptionString[0], 7, L' '); SPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Second); *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER; break; } } break; case EFI_IFR_STRING_OP: if (Selected) { StringPtr = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16)); ASSERT (StringPtr); Status = ReadString (MenuOption, gPromptForData, StringPtr); if (!EFI_ERROR (Status)) { EfiCopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16)); SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); } gBS->FreePool (StringPtr); } else { *OptionString = EfiLibAllocateZeroPool (BufferSize); ASSERT (*OptionString); if (((CHAR16 *) Question->BufferValue)[0] == 0x0000) { *(OptionString[0]) = '_'; } else { if ((Maximum * sizeof (CHAR16)) < BufferSize) { BufferSize = Maximum * sizeof (CHAR16); } EfiCopyMem (OptionString[0], (CHAR16 *) Question->BufferValue, BufferSize); } } break; case EFI_IFR_PASSWORD_OP: if (Selected) { StringPtr = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16)); ASSERT (StringPtr); // // For interactive passwords, old password is validated by callback // if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) { // // Use a NULL password to test whether old password is required // *StringPtr = 0; Status = PasswordCallback (Selection, MenuOption, StringPtr); if (Status == EFI_NOT_AVAILABLE_YET) { // // Callback request to terminate password input // gBS->FreePool (StringPtr); return EFI_SUCCESS; } if (EFI_ERROR (Status)) { // // Old password exist, ask user for the old password // Status = ReadString (MenuOption, gPromptForPassword, StringPtr); if (EFI_ERROR (Status)) { gBS->FreePool (StringPtr); return Status; } // // Check user input old password // Status = PasswordCallback (Selection, MenuOption, StringPtr); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_READY) { // // Typed in old password incorrect // PasswordInvalid (); } else { Status = EFI_SUCCESS; } gBS->FreePool (StringPtr); return Status; } } } else { // // For non-interactive password, validate old password in local // if (*((CHAR16 *) Question->BufferValue) != 0) { // // There is something there! Prompt for password // Status = ReadString (MenuOption, gPromptForPassword, StringPtr); if (EFI_ERROR (Status)) { gBS->FreePool (StringPtr); return Status; } TempString = EfiLibAllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue); TempString[Maximum] = L'\0'; if (EfiStrCmp (StringPtr, TempString) != 0) { // // Typed in old password incorrect // PasswordInvalid (); gBS->FreePool (StringPtr); gBS->FreePool (TempString); return Status; } gBS->FreePool (TempString); } } // // Ask for new password // EfiZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16)); Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr); if (EFI_ERROR (Status)) { // // Reset state machine for interactive password // if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) { PasswordCallback (Selection, MenuOption, NULL); } gBS->FreePool (StringPtr); return Status; } // // Confirm new password // TempString = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16)); ASSERT (TempString); Status = ReadString (MenuOption, gConfirmPassword, TempString); if (EFI_ERROR (Status)) { // // Reset state machine for interactive password // if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) { PasswordCallback (Selection, MenuOption, NULL); } gBS->FreePool (StringPtr); gBS->FreePool (TempString); return Status; } // // Compare two typed-in new passwords // if (EfiStrCmp (StringPtr, TempString) == 0) { // // Two password match, send it to Configuration Driver // if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) { PasswordCallback (Selection, MenuOption, StringPtr); } else { EfiCopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16)); SetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE); } } else { // // Reset state machine for interactive password // if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) { PasswordCallback (Selection, MenuOption, NULL); } // // Two password mismatch, prompt error message // do { CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); } gBS->FreePool (TempString); gBS->FreePool (StringPtr); } break; default: break; } return Status; }
EFI_STATUS AddString ( IN VOID *StringBuffer, IN CHAR16 *Language, IN CHAR16 *String, IN OUT STRING_REF *StringToken ) /*++ Routine Description: Add a string to the incoming buffer and return the token and offset data Arguments: StringBuffer - The incoming buffer Language - Currrent language String - The string to be added StringToken - The index where the string placed Returns: EFI_OUT_OF_RESOURCES - No enough buffer to allocate EFI_SUCCESS - String successfully added to the incoming buffer --*/ { EFI_HII_STRING_PACK *StringPack; EFI_HII_STRING_PACK *StringPackBuffer; VOID *NewBuffer; RELOFST *PackSource; RELOFST *PackDestination; UINT8 *Source; UINT8 *Destination; UINTN Index; BOOLEAN Finished; StringPack = (EFI_HII_STRING_PACK *) StringBuffer; Finished = FALSE; // // Pre-allocate a buffer sufficient for us to work on. // We will use it as a destination scratch pad to build data on // and when complete shift the data back to the original buffer // NewBuffer = EfiLibAllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE); if (NewBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } StringPackBuffer = (EFI_HII_STRING_PACK *) NewBuffer; // // StringPack is terminated with a length 0 entry // for (; StringPack->Header.Length != 0;) { // // If this stringpack's language is same as CurrentLanguage, use it // if (EfiCompareMem ((VOID *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language, 3) == 0) { // // We have some data in this string pack, copy the string package up to the string data // EfiCopyMem (&StringPackBuffer->Header, &StringPack->Header, sizeof (StringPack)); // // These are references in the structure to tokens, need to increase them by the space occupied by an additional StringPointer // StringPackBuffer->LanguageNameString = (UINT16) (StringPackBuffer->LanguageNameString + (UINT16) sizeof (RELOFST)); StringPackBuffer->PrintableLanguageName = (UINT16) (StringPackBuffer->PrintableLanguageName + (UINT16) sizeof (RELOFST)); PackSource = (RELOFST *) (StringPack + 1); PackDestination = (RELOFST *) (StringPackBuffer + 1); for (Index = 0; PackSource[Index] != 0x0000; Index++) { // // Copy the stringpointers from old to new buffer // remember that we are adding a string, so the string offsets will all go up by sizeof (RELOFST) // PackDestination[Index] = (UINT16) (PackDestination[Index] + sizeof (RELOFST)); } // // Add a new stringpointer in the new buffer since we are adding a string. Null terminate it // PackDestination[Index] = (UINT16)(PackDestination[Index-1] + EfiStrSize((CHAR16 *)((CHAR8 *)(StringPack) + PackSource[Index-1]))); PackDestination[Index + 1] = (UINT16) 0; // // Index is the token value for the new string // *StringToken = (UINT16) Index; // // Source now points to the beginning of the old buffer strings // Destination now points to the beginning of the new buffer strings // Source = (UINT8 *) &PackSource[Index + 1]; Destination = (UINT8 *) &PackDestination[Index + 2]; // // This should copy all the strings from the old buffer to the new buffer // for (; Index != 0; Index--) { // // Copy Source string to destination buffer // EfiStrCpy ((CHAR16 *) Destination, (CHAR16 *) Source); // // Adjust the source/destination to the next string location // Destination = Destination + EfiStrSize ((CHAR16 *) Source); Source = Source + EfiStrSize ((CHAR16 *) Source); } // // This copies the new string to the destination buffer // EfiStrCpy ((CHAR16 *) Destination, (CHAR16 *) String); // // Adjust the size of the changed string pack by adding the size of the new string // along with the size of the additional offset entry for the new string // StringPackBuffer->Header.Length = (UINT32) ((UINTN) StringPackBuffer->Header.Length + EfiStrSize (String) + sizeof (RELOFST)); // // Advance the buffers to point to the next spots. // StringPackBuffer = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPackBuffer->Header.Length); StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length); Finished = TRUE; continue; } // // This isn't the language of the stringpack we were asked to add a string to // so we need to copy it to the new buffer. // EfiCopyMem (&StringPackBuffer->Header, &StringPack->Header, StringPack->Header.Length); // // Advance the buffers to point to the next spots. // StringPackBuffer = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPack->Header.Length); StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length); } // // If we didn't copy the new data to a stringpack yet // if (!Finished) { PackDestination = (RELOFST *) (StringPackBuffer + 1); // // Pointing to a new string pack location // StringPackBuffer->Header.Length = (UINT32) ( sizeof (EFI_HII_STRING_PACK) - sizeof (EFI_STRING) + sizeof (RELOFST) + sizeof (RELOFST) + EfiStrSize (Language) + EfiStrSize (String) ); StringPackBuffer->Header.Type = EFI_HII_STRING; StringPackBuffer->LanguageNameString = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer); StringPackBuffer->PrintableLanguageName = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer); StringPackBuffer->Attributes = 0; PackDestination[0] = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer); PackDestination[1] = (UINT16) (PackDestination[0] + EfiStrSize (Language)); PackDestination[2] = (UINT16) 0; // // The first string location will be set to destination. The minimum number of strings // associated with a stringpack will always be token 0 stored as the languagename (e.g. ENG, SPA, etc) // and token 1 as the new string being added and and null entry for the stringpointers // Destination = (CHAR8 *) &PackDestination[3]; // // Copy the language name string to the new buffer // EfiStrCpy ((CHAR16 *) Destination, Language); // // Advance the destination to the new empty spot // Destination = Destination + EfiStrSize (Language); // // Copy the string to the new buffer // EfiStrCpy ((CHAR16 *) Destination, String); // // Since we are starting with a new string pack - we know the new string is token 1 // *StringToken = (UINT16) 1; } // // Zero out the original buffer and copy the updated data in the new buffer to the old buffer // EfiZeroMem (StringBuffer, DEFAULT_STRING_BUFFER_SIZE); EfiCopyMem (StringBuffer, NewBuffer, DEFAULT_STRING_BUFFER_SIZE); // // Free the newly created buffer since we don't need it anymore // gBS->FreePool (NewBuffer); return EFI_SUCCESS; }
EFI_STATUS AmdFchWheaInitEntryEinj ( VOID ) { EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; EFI_STATUS Status; INTN Index; UINTN Handle; EFI_ACPI_TABLE_VERSION Version; EFI_ACPI_DESCRIPTION_HEADER *Table; EFI_ACPI_DESCRIPTION_HEADER *NewTable; Status = gBS->LocateProtocol ( &gEfiAcpiSupportGuid, NULL, &AcpiSupport ); if (EFI_ERROR (Status)) { return Status; } // // Search EINJ table // Index = 0; Handle = 0; do { Table = NULL; Status = AcpiSupport->GetAcpiTable ( AcpiSupport, Index, &Table, &Version, &Handle ); if (EFI_ERROR (Status)) { break; } // // Check Signture and update EINJ table // if (Table->Signature == 0x4A4E4945) { // // allocate memory for new Table // Status = gBS->AllocatePool ( EfiReservedMemoryType, MAX_EINJ_SIZE, &NewTable ); if (Status != EFI_SUCCESS) { return Status; } EfiZeroMem (NewTable, MAX_EINJ_SIZE); // // Copy Table // EfiCopyMem (NewTable, Table, Table->Length); // // Update new table // AmdFchUpdateEinj (NewTable); if (!EFI_ERROR (Status)) { // Patch EINJ table here and save table back. // // Remove previous table // gBS->FreePool (Table); Table = NULL; Status = AcpiSupport->SetAcpiTable ( AcpiSupport, Table, TRUE, Version, &Handle ); // // Add new table // Handle = 0; Status = AcpiSupport->SetAcpiTable ( AcpiSupport, NewTable, TRUE, Version, &Handle ); gBS->FreePool (NewTable); return Status; } gBS->FreePool (NewTable); } gBS->FreePool (Table); Index++; } while (TRUE); return Status; }
EFI_STATUS EFIAPI WinNtConsoleDriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) /*++ Routine Description: Arguments: Returns: None --*/ // TODO: This - add argument and description to function comment // TODO: Handle - add argument and description to function comment // TODO: RemainingDevicePath - add argument and description to function comment { EFI_STATUS Status; EFI_WIN_NT_IO_PROTOCOL *WinNtIo; WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private; // // Grab the IO abstraction we need to get any work done // Status = gBS->OpenProtocol ( Handle, &gEfiWinNtIoProtocolGuid, &WinNtIo, This->DriverBindingHandle, Handle, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA), &Private ); if (EFI_ERROR (Status)) { goto Done; } EfiZeroMem (Private, sizeof (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA)); Private->Signature = WIN_NT_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE; Private->Handle = Handle; Private->WinNtIo = WinNtIo; Private->WinNtThunk = WinNtIo->WinNtThunk; WinNtSimpleTextOutOpenWindow (Private); WinNtSimpleTextInAttachToWindow (Private); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiSimpleTextOutProtocolGuid, &Private->SimpleTextOut, &gEfiSimpleTextInProtocolGuid, &Private->SimpleTextIn, NULL ); if (!EFI_ERROR (Status)) { return Status; } Done: gBS->CloseProtocol ( Handle, &gEfiWinNtIoProtocolGuid, This->DriverBindingHandle, Handle ); if (Private != NULL) { EfiLibFreeUnicodeStringTable (Private->ControllerNameTable); if (Private->NtOutHandle != NULL) { Private->WinNtThunk->CloseHandle (Private->NtOutHandle); } if (Private->SimpleTextIn.WaitForKey != NULL) { gBS->CloseEvent (Private->SimpleTextIn.WaitForKey); } gBS->FreePool (Private); } return Status; }
EFI_DEBUG_STATUS DebuggerCallStack ( IN CHAR16 *CommandArg, IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext ) /*++ Routine Description: DebuggerCommand - CallStack Arguments: CommandArg - The argument for this command DebuggerPrivate - EBC Debugger private data structure InterruptType - Interrupt type. SystemContext - EBC system context. Returns: EFI_DEBUG_CONTINUE - formal return value --*/ { INTN Index; UINTN SubIndex; CHAR8 *FuncName; EFI_DEBUGGER_CALLSTACK_CONTEXT *CallStackEntry; BOOLEAN ShowParameter; UINTN ParameterNumber; ShowParameter = FALSE; ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER; // // Check argument // if (CommandArg != NULL) { if (EfiStriCmp (CommandArg, L"c") == 0) { // // Clear Call-Stack // DebuggerPrivate->CallStackEntryCount = 0; EfiZeroMem (DebuggerPrivate->CallStackEntry, sizeof(DebuggerPrivate->CallStackEntry)); EDBPrint (L"Call-Stack is cleared\n"); return EFI_DEBUG_CONTINUE; } else if (EfiStriCmp (CommandArg, L"p") == 0) { // // Print Call-Stack with parameter // ShowParameter = TRUE; CommandArg = StrGetNextTokenLine (L" "); if (CommandArg != NULL) { // // Try to get the parameter number // ParameterNumber = Atoi (CommandArg); if (ParameterNumber > 16) { EDBPrint (L"Call-Stack argument Invalid\n"); return EFI_DEBUG_CONTINUE; } } } else { EDBPrint (L"Call-Stack argument Invalid\n"); return EFI_DEBUG_CONTINUE; } } // // Check CallStack Entry Count // if (DebuggerPrivate->CallStackEntryCount == 0) { EDBPrint (L"No Call-Stack\n"); return EFI_DEBUG_CONTINUE; } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) { EDBPrint (L"Call-Stack Crash, re-initialize!\n"); DebuggerPrivate->CallStackEntryCount = 0; return EFI_DEBUG_CONTINUE; } // // Go through each CallStack entry and print // EDBPrint (L"Call-Stack (TOP):\n"); EDBPrint (L" Caller Callee Name\n"); EDBPrint (L" ================== ================== ========\n"); //EDBPrint (L" 0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n"); for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) { // // Get CallStack and print // CallStackEntry = &DebuggerPrivate->CallStackEntry[Index]; EDBPrint ( L" 0x%016lx 0x%016lx", CallStackEntry->SourceAddress, CallStackEntry->DestAddress ); FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress); if (FuncName != NULL) { EDBPrint (L" %a()", FuncName); } EDBPrint (L"\n"); if (ShowParameter) { // // Print parameter // if (sizeof(UINTN) == sizeof(UINT64)) { EDBPrint ( L" Parameter Address (0x%016lx) (\n", CallStackEntry->ParameterAddr ); if (ParameterNumber == 0) { EDBPrint (L" )\n"); continue; } // // Print each parameter // for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) { if (SubIndex % 2 == 0) { EDBPrint (L" "); } EDBPrint ( L"0x%016lx, ", CallStackEntry->Parameter[SubIndex] ); if (SubIndex % 2 == 1) { EDBPrint (L"\n"); } } if (SubIndex % 2 == 0) { EDBPrint (L" "); } EDBPrint ( L"0x%016lx\n", CallStackEntry->Parameter[SubIndex] ); EDBPrint (L" )\n"); // // break only for parameter // if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) && (Index != 0)) { if (SetPageBreak ()) { break; } } } else { EDBPrint ( L" Parameter Address (0x%08x) (\n", CallStackEntry->ParameterAddr ); if (ParameterNumber == 0) { EDBPrint (L" )\n"); continue; } // // Print each parameter // for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) { if (SubIndex % 4 == 0) { EDBPrint (L" "); } EDBPrint ( L"0x%08x, ", CallStackEntry->Parameter[SubIndex] ); if (SubIndex % 4 == 3) { EDBPrint (L"\n"); } } if (SubIndex % 4 == 0) { EDBPrint (L" "); } EDBPrint ( L"0x%08x\n", CallStackEntry->Parameter[SubIndex] ); EDBPrint (L" )\n"); // // break only for parameter // if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) && (Index != 0)) { if (SetPageBreak ()) { break; } } } } } // // Done // return EFI_DEBUG_CONTINUE; }
/******************************************************************************** * Name: AmdFchWheaInitEntry * * Description * AmdFchWheaInit Entrypoint * * Input * * Output * EFI_UNSUPPORTED : unsupported function * *********************************************************************************/ EFI_STATUS AmdFchWheaInitEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; BOOLEAN InSmm; FCH_INIT_PROTOCOL *AmdFchInit; EFI_SMM_BASE_PROTOCOL *SmmBase; FCH_SMM_SW_DISPATCH_PROTOCOL *AmdSwDispatch; FCH_SMM_SW_REGISTER_CONTEXT SwRegisterContext; EFI_HANDLE SwHandle; FCH_SMM_MISC_DISPATCH_PROTOCOL *AmdFchSmmMiscDispatch; FCH_SMM_MISC_REGISTER_CONTEXT MiscRegisterContext; EFI_HANDLE MiscHandle; EFI_SMM_SYSTEM_TABLE *mSmst; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; EFI_DEVICE_PATH_PROTOCOL *CompleteFilePath; EFI_HANDLE SmmImageHandle; EFI_EVENT InstallAmdTableEvent; EFI_HANDLE Handle; UINT8 *buffer; InSmm = FALSE; DxeInitializeDriverLib (ImageHandle, SystemTable); Status = gBS->LocateProtocol ( &gFchInitProtocolGuid, NULL, &AmdFchInit ); ASSERT_EFI_ERROR (Status); if (AmdFchInit->FchPolicy.Gpp.PcieAer == 0) { return Status; } Status = gBS->LocateProtocol ( &gEfiSmmBaseProtocolGuid, NULL, &SmmBase ); if (EFI_ERROR (Status)) { return Status; } SmmBase->GetSmstLocation ( SmmBase, &mSmst ); SmmBase->InSmm ( SmmBase, &InSmm ); if (!InSmm) { Status = EfiCreateEventReadyToBoot ( EFI_TPL_CALLBACK, AmdWheaCheckInstallTables, NULL, &InstallAmdTableEvent ); // // Allocate memory and Initialize for Data block // Status = gBS->AllocatePool ( EfiReservedMemoryType, sizeof (AMD_FCH_WHEA_EINJ_BUFFER), (VOID **)&buffer ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (buffer, sizeof (AMD_FCH_WHEA_EINJ_BUFFER)); mEinjData = (AMD_FCH_WHEA_EINJ_BUFFER *)buffer; mEinjData->Valid = FALSE; mEinjData->PlatformEinjValid = FALSE; // // Allocate memory and Initialize for Error Data block // Status = gBS->AllocatePool ( EfiReservedMemoryType, MAX_ERROR_BLOCK_SIZE, (VOID **)&buffer ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (buffer, MAX_ERROR_BLOCK_SIZE); mEinjData->AmdHwErrBlk = (GENERIC_ERROR_STATUS_BLOCK *)buffer; AmdErrBlkAddressUpdate (); Handle = ImageHandle; Status = gBS->InstallProtocolInterface ( &Handle, &mEfiAmdFchWheaDataGuid, EFI_NATIVE_INTERFACE, mEinjData ); if (EFI_ERROR (Status)) { return (Status); } if (ImageHandle != NULL) { Status = gBS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, &LoadedImage ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID*) &ImageDevicePath ); if (EFI_ERROR (Status)) { return Status; } CompleteFilePath = AppendDevicePath ( ImageDevicePath, LoadedImage->FilePath ); // Load the image in memory to SMRAM, this automatically triggers SMI SmmBase->Register ( SmmBase, CompleteFilePath, NULL, 0, &SmmImageHandle, FALSE ); } } else { Status = gBS->LocateProtocol ( &mEfiAmdFchWheaDataGuid, NULL, &mEinjData ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->LocateProtocol ( &gFchSmmSwDispatchProtocolGuid, NULL, &AmdSwDispatch ); ASSERT_EFI_ERROR (Status); SwRegisterContext.AmdSwValue = EINJ_TRIGGER_ACTION_SWSMI; Status = AmdSwDispatch->Register ( AmdSwDispatch, AmdSmiEinjTriggerActionCallBack, &SwRegisterContext, &SwHandle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->LocateProtocol ( &gFchSmmMiscDispatchProtocolGuid, NULL, &AmdFchSmmMiscDispatch ); ASSERT_EFI_ERROR (Status); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT21; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT22; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT23; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT24; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB4) &= ~(BIT11 + BIT13 + BIT15 + BIT17); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB4) |= (BIT10 + BIT12 + BIT14 + BIT16); } return Status; }
EFI_STATUS ExtractDataFromHiiHandle ( IN EFI_HII_HANDLE HiiHandle, IN OUT UINT16 *ImageLength, OUT UINT8 *DefaultImage, OUT EFI_GUID *Guid ) /*++ Routine Description: Extract information pertaining to the HiiHandle Arguments: HiiHandle - Hii handle ImageLength - For input, length of DefaultImage; For output, length of actually required DefaultImage - Image buffer prepared by caller Guid - Guid information about the form Returns: EFI_OUT_OF_RESOURCES - No enough buffer to allocate EFI_BUFFER_TOO_SMALL - DefualtImage has no enough ImageLength EFI_SUCCESS - Successfully extract data from Hii database. --*/ { EFI_STATUS Status; EFI_HII_PROTOCOL *Hii; UINTN DataLength; UINT8 *RawData; UINT8 *OldData; UINTN Index; UINTN Temp; UINTN SizeOfNvStore; UINTN CachedStart; DataLength = DEFAULT_FORM_BUFFER_SIZE; SizeOfNvStore = 0; CachedStart = 0; Status = GetHiiInterface (&Hii); if (EFI_ERROR (Status)) { return Status; } // // Allocate space for retrieval of IFR data // RawData = EfiLibAllocateZeroPool ((UINTN) DataLength); if (RawData == NULL) { return EFI_OUT_OF_RESOURCES; } // // Get all the forms associated with this HiiHandle // Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData); if (EFI_ERROR (Status)) { gBS->FreePool (RawData); // // Allocate space for retrieval of IFR data // RawData = EfiLibAllocateZeroPool ((UINTN) DataLength); if (RawData == NULL) { return EFI_OUT_OF_RESOURCES; } // // Get all the forms associated with this HiiHandle // Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData); } OldData = RawData; // // Point RawData to the beginning of the form data // RawData = (UINT8 *) ((UINTN) RawData + sizeof (EFI_HII_PACK_HEADER)); for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) { switch (RawData[Index]) { case EFI_IFR_FORM_SET_OP: // // Copy the GUID information from this handle // EfiCopyMem (Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID)); break; case EFI_IFR_ONE_OF_OP: case EFI_IFR_CHECKBOX_OP: case EFI_IFR_NUMERIC_OP: case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: case EFI_IFR_PASSWORD_OP: case EFI_IFR_STRING_OP: // // Remember, multiple op-codes may reference the same item, so let's keep a running // marker of what the highest QuestionId that wasn't zero length. This will accurately // maintain the Size of the NvStore // if (((EFI_IFR_ONE_OF *) &RawData[Index])->Width != 0) { Temp = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width; if (SizeOfNvStore < Temp) { SizeOfNvStore = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width; } } } Index = RawData[Index + 1] + Index; } // // Return an error if buffer is too small // if (SizeOfNvStore > *ImageLength) { gBS->FreePool (OldData); *ImageLength = (UINT16) SizeOfNvStore; return EFI_BUFFER_TOO_SMALL; } EfiZeroMem (DefaultImage, SizeOfNvStore); // // Copy the default image information to the user's buffer // for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) { switch (RawData[Index]) { case EFI_IFR_ONE_OF_OP: CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId; break; case EFI_IFR_ONE_OF_OPTION_OP: if (((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Flags & EFI_IFR_FLAG_DEFAULT) { EfiCopyMem (&DefaultImage[CachedStart], &((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value, 2); } break; case EFI_IFR_CHECKBOX_OP: DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId] = ((EFI_IFR_CHECK_BOX *) &RawData[Index])->Flags; break; case EFI_IFR_NUMERIC_OP: EfiCopyMem ( &DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId], &((EFI_IFR_NUMERIC *) &RawData[Index])->Default, 2 ); break; } Index = RawData[Index + 1] + Index; } *ImageLength = (UINT16) SizeOfNvStore; // // Free our temporary repository of form data // gBS->FreePool (OldData); return EFI_SUCCESS; }
EFI_STATUS EFIAPI GetProposedResources ( IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, IN EFI_HANDLE RootBridgeHandle, OUT VOID **Configuration ) /*++ Routine Description: This function returns the proposed resource settings for the specified PCI Root Bridge Arguments: This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance RootBridgeHandle -- The PCI Root Bridge handle Configuration -- The pointer to the pointer to the PCI I/O and memory resource descriptor Returns: --*/ // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment // TODO: EFI_SUCCESS - add return value to function comment // TODO: EFI_INVALID_PARAMETER - add return value to function comment { EFI_LIST_ENTRY *List; PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance; UINTN Index; UINTN Number; VOID *Buffer; UINT8 *Temp; EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr; EFI_STATUS Status; UINT64 ResStatus; Buffer = NULL; Number = 0; // // Get the Host Bridge Instance from the resource allocation protocol // HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); List = HostBridgeInstance->Head.ForwardLink; // // Enumerate the root bridges in this host bridge // while (List != &HostBridgeInstance->Head) { RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List); if (RootBridgeHandle == RootBridgeInstance->Handle) { for (Index = 0; Index < TypeBus; Index++) { if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) { Number++; } } if (Number > 0) { Status = gBS->AllocatePool ( EfiBootServicesData, Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR), &Buffer ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } EfiZeroMem (Buffer, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Number + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); } else { return EFI_INVALID_PARAMETER; } Temp = Buffer; for (Index = 0; Index < TypeBus; Index++) { if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) { ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp; ResStatus = RootBridgeInstance->ResAllocNode[Index].Status; switch (Index) { case TypeIo: // // Io // ptr->Desc = 0x8A; ptr->Len = 0x2B; ptr->ResType = 1; ptr->GenFlag = 0; ptr->SpecificFlag = 0; ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base; ptr->AddrRangeMax = 0; ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS; ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length; break; case TypeMem32: // // Memory 32 // ptr->Desc = 0x8A; ptr->Len = 0x2B; ptr->ResType = 0; ptr->GenFlag = 0; ptr->SpecificFlag = 0; ptr->AddrSpaceGranularity = 32; ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base; ptr->AddrRangeMax = 0; ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS; ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length; break; case TypePMem32: // // Prefetch memory 32 // ptr->Desc = 0x8A; ptr->Len = 0x2B; ptr->ResType = 0; ptr->GenFlag = 0; ptr->SpecificFlag = 6; ptr->AddrSpaceGranularity = 32; ptr->AddrRangeMin = 0; ptr->AddrRangeMax = 0; ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT; ptr->AddrLen = 0; break; case TypeMem64: // // Memory 64 // ptr->Desc = 0x8A; ptr->Len = 0x2B; ptr->ResType = 0; ptr->GenFlag = 0; ptr->SpecificFlag = 0; ptr->AddrSpaceGranularity = 64; ptr->AddrRangeMin = 0; ptr->AddrRangeMax = 0; ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT; ptr->AddrLen = 0; break; case TypePMem64: // // Prefetch memory 64 // ptr->Desc = 0x8A; ptr->Len = 0x2B; ptr->ResType = 0; ptr->GenFlag = 0; ptr->SpecificFlag = 6; ptr->AddrSpaceGranularity = 64; ptr->AddrRangeMin = 0; ptr->AddrRangeMax = 0; ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT; ptr->AddrLen = 0; break; } Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); } } ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Desc = 0x79; ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Checksum = 0x0; *Configuration = Buffer; return EFI_SUCCESS; } List = List->ForwardLink; } return EFI_INVALID_PARAMETER; }
EFI_STATUS LoadBmp ( IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltBuffer, IN UINTN *Width, IN UINTN *Height ) /*++ Routine Description: Assistant function for loading a bmp file Arguments: BltBuffer - Buffer for loading a bmp file Width - Width of the bmp file Height - Height of the bmp file Returns: EFI_SUCCESS - No error returns --*/ { EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; EFI_STATUS Status; UINTN IndexX; UINTN IndexY; UINTN m; UINTN Wx; UINTN Hy; Wx = 150; Hy = 150; Status = gtBS->AllocatePool ( EfiBootServicesData, Wx * Hy * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), (VOID **) &Blt ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (Blt, Wx * Hy * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); for (IndexY = 0; IndexY < Hy / 3; IndexY++) { for (IndexX = 0; IndexX < Wx; IndexX++) { m = IndexY * Wx + IndexX; Blt[m].Blue = 0xFF; Blt[m].Green = 0x00; Blt[m].Red = 0x00; Blt[m].Reserved = 0x00; } } for (IndexY = Hy / 3; IndexY < (Hy / 3) * 2; IndexY++) { for (IndexX = 0; IndexX < Wx; IndexX++) { m = IndexY * Wx + IndexX; Blt[m].Blue = 0x00; Blt[m].Green = 0xFF; Blt[m].Red = 0x00; Blt[m].Reserved = 0x00; } } for (IndexY = (Hy / 3) * 2; IndexY < Hy; IndexY++) { for (IndexX = 0; IndexX < Wx; IndexX++) { m = IndexY * Wx + IndexX; Blt[m].Blue = 0x00; Blt[m].Green = 0x00; Blt[m].Red = 0xFF; Blt[m].Reserved = 0x00; } } *BltBuffer = Blt; *Width = Wx; *Height = Hy; return EFI_SUCCESS; }
VOID EFIAPI InvokeAmdInitLate ( IN EFI_EVENT Event, IN VOID *Context ) /*++ Routine Description: Invoke AmdinitLate entry point. This function gets called each time the EFI_EVENT_SIGNAL_READY_TO_BOOT gets signaled Arguments & Return Values: Standard event handling function prototype --*/ { AMD_INTERFACE_PARAMS AmdInterfaceParams; AGESA_STATUS AgesaStatus; AMD_DXE_INIT_LATE_PROTOCOL AmdInitLateProtocol; EFI_HANDLE Handle; // // Prepare for AmdInitLate // EfiZeroMem (&AmdInterfaceParams, sizeof (AMD_INTERFACE_PARAMS)); AmdInterfaceParams.StdHeader.ImageBasePtr = 0; AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM; AmdInterfaceParams.AllocationMethod = PostMemDram; AmdInterfaceParams.AgesaFunctionName = AMD_INIT_LATE; AgesaStatus = AmdCreateStruct (&AmdInterfaceParams); ((AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr)->StdHeader = AmdInterfaceParams.StdHeader; OemCustomizeInitLate (gBS, (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr); AgesaStatus = AmdInitLate ((AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr); OemHookAfterInitLate (gBS, (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr); if ((AgesaStatus == AGESA_CRITICAL) || (AgesaStatus == AGESA_FATAL)) { return; } mAgesaDxePrivate->LateParamsPtr = (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr; // // Now Install the AmdDxeInitLateProtocol which helps notify any consumer // which is depending upon it. // AmdInitLateProtocol.Revision = AGESA_DXE_INIT_LATE_REV; Handle = NULL; gBS->InstallProtocolInterface ( &Handle, &gAmdDxeInitLateProtocolGuid, EFI_NATIVE_INTERFACE, &AmdInitLateProtocol ); // // Install the AMD_AGESA_DXE_PROTOCOL to notify OEM to override default value // Handle = NULL; gBS->InstallProtocolInterface ( &Handle, &gAmdAgesaDxeProtocolGuid, EFI_NATIVE_INTERFACE, &mAgesaDxePrivate->CpuInterface ); // // Install AgesaDxeMiscellaneous Protocol // Handle = NULL; gBS->CopyMem ( &mAgesaDxePrivate->AgesaMiscServices.StdHeader, &AmdInterfaceParams.StdHeader, sizeof (AMD_CONFIG_PARAMS) ); mAgesaDxePrivate->AgesaMiscServices.GetDimmInfo = AgesaGetDimmInfo; gBS->InstallProtocolInterface ( &Handle, &gAmdAgesaDxeMiscServicesProtocolGuid, EFI_NATIVE_INTERFACE, &mAgesaDxePrivate->AgesaMiscServices ); return; }
VOID WriteBootToOsPerformanceData ( VOID ) /*++ Routine Description: Allocates a block of memory and writes performance data of booting to OS into it. Arguments: None Returns: None --*/ { EFI_STATUS Status; EFI_CPU_ARCH_PROTOCOL *Cpu; EFI_PERFORMANCE_PROTOCOL *DrvPerf; UINT32 mAcpiLowMemoryLength; UINT32 LimitCount; EFI_PERF_HEADER mPerfHeader; EFI_PERF_DATA mPerfData; EFI_GAUGE_DATA *DumpData; EFI_HANDLE *Handles; UINTN NoHandles; UINT8 *Ptr; UINT8 *PdbFileName; UINT32 mIndex; UINT64 Ticker; UINT64 Freq; UINT32 Duration; UINT64 CurrentTicker; UINT64 TimerPeriod; // // Retrive time stamp count as early as possilbe // Ticker = EfiReadTsc (); // // Get performance architecture protocol // Status = gBS->LocateProtocol ( &gEfiPerformanceProtocolGuid, NULL, &DrvPerf ); if (EFI_ERROR (Status)) { return ; } // // Get CPU frequency // Status = gBS->LocateProtocol ( &gEfiCpuArchProtocolGuid, NULL, &Cpu ); if (EFI_ERROR (Status)) { return ; } // // Get Cpu Frequency // Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod); if (EFI_ERROR (Status)) { return ; } // // Put Detailed performance data into memory // Handles = NULL; Status = gBS->LocateHandleBuffer ( AllHandles, NULL, NULL, &NoHandles, &Handles ); if (EFI_ERROR (Status)) { return ; } // // Allocate a block of memory that contain performance data to OS // if it is not allocated yet. // if (mAcpiLowMemoryBase == 0x0FFFFFFFF) { Status = gBS->AllocatePages ( AllocateMaxAddress, EfiReservedMemoryType, 4, &mAcpiLowMemoryBase ); if (EFI_ERROR (Status)) { gBS->FreePool (Handles); return ; } } mAcpiLowMemoryLength = EFI_PAGES_TO_SIZE(4); Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (EFI_PERF_HEADER)); LimitCount = (mAcpiLowMemoryLength - sizeof (EFI_PERF_HEADER)) / sizeof (EFI_PERF_DATA); // // Initialize performance data structure // EfiZeroMem (&mPerfHeader, sizeof (EFI_PERF_HEADER)); Freq = DivU64x32 (1000000000000, (UINTN) TimerPeriod, NULL); mPerfHeader.CpuFreq = Freq; // // Record BDS raw performance data // mPerfHeader.BDSRaw = Ticker; // // Get DXE drivers performance // for (mIndex = 0; mIndex < NoHandles; mIndex++) { Ticker = 0; PdbFileName = NULL; DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host NULL // PrecGauge ); while (DumpData) { if (DumpData->Handle == Handles[mIndex]) { PdbFileName = &(DumpData->PdbFileName[0]); if (DumpData->StartTick < DumpData->EndTick) { Ticker += (DumpData->EndTick - DumpData->StartTick); } } DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host DumpData // PrecGauge ); } Duration = (UINT32) DivU64x32 ( Ticker, (UINT32) Freq, NULL ); if (Duration > 0) { EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA)); if (PdbFileName != NULL) { EfiAsciiStrCpy (mPerfData.Token, PdbFileName); } mPerfData.Duration = Duration; EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA)); Ptr += sizeof (EFI_PERF_DATA); mPerfHeader.Count++; if (mPerfHeader.Count == LimitCount) { goto Done; } } } gBS->FreePool (Handles); // // Get inserted performance data // DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host NULL // PrecGauge ); while (DumpData) { if ((DumpData->Handle) || (DumpData->StartTick > DumpData->EndTick)) { DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host DumpData // PrecGauge ); continue; } EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA)); ConvertChar16ToChar8 ((UINT8 *) mPerfData.Token, DumpData->Token); mPerfData.Duration = (UINT32) DivU64x32 ( DumpData->EndTick - DumpData->StartTick, (UINT32) Freq, NULL ); EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA)); Ptr += sizeof (EFI_PERF_DATA); mPerfHeader.Count++; if (mPerfHeader.Count == LimitCount) { goto Done; } DumpData = DrvPerf->GetGauge ( DrvPerf, // Context NULL, // Handle NULL, // Token NULL, // Host DumpData // PrecGauge ); } Done: mPerfHeader.Signiture = 0x66726550; // // Put performance data to memory // EfiCopyMem ( (UINTN *) (UINTN) mAcpiLowMemoryBase, &mPerfHeader, sizeof (EFI_PERF_HEADER) ); gRT->SetVariable ( L"PerfDataMemAddr", &gEfiGenericVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (UINT32), (VOID *) &mAcpiLowMemoryBase ); return ; }
EFI_STATUS TestRecoveryEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Test recovery library driver's entry point. Arguments: ImageHandle - the driver image handle. SystemTable - the system table. Returns: EFI_SUCCESS - the driver is loaded successfully. EFI_ALREADY_STARTED - the driver has already been loaded before. --*/ { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; TSL_INIT_PRIVATE_DATA *Private; // Initialize driver lib EfiInitializeDriverLib (ImageHandle, SystemTable); // // Fill in the Unload() function // Status = gBS->OpenProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } LoadedImage->Unload = TslInitUnload; // // Open the TslInit protocol to perform the supported test. // Status = gBS->OpenProtocol ( ImageHandle, &gEfiTslInitInterfaceGuid, NULL, ImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (!EFI_ERROR (Status)) { return EFI_ALREADY_STARTED; } // // Initialize the TslInit private data // Status = gBS->AllocatePool( EfiBootServicesData, sizeof (TSL_INIT_PRIVATE_DATA), (VOID **)&Private ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (Private, sizeof(TSL_INIT_PRIVATE_DATA)); Private->Signature = TSL_INIT_PRIVATE_DATA_SIGNATURE; Private->ImageHandle = ImageHandle; Private->TslInit.Revision = 0x10000; Private->TslInit.LibraryGuid = gEfiTestRecoveryLibraryGuid; Private->TslInit.Open = TslOpen; Private->TslInit.Close = TslClose; // // Install TslInit protocol // Status = gBS->InstallProtocolInterface ( &ImageHandle, &gEfiTslInitInterfaceGuid, EFI_NATIVE_INTERFACE, &(Private->TslInit) ); return Status; }