2 Emu driver to produce CPU Architectural Protocol.
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2011, Apple Inc. All rights reserved.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "CpuDriver.h"
20 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate
= {
21 CPU_ARCH_PROT_PRIVATE_SIGNATURE
,
29 EmuRegisterInterruptHandler
,
31 EmuSetMemoryAttributes
,
48 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
53 // Service routines for the driver
57 EmuFlushCpuDataCache (
58 IN EFI_CPU_ARCH_PROTOCOL
*This
,
59 IN EFI_PHYSICAL_ADDRESS Start
,
61 IN EFI_CPU_FLUSH_TYPE FlushType
64 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
66 // Only WB flush is supported. We actually need do nothing on Emu emulator
67 // environment. Classify this to follow EFI spec
72 // Other flush types are not supported by Emu emulator
74 return EFI_UNSUPPORTED
;
80 IN EFI_CPU_ARCH_PROTOCOL
*This
83 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
85 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
86 Private
->InterruptState
= TRUE
;
87 gEmuThunk
->EnableInterrupt ();
94 IN EFI_CPU_ARCH_PROTOCOL
*This
97 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
99 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
100 Private
->InterruptState
= FALSE
;
101 gEmuThunk
->DisableInterrupt ();
107 EmuGetInterruptState (
108 IN EFI_CPU_ARCH_PROTOCOL
*This
,
112 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
115 return EFI_INVALID_PARAMETER
;
118 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
119 *State
= Private
->InterruptState
;
126 IN EFI_CPU_ARCH_PROTOCOL
*This
,
127 IN EFI_CPU_INIT_TYPE InitType
130 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
132 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
133 return EFI_UNSUPPORTED
;
138 EmuRegisterInterruptHandler (
139 IN EFI_CPU_ARCH_PROTOCOL
*This
,
140 IN EFI_EXCEPTION_TYPE InterruptType
,
141 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
144 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
147 // Do parameter checking for EFI spec conformance
149 if (InterruptType
< 0 || InterruptType
> 0xff) {
150 return EFI_UNSUPPORTED
;
153 // Do nothing for Emu emulation
155 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
156 return EFI_UNSUPPORTED
;
162 IN EFI_CPU_ARCH_PROTOCOL
*This
,
163 IN UINT32 TimerIndex
,
164 OUT UINT64
*TimerValue
,
165 OUT UINT64
*TimerPeriod OPTIONAL
168 if (TimerValue
== NULL
) {
169 return EFI_INVALID_PARAMETER
;
172 if (TimerIndex
!= 0) {
173 return EFI_INVALID_PARAMETER
;
176 *TimerValue
= gEmuThunk
->QueryPerformanceCounter ();
178 if (TimerPeriod
!= NULL
) {
179 *TimerPeriod
= mTimerPeriod
;
188 EmuSetMemoryAttributes (
189 IN EFI_CPU_ARCH_PROTOCOL
*This
,
190 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
195 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
198 // Check for invalid parameter for Spec conformance
201 return EFI_INVALID_PARAMETER
;
205 // Do nothing for Nt32 emulation
207 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
208 return EFI_UNSUPPORTED
;
216 @param Smbios Pointer to SMBIOS protocol instance.
217 @param Buffer Pointer to the data buffer.
222 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
227 EFI_SMBIOS_HANDLE SmbiosHandle
;
230 Status
= Smbios
->Add (
234 (EFI_SMBIOS_TABLE_HEADER
*)Buffer
236 ASSERT_EFI_ERROR (Status
);
246 EFI_SMBIOS_PROTOCOL
*Smbios
;
247 EFI_HII_HANDLE HiiHandle
;
250 EFI_STRING CpuVerStr
;
251 SMBIOS_TABLE_TYPE4
*SmbiosRecord
;
252 CHAR8
*OptionalStrStart
;
255 // Locate Smbios protocol.
257 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
259 if (EFI_ERROR (Status
)) {
264 // Initialize strings to HII database
266 HiiHandle
= HiiAddPackages (
272 ASSERT (HiiHandle
!= NULL
);
274 Token
= STRING_TOKEN (STR_PROCESSOR_VERSION
);
275 CpuVerStr
= HiiGetPackageString(&gEfiCallerIdGuid
, Token
, NULL
);
276 CpuVerStrLen
= StrLen(CpuVerStr
);
277 ASSERT (CpuVerStrLen
<= SMBIOS_STRING_MAX_LENGTH
);
279 TotalSize
= sizeof(SMBIOS_TABLE_TYPE4
) + CpuVerStrLen
+ 1 + 1;
280 SmbiosRecord
= AllocatePool(TotalSize
);
281 ZeroMem(SmbiosRecord
, TotalSize
);
283 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
;
284 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE4
);
286 // Make handle chosen by smbios protocol.add automatically.
288 SmbiosRecord
->Hdr
.Handle
= 0;
290 // Processor version is the 1st string.
292 SmbiosRecord
->ProcessorVersion
= 1;
294 // Store CPU frequency data record to data hub - It's an emulator so make up a value
296 SmbiosRecord
->CurrentSpeed
= 1234;
298 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
299 UnicodeStrToAsciiStr(CpuVerStr
, OptionalStrStart
);
302 // Now we have got the full smbios record, call smbios protocol to add this record.
304 LogSmbiosData(Smbios
, (UINT8
*) SmbiosRecord
);
305 FreePool (SmbiosRecord
);
311 IN EFI_HANDLE ImageHandle
,
312 IN EFI_SYSTEM_TABLE
*SystemTable
319 // Retrieve the frequency of the performance counter in Hz.
321 Frequency
= gEmuThunk
->QueryPerformanceFrequency ();
324 // Convert frequency in Hz to a clock period in femtoseconds.
326 mTimerPeriod
= DivU64x64Remainder (1000000000000000, Frequency
, NULL
);
330 CpuMpServicesInit ();
332 Status
= gBS
->InstallMultipleProtocolInterfaces (
333 &mCpuTemplate
.Handle
,
334 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
335 &gEfiCpuIo2ProtocolGuid
, &mCpuTemplate
.CpuIo
,
338 ASSERT_EFI_ERROR (Status
);