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