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