3 Copyright (c) 2006 - 2009, 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 Unix 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
24 #include <FrameworkDxe.h>
25 #include <IndustryStandard/SmBios.h>
26 #include <Protocol/Cpu.h>
27 #include <Protocol/Smbios.h>
28 #include <Guid/DataHubRecords.h>
29 #include <Protocol/CpuIo2.h>
30 #include <Protocol/FrameworkHii.h>
31 #include <Protocol/UnixThunk.h>
33 #include <Library/BaseLib.h>
34 #include <Library/DebugLib.h>
35 #include <Library/HiiLib.h>
36 #include <Library/UefiLib.h>
37 #include <Library/UefiDriverEntryPoint.h>
38 #include <Library/BaseMemoryLib.h>
39 #include <Library/MemoryAllocationLib.h>
40 #include <Library/UefiBootServicesTableLib.h>
41 #include <Library/UnixLib.h>
43 #include "CpuDriver.h"
45 #include <Protocol/UnixIo.h>
47 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
49 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate
= {
50 CPU_ARCH_PROT_PRIVATE_SIGNATURE
,
53 UnixFlushCpuDataCache
,
56 UnixGetInterruptState
,
58 UnixRegisterInterruptHandler
,
60 UnixSetMemoryAttributes
,
79 // Service routines for the driver
83 UnixFlushCpuDataCache (
84 IN EFI_CPU_ARCH_PROTOCOL
*This
,
85 IN EFI_PHYSICAL_ADDRESS Start
,
87 IN EFI_CPU_FLUSH_TYPE FlushType
93 This routine would provide support for flushing the CPU data cache.
94 In the case of UNIX emulation environment, this flushing is not necessary and
95 is thus not implemented.
99 Pointer to CPU Architectural Protocol interface
100 Start adddress in memory to flush
101 Length of memory to flush
110 // TODO: This - add argument and description to function comment
111 // TODO: FlushType - add argument and description to function comment
112 // TODO: EFI_UNSUPPORTED - add return value to function comment
114 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
116 // Only WB flush is supported. We actually need do nothing on UNIX emulator
117 // environment. Classify this to follow EFI spec
122 // Other flush types are not supported by UNIX emulator
124 return EFI_UNSUPPORTED
;
129 UnixEnableInterrupt (
130 IN EFI_CPU_ARCH_PROTOCOL
*This
136 This routine provides support for emulation of the interrupt enable of the
137 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
138 Architectural Protocol observes in order to defer behaviour while in its
139 emulated interrupt, or timer tick.
143 Pointer to CPU Architectural Protocol interface
151 // TODO: This - add argument and description to function comment
153 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
155 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
156 Private
->InterruptState
= TRUE
;
157 gUnix
->EnableInterrupt ();
163 UnixDisableInterrupt (
164 IN EFI_CPU_ARCH_PROTOCOL
*This
170 This routine provides support for emulation of the interrupt disable of the
171 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
172 Architectural Protocol observes in order to defer behaviour while in its
173 emulated interrupt, or timer tick.
177 Pointer to CPU Architectural Protocol interface
185 // TODO: This - add argument and description to function comment
187 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
189 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
190 Private
->InterruptState
= FALSE
;
191 gUnix
->DisableInterrupt ();
197 UnixGetInterruptState (
198 IN EFI_CPU_ARCH_PROTOCOL
*This
,
205 This routine provides support for emulation of the interrupt disable of the
206 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
207 Architectural Protocol observes in order to defer behaviour while in its
208 emulated interrupt, or timer tick.
212 Pointer to CPU Architectural Protocol interface
220 // TODO: This - add argument and description to function comment
221 // TODO: State - add argument and description to function comment
222 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
224 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
227 return EFI_INVALID_PARAMETER
;
230 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
231 *State
= Private
->InterruptState
;
238 IN EFI_CPU_ARCH_PROTOCOL
*This
,
239 IN EFI_CPU_INIT_TYPE InitType
245 This routine would support generation of a CPU INIT. At
246 present, this code does not provide emulation.
250 Pointer to CPU Architectural Protocol interface
256 EFI_UNSUPPORTED - not yet implemented
259 // TODO: This - add argument and description to function comment
260 // TODO: InitType - add argument and description to function comment
262 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
264 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
265 return EFI_UNSUPPORTED
;
270 UnixRegisterInterruptHandler (
271 IN EFI_CPU_ARCH_PROTOCOL
*This
,
272 IN EFI_EXCEPTION_TYPE InterruptType
,
273 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
279 This routine would support registration of an interrupt handler. At
280 present, this code does not provide emulation.
284 Pointer to CPU Architectural Protocol interface
285 Pointer to interrupt handlers
291 EFI_UNSUPPORTED - not yet implemented
294 // TODO: This - add argument and description to function comment
295 // TODO: InterruptType - add argument and description to function comment
296 // TODO: InterruptHandler - add argument and description to function comment
298 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
301 // Do parameter checking for EFI spec conformance
303 if (InterruptType
< 0 || InterruptType
> 0xff) {
304 return EFI_UNSUPPORTED
;
307 // Do nothing for Nt32 emulation
309 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
310 return EFI_UNSUPPORTED
;
316 IN EFI_CPU_ARCH_PROTOCOL
*This
,
317 IN UINT32 TimerIndex
,
318 OUT UINT64
*TimerValue
,
319 OUT UINT64
*TimerPeriod OPTIONAL
325 This routine would support querying of an on-CPU timer. At present,
326 this code does not provide timer emulation.
330 This - Pointer to CPU Architectural Protocol interface
331 TimerIndex - Index of given CPU timer
332 TimerValue - Output of the timer
333 TimerPeriod - Output of the timer period
337 EFI_UNSUPPORTED - not yet implemented
338 EFI_INVALID_PARAMETER - TimeValue is NULL
342 if (TimerValue
== NULL
) {
343 return EFI_INVALID_PARAMETER
;
347 // No timer supported
349 return EFI_UNSUPPORTED
;
354 UnixSetMemoryAttributes (
355 IN EFI_CPU_ARCH_PROTOCOL
*This
,
356 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
364 This routine would support querying of an on-CPU timer. At present,
365 this code does not provide timer emulation.
369 Pointer to CPU Architectural Protocol interface
370 Start address of memory region
371 The size in bytes of the memory region
372 The bit mask of attributes to set for the memory region
377 EFI_UNSUPPORTED - not yet implemented
380 // TODO: This - add argument and description to function comment
381 // TODO: BaseAddress - add argument and description to function comment
382 // TODO: Length - add argument and description to function comment
383 // TODO: Attributes - add argument and description to function comment
384 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
386 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
389 // Check for invalid parameter for Spec conformance
392 return EFI_INVALID_PARAMETER
;
396 // Do nothing for Nt32 emulation
398 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
399 return EFI_UNSUPPORTED
;
407 @param Smbios Pointer to SMBIOS protocol instance.
408 @param Buffer Pointer to the data buffer.
413 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
418 EFI_SMBIOS_HANDLE SmbiosHandle
;
421 Status
= Smbios
->Add (
425 (EFI_SMBIOS_TABLE_HEADER
*)Buffer
427 ASSERT_EFI_ERROR (Status
);
437 This function will log processor version and frequency data to data hub.
440 Event - Event whose notification function is being invoked.
441 Context - Pointer to the notification function's context.
449 EFI_SMBIOS_PROTOCOL
*Smbios
;
451 EFI_HII_HANDLE HiiHandle
;
454 EFI_STRING CpuVerStr
;
455 SMBIOS_TABLE_TYPE4
*SmbiosRecord
;
456 CHAR8
*OptionalStrStart
;
459 // Locate Smbios protocol.
461 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
463 if (EFI_ERROR (Status
)) {
468 // Initialize strings to HII database
470 HiiHandle
= HiiAddPackages (
476 ASSERT (HiiHandle
!= NULL
);
479 Token
= STRING_TOKEN (STR_INTEL_GENUINE_PROCESSOR
);
480 CpuVerStr
= HiiGetPackageString(&gEfiCallerIdGuid
, Token
, NULL
);
481 CpuVerStrLen
= StrLen(CpuVerStr
);
482 ASSERT (CpuVerStrLen
<= SMBIOS_STRING_MAX_LENGTH
);
484 TotalSize
= sizeof(SMBIOS_TABLE_TYPE4
) + CpuVerStrLen
+ 1 + 1;
485 SmbiosRecord
= AllocatePool(TotalSize
);
486 ZeroMem(SmbiosRecord
, TotalSize
);
488 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
;
489 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE4
);
491 // Make handle chosen by smbios protocol.add automatically.
493 SmbiosRecord
->Hdr
.Handle
= 0;
495 // Processor version is the 1st string.
497 SmbiosRecord
->ProcessorVersion
= 1;
499 // Store CPU frequency data record to data hub - It's an emulator so make up a value
501 SmbiosRecord
->CurrentSpeed
= 1234;
503 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
504 UnicodeStrToAsciiStr(CpuVerStr
, OptionalStrStart
);
507 // Now we have got the full smbios record, call smbios protocol to add this record.
509 LogSmbiosData(Smbios
, (UINT8
*) SmbiosRecord
);
510 FreePool (SmbiosRecord
);
516 IN EFI_HANDLE ImageHandle
,
517 IN EFI_SYSTEM_TABLE
*SystemTable
523 Initialize the state information for the CPU Architectural Protocol
527 ImageHandle of the loaded driver
528 Pointer to the System Table
534 EFI_SUCCESS - protocol instance can be published
535 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
536 EFI_DEVICE_ERROR - cannot create the thread
539 // TODO: SystemTable - add argument and description to function comment
545 Status
= gBS
->InstallMultipleProtocolInterfaces (
546 &mCpuTemplate
.Handle
,
547 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
548 &gEfiCpuIo2ProtocolGuid
, &mCpuTemplate
.CpuIo
,
551 ASSERT_EFI_ERROR (Status
);
553 DEBUG ((EFI_D_ERROR
, "CPU Architectural Protocol Loaded\n"));