3 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 NT Emulation Architectural Protocol Driver as defined in Tiano.
19 This CPU module abstracts the interrupt subsystem of a platform and
20 the CPU-specific setjump/long pair. Other services are not implemented
26 #include "CpuDriver.h"
30 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate
= {
31 CPU_ARCH_PROT_PRIVATE_SIGNATURE
,
34 WinNtFlushCpuDataCache
,
36 WinNtDisableInterrupt
,
37 WinNtGetInterruptState
,
39 WinNtRegisterInterruptHandler
,
41 WinNtSetMemoryAttributes
,
47 CpuMemoryServiceWrite
,
55 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
60 // Service routines for the driver
64 WinNtFlushCpuDataCache (
65 IN EFI_CPU_ARCH_PROTOCOL
*This
,
66 IN EFI_PHYSICAL_ADDRESS Start
,
68 IN EFI_CPU_FLUSH_TYPE FlushType
74 This routine would provide support for flushing the CPU data cache.
75 In the case of NT emulation environment, this flushing is not necessary and
76 is thus not implemented.
80 Pointer to CPU Architectural Protocol interface
81 Start adddress in memory to flush
82 Length of memory to flush
91 // TODO: This - add argument and description to function comment
92 // TODO: FlushType - add argument and description to function comment
93 // TODO: EFI_UNSUPPORTED - add return value to function comment
95 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
97 // Only WB flush is supported. We actually need do nothing on NT emulator
98 // environment. Classify this to follow EFI spec
103 // Other flush types are not supported by NT emulator
105 return EFI_UNSUPPORTED
;
111 WinNtEnableInterrupt (
112 IN EFI_CPU_ARCH_PROTOCOL
*This
118 This routine provides support for emulation of the interrupt enable of the
119 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
120 Architectural Protocol observes in order to defer behaviour while in its
121 emulated interrupt, or timer tick.
125 Pointer to CPU Architectural Protocol interface
133 // TODO: This - add argument and description to function comment
135 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
137 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
138 Private
->InterruptState
= TRUE
;
145 WinNtDisableInterrupt (
146 IN EFI_CPU_ARCH_PROTOCOL
*This
152 This routine provides support for emulation of the interrupt disable of the
153 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
154 Architectural Protocol observes in order to defer behaviour while in its
155 emulated interrupt, or timer tick.
159 Pointer to CPU Architectural Protocol interface
167 // TODO: This - add argument and description to function comment
169 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
171 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
172 Private
->InterruptState
= FALSE
;
179 WinNtGetInterruptState (
180 IN EFI_CPU_ARCH_PROTOCOL
*This
,
187 This routine provides support for emulation of the interrupt disable of the
188 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
189 Architectural Protocol observes in order to defer behaviour while in its
190 emulated interrupt, or timer tick.
194 Pointer to CPU Architectural Protocol interface
202 // TODO: This - add argument and description to function comment
203 // TODO: State - add argument and description to function comment
204 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
206 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
209 return EFI_INVALID_PARAMETER
;
212 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
213 *State
= Private
->InterruptState
;
221 IN EFI_CPU_ARCH_PROTOCOL
*This
,
222 IN EFI_CPU_INIT_TYPE InitType
228 This routine would support generation of a CPU INIT. At
229 present, this code does not provide emulation.
233 Pointer to CPU Architectural Protocol interface
239 EFI_UNSUPPORTED - not yet implemented
242 // TODO: This - add argument and description to function comment
243 // TODO: InitType - add argument and description to function comment
245 return EFI_UNSUPPORTED
;
251 WinNtRegisterInterruptHandler (
252 IN EFI_CPU_ARCH_PROTOCOL
*This
,
253 IN EFI_EXCEPTION_TYPE InterruptType
,
254 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
260 This routine would support registration of an interrupt handler. At
261 present, this code does not provide emulation.
265 Pointer to CPU Architectural Protocol interface
266 Pointer to interrupt handlers
272 EFI_UNSUPPORTED - not yet implemented
275 // TODO: This - add argument and description to function comment
276 // TODO: InterruptType - add argument and description to function comment
277 // TODO: InterruptHandler - add argument and description to function comment
281 // Do parameter checking for EFI spec conformance
283 if (InterruptType
< 0 || InterruptType
> 0xff) {
284 return EFI_UNSUPPORTED
;
287 // Do nothing for Nt32 emulation
289 return EFI_UNSUPPORTED
;
296 IN EFI_CPU_ARCH_PROTOCOL
*This
,
297 IN UINT32 TimerIndex
,
298 OUT UINT64
*TimerValue
,
299 OUT UINT64
*TimerPeriod OPTIONAL
305 This routine would support querying of an on-CPU timer. At present,
306 this code does not provide timer emulation.
310 This - Pointer to CPU Architectural Protocol interface
311 TimerIndex - Index of given CPU timer
312 TimerValue - Output of the timer
313 TimerPeriod - Output of the timer period
317 EFI_UNSUPPORTED - not yet implemented
318 EFI_INVALID_PARAMETER - TimeValue is NULL
322 if (TimerValue
== NULL
) {
323 return EFI_INVALID_PARAMETER
;
326 if (TimerIndex
!= 0) {
327 return EFI_INVALID_PARAMETER
;
330 gWinNt
->QueryPerformanceCounter (TimerValue
);
332 if (TimerPeriod
!= NULL
) {
333 *TimerPeriod
= mTimerPeriod
;
342 WinNtSetMemoryAttributes (
343 IN EFI_CPU_ARCH_PROTOCOL
*This
,
344 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
352 This routine would support querying of an on-CPU timer. At present,
353 this code does not provide timer emulation.
357 Pointer to CPU Architectural Protocol interface
358 Start address of memory region
359 The size in bytes of the memory region
360 The bit mask of attributes to set for the memory region
365 EFI_UNSUPPORTED - not yet implemented
368 // TODO: This - add argument and description to function comment
369 // TODO: BaseAddress - add argument and description to function comment
370 // TODO: Length - add argument and description to function comment
371 // TODO: Attributes - add argument and description to function comment
372 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
375 // Check for invalid parameter for Spec conformance
378 return EFI_INVALID_PARAMETER
;
382 // Do nothing for Nt32 emulation
384 return EFI_UNSUPPORTED
;
392 @param Smbios Pointer to SMBIOS protocol instance.
393 @param Buffer Pointer to the data buffer.
398 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
403 EFI_SMBIOS_HANDLE SmbiosHandle
;
406 Status
= Smbios
->Add (
410 (EFI_SMBIOS_TABLE_HEADER
*)Buffer
412 ASSERT_EFI_ERROR (Status
);
423 This function will log processor version and frequency data to Smbios.
426 Event - Event whose notification function is being invoked.
427 Context - Pointer to the notification function's context.
436 EFI_SMBIOS_PROTOCOL
*Smbios
;
437 EFI_HII_HANDLE HiiHandle
;
440 EFI_STRING CpuVerStr
;
441 SMBIOS_TABLE_TYPE4
*SmbiosRecord
;
442 CHAR8
*OptionalStrStart
;
445 // Locate Smbios protocol.
447 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
449 if (EFI_ERROR (Status
)) {
454 // Initialize strings to HII database
456 HiiHandle
= HiiAddPackages (
462 ASSERT (HiiHandle
!= NULL
);
464 Token
= STRING_TOKEN (STR_PROCESSOR_VERSION
);
465 CpuVerStr
= HiiGetPackageString(&gEfiCallerIdGuid
, Token
, NULL
);
466 CpuVerStrLen
= StrLen(CpuVerStr
);
467 ASSERT (CpuVerStrLen
<= SMBIOS_STRING_MAX_LENGTH
);
470 TotalSize
= sizeof(SMBIOS_TABLE_TYPE4
) + CpuVerStrLen
+ 1 + 1;
471 SmbiosRecord
= AllocatePool(TotalSize
);
472 ZeroMem(SmbiosRecord
, TotalSize
);
474 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
;
475 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE4
);
477 // Make handle chosen by smbios protocol.add automatically.
479 SmbiosRecord
->Hdr
.Handle
= 0;
481 // Processor version is the 1st string.
483 SmbiosRecord
->ProcessorVersion
= 1;
485 // Store CPU frequency data record to data hub - It's an emulator so make up a value
487 SmbiosRecord
->CurrentSpeed
= 1234;
489 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
490 UnicodeStrToAsciiStr(CpuVerStr
, OptionalStrStart
);
493 // Now we have got the full smbios record, call smbios protocol to add this record.
495 LogSmbiosData(Smbios
, (UINT8
*) SmbiosRecord
);
496 FreePool (SmbiosRecord
);
505 IN EFI_HANDLE ImageHandle
,
506 IN EFI_SYSTEM_TABLE
*SystemTable
512 Initialize the state information for the CPU Architectural Protocol
516 ImageHandle of the loaded driver
517 Pointer to the System Table
523 EFI_SUCCESS - protocol instance can be published
524 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
525 EFI_DEVICE_ERROR - cannot create the thread
533 // Retrieve the frequency of the performance counter in Hz.
535 gWinNt
->QueryPerformanceFrequency (&Frequency
);
538 // Convert frequency in Hz to a clock period in femtoseconds.
540 mTimerPeriod
= DivU64x64Remainder (1000000000000000, Frequency
, NULL
);
544 Status
= gBS
->InstallMultipleProtocolInterfaces (
545 &mCpuTemplate
.Handle
,
546 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
547 &gEfiCpuIo2ProtocolGuid
, &mCpuTemplate
.CpuIo
,
550 ASSERT_EFI_ERROR (Status
);