-/*++\r
+/**@file\r
\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
the CPU-specific setjump/long pair. Other services are not implemented\r
in this driver.\r
\r
---*/\r
+**/\r
\r
\r
#include "CpuDriver.h"\r
\r
+UINT64 mTimerPeriod;\r
\r
CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate = {\r
CPU_ARCH_PROT_PRIVATE_SIGNATURE,\r
WinNtRegisterInterruptHandler,\r
WinNtGetTimerValue,\r
WinNtSetMemoryAttributes,\r
- 0,\r
+ 1,\r
4\r
},\r
{\r
\r
\r
\r
-typedef union {\r
- EFI_CPU_DATA_RECORD *DataRecord;\r
- UINT8 *Raw;\r
-} EFI_CPU_DATA_RECORD_BUFFER;\r
-\r
-EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader = {\r
- EFI_PROCESSOR_SUBCLASS_VERSION, // Version\r
- sizeof (EFI_SUBCLASS_TYPE1_HEADER), // Header Size\r
- 0, // Instance, Initialize later\r
- EFI_SUBCLASS_INSTANCE_NON_APPLICABLE, // SubInstance\r
- 0 // RecordType, Initialize later\r
-};\r
-\r
//\r
// Service routines for the driver\r
//\r
// TODO: This - add argument and description to function comment\r
// TODO: InitType - add argument and description to function comment\r
{\r
- CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
-\r
- Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
return EFI_UNSUPPORTED;\r
}\r
\r
// TODO: InterruptType - add argument and description to function comment\r
// TODO: InterruptHandler - add argument and description to function comment\r
{\r
- CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
\r
//\r
// Do parameter checking for EFI spec conformance\r
//\r
// Do nothing for Nt32 emulation\r
//\r
- Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
return EFI_UNSUPPORTED;\r
}\r
\r
if (TimerValue == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
-\r
- //\r
- // No timer supported\r
- //\r
- return EFI_UNSUPPORTED;\r
+ \r
+ if (TimerIndex != 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ gWinNt->QueryPerformanceCounter ((LARGE_INTEGER *)TimerValue);\r
+ \r
+ if (TimerPeriod != NULL) {\r
+ *TimerPeriod = mTimerPeriod;\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
}\r
\r
\r
// TODO: Attributes - add argument and description to function comment\r
// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
{\r
- CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
-\r
//\r
// Check for invalid parameter for Spec conformance\r
//\r
//\r
// Do nothing for Nt32 emulation\r
//\r
- Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
return EFI_UNSUPPORTED;\r
}\r
\r
\r
+\r
+/**\r
+ Logs SMBIOS record.\r
+\r
+ @param Smbios Pointer to SMBIOS protocol instance.\r
+ @param Buffer Pointer to the data buffer.\r
+\r
+**/\r
+VOID\r
+LogSmbiosData (\r
+ IN EFI_SMBIOS_PROTOCOL *Smbios,\r
+ IN UINT8 *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SMBIOS_HANDLE SmbiosHandle;\r
+ \r
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
+ Status = Smbios->Add (\r
+ Smbios,\r
+ NULL,\r
+ &SmbiosHandle,\r
+ (EFI_SMBIOS_TABLE_HEADER*)Buffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+\r
VOID\r
-CpuUpdateDataHub (\r
+CpuUpdateSmbios (\r
VOID\r
)\r
/*++\r
\r
Routine Description:\r
- This function will log processor version and frequency data to data hub.\r
+ This function will log processor version and frequency data to Smbios.\r
\r
Arguments:\r
Event - Event whose notification function is being invoked.\r
--*/\r
{\r
EFI_STATUS Status;\r
- EFI_CPU_DATA_RECORD_BUFFER RecordBuffer;\r
- UINT32 HeaderSize;\r
UINT32 TotalSize;\r
- EFI_DATA_HUB_PROTOCOL *DataHub;\r
- EFI_HII_PROTOCOL *Hii;\r
- EFI_HII_HANDLE StringHandle;\r
- EFI_HII_PACKAGES *PackageList;\r
-\r
+ EFI_SMBIOS_PROTOCOL *Smbios;\r
+ EFI_HII_HANDLE HiiHandle;\r
+ STRING_REF Token;\r
+ UINTN CpuVerStrLen;\r
+ EFI_STRING CpuVerStr;\r
+ SMBIOS_TABLE_TYPE4 *SmbiosRecord;\r
+ CHAR8 *OptionalStrStart;\r
\r
//\r
- // Locate DataHub protocol.\r
+ // Locate Smbios protocol.\r
//\r
- Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);\r
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);\r
+ \r
if (EFI_ERROR (Status)) {\r
return;\r
}\r
\r
//\r
- // Locate DataHub protocol.\r
+ // Initialize strings to HII database\r
//\r
- Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
+ HiiHandle = HiiAddPackages (\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ CpuStrings,\r
+ NULL\r
+ );\r
+ ASSERT (HiiHandle != NULL);\r
+\r
+ Token = STRING_TOKEN (STR_PROCESSOR_VERSION);\r
+ CpuVerStr = HiiGetPackageString(&gEfiCallerIdGuid, Token, NULL);\r
+ CpuVerStrLen = StrLen(CpuVerStr);\r
+ ASSERT (CpuVerStrLen <= SMBIOS_STRING_MAX_LENGTH);\r
+\r
+\r
+ TotalSize = (UINT32)(sizeof(SMBIOS_TABLE_TYPE4) + CpuVerStrLen + 1 + 1);\r
+ SmbiosRecord = AllocatePool(TotalSize);\r
+ ZeroMem(SmbiosRecord, TotalSize);\r
+\r
+ SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION;\r
+ SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4);\r
//\r
- // Initialize data record header\r
+ // Make handle chosen by smbios protocol.add automatically.\r
//\r
- mCpuDataRecordHeader.Instance = 1;\r
- HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER);\r
-\r
- RecordBuffer.Raw = AllocatePool (HeaderSize + EFI_CPU_DATA_MAXIMUM_LENGTH);\r
- if (RecordBuffer.Raw == NULL) {\r
- return ;\r
- }\r
-\r
+ SmbiosRecord->Hdr.Handle = 0; \r
//\r
- // Initialize strings to HII database\r
+ // Processor version is the 1st string.\r
//\r
- PackageList = PreparePackages (1, &gEfiProcessorProducerGuid, CpuStrings);\r
- Status = Hii->NewPack (Hii, PackageList, &StringHandle);\r
- ASSERT (!EFI_ERROR (Status));\r
- FreePool (PackageList);\r
-\r
- CopyMem (RecordBuffer.Raw, &mCpuDataRecordHeader, HeaderSize);\r
-\r
-\r
- RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorVersionRecordType;\r
- RecordBuffer.DataRecord->VariableRecord.ProcessorVersion = STRING_TOKEN (STR_PROCESSOR_VERSION);\r
- TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_VERSION_DATA);\r
+ SmbiosRecord->ProcessorVersion = 1;\r
+ //\r
+ // Store CPU frequency data record to data hub - It's an emulator so make up a value\r
+ //\r
+ SmbiosRecord->CurrentSpeed = 1234;\r
\r
- Status = DataHub->LogData (\r
- DataHub,\r
- &gEfiProcessorSubClassGuid,\r
- &gEfiProcessorProducerGuid,\r
- EFI_DATA_RECORD_CLASS_DATA,\r
- RecordBuffer.Raw,\r
- TotalSize\r
- );\r
+ OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);\r
+ UnicodeStrToAsciiStr(CpuVerStr, OptionalStrStart);\r
\r
//\r
- // Store CPU frequency data record to data hub - It's an emulator so make up a value\r
+ // Now we have got the full smbios record, call smbios protocol to add this record.\r
//\r
- RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorCoreFrequencyRecordType;\r
- RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Value = 1234;\r
- RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Exponent = 6;\r
- TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA);\r
-\r
- Status = DataHub->LogData (\r
- DataHub,\r
- &gEfiProcessorSubClassGuid,\r
- &gEfiProcessorProducerGuid,\r
- EFI_DATA_RECORD_CLASS_DATA,\r
- RecordBuffer.Raw,\r
- TotalSize\r
- );\r
-\r
- FreePool (RecordBuffer.Raw);\r
+ LogSmbiosData(Smbios, (UINT8 *) SmbiosRecord);\r
+ FreePool (SmbiosRecord);\r
+\r
}\r
\r
\r
\r
--*/\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ UINT64 Frequency;\r
\r
- CpuUpdateDataHub ();\r
+ //\r
+ // Retrieve the frequency of the performance counter in Hz.\r
+ // \r
+ gWinNt->QueryPerformanceFrequency ((LARGE_INTEGER *)&Frequency);\r
+ \r
+ //\r
+ // Convert frequency in Hz to a clock period in femtoseconds.\r
+ //\r
+ mTimerPeriod = DivU64x64Remainder (1000000000000000, Frequency, NULL);\r
+ \r
+ CpuUpdateSmbios ();\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&mCpuTemplate.Handle,\r
&gEfiCpuArchProtocolGuid, &mCpuTemplate.Cpu,\r
- &gEfiCpuIoProtocolGuid, &mCpuTemplate.CpuIo,\r
+ &gEfiCpuIo2ProtocolGuid, &mCpuTemplate.CpuIo,\r
NULL\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
return Status;\r
}\r
-\r
-\r