3 Copyright (c) 2006 - 2007, 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 EFI_CPU_DATA_RECORD
*DataRecord
;
61 } EFI_CPU_DATA_RECORD_BUFFER
;
63 EFI_SUBCLASS_TYPE1_HEADER mCpuDataRecordHeader
= {
64 EFI_PROCESSOR_SUBCLASS_VERSION
, // Version
65 sizeof (EFI_SUBCLASS_TYPE1_HEADER
), // Header Size
66 0, // Instance, Initialize later
67 EFI_SUBCLASS_INSTANCE_NON_APPLICABLE
, // SubInstance
68 0 // RecordType, Initialize later
72 // Service routines for the driver
76 WinNtFlushCpuDataCache (
77 IN EFI_CPU_ARCH_PROTOCOL
*This
,
78 IN EFI_PHYSICAL_ADDRESS Start
,
80 IN EFI_CPU_FLUSH_TYPE FlushType
86 This routine would provide support for flushing the CPU data cache.
87 In the case of NT emulation environment, this flushing is not necessary and
88 is thus not implemented.
92 Pointer to CPU Architectural Protocol interface
93 Start adddress in memory to flush
94 Length of memory to flush
103 // TODO: This - add argument and description to function comment
104 // TODO: FlushType - add argument and description to function comment
105 // TODO: EFI_UNSUPPORTED - add return value to function comment
107 if (FlushType
== EfiCpuFlushTypeWriteBackInvalidate
) {
109 // Only WB flush is supported. We actually need do nothing on NT emulator
110 // environment. Classify this to follow EFI spec
115 // Other flush types are not supported by NT emulator
117 return EFI_UNSUPPORTED
;
123 WinNtEnableInterrupt (
124 IN EFI_CPU_ARCH_PROTOCOL
*This
130 This routine provides support for emulation of the interrupt enable of the
131 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
132 Architectural Protocol observes in order to defer behaviour while in its
133 emulated interrupt, or timer tick.
137 Pointer to CPU Architectural Protocol interface
145 // TODO: This - add argument and description to function comment
147 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
149 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
150 Private
->InterruptState
= TRUE
;
157 WinNtDisableInterrupt (
158 IN EFI_CPU_ARCH_PROTOCOL
*This
164 This routine provides support for emulation of the interrupt disable of the
165 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
166 Architectural Protocol observes in order to defer behaviour while in its
167 emulated interrupt, or timer tick.
171 Pointer to CPU Architectural Protocol interface
179 // TODO: This - add argument and description to function comment
181 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
183 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
184 Private
->InterruptState
= FALSE
;
191 WinNtGetInterruptState (
192 IN EFI_CPU_ARCH_PROTOCOL
*This
,
199 This routine provides support for emulation of the interrupt disable of the
200 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer
201 Architectural Protocol observes in order to defer behaviour while in its
202 emulated interrupt, or timer tick.
206 Pointer to CPU Architectural Protocol interface
214 // TODO: This - add argument and description to function comment
215 // TODO: State - add argument and description to function comment
216 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
218 CPU_ARCH_PROTOCOL_PRIVATE
*Private
;
221 return EFI_INVALID_PARAMETER
;
224 Private
= CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This
);
225 *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 return EFI_UNSUPPORTED
;
263 WinNtRegisterInterruptHandler (
264 IN EFI_CPU_ARCH_PROTOCOL
*This
,
265 IN EFI_EXCEPTION_TYPE InterruptType
,
266 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
272 This routine would support registration of an interrupt handler. At
273 present, this code does not provide emulation.
277 Pointer to CPU Architectural Protocol interface
278 Pointer to interrupt handlers
284 EFI_UNSUPPORTED - not yet implemented
287 // TODO: This - add argument and description to function comment
288 // TODO: InterruptType - add argument and description to function comment
289 // TODO: InterruptHandler - add argument and description to function comment
293 // Do parameter checking for EFI spec conformance
295 if (InterruptType
< 0 || InterruptType
> 0xff) {
296 return EFI_UNSUPPORTED
;
299 // Do nothing for Nt32 emulation
301 return EFI_UNSUPPORTED
;
308 IN EFI_CPU_ARCH_PROTOCOL
*This
,
309 IN UINT32 TimerIndex
,
310 OUT UINT64
*TimerValue
,
311 OUT UINT64
*TimerPeriod OPTIONAL
317 This routine would support querying of an on-CPU timer. At present,
318 this code does not provide timer emulation.
322 This - Pointer to CPU Architectural Protocol interface
323 TimerIndex - Index of given CPU timer
324 TimerValue - Output of the timer
325 TimerPeriod - Output of the timer period
329 EFI_UNSUPPORTED - not yet implemented
330 EFI_INVALID_PARAMETER - TimeValue is NULL
334 if (TimerValue
== NULL
) {
335 return EFI_INVALID_PARAMETER
;
339 // No timer supported
341 return EFI_UNSUPPORTED
;
347 WinNtSetMemoryAttributes (
348 IN EFI_CPU_ARCH_PROTOCOL
*This
,
349 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
357 This routine would support querying of an on-CPU timer. At present,
358 this code does not provide timer emulation.
362 Pointer to CPU Architectural Protocol interface
363 Start address of memory region
364 The size in bytes of the memory region
365 The bit mask of attributes to set for the memory region
370 EFI_UNSUPPORTED - not yet implemented
373 // TODO: This - add argument and description to function comment
374 // TODO: BaseAddress - add argument and description to function comment
375 // TODO: Length - add argument and description to function comment
376 // TODO: Attributes - add argument and description to function comment
377 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
380 // Check for invalid parameter for Spec conformance
383 return EFI_INVALID_PARAMETER
;
387 // Do nothing for Nt32 emulation
389 return EFI_UNSUPPORTED
;
400 This function will log processor version and frequency data to data hub.
403 Event - Event whose notification function is being invoked.
404 Context - Pointer to the notification function's context.
412 EFI_CPU_DATA_RECORD_BUFFER RecordBuffer
;
415 EFI_DATA_HUB_PROTOCOL
*DataHub
;
416 EFI_HII_HANDLE HiiHandle
;
419 // Locate DataHub protocol.
421 Status
= gBS
->LocateProtocol (&gEfiDataHubProtocolGuid
, NULL
, (VOID
**)&DataHub
);
422 if (EFI_ERROR (Status
)) {
427 // Initialize data record header
429 mCpuDataRecordHeader
.Instance
= 1;
430 HeaderSize
= sizeof (EFI_SUBCLASS_TYPE1_HEADER
);
432 RecordBuffer
.Raw
= AllocatePool (HeaderSize
+ EFI_CPU_DATA_MAXIMUM_LENGTH
);
433 if (RecordBuffer
.Raw
== NULL
) {
438 // Initialize strings to HII database
440 HiiHandle
= HiiAddPackages (
446 ASSERT (HiiHandle
!= NULL
);
448 CopyMem (RecordBuffer
.Raw
, &mCpuDataRecordHeader
, HeaderSize
);
451 RecordBuffer
.DataRecord
->DataRecordHeader
.RecordType
= ProcessorVersionRecordType
;
452 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorVersion
= STRING_TOKEN (STR_PROCESSOR_VERSION
);
453 TotalSize
= HeaderSize
+ sizeof (EFI_PROCESSOR_VERSION_DATA
);
455 Status
= DataHub
->LogData (
457 &gEfiProcessorSubClassGuid
,
459 EFI_DATA_RECORD_CLASS_DATA
,
465 // Store CPU frequency data record to data hub - It's an emulator so make up a value
467 RecordBuffer
.DataRecord
->DataRecordHeader
.RecordType
= ProcessorCoreFrequencyRecordType
;
468 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorCoreFrequency
.Value
= 1234;
469 RecordBuffer
.DataRecord
->VariableRecord
.ProcessorCoreFrequency
.Exponent
= 6;
470 TotalSize
= HeaderSize
+ sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA
);
472 Status
= DataHub
->LogData (
474 &gEfiProcessorSubClassGuid
,
476 EFI_DATA_RECORD_CLASS_DATA
,
481 FreePool (RecordBuffer
.Raw
);
489 IN EFI_HANDLE ImageHandle
,
490 IN EFI_SYSTEM_TABLE
*SystemTable
496 Initialize the state information for the CPU Architectural Protocol
500 ImageHandle of the loaded driver
501 Pointer to the System Table
507 EFI_SUCCESS - protocol instance can be published
508 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
509 EFI_DEVICE_ERROR - cannot create the thread
517 Status
= gBS
->InstallMultipleProtocolInterfaces (
518 &mCpuTemplate
.Handle
,
519 &gEfiCpuArchProtocolGuid
, &mCpuTemplate
.Cpu
,
520 &gEfiCpuIoProtocolGuid
, &mCpuTemplate
.CpuIo
,
523 ASSERT_EFI_ERROR (Status
);