3 Copyright (c) 2006, 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
25 #include <Protocol/Cpu.h>
26 #include <Protocol/DataHub.h>
27 #include <Guid/DataHubRecords.h>
28 #include <Protocol/CpuIo.h>
29 #include <Protocol/FrameworkHii.h>
31 #include <Library/BaseLib.h>
32 #include <Library/DebugLib.h>
33 #include <Library/HiiLib.h>
34 #include <Library/UefiLib.h>
35 #include <Library/UefiDriverEntryPoint.h>
36 #include <Library/BaseMemoryLib.h>
37 #include <Library/MemoryAllocationLib.h>
38 #include <Library/UefiBootServicesTableLib.h>
39 #include <Framework/DataHubRecords.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
,
63 CpuMemoryServiceWrite
,
72 EFI_CPU_DATA_RECORD
*DataRecord
;
74 } EFI_CPU_DATA_RECORD_BUFFER
;
76 EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader
= {
77 EFI_PROCESSOR_SUBCLASS_VERSION
, // Version
78 sizeof (EFI_SUBCLASS_TYPE1_HEADER
), // Header Size
79 0, // Instance, Initialize later
80 EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
, // SubInstance
81 0 // RecordType, Initialize later
85 // Service routines for the driver
89 UnixFlushCpuDataCache (
90 IN EFI_CPU_ARCH_PROTOCOL
*This
,
91 IN EFI_PHYSICAL_ADDRESS Start
,
93 IN EFI_CPU_FLUSH_TYPE FlushType
99 This routine would provide support for flushing the CPU data cache.
100 In the case of UNIX emulation environment, this flushing is not necessary and
101 is thus not implemented.
105 Pointer to CPU Architectural Protocol interface
106 Start adddress in memory to flush
107 Length of memory to flush
116 // TODO: This - add argument and description to function comment
117 // TODO: FlushType - add argument and description to function comment
118 // TODO: EFI_UNSUPPORTED - add return value to function comment
120 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
122 // Only WB flush is supported. We actually need do nothing on UNIX emulator
123 // environment. Classify this to follow EFI spec
128 // Other flush types are not supported by UNIX emulator
130 return EFI_UNSUPPORTED
;
135 UnixEnableInterrupt (
136 IN EFI_CPU_ARCH_PROTOCOL
*This
142 This routine provides support for emulation of the interrupt enable of the
143 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
144 Architectural Protocol observes in order to defer behaviour while in its
145 emulated interrupt, or timer tick.
149 Pointer to CPU Architectural Protocol interface
157 // TODO: This - add argument and description to function comment
159 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
161 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
162 Private
->InterruptState
= TRUE
;
168 UnixDisableInterrupt (
169 IN EFI_CPU_ARCH_PROTOCOL
*This
175 This routine provides support for emulation of the interrupt disable of the
176 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
177 Architectural Protocol observes in order to defer behaviour while in its
178 emulated interrupt, or timer tick.
182 Pointer to CPU Architectural Protocol interface
190 // TODO: This - add argument and description to function comment
192 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
194 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
195 Private
->InterruptState
= FALSE
;
201 UnixGetInterruptState (
202 IN EFI_CPU_ARCH_PROTOCOL
*This
,
209 This routine provides support for emulation of the interrupt disable of the
210 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
211 Architectural Protocol observes in order to defer behaviour while in its
212 emulated interrupt, or timer tick.
216 Pointer to CPU Architectural Protocol interface
224 // TODO: This - add argument and description to function comment
225 // TODO: State - add argument and description to function comment
226 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
228 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
231 return EFI_INVALID_PARAMETER
;
234 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
235 *State
= Private
->InterruptState
;
242 IN EFI_CPU_ARCH_PROTOCOL
*This
,
243 IN EFI_CPU_INIT_TYPE InitType
249 This routine would support generation of a CPU INIT. At
250 present, this code does not provide emulation.
254 Pointer to CPU Architectural Protocol interface
260 EFI_UNSUPPORTED - not yet implemented
263 // TODO: This - add argument and description to function comment
264 // TODO: InitType - add argument and description to function comment
266 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
268 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
269 return EFI_UNSUPPORTED
;
274 UnixRegisterInterruptHandler (
275 IN EFI_CPU_ARCH_PROTOCOL
*This
,
276 IN EFI_EXCEPTION_TYPE InterruptType
,
277 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
283 This routine would support registration of an interrupt handler. At
284 present, this code does not provide emulation.
288 Pointer to CPU Architectural Protocol interface
289 Pointer to interrupt handlers
295 EFI_UNSUPPORTED - not yet implemented
298 // TODO: This - add argument and description to function comment
299 // TODO: InterruptType - add argument and description to function comment
300 // TODO: InterruptHandler - add argument and description to function comment
302 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
305 // Do parameter checking for EFI spec conformance
307 if (InterruptType
< 0 || InterruptType
> 0xff) {
308 return EFI_UNSUPPORTED
;
311 // Do nothing for Nt32 emulation
313 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
314 return EFI_UNSUPPORTED
;
320 IN EFI_CPU_ARCH_PROTOCOL
*This
,
321 IN UINT32 TimerIndex
,
322 OUT UINT64
*TimerValue
,
323 OUT UINT64
*TimerPeriod OPTIONAL
329 This routine would support querying of an on-CPU timer. At present,
330 this code does not provide timer emulation.
334 This - Pointer to CPU Architectural Protocol interface
335 TimerIndex - Index of given CPU timer
336 TimerValue - Output of the timer
337 TimerPeriod - Output of the timer period
341 EFI_UNSUPPORTED - not yet implemented
342 EFI_INVALID_PARAMETER - TimeValue is NULL
346 if (TimerValue
== NULL
) {
347 return EFI_INVALID_PARAMETER
;
351 // No timer supported
353 return EFI_UNSUPPORTED
;
358 UnixSetMemoryAttributes (
359 IN EFI_CPU_ARCH_PROTOCOL
*This
,
360 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
368 This routine would support querying of an on-CPU timer. At present,
369 this code does not provide timer emulation.
373 Pointer to CPU Architectural Protocol interface
374 Start address of memory region
375 The size in bytes of the memory region
376 The bit mask of attributes to set for the memory region
381 EFI_UNSUPPORTED - not yet implemented
384 // TODO: This - add argument and description to function comment
385 // TODO: BaseAddress - add argument and description to function comment
386 // TODO: Length - add argument and description to function comment
387 // TODO: Attributes - add argument and description to function comment
388 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
390 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
393 // Check for invalid parameter for Spec conformance
396 return EFI_INVALID_PARAMETER
;
400 // Do nothing for Nt32 emulation
402 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
403 return EFI_UNSUPPORTED
;
413 This function will log processor version and frequency data to data hub.
416 Event - Event whose notification function is being invoked.
417 Context - Pointer to the notification function's context.
425 EFI_CPU_DATA_RECORD_BUFFER RecordBuffer
;
428 EFI_DATA_HUB_PROTOCOL
*DataHub
;
429 EFI_HII_HANDLE HiiHandle
;
432 // Locate DataHub protocol.
434 Status
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, &DataHub
);
435 if (EFI_ERROR (Status
)) {
440 // Initialize data record header
442 mCpuDataRecordHeader
.Instance
= 1;
443 HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
445 RecordBuffer
.Raw
= AllocatePool (HeaderSize
+ EFI_CPU_DATA_MAXIMUM_LENGTH
);
446 if (RecordBuffer
.Raw
== NULL
) {
451 // Initialize strings to HII database
453 HiiHandle
= HiiAddPackages (
459 ASSERT (HiiHandle
!= NULL
);
461 CopyMem (RecordBuffer
.Raw
, &mCpuDataRecordHeader
, HeaderSize
);
464 RecordBuffer
.DataRecord
->DataRecordHeader
.RecordType
= EFI_PROCESSOR_VERSION_RECORD_NUMBER
;
465 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorVersion
= STRING_TOKEN (STR_INTEL_GENUINE_PROCESSOR
);
466 TotalSize
= HeaderSize
+ sizeof (EFI_PROCESSOR_VERSION_DATA
);
468 Status
= DataHub
->LogData (
470 &gEfiProcessorSubClassGuid
,
472 EFI_DATA_RECORD_CLASS_DATA
,
478 // Store CPU frequency data record to data hub - It's an emulator so make up a value
480 RecordBuffer
.DataRecord
->DataRecordHeader
.RecordType
= EFI_PROCESSOR_FREQUENCY_RECORD_NUMBER
;
481 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorCoreFrequency
.Value
= 1234;
482 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorCoreFrequency
.Exponent
= 6;
483 TotalSize
= HeaderSize
+ sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA
);
485 Status
= DataHub
->LogData (
487 &gEfiProcessorSubClassGuid
,
489 EFI_DATA_RECORD_CLASS_DATA
,
494 FreePool (RecordBuffer
.Raw
);
500 IN EFI_HANDLE ImageHandle
,
501 IN EFI_SYSTEM_TABLE
*SystemTable
507 Initialize the state information for the CPU Architectural Protocol
511 ImageHandle of the loaded driver
512 Pointer to the System Table
518 EFI_SUCCESS - protocol instance can be published
519 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
520 EFI_DEVICE_ERROR - cannot create the thread
523 // TODO: SystemTable - add argument and description to function comment
529 Status
= gBS
->InstallMultipleProtocolInterfaces (
530 &mCpuTemplate
.Handle
,
531 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
532 &gEfiCpuIoProtocolGuid
, &mCpuTemplate
.CpuIo
,
535 ASSERT_EFI_ERROR (Status
);
537 DEBUG ((EFI_D_ERROR
, "CPU Architectural Protocol Loaded\n"));