cpu.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 745 行 · 第 1/2 页
C
745 行
Status
EFI_UNSUPPORTED - not yet implemented
--*/
// TODO: This - add argument and description to function comment
// TODO: BaseAddress - add argument and description to function comment
// TODO: Length - add argument and description to function comment
// TODO: Attributes - add argument and description to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
{
CPU_ARCH_PROTOCOL_PRIVATE *Private;
//
// Check for invalid parameter for EFI Spec conformance
//
if (Length == 0) {
return EFI_INVALID_PARAMETER;
}
if ((BaseAddress &~EFI_CACHE_VALID_ADDRESS) != 0 || (Length &~EFI_CACHE_VALID_ADDRESS) != 0) {
return EFI_UNSUPPORTED;
}
//
// Do nothing for Nt32 emulation
//
Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
return EFI_UNSUPPORTED;
}
EFI_DRIVER_ENTRY_POINT (InitializeCpu)
EFI_STATUS
EFIAPI
InitializeCpu (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initialize the state information for the CPU Architectural Protocol
Arguments:
ImageHandle of the loaded driver
Pointer to the System Table
Returns:
Status
EFI_SUCCESS - protocol instance can be published
EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
EFI_DEVICE_ERROR - cannot create the thread
--*/
// TODO: SystemTable - add argument and description to function comment
{
EFI_STATUS Status;
EFI_EVENT Event;
CPU_ARCH_PROTOCOL_PRIVATE *Private;
VOID *Registration;
EfiInitializeDriverLib (ImageHandle, SystemTable);
EfiInitializeWinNtDriverLib (ImageHandle, SystemTable);
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (CPU_ARCH_PROTOCOL_PRIVATE),
&Private
);
ASSERT_EFI_ERROR (Status);
Private->Signature = CPU_ARCH_PROT_PRIVATE_SIGNATURE;
Private->Cpu.FlushDataCache = WinNtFlushCpuDataCache;
Private->Cpu.EnableInterrupt = WinNtEnableInterrupt;
Private->Cpu.DisableInterrupt = WinNtDisableInterrupt;
Private->Cpu.GetInterruptState = WinNtGetInterruptState;
Private->Cpu.Init = WinNtInit;
Private->Cpu.RegisterInterruptHandler = WinNtRegisterInterruptHandler;
Private->Cpu.GetTimerValue = WinNtGetTimerValue;
Private->Cpu.SetMemoryAttributes = WinNtSetMemoryAttributes;
Private->Cpu.NumberOfTimers = 0;
Private->Cpu.DmaBufferAlignment = 4;
Private->InterruptState = TRUE;
Private->Handle = NULL;
Status = gBS->InstallProtocolInterface (
&Private->Handle,
&gEfiCpuArchProtocolGuid,
EFI_NATIVE_INTERFACE,
&Private->Cpu
);
ASSERT_EFI_ERROR (Status);
//
// Install notify function to store processor data to HII database and data hub.
//
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
WinNtIoProtocolNotifyFunction,
ImageHandle,
&Event
);
ASSERT (!EFI_ERROR (Status));
Status = gBS->RegisterProtocolNotify (
&gEfiWinNtIoProtocolGuid,
Event,
&Registration
);
ASSERT (!EFI_ERROR (Status));
//
// Should be at EFI_D_INFO, but lets us now things are running
//
DEBUG ((EFI_D_ERROR, "CPU Architectural Protocol Loaded\n"));
return Status;
}
UINTN
Atoi (
CHAR16 *String
)
/*++
Routine Description:
Convert a unicode string to a UINTN
Arguments:
String - Unicode string.
Returns:
UINTN of the number represented by String.
--*/
{
UINTN Number;
CHAR16 *Str;
//
// skip preceeding white space
//
Str = String;
while ((*Str) && (*Str == ' ' || *Str == '"')) {
Str++;
}
//
// Convert ot a Number
//
Number = 0;
while (*Str != '\0') {
if ((*Str >= '0') && (*Str <= '9')) {
Number = (Number * 10) +*Str - '0';
} else {
break;
}
Str++;
}
return Number;
}
VOID
EFIAPI
WinNtIoProtocolNotifyFunction (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
This function will log processor version and frequency data to data hub.
Arguments:
Event - Event whose notification function is being invoked.
Context - Pointer to the notification function's context.
Returns:
None.
--*/
{
EFI_STATUS Status;
EFI_CPU_DATA_RECORD_BUFFER RecordBuffer;
EFI_DATA_RECORD_HEADER *Record;
EFI_SUBCLASS_TYPE1_HEADER *DataHeader;
UINT32 HeaderSize;
UINT32 TotalSize;
UINTN HandleCount;
UINTN HandleIndex;
UINT64 MonotonicCount;
BOOLEAN RecordFound;
EFI_HANDLE *HandleBuffer;
EFI_WIN_NT_IO_PROTOCOL *WinNtIo;
EFI_DATA_HUB_PROTOCOL *DataHub;
EFI_HII_PROTOCOL *Hii;
EFI_HII_HANDLE StringHandle;
EFI_HII_PACKAGES *PackageList;
STRING_REF Token;
DataHub = NULL;
Token = 0;
MonotonicCount = 0;
RecordFound = FALSE;
//
// Retrieve the list of all handles from the handle database
//
Status = gBS->LocateHandleBuffer (
AllHandles,
&gEfiWinNtIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return ;
}
//
// Locate HII protocol
//
Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);
if (EFI_ERROR (Status)) {
return ;
}
//
// Locate DataHub protocol.
//
Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);
if (EFI_ERROR (Status)) {
return ;
}
//
// Initialize data record header
//
mCpuDataRecordHeader.Instance = 1;
HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER);
RecordBuffer.Raw = EfiLibAllocatePool (HeaderSize + EFI_CPU_DATA_MAXIMUM_LENGTH);
if (RecordBuffer.Raw == NULL) {
return ;
}
EfiCopyMem (RecordBuffer.Raw, &mCpuDataRecordHeader, HeaderSize);
//
// Search the Handle array to find the CPU model and speed information
//
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
Status = gBS->OpenProtocol (
HandleBuffer[HandleIndex],
&gEfiWinNtIoProtocolGuid,
&WinNtIo,
Context,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
continue;
}
if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) &&
EfiCompareGuid (WinNtIo->TypeGuid, &gEfiWinNtCPUModelGuid)
) {
//
// Check if this record has been stored in data hub
//
do {
Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
if (EfiCompareGuid (&Record->DataRecordGuid, &gProcessorSubClassName) &&
(DataHeader->RecordType == ProcessorVersionRecordType)
) {
RecordFound = TRUE;
}
}
} while (MonotonicCount != 0);
if (RecordFound) {
RecordFound = FALSE;
continue;
}
//
// Initialize strings to HII database
//
PackageList = PreparePackages (1, &gProcessorProducerGuid, STRING_ARRAY_NAME);
Status = Hii->NewPack (Hii, PackageList, &StringHandle);
ASSERT (!EFI_ERROR (Status));
gBS->FreePool (PackageList);
//
// Store processor version data record to data hub
//
Status = Hii->NewString (Hii, NULL, StringHandle, &Token, WinNtIo->EnvString);
ASSERT (!EFI_ERROR (Status));
RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorVersionRecordType;
RecordBuffer.DataRecord->VariableRecord.ProcessorVersion = Token;
TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_VERSION_DATA);
Status = DataHub->LogData (
DataHub,
&gProcessorSubClassName,
&gProcessorProducerGuid,
EFI_DATA_RECORD_CLASS_DATA,
RecordBuffer.Raw,
TotalSize
);
}
if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) &&
EfiCompareGuid (WinNtIo->TypeGuid, &gEfiWinNtCPUSpeedGuid)
) {
//
// Check if this record has been stored in data hub
//
do {
Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
if (EfiCompareGuid (&Record->DataRecordGuid, &gProcessorSubClassName) &&
(DataHeader->RecordType == ProcessorCoreFrequencyRecordType)
) {
RecordFound = TRUE;
}
}
} while (MonotonicCount != 0);
if (RecordFound) {
RecordFound = FALSE;
continue;
}
//
// Store CPU frequency data record to data hub
//
RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorCoreFrequencyRecordType;
RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Value = (UINT16) Atoi (WinNtIo->EnvString);
RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Exponent = 6;
TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA);
Status = DataHub->LogData (
DataHub,
&gProcessorSubClassName,
&gProcessorProducerGuid,
EFI_DATA_RECORD_CLASS_DATA,
RecordBuffer.Raw,
TotalSize
);
gBS->FreePool (RecordBuffer.Raw);
}
gBS->CloseProtocol (
HandleBuffer[HandleIndex],
&gEfiWinNtIoProtocolGuid,
Context,
NULL
);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?