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 return EFI_UNSUPPORTED
;
135 EmuRegisterInterruptHandler (
136 IN EFI_CPU_ARCH_PROTOCOL
*This
,
137 IN EFI_EXCEPTION_TYPE InterruptType
,
138 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
142 // Do parameter checking for EFI spec conformance
144 if (InterruptType
< 0 || InterruptType
> 0xff) {
145 return EFI_UNSUPPORTED
;
148 // Do nothing for Emu emulation
150 return EFI_UNSUPPORTED
;
156 IN EFI_CPU_ARCH_PROTOCOL
*This
,
157 IN UINT32 TimerIndex
,
158 OUT UINT64
*TimerValue
,
159 OUT UINT64
*TimerPeriod OPTIONAL
162 if (TimerValue
== NULL
) {
163 return EFI_INVALID_PARAMETER
;
166 if (TimerIndex
!= 0) {
167 return EFI_INVALID_PARAMETER
;
170 *TimerValue
= gEmuThunk
->QueryPerformanceCounter ();
172 if (TimerPeriod
!= NULL
) {
173 *TimerPeriod
= mTimerPeriod
;
182 EmuSetMemoryAttributes (
183 IN EFI_CPU_ARCH_PROTOCOL
*This
,
184 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
190 // Check for invalid parameter for Spec conformance
193 return EFI_INVALID_PARAMETER
;
197 // Do nothing for Nt32 emulation
199 return EFI_UNSUPPORTED
;
207 @param Smbios Pointer to SMBIOS protocol instance.
208 @param Buffer Pointer to the data buffer.
213 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
218 EFI_SMBIOS_HANDLE SmbiosHandle
;
221 Status
= Smbios
->Add (
225 (EFI_SMBIOS_TABLE_HEADER
*)Buffer
227 ASSERT_EFI_ERROR (Status
);
237 EFI_SMBIOS_PROTOCOL
*Smbios
;
238 EFI_HII_HANDLE HiiHandle
;
241 EFI_STRING CpuVerStr
;
242 SMBIOS_TABLE_TYPE4
*SmbiosRecord
;
243 CHAR8
*OptionalStrStart
;
246 // Locate Smbios protocol.
248 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
250 if (EFI_ERROR (Status
)) {
255 // Initialize strings to HII database
257 HiiHandle
= HiiAddPackages (
263 ASSERT (HiiHandle
!= NULL
);
265 Token
= STRING_TOKEN (STR_PROCESSOR_VERSION
);
266 CpuVerStr
= HiiGetPackageString(&gEfiCallerIdGuid
, Token
, NULL
);
267 CpuVerStrLen
= StrLen(CpuVerStr
);
268 ASSERT (CpuVerStrLen
<= SMBIOS_STRING_MAX_LENGTH
);
270 TotalSize
= sizeof(SMBIOS_TABLE_TYPE4
) + CpuVerStrLen
+ 1 + 1;
271 SmbiosRecord
= AllocatePool(TotalSize
);
272 ZeroMem(SmbiosRecord
, TotalSize
);
274 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
;
275 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE4
);
277 // Make handle chosen by smbios protocol.add automatically.
279 SmbiosRecord
->Hdr
.Handle
= 0;
281 // Processor version is the 1st string.
283 SmbiosRecord
->ProcessorVersion
= 1;
285 // Store CPU frequency data record to data hub - It's an emulator so make up a value
287 SmbiosRecord
->CurrentSpeed
= 1234;
289 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
290 UnicodeStrToAsciiStr(CpuVerStr
, OptionalStrStart
);
293 // Now we have got the full smbios record, call smbios protocol to add this record.
295 LogSmbiosData(Smbios
, (UINT8
*) SmbiosRecord
);
296 FreePool (SmbiosRecord
);
302 Callback function for idle events.
304 @param Event Event whose notification function is being invoked.
305 @param Context The pointer to the notification function's context,
306 which is implementation-dependent.
311 IdleLoopEventCallback (
316 gEmuThunk
->CpuSleep ();
323 IN EFI_HANDLE ImageHandle
,
324 IN EFI_SYSTEM_TABLE
*SystemTable
329 EFI_EVENT IdleLoopEvent
;
332 // Retrieve the frequency of the performance counter in Hz.
334 Frequency
= gEmuThunk
->QueryPerformanceFrequency ();
337 // Convert frequency in Hz to a clock period in femtoseconds.
339 mTimerPeriod
= DivU64x64Remainder (1000000000000000ULL, Frequency
, NULL
);
343 CpuMpServicesInit ();
345 Status
= gBS
->CreateEventEx (
348 IdleLoopEventCallback
,
353 ASSERT_EFI_ERROR (Status
);
356 Status
= gBS
->InstallMultipleProtocolInterfaces (
357 &mCpuTemplate
.Handle
,
358 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
359 &gEfiCpuIo2ProtocolGuid
, &mCpuTemplate
.CpuIo
,
362 ASSERT_EFI_ERROR (Status
);