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>
30 #include <Guid/DataHubProducer.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 <Framework/DataHubRecords.h>
41 #include "CpuDriver.h"
43 #include <Protocol/UnixIo.h>
45 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
47 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate
= {
48 CPU_ARCH_PROT_PRIVATE_SIGNATURE
,
51 UnixFlushCpuDataCache
,
54 UnixGetInterruptState
,
56 UnixRegisterInterruptHandler
,
58 UnixSetMemoryAttributes
,
64 CpuMemoryServiceWrite
,
73 EFI_CPU_DATA_RECORD
*DataRecord
;
75 } EFI_CPU_DATA_RECORD_BUFFER
;
77 EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader
= {
78 EFI_PROCESSOR_SUBCLASS_VERSION
, // Version
79 sizeof (EFI_SUBCLASS_TYPE1_HEADER
), // Header Size
80 0, // Instance, Initialize later
81 EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
, // SubInstance
82 0 // RecordType, Initialize later
86 // Service routines for the driver
90 UnixFlushCpuDataCache (
91 IN EFI_CPU_ARCH_PROTOCOL
*This
,
92 IN EFI_PHYSICAL_ADDRESS Start
,
94 IN EFI_CPU_FLUSH_TYPE FlushType
100 This routine would provide support for flushing the CPU data cache.
101 In the case of UNIX emulation environment, this flushing is not necessary and
102 is thus not implemented.
106 Pointer to CPU Architectural Protocol interface
107 Start adddress in memory to flush
108 Length of memory to flush
117 // TODO: This - add argument and description to function comment
118 // TODO: FlushType - add argument and description to function comment
119 // TODO: EFI_UNSUPPORTED - add return value to function comment
121 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
123 // Only WB flush is supported. We actually need do nothing on UNIX emulator
124 // environment. Classify this to follow EFI spec
129 // Other flush types are not supported by UNIX emulator
131 return EFI_UNSUPPORTED
;
136 UnixEnableInterrupt (
137 IN EFI_CPU_ARCH_PROTOCOL
*This
143 This routine provides support for emulation of the interrupt enable of the
144 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
145 Architectural Protocol observes in order to defer behaviour while in its
146 emulated interrupt, or timer tick.
150 Pointer to CPU Architectural Protocol interface
158 // TODO: This - add argument and description to function comment
160 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
162 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
163 Private
->InterruptState
= TRUE
;
169 UnixDisableInterrupt (
170 IN EFI_CPU_ARCH_PROTOCOL
*This
176 This routine provides support for emulation of the interrupt disable of the
177 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
178 Architectural Protocol observes in order to defer behaviour while in its
179 emulated interrupt, or timer tick.
183 Pointer to CPU Architectural Protocol interface
191 // TODO: This - add argument and description to function comment
193 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
195 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
196 Private
->InterruptState
= FALSE
;
202 UnixGetInterruptState (
203 IN EFI_CPU_ARCH_PROTOCOL
*This
,
210 This routine provides support for emulation of the interrupt disable of the
211 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
212 Architectural Protocol observes in order to defer behaviour while in its
213 emulated interrupt, or timer tick.
217 Pointer to CPU Architectural Protocol interface
225 // TODO: This - add argument and description to function comment
226 // TODO: State - add argument and description to function comment
227 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
229 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
232 return EFI_INVALID_PARAMETER
;
235 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
236 *State
= Private
->InterruptState
;
243 IN EFI_CPU_ARCH_PROTOCOL
*This
,
244 IN EFI_CPU_INIT_TYPE InitType
250 This routine would support generation of a CPU INIT. At
251 present, this code does not provide emulation.
255 Pointer to CPU Architectural Protocol interface
261 EFI_UNSUPPORTED - not yet implemented
264 // TODO: This - add argument and description to function comment
265 // TODO: InitType - add argument and description to function comment
267 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
269 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
270 return EFI_UNSUPPORTED
;
275 UnixRegisterInterruptHandler (
276 IN EFI_CPU_ARCH_PROTOCOL
*This
,
277 IN EFI_EXCEPTION_TYPE InterruptType
,
278 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
284 This routine would support registration of an interrupt handler. At
285 present, this code does not provide emulation.
289 Pointer to CPU Architectural Protocol interface
290 Pointer to interrupt handlers
296 EFI_UNSUPPORTED - not yet implemented
299 // TODO: This - add argument and description to function comment
300 // TODO: InterruptType - add argument and description to function comment
301 // TODO: InterruptHandler - add argument and description to function comment
303 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
306 // Do parameter checking for EFI spec conformance
308 if (InterruptType
< 0 || InterruptType
> 0xff) {
309 return EFI_UNSUPPORTED
;
312 // Do nothing for Nt32 emulation
314 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
315 return EFI_UNSUPPORTED
;
321 IN EFI_CPU_ARCH_PROTOCOL
*This
,
322 IN UINT32 TimerIndex
,
323 OUT UINT64
*TimerValue
,
324 OUT UINT64
*TimerPeriod OPTIONAL
330 This routine would support querying of an on-CPU timer. At present,
331 this code does not provide timer emulation.
335 This - Pointer to CPU Architectural Protocol interface
336 TimerIndex - Index of given CPU timer
337 TimerValue - Output of the timer
338 TimerPeriod - Output of the timer period
342 EFI_UNSUPPORTED - not yet implemented
343 EFI_INVALID_PARAMETER - TimeValue is NULL
347 if (TimerValue
== NULL
) {
348 return EFI_INVALID_PARAMETER
;
352 // No timer supported
354 return EFI_UNSUPPORTED
;
359 UnixSetMemoryAttributes (
360 IN EFI_CPU_ARCH_PROTOCOL
*This
,
361 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
369 This routine would support querying of an on-CPU timer. At present,
370 this code does not provide timer emulation.
374 Pointer to CPU Architectural Protocol interface
375 Start address of memory region
376 The size in bytes of the memory region
377 The bit mask of attributes to set for the memory region
382 EFI_UNSUPPORTED - not yet implemented
385 // TODO: This - add argument and description to function comment
386 // TODO: BaseAddress - add argument and description to function comment
387 // TODO: Length - add argument and description to function comment
388 // TODO: Attributes - add argument and description to function comment
389 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
391 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
394 // Check for invalid parameter for Spec conformance
397 return EFI_INVALID_PARAMETER
;
401 // Do nothing for Nt32 emulation
403 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
404 return EFI_UNSUPPORTED
;
414 This function will log processor version and frequency data to data hub.
417 Event - Event whose notification function is being invoked.
418 Context - Pointer to the notification function's context.
426 EFI_CPU_DATA_RECORD_BUFFER RecordBuffer
;
429 EFI_DATA_HUB_PROTOCOL
*DataHub
;
430 EFI_HII_HANDLE HiiHandle
;
433 // Locate DataHub protocol.
435 Status
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, &DataHub
);
436 if (EFI_ERROR (Status
)) {
441 // Initialize data record header
443 mCpuDataRecordHeader
.Instance
= 1;
444 HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
446 RecordBuffer
.Raw
= AllocatePool (HeaderSize
+ EFI_CPU_DATA_MAXIMUM_LENGTH
);
447 if (RecordBuffer
.Raw
== NULL
) {
452 // Initialize strings to HII database
454 HiiLibAddPackages (1, &gEfiProcessorProducerGuid
, NULL
, &HiiHandle
, CpuStrings
);
457 CopyMem (RecordBuffer
.Raw
, &mCpuDataRecordHeader
, HeaderSize
);
460 RecordBuffer
.DataRecord
->DataRecordHeader
.RecordType
= ProcessorVersionRecordType
;
461 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorVersion
= STRING_TOKEN (STR_INTEL_GENUINE_PROCESSOR
);
462 TotalSize
= HeaderSize
+ sizeof (EFI_PROCESSOR_VERSION_DATA
);
464 Status
= DataHub
->LogData (
466 &gEfiProcessorSubClassGuid
,
467 &gEfiProcessorProducerGuid
,
468 EFI_DATA_RECORD_CLASS_DATA
,
474 // Store CPU frequency data record to data hub - It's an emulator so make up a value
476 RecordBuffer
.DataRecord
->DataRecordHeader
.RecordType
= ProcessorCoreFrequencyRecordType
;
477 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorCoreFrequency
.Value
= 1234;
478 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorCoreFrequency
.Exponent
= 6;
479 TotalSize
= HeaderSize
+ sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA
);
481 Status
= DataHub
->LogData (
483 &gEfiProcessorSubClassGuid
,
484 &gEfiProcessorProducerGuid
,
485 EFI_DATA_RECORD_CLASS_DATA
,
490 FreePool (RecordBuffer
.Raw
);
496 IN EFI_HANDLE ImageHandle
,
497 IN EFI_SYSTEM_TABLE
*SystemTable
503 Initialize the state information for the CPU Architectural Protocol
507 ImageHandle of the loaded driver
508 Pointer to the System Table
514 EFI_SUCCESS - protocol instance can be published
515 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
516 EFI_DEVICE_ERROR - cannot create the thread
519 // TODO: SystemTable - add argument and description to function comment
525 Status
= gBS
->InstallMultipleProtocolInterfaces (
526 &mCpuTemplate
.Handle
,
527 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
528 &gEfiCpuIoProtocolGuid
, &mCpuTemplate
.CpuIo
,
531 ASSERT_EFI_ERROR (Status
);
533 DEBUG ((EFI_D_ERROR
, "CPU Architectural Protocol Loaded\n"));