3 Copyright (c) 2006 - 2009, Intel Corporation
4 All rights reserved. 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"
29 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate
= {
30 CPU_ARCH_PROT_PRIVATE_SIGNATURE
,
33 WinNtFlushCpuDataCache
,
35 WinNtDisableInterrupt
,
36 WinNtGetInterruptState
,
38 WinNtRegisterInterruptHandler
,
40 WinNtSetMemoryAttributes
,
46 CpuMemoryServiceWrite
,
54 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
59 // Service routines for the driver
63 WinNtFlushCpuDataCache (
64 IN EFI_CPU_ARCH_PROTOCOL
*This
,
65 IN EFI_PHYSICAL_ADDRESS Start
,
67 IN EFI_CPU_FLUSH_TYPE FlushType
73 This routine would provide support for flushing the CPU data cache.
74 In the case of NT emulation environment, this flushing is not necessary and
75 is thus not implemented.
79 Pointer to CPU Architectural Protocol interface
80 Start adddress in memory to flush
81 Length of memory to flush
90 // TODO: This - add argument and description to function comment
91 // TODO: FlushType - add argument and description to function comment
92 // TODO: EFI_UNSUPPORTED - add return value to function comment
94 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
96 // Only WB flush is supported. We actually need do nothing on NT emulator
97 // environment. Classify this to follow EFI spec
102 // Other flush types are not supported by NT emulator
104 return EFI_UNSUPPORTED
;
110 WinNtEnableInterrupt (
111 IN EFI_CPU_ARCH_PROTOCOL
*This
117 This routine provides support for emulation of the interrupt enable of the
118 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
119 Architectural Protocol observes in order to defer behaviour while in its
120 emulated interrupt, or timer tick.
124 Pointer to CPU Architectural Protocol interface
132 // TODO: This - add argument and description to function comment
134 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
136 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
137 Private
->InterruptState
= TRUE
;
144 WinNtDisableInterrupt (
145 IN EFI_CPU_ARCH_PROTOCOL
*This
151 This routine provides support for emulation of the interrupt disable of the
152 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
153 Architectural Protocol observes in order to defer behaviour while in its
154 emulated interrupt, or timer tick.
158 Pointer to CPU Architectural Protocol interface
166 // TODO: This - add argument and description to function comment
168 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
170 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
171 Private
->InterruptState
= FALSE
;
178 WinNtGetInterruptState (
179 IN EFI_CPU_ARCH_PROTOCOL
*This
,
186 This routine provides support for emulation of the interrupt disable of the
187 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
188 Architectural Protocol observes in order to defer behaviour while in its
189 emulated interrupt, or timer tick.
193 Pointer to CPU Architectural Protocol interface
201 // TODO: This - add argument and description to function comment
202 // TODO: State - add argument and description to function comment
203 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
205 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
208 return EFI_INVALID_PARAMETER
;
211 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
212 *State
= Private
->InterruptState
;
220 IN EFI_CPU_ARCH_PROTOCOL
*This
,
221 IN EFI_CPU_INIT_TYPE InitType
227 This routine would support generation of a CPU INIT. At
228 present, this code does not provide emulation.
232 Pointer to CPU Architectural Protocol interface
238 EFI_UNSUPPORTED - not yet implemented
241 // TODO: This - add argument and description to function comment
242 // TODO: InitType - add argument and description to function comment
244 return EFI_UNSUPPORTED
;
250 WinNtRegisterInterruptHandler (
251 IN EFI_CPU_ARCH_PROTOCOL
*This
,
252 IN EFI_EXCEPTION_TYPE InterruptType
,
253 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
259 This routine would support registration of an interrupt handler. At
260 present, this code does not provide emulation.
264 Pointer to CPU Architectural Protocol interface
265 Pointer to interrupt handlers
271 EFI_UNSUPPORTED - not yet implemented
274 // TODO: This - add argument and description to function comment
275 // TODO: InterruptType - add argument and description to function comment
276 // TODO: InterruptHandler - add argument and description to function comment
280 // Do parameter checking for EFI spec conformance
282 if (InterruptType
< 0 || InterruptType
> 0xff) {
283 return EFI_UNSUPPORTED
;
286 // Do nothing for Nt32 emulation
288 return EFI_UNSUPPORTED
;
295 IN EFI_CPU_ARCH_PROTOCOL
*This
,
296 IN UINT32 TimerIndex
,
297 OUT UINT64
*TimerValue
,
298 OUT UINT64
*TimerPeriod OPTIONAL
304 This routine would support querying of an on-CPU timer. At present,
305 this code does not provide timer emulation.
309 This - Pointer to CPU Architectural Protocol interface
310 TimerIndex - Index of given CPU timer
311 TimerValue - Output of the timer
312 TimerPeriod - Output of the timer period
316 EFI_UNSUPPORTED - not yet implemented
317 EFI_INVALID_PARAMETER - TimeValue is NULL
321 if (TimerValue
== NULL
) {
322 return EFI_INVALID_PARAMETER
;
326 // No timer supported
328 return EFI_UNSUPPORTED
;
334 WinNtSetMemoryAttributes (
335 IN EFI_CPU_ARCH_PROTOCOL
*This
,
336 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
344 This routine would support querying of an on-CPU timer. At present,
345 this code does not provide timer emulation.
349 Pointer to CPU Architectural Protocol interface
350 Start address of memory region
351 The size in bytes of the memory region
352 The bit mask of attributes to set for the memory region
357 EFI_UNSUPPORTED - not yet implemented
360 // TODO: This - add argument and description to function comment
361 // TODO: BaseAddress - add argument and description to function comment
362 // TODO: Length - add argument and description to function comment
363 // TODO: Attributes - add argument and description to function comment
364 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
367 // Check for invalid parameter for Spec conformance
370 return EFI_INVALID_PARAMETER
;
374 // Do nothing for Nt32 emulation
376 return EFI_UNSUPPORTED
;
384 @param Smbios Pointer to SMBIOS protocol instance.
385 @param Buffer Pointer to the data buffer.
390 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
395 EFI_SMBIOS_HANDLE SmbiosHandle
;
398 Status
= Smbios
->Add (
402 (EFI_SMBIOS_TABLE_HEADER
*)Buffer
404 ASSERT_EFI_ERROR (Status
);
415 This function will log processor version and frequency data to Smbios.
418 Event - Event whose notification function is being invoked.
419 Context - Pointer to the notification function's context.
428 EFI_SMBIOS_PROTOCOL
*Smbios
;
429 EFI_HII_HANDLE HiiHandle
;
432 EFI_STRING CpuVerStr
;
433 SMBIOS_TABLE_TYPE4
*SmbiosRecord
;
434 CHAR8
*OptionalStrStart
;
437 // Locate Smbios protocol.
439 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
441 if (EFI_ERROR (Status
)) {
446 // Initialize strings to HII database
448 HiiHandle
= HiiAddPackages (
454 ASSERT (HiiHandle
!= NULL
);
456 Token
= STRING_TOKEN (STR_PROCESSOR_VERSION
);
457 CpuVerStr
= HiiGetPackageString(&gEfiCallerIdGuid
, Token
, NULL
);
458 CpuVerStrLen
= StrLen(CpuVerStr
);
459 ASSERT (CpuVerStrLen
<= SMBIOS_STRING_MAX_LENGTH
);
462 TotalSize
= sizeof(SMBIOS_TABLE_TYPE4
) + CpuVerStrLen
+ 1 + 1;
463 SmbiosRecord
= AllocatePool(TotalSize
);
464 ZeroMem(SmbiosRecord
, TotalSize
);
466 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
;
467 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE4
);
469 // Make handle chosen by smbios protocol.add automatically.
471 SmbiosRecord
->Hdr
.Handle
= 0;
473 // Processor version is the 1st string.
475 SmbiosRecord
->ProcessorVersion
= 1;
477 // Store CPU frequency data record to data hub - It's an emulator so make up a value
479 SmbiosRecord
->CurrentSpeed
= 1234;
481 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
482 UnicodeStrToAsciiStr(CpuVerStr
, OptionalStrStart
);
485 // Now we have got the full smbios record, call smbios protocol to add this record.
487 LogSmbiosData(Smbios
, (UINT8
*) SmbiosRecord
);
488 FreePool (SmbiosRecord
);
497 IN EFI_HANDLE ImageHandle
,
498 IN EFI_SYSTEM_TABLE
*SystemTable
504 Initialize the state information for the CPU Architectural Protocol
508 ImageHandle of the loaded driver
509 Pointer to the System Table
515 EFI_SUCCESS - protocol instance can be published
516 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
517 EFI_DEVICE_ERROR - cannot create the thread
525 Status
= gBS
->InstallMultipleProtocolInterfaces (
526 &mCpuTemplate
.Handle
,
527 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
528 &gEfiCpuIo2ProtocolGuid
, &mCpuTemplate
.CpuIo
,
531 ASSERT_EFI_ERROR (Status
);