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 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>
32 #include <Library/BaseLib.h>
33 #include <Library/DebugLib.h>
34 #include <Library/HiiLib.h>
35 #include <Library/UefiLib.h>
36 #include <Library/UefiDriverEntryPoint.h>
37 #include <Library/BaseMemoryLib.h>
38 #include <Library/MemoryAllocationLib.h>
39 #include <Library/UefiBootServicesTableLib.h>
40 #include "CpuDriver.h"
42 #include <Protocol/UnixIo.h>
44 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
46 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate
= {
47 CPU_ARCH_PROT_PRIVATE_SIGNATURE
,
50 UnixFlushCpuDataCache
,
53 UnixGetInterruptState
,
55 UnixRegisterInterruptHandler
,
57 UnixSetMemoryAttributes
,
76 // Service routines for the driver
80 UnixFlushCpuDataCache (
81 IN EFI_CPU_ARCH_PROTOCOL
*This
,
82 IN EFI_PHYSICAL_ADDRESS Start
,
84 IN EFI_CPU_FLUSH_TYPE FlushType
90 This routine would provide support for flushing the CPU data cache.
91 In the case of UNIX emulation environment, this flushing is not necessary and
92 is thus not implemented.
96 Pointer to CPU Architectural Protocol interface
97 Start adddress in memory to flush
98 Length of memory to flush
107 // TODO: This - add argument and description to function comment
108 // TODO: FlushType - add argument and description to function comment
109 // TODO: EFI_UNSUPPORTED - add return value to function comment
111 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
113 // Only WB flush is supported. We actually need do nothing on UNIX emulator
114 // environment. Classify this to follow EFI spec
119 // Other flush types are not supported by UNIX emulator
121 return EFI_UNSUPPORTED
;
126 UnixEnableInterrupt (
127 IN EFI_CPU_ARCH_PROTOCOL
*This
133 This routine provides support for emulation of the interrupt enable of the
134 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
135 Architectural Protocol observes in order to defer behaviour while in its
136 emulated interrupt, or timer tick.
140 Pointer to CPU Architectural Protocol interface
148 // TODO: This - add argument and description to function comment
150 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
152 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
153 Private
->InterruptState
= TRUE
;
159 UnixDisableInterrupt (
160 IN EFI_CPU_ARCH_PROTOCOL
*This
166 This routine provides support for emulation of the interrupt disable of the
167 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
168 Architectural Protocol observes in order to defer behaviour while in its
169 emulated interrupt, or timer tick.
173 Pointer to CPU Architectural Protocol interface
181 // TODO: This - add argument and description to function comment
183 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
185 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
186 Private
->InterruptState
= FALSE
;
192 UnixGetInterruptState (
193 IN EFI_CPU_ARCH_PROTOCOL
*This
,
200 This routine provides support for emulation of the interrupt disable of the
201 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
202 Architectural Protocol observes in order to defer behaviour while in its
203 emulated interrupt, or timer tick.
207 Pointer to CPU Architectural Protocol interface
215 // TODO: This - add argument and description to function comment
216 // TODO: State - add argument and description to function comment
217 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
219 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
222 return EFI_INVALID_PARAMETER
;
225 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
226 *State
= Private
->InterruptState
;
233 IN EFI_CPU_ARCH_PROTOCOL
*This
,
234 IN EFI_CPU_INIT_TYPE InitType
240 This routine would support generation of a CPU INIT. At
241 present, this code does not provide emulation.
245 Pointer to CPU Architectural Protocol interface
251 EFI_UNSUPPORTED - not yet implemented
254 // TODO: This - add argument and description to function comment
255 // TODO: InitType - add argument and description to function comment
257 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
259 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
260 return EFI_UNSUPPORTED
;
265 UnixRegisterInterruptHandler (
266 IN EFI_CPU_ARCH_PROTOCOL
*This
,
267 IN EFI_EXCEPTION_TYPE InterruptType
,
268 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
274 This routine would support registration of an interrupt handler. At
275 present, this code does not provide emulation.
279 Pointer to CPU Architectural Protocol interface
280 Pointer to interrupt handlers
286 EFI_UNSUPPORTED - not yet implemented
289 // TODO: This - add argument and description to function comment
290 // TODO: InterruptType - add argument and description to function comment
291 // TODO: InterruptHandler - add argument and description to function comment
293 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
296 // Do parameter checking for EFI spec conformance
298 if (InterruptType
< 0 || InterruptType
> 0xff) {
299 return EFI_UNSUPPORTED
;
302 // Do nothing for Nt32 emulation
304 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
305 return EFI_UNSUPPORTED
;
311 IN EFI_CPU_ARCH_PROTOCOL
*This
,
312 IN UINT32 TimerIndex
,
313 OUT UINT64
*TimerValue
,
314 OUT UINT64
*TimerPeriod OPTIONAL
320 This routine would support querying of an on-CPU timer. At present,
321 this code does not provide timer emulation.
325 This - Pointer to CPU Architectural Protocol interface
326 TimerIndex - Index of given CPU timer
327 TimerValue - Output of the timer
328 TimerPeriod - Output of the timer period
332 EFI_UNSUPPORTED - not yet implemented
333 EFI_INVALID_PARAMETER - TimeValue is NULL
337 if (TimerValue
== NULL
) {
338 return EFI_INVALID_PARAMETER
;
342 // No timer supported
344 return EFI_UNSUPPORTED
;
349 UnixSetMemoryAttributes (
350 IN EFI_CPU_ARCH_PROTOCOL
*This
,
351 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
359 This routine would support querying of an on-CPU timer. At present,
360 this code does not provide timer emulation.
364 Pointer to CPU Architectural Protocol interface
365 Start address of memory region
366 The size in bytes of the memory region
367 The bit mask of attributes to set for the memory region
372 EFI_UNSUPPORTED - not yet implemented
375 // TODO: This - add argument and description to function comment
376 // TODO: BaseAddress - add argument and description to function comment
377 // TODO: Length - add argument and description to function comment
378 // TODO: Attributes - add argument and description to function comment
379 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
381 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
384 // Check for invalid parameter for Spec conformance
387 return EFI_INVALID_PARAMETER
;
391 // Do nothing for Nt32 emulation
393 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
394 return EFI_UNSUPPORTED
;
402 @param Smbios Pointer to SMBIOS protocol instance.
403 @param Buffer Pointer to the data buffer.
408 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
413 EFI_SMBIOS_HANDLE SmbiosHandle
;
416 Status
= Smbios
->Add (
420 (EFI_SMBIOS_TABLE_HEADER
*)Buffer
422 ASSERT_EFI_ERROR (Status
);
432 This function will log processor version and frequency data to data hub.
435 Event - Event whose notification function is being invoked.
436 Context - Pointer to the notification function's context.
444 EFI_SMBIOS_PROTOCOL
*Smbios
;
446 EFI_HII_HANDLE HiiHandle
;
449 EFI_STRING CpuVerStr
;
450 SMBIOS_TABLE_TYPE4
*SmbiosRecord
;
451 CHAR8
*OptionalStrStart
;
454 // Locate Smbios protocol.
456 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&Smbios
);
458 if (EFI_ERROR (Status
)) {
463 // Initialize strings to HII database
465 HiiHandle
= HiiAddPackages (
471 ASSERT (HiiHandle
!= NULL
);
474 Token
= STRING_TOKEN (STR_INTEL_GENUINE_PROCESSOR
);
475 CpuVerStr
= HiiGetPackageString(&gEfiCallerIdGuid
, Token
, NULL
);
476 CpuVerStrLen
= StrLen(CpuVerStr
);
477 ASSERT (CpuVerStrLen
<= SMBIOS_STRING_MAX_LENGTH
);
479 TotalSize
= sizeof(SMBIOS_TABLE_TYPE4
) + CpuVerStrLen
+ 1 + 1;
480 SmbiosRecord
= AllocatePool(TotalSize
);
481 ZeroMem(SmbiosRecord
, TotalSize
);
483 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
;
484 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE4
);
486 // Make handle chosen by smbios protocol.add automatically.
488 SmbiosRecord
->Hdr
.Handle
= 0;
490 // Processor version is the 1st string.
492 SmbiosRecord
->ProcessorVersion
= 1;
494 // Store CPU frequency data record to data hub - It's an emulator so make up a value
496 SmbiosRecord
->CurrentSpeed
= 1234;
498 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
499 UnicodeStrToAsciiStr(CpuVerStr
, OptionalStrStart
);
502 // Now we have got the full smbios record, call smbios protocol to add this record.
504 LogSmbiosData(Smbios
, (UINT8
*) SmbiosRecord
);
505 FreePool (SmbiosRecord
);
511 IN EFI_HANDLE ImageHandle
,
512 IN EFI_SYSTEM_TABLE
*SystemTable
518 Initialize the state information for the CPU Architectural Protocol
522 ImageHandle of the loaded driver
523 Pointer to the System Table
529 EFI_SUCCESS - protocol instance can be published
530 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
531 EFI_DEVICE_ERROR - cannot create the thread
534 // TODO: SystemTable - add argument and description to function comment
540 Status
= gBS
->InstallMultipleProtocolInterfaces (
541 &mCpuTemplate
.Handle
,
542 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
543 &gEfiCpuIo2ProtocolGuid
, &mCpuTemplate
.CpuIo
,
546 ASSERT_EFI_ERROR (Status
);
548 DEBUG ((EFI_D_ERROR
, "CPU Architectural Protocol Loaded\n"));