]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/CpuRuntimeDxe/Cpu.c
Removed PCD entries for CPU properties as they should be defined in UNI file. Added...
[mirror_edk2.git] / Nt32Pkg / CpuRuntimeDxe / Cpu.c
1 /*++
2
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
8
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.
11
12 Module Name:
13
14 Cpu.c
15
16 Abstract:
17
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
21 in this driver.
22
23 --*/
24
25
26 #include "CpuDriver.h"
27
28
29 CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate = {
30 CPU_ARCH_PROT_PRIVATE_SIGNATURE,
31 NULL,
32 {
33 WinNtFlushCpuDataCache,
34 WinNtEnableInterrupt,
35 WinNtDisableInterrupt,
36 WinNtGetInterruptState,
37 WinNtInit,
38 WinNtRegisterInterruptHandler,
39 WinNtGetTimerValue,
40 WinNtSetMemoryAttributes,
41 0,
42 4
43 },
44 {
45 CpuMemoryServiceRead,
46 CpuMemoryServiceWrite,
47 CpuIoServiceRead,
48 CpuIoServiceWrite
49 },
50 0,
51 TRUE
52 };
53
54 #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
55
56
57
58 typedef union {
59 EFI_CPU_DATA_RECORD *DataRecord;
60 UINT8 *Raw;
61 } EFI_CPU_DATA_RECORD_BUFFER;
62
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
69 };
70
71 //
72 // Service routines for the driver
73 //
74 EFI_STATUS
75 EFIAPI
76 WinNtFlushCpuDataCache (
77 IN EFI_CPU_ARCH_PROTOCOL *This,
78 IN EFI_PHYSICAL_ADDRESS Start,
79 IN UINT64 Length,
80 IN EFI_CPU_FLUSH_TYPE FlushType
81 )
82 /*++
83
84 Routine Description:
85
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.
89
90 Arguments:
91
92 Pointer to CPU Architectural Protocol interface
93 Start adddress in memory to flush
94 Length of memory to flush
95 Flush type
96
97 Returns:
98
99 Status
100 EFI_SUCCESS
101
102 --*/
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
106 {
107 if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
108 //
109 // Only WB flush is supported. We actually need do nothing on NT emulator
110 // environment. Classify this to follow EFI spec
111 //
112 return EFI_SUCCESS;
113 }
114 //
115 // Other flush types are not supported by NT emulator
116 //
117 return EFI_UNSUPPORTED;
118 }
119
120
121 EFI_STATUS
122 EFIAPI
123 WinNtEnableInterrupt (
124 IN EFI_CPU_ARCH_PROTOCOL *This
125 )
126 /*++
127
128 Routine Description:
129
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.
134
135 Arguments:
136
137 Pointer to CPU Architectural Protocol interface
138
139 Returns:
140
141 Status
142 EFI_SUCCESS
143
144 --*/
145 // TODO: This - add argument and description to function comment
146 {
147 CPU_ARCH_PROTOCOL_PRIVATE *Private;
148
149 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
150 Private->InterruptState = TRUE;
151 return EFI_SUCCESS;
152 }
153
154
155 EFI_STATUS
156 EFIAPI
157 WinNtDisableInterrupt (
158 IN EFI_CPU_ARCH_PROTOCOL *This
159 )
160 /*++
161
162 Routine Description:
163
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.
168
169 Arguments:
170
171 Pointer to CPU Architectural Protocol interface
172
173 Returns:
174
175 Status
176 EFI_SUCCESS
177
178 --*/
179 // TODO: This - add argument and description to function comment
180 {
181 CPU_ARCH_PROTOCOL_PRIVATE *Private;
182
183 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
184 Private->InterruptState = FALSE;
185 return EFI_SUCCESS;
186 }
187
188
189 EFI_STATUS
190 EFIAPI
191 WinNtGetInterruptState (
192 IN EFI_CPU_ARCH_PROTOCOL *This,
193 OUT BOOLEAN *State
194 )
195 /*++
196
197 Routine Description:
198
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.
203
204 Arguments:
205
206 Pointer to CPU Architectural Protocol interface
207
208 Returns:
209
210 Status
211 EFI_SUCCESS
212
213 --*/
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
217 {
218 CPU_ARCH_PROTOCOL_PRIVATE *Private;
219
220 if (State == NULL) {
221 return EFI_INVALID_PARAMETER;
222 }
223
224 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
225 *State = Private->InterruptState;
226 return EFI_SUCCESS;
227 }
228
229
230 EFI_STATUS
231 EFIAPI
232 WinNtInit (
233 IN EFI_CPU_ARCH_PROTOCOL *This,
234 IN EFI_CPU_INIT_TYPE InitType
235 )
236 /*++
237
238 Routine Description:
239
240 This routine would support generation of a CPU INIT. At
241 present, this code does not provide emulation.
242
243 Arguments:
244
245 Pointer to CPU Architectural Protocol interface
246 INIT Type
247
248 Returns:
249
250 Status
251 EFI_UNSUPPORTED - not yet implemented
252
253 --*/
254 // TODO: This - add argument and description to function comment
255 // TODO: InitType - add argument and description to function comment
256 {
257 CPU_ARCH_PROTOCOL_PRIVATE *Private;
258
259 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
260 return EFI_UNSUPPORTED;
261 }
262
263
264 EFI_STATUS
265 EFIAPI
266 WinNtRegisterInterruptHandler (
267 IN EFI_CPU_ARCH_PROTOCOL *This,
268 IN EFI_EXCEPTION_TYPE InterruptType,
269 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
270 )
271 /*++
272
273 Routine Description:
274
275 This routine would support registration of an interrupt handler. At
276 present, this code does not provide emulation.
277
278 Arguments:
279
280 Pointer to CPU Architectural Protocol interface
281 Pointer to interrupt handlers
282 Interrupt type
283
284 Returns:
285
286 Status
287 EFI_UNSUPPORTED - not yet implemented
288
289 --*/
290 // TODO: This - add argument and description to function comment
291 // TODO: InterruptType - add argument and description to function comment
292 // TODO: InterruptHandler - add argument and description to function comment
293 {
294 CPU_ARCH_PROTOCOL_PRIVATE *Private;
295
296 //
297 // Do parameter checking for EFI spec conformance
298 //
299 if (InterruptType < 0 || InterruptType > 0xff) {
300 return EFI_UNSUPPORTED;
301 }
302 //
303 // Do nothing for Nt32 emulation
304 //
305 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
306 return EFI_UNSUPPORTED;
307 }
308
309
310 EFI_STATUS
311 EFIAPI
312 WinNtGetTimerValue (
313 IN EFI_CPU_ARCH_PROTOCOL *This,
314 IN UINT32 TimerIndex,
315 OUT UINT64 *TimerValue,
316 OUT UINT64 *TimerPeriod OPTIONAL
317 )
318 /*++
319
320 Routine Description:
321
322 This routine would support querying of an on-CPU timer. At present,
323 this code does not provide timer emulation.
324
325 Arguments:
326
327 This - Pointer to CPU Architectural Protocol interface
328 TimerIndex - Index of given CPU timer
329 TimerValue - Output of the timer
330 TimerPeriod - Output of the timer period
331
332 Returns:
333
334 EFI_UNSUPPORTED - not yet implemented
335 EFI_INVALID_PARAMETER - TimeValue is NULL
336
337 --*/
338 {
339 if (TimerValue == NULL) {
340 return EFI_INVALID_PARAMETER;
341 }
342
343 //
344 // No timer supported
345 //
346 return EFI_UNSUPPORTED;
347 }
348
349
350 EFI_STATUS
351 EFIAPI
352 WinNtSetMemoryAttributes (
353 IN EFI_CPU_ARCH_PROTOCOL *This,
354 IN EFI_PHYSICAL_ADDRESS BaseAddress,
355 IN UINT64 Length,
356 IN UINT64 Attributes
357 )
358 /*++
359
360 Routine Description:
361
362 This routine would support querying of an on-CPU timer. At present,
363 this code does not provide timer emulation.
364
365 Arguments:
366
367 Pointer to CPU Architectural Protocol interface
368 Start address of memory region
369 The size in bytes of the memory region
370 The bit mask of attributes to set for the memory region
371
372 Returns:
373
374 Status
375 EFI_UNSUPPORTED - not yet implemented
376
377 --*/
378 // TODO: This - add argument and description to function comment
379 // TODO: BaseAddress - add argument and description to function comment
380 // TODO: Length - add argument and description to function comment
381 // TODO: Attributes - add argument and description to function comment
382 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
383 {
384 CPU_ARCH_PROTOCOL_PRIVATE *Private;
385
386 //
387 // Check for invalid parameter for Spec conformance
388 //
389 if (Length == 0) {
390 return EFI_INVALID_PARAMETER;
391 }
392
393 //
394 // Do nothing for Nt32 emulation
395 //
396 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
397 return EFI_UNSUPPORTED;
398 }
399
400
401 VOID
402 CpuUpdateDataHub (
403 VOID
404 )
405 /*++
406
407 Routine Description:
408 This function will log processor version and frequency data to data hub.
409
410 Arguments:
411 Event - Event whose notification function is being invoked.
412 Context - Pointer to the notification function's context.
413
414 Returns:
415 None.
416
417 --*/
418 {
419 EFI_STATUS Status;
420 EFI_CPU_DATA_RECORD_BUFFER RecordBuffer;
421 UINT32 HeaderSize;
422 UINT32 TotalSize;
423 EFI_DATA_HUB_PROTOCOL *DataHub;
424 EFI_HII_PROTOCOL *Hii;
425 EFI_HII_HANDLE StringHandle;
426 EFI_HII_PACKAGES *PackageList;
427
428
429 //
430 // Locate DataHub protocol.
431 //
432 Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);
433 if (EFI_ERROR (Status)) {
434 return;
435 }
436
437 //
438 // Locate DataHub protocol.
439 //
440 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);
441 if (EFI_ERROR (Status)) {
442 return;
443 }
444
445 //
446 // Initialize data record header
447 //
448 mCpuDataRecordHeader.Instance = 1;
449 HeaderSize = sizeof (EFI_SUBCLASS_TYPE1_HEADER);
450
451 RecordBuffer.Raw = AllocatePool (HeaderSize + EFI_CPU_DATA_MAXIMUM_LENGTH);
452 if (RecordBuffer.Raw == NULL) {
453 return ;
454 }
455
456 //
457 // Initialize strings to HII database
458 //
459 PackageList = PreparePackages (1, &gEfiProcessorProducerGuid, CpuStrings);
460 Status = Hii->NewPack (Hii, PackageList, &StringHandle);
461 ASSERT (!EFI_ERROR (Status));
462 FreePool (PackageList);
463
464 CopyMem (RecordBuffer.Raw, &mCpuDataRecordHeader, HeaderSize);
465
466
467 RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorVersionRecordType;
468 RecordBuffer.DataRecord->VariableRecord.ProcessorVersion = STRING_TOKEN (STR_PROCESSOR_VERSION);
469 TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_VERSION_DATA);
470
471 Status = DataHub->LogData (
472 DataHub,
473 &gEfiProcessorSubClassGuid,
474 &gEfiProcessorProducerGuid,
475 EFI_DATA_RECORD_CLASS_DATA,
476 RecordBuffer.Raw,
477 TotalSize
478 );
479
480 //
481 // Store CPU frequency data record to data hub - It's an emulator so make up a value
482 //
483 RecordBuffer.DataRecord->DataRecordHeader.RecordType = ProcessorCoreFrequencyRecordType;
484 RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Value = 1234;
485 RecordBuffer.DataRecord->VariableRecord.ProcessorCoreFrequency.Exponent = 6;
486 TotalSize = HeaderSize + sizeof (EFI_PROCESSOR_CORE_FREQUENCY_DATA);
487
488 Status = DataHub->LogData (
489 DataHub,
490 &gEfiProcessorSubClassGuid,
491 &gEfiProcessorProducerGuid,
492 EFI_DATA_RECORD_CLASS_DATA,
493 RecordBuffer.Raw,
494 TotalSize
495 );
496
497 FreePool (RecordBuffer.Raw);
498 }
499
500
501
502 EFI_STATUS
503 EFIAPI
504 InitializeCpu (
505 IN EFI_HANDLE ImageHandle,
506 IN EFI_SYSTEM_TABLE *SystemTable
507 )
508 /*++
509
510 Routine Description:
511
512 Initialize the state information for the CPU Architectural Protocol
513
514 Arguments:
515
516 ImageHandle of the loaded driver
517 Pointer to the System Table
518
519 Returns:
520
521 Status
522
523 EFI_SUCCESS - protocol instance can be published
524 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
525 EFI_DEVICE_ERROR - cannot create the thread
526
527 --*/
528 {
529 EFI_STATUS Status;
530
531 CpuUpdateDataHub ();
532
533 Status = gBS->InstallMultipleProtocolInterfaces (
534 &mCpuTemplate.Handle,
535 &gEfiCpuArchProtocolGuid, &mCpuTemplate.Cpu,
536 &gEfiCpuIoProtocolGuid, &mCpuTemplate.CpuIo,
537 NULL
538 );
539 ASSERT_EFI_ERROR (Status);
540
541 return Status;
542 }
543
544