3 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
12 NT Emulation Architectural Protocol Driver as defined in Tiano.
13 This CPU module abstracts the interrupt subsystem of a platform and
14 the CPU-specific setjump/long pair. Other services are not implemented
20 #include "CpuDriver.h"
24 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate
= {
25 CPU_ARCH_PROT_PRIVATE_SIGNATURE
,
28 WinNtFlushCpuDataCache
,
30 WinNtDisableInterrupt
,
31 WinNtGetInterruptState
,
33 WinNtRegisterInterruptHandler
,
35 WinNtSetMemoryAttributes
,
41 CpuMemoryServiceWrite
,
49 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
54 // Service routines for the driver
58 WinNtFlushCpuDataCache (
59 IN EFI_CPU_ARCH_PROTOCOL
*This
,
60 IN EFI_PHYSICAL_ADDRESS Start
,
62 IN EFI_CPU_FLUSH_TYPE FlushType
68 This routine would provide support for flushing the CPU data cache.
69 In the case of NT emulation environment, this flushing is not necessary and
70 is thus not implemented.
74 Pointer to CPU Architectural Protocol interface
75 Start adddress in memory to flush
76 Length of memory to flush
85 // TODO: This - add argument and description to function comment
86 // TODO: FlushType - add argument and description to function comment
87 // TODO: EFI_UNSUPPORTED - add return value to function comment
89 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
91 // Only WB flush is supported. We actually need do nothing on NT emulator
92 // environment. Classify this to follow EFI spec
97 // Other flush types are not supported by NT emulator
99 return EFI_UNSUPPORTED
;
105 WinNtEnableInterrupt (
106 IN EFI_CPU_ARCH_PROTOCOL
*This
112 This routine provides support for emulation of the interrupt enable of the
113 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
114 Architectural Protocol observes in order to defer behaviour while in its
115 emulated interrupt, or timer tick.
119 Pointer to CPU Architectural Protocol interface
127 // TODO: This - add argument and description to function comment
129 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
131 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
132 Private
->InterruptState
= TRUE
;
139 WinNtDisableInterrupt (
140 IN EFI_CPU_ARCH_PROTOCOL
*This
146 This routine provides support for emulation of the interrupt disable of the
147 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
148 Architectural Protocol observes in order to defer behaviour while in its
149 emulated interrupt, or timer tick.
153 Pointer to CPU Architectural Protocol interface
161 // TODO: This - add argument and description to function comment
163 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
165 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
166 Private
->InterruptState
= FALSE
;
173 WinNtGetInterruptState (
174 IN EFI_CPU_ARCH_PROTOCOL
*This
,
181 This routine provides support for emulation of the interrupt disable of the
182 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
183 Architectural Protocol observes in order to defer behaviour while in its
184 emulated interrupt, or timer tick.
188 Pointer to CPU Architectural Protocol interface
196 // TODO: This - add argument and description to function comment
197 // TODO: State - add argument and description to function comment
198 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
200 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
203 return EFI_INVALID_PARAMETER
;
206 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
207 *State
= Private
->InterruptState
;
215 IN EFI_CPU_ARCH_PROTOCOL
*This
,
216 IN EFI_CPU_INIT_TYPE InitType
222 This routine would support generation of a CPU INIT. At
223 present, this code does not provide emulation.
227 Pointer to CPU Architectural Protocol interface
233 EFI_UNSUPPORTED - not yet implemented
236 // TODO: This - add argument and description to function comment
237 // TODO: InitType - add argument and description to function comment
239 return EFI_UNSUPPORTED
;
245 WinNtRegisterInterruptHandler (
246 IN EFI_CPU_ARCH_PROTOCOL
*This
,
247 IN EFI_EXCEPTION_TYPE InterruptType
,
248 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
254 This routine would support registration of an interrupt handler. At
255 present, this code does not provide emulation.
259 Pointer to CPU Architectural Protocol interface
260 Pointer to interrupt handlers
266 EFI_UNSUPPORTED - not yet implemented
269 // TODO: This - add argument and description to function comment
270 // TODO: InterruptType - add argument and description to function comment
271 // TODO: InterruptHandler - add argument and description to function comment
275 // Do parameter checking for EFI spec conformance
277 if (InterruptType
< 0 || InterruptType
> 0xff) {
278 return EFI_UNSUPPORTED
;
281 // Do nothing for Nt32 emulation
283 return EFI_UNSUPPORTED
;
290 IN EFI_CPU_ARCH_PROTOCOL
*This
,
291 IN UINT32 TimerIndex
,
292 OUT UINT64
*TimerValue
,
293 OUT UINT64
*TimerPeriod OPTIONAL
299 This routine would support querying of an on-CPU timer. At present,
300 this code does not provide timer emulation.
304 This - Pointer to CPU Architectural Protocol interface
305 TimerIndex - Index of given CPU timer
306 TimerValue - Output of the timer
307 TimerPeriod - Output of the timer period
311 EFI_UNSUPPORTED - not yet implemented
312 EFI_INVALID_PARAMETER - TimeValue is NULL
316 if (TimerValue
== NULL
) {
317 return EFI_INVALID_PARAMETER
;
320 if (TimerIndex
!= 0) {
321 return EFI_INVALID_PARAMETER
;
324 gWinNt
->QueryPerformanceCounter ((LARGE_INTEGER
*)TimerValue
);
326 if (TimerPeriod
!= NULL
) {
327 *TimerPeriod
= mTimerPeriod
;
336 WinNtSetMemoryAttributes (
337 IN EFI_CPU_ARCH_PROTOCOL
*This
,
338 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
346 This routine would support querying of an on-CPU timer. At present,
347 this code does not provide timer emulation.
351 Pointer to CPU Architectural Protocol interface
352 Start address of memory region
353 The size in bytes of the memory region
354 The bit mask of attributes to set for the memory region
359 EFI_UNSUPPORTED - not yet implemented
362 // TODO: This - add argument and description to function comment
363 // TODO: BaseAddress - add argument and description to function comment
364 // TODO: Length - add argument and description to function comment
365 // TODO: Attributes - add argument and description to function comment
366 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
369 // Check for invalid parameter for Spec conformance
372 return EFI_INVALID_PARAMETER
;
376 // Do nothing for Nt32 emulation
378 return EFI_UNSUPPORTED
;
386 @param Smbios Pointer to SMBIOS protocol instance.
387 @param Buffer Pointer to the data buffer.
392 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
397 EFI_SMBIOS_HANDLE SmbiosHandle
;
399 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
400 Status
= Smbios
->Add (
404 (EFI_SMBIOS_TABLE_HEADER
*)Buffer
406 ASSERT_EFI_ERROR (Status
);
417 This function will log processor version and frequency data to Smbios.
420 Event - Event whose notification function is being invoked.
421 Context - Pointer to the notification function's context.
430 EFI_SMBIOS_PROTOCOL
*Smbios
;
431 EFI_HII_HANDLE HiiHandle
;
434 EFI_STRING CpuVerStr
;
435 SMBIOS_TABLE_TYPE4
*SmbiosRecord
;
436 CHAR8
*OptionalStrStart
;
439 // Locate Smbios protocol.
441 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
443 if (EFI_ERROR (Status
)) {
448 // Initialize strings to HII database
450 HiiHandle
= HiiAddPackages (
456 ASSERT (HiiHandle
!= NULL
);
458 Token
= STRING_TOKEN (STR_PROCESSOR_VERSION
);
459 CpuVerStr
= HiiGetPackageString(&gEfiCallerIdGuid
, Token
, NULL
);
460 CpuVerStrLen
= StrLen(CpuVerStr
);
461 ASSERT (CpuVerStrLen
<= SMBIOS_STRING_MAX_LENGTH
);
464 TotalSize
= (UINT32
)(sizeof(SMBIOS_TABLE_TYPE4
) + CpuVerStrLen
+ 1 + 1);
465 SmbiosRecord
= AllocatePool(TotalSize
);
466 ZeroMem(SmbiosRecord
, TotalSize
);
468 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
;
469 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE4
);
471 // Make handle chosen by smbios protocol.add automatically.
473 SmbiosRecord
->Hdr
.Handle
= 0;
475 // Processor version is the 1st string.
477 SmbiosRecord
->ProcessorVersion
= 1;
479 // Store CPU frequency data record to data hub - It's an emulator so make up a value
481 SmbiosRecord
->CurrentSpeed
= 1234;
483 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
484 UnicodeStrToAsciiStr(CpuVerStr
, OptionalStrStart
);
487 // Now we have got the full smbios record, call smbios protocol to add this record.
489 LogSmbiosData(Smbios
, (UINT8
*) SmbiosRecord
);
490 FreePool (SmbiosRecord
);
499 IN EFI_HANDLE ImageHandle
,
500 IN EFI_SYSTEM_TABLE
*SystemTable
506 Initialize the state information for the CPU Architectural Protocol
510 ImageHandle of the loaded driver
511 Pointer to the System Table
517 EFI_SUCCESS - protocol instance can be published
518 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
519 EFI_DEVICE_ERROR - cannot create the thread
527 // Retrieve the frequency of the performance counter in Hz.
529 gWinNt
->QueryPerformanceFrequency ((LARGE_INTEGER
*)&Frequency
);
532 // Convert frequency in Hz to a clock period in femtoseconds.
534 mTimerPeriod
= DivU64x64Remainder (1000000000000000, Frequency
, NULL
);
538 Status
= gBS
->InstallMultipleProtocolInterfaces (
539 &mCpuTemplate
.Handle
,
540 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
541 &gEfiCpuIo2ProtocolGuid
, &mCpuTemplate
.CpuIo
,
544 ASSERT_EFI_ERROR (Status
);