]> git.proxmox.com Git - mirror_edk2.git/blame - UnixPkg/CpuRuntimeDxe/Cpu.c
Update the copyright notice format
[mirror_edk2.git] / UnixPkg / CpuRuntimeDxe / Cpu.c
CommitLineData
804405e7 1/*++\r
2\r
f9b8ab56
HT
3Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
4This program and the accompanying materials\r
804405e7 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
bac49e77 24#include <FrameworkDxe.h>\r
aaa2cc19 25#include <IndustryStandard/SmBios.h>\r
804405e7 26#include <Protocol/Cpu.h>\r
aaa2cc19 27#include <Protocol/Smbios.h>\r
804405e7 28#include <Guid/DataHubRecords.h>\r
5161b24d 29#include <Protocol/CpuIo2.h>\r
804405e7 30#include <Protocol/FrameworkHii.h>\r
804405e7 31\r
32#include <Library/BaseLib.h>\r
33#include <Library/DebugLib.h>\r
34#include <Library/HiiLib.h>\r
35#include <Library/UefiLib.h>\r
36#include <Library/UefiDriverEntryPoint.h>\r
37#include <Library/BaseMemoryLib.h>\r
38#include <Library/MemoryAllocationLib.h>\r
39#include <Library/UefiBootServicesTableLib.h>\r
804405e7 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
ccd55824 62 {\r
63 CpuMemoryServiceRead,\r
64 CpuMemoryServiceWrite\r
65 },\r
66 {\r
67 CpuIoServiceRead,\r
68 CpuIoServiceWrite\r
69 }\r
804405e7 70 },\r
804405e7 71 TRUE\r
72};\r
73\r
804405e7 74\r
75//\r
76// Service routines for the driver\r
77//\r
78EFI_STATUS\r
79EFIAPI\r
80UnixFlushCpuDataCache (\r
81 IN EFI_CPU_ARCH_PROTOCOL *This,\r
82 IN EFI_PHYSICAL_ADDRESS Start,\r
83 IN UINT64 Length,\r
84 IN EFI_CPU_FLUSH_TYPE FlushType\r
85 )\r
86/*++\r
87\r
88Routine Description:\r
89\r
90 This routine would provide support for flushing the CPU data cache.\r
91 In the case of UNIX emulation environment, this flushing is not necessary and\r
92 is thus not implemented.\r
93\r
94Arguments:\r
95\r
96 Pointer to CPU Architectural Protocol interface\r
97 Start adddress in memory to flush\r
98 Length of memory to flush\r
99 Flush type\r
100\r
101Returns:\r
102\r
103 Status\r
104 EFI_SUCCESS\r
105\r
106--*/\r
107// TODO: This - add argument and description to function comment\r
108// TODO: FlushType - add argument and description to function comment\r
109// TODO: EFI_UNSUPPORTED - add return value to function comment\r
110{\r
111 if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {\r
112 //\r
113 // Only WB flush is supported. We actually need do nothing on UNIX emulator\r
114 // environment. Classify this to follow EFI spec\r
115 //\r
116 return EFI_SUCCESS;\r
117 }\r
118 //\r
119 // Other flush types are not supported by UNIX emulator\r
120 //\r
121 return EFI_UNSUPPORTED;\r
122}\r
123\r
124EFI_STATUS\r
125EFIAPI\r
126UnixEnableInterrupt (\r
127 IN EFI_CPU_ARCH_PROTOCOL *This\r
128 )\r
129/*++\r
130\r
131Routine Description:\r
132\r
133 This routine provides support for emulation of the interrupt enable of the\r
134 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer\r
135 Architectural Protocol observes in order to defer behaviour while in its\r
136 emulated interrupt, or timer tick.\r
137\r
138Arguments:\r
139\r
140 Pointer to CPU Architectural Protocol interface\r
141\r
142Returns:\r
143\r
144 Status\r
145 EFI_SUCCESS\r
146\r
147--*/\r
148// TODO: This - add argument and description to function comment\r
149{\r
150 CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
151\r
152 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
153 Private->InterruptState = TRUE;\r
154 return EFI_SUCCESS;\r
155}\r
156\r
157EFI_STATUS\r
158EFIAPI\r
159UnixDisableInterrupt (\r
160 IN EFI_CPU_ARCH_PROTOCOL *This\r
161 )\r
162/*++\r
163\r
164Routine Description:\r
165\r
166 This routine provides support for emulation of the interrupt disable of the\r
167 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer\r
168 Architectural Protocol observes in order to defer behaviour while in its\r
169 emulated interrupt, or timer tick.\r
170\r
171Arguments:\r
172\r
173 Pointer to CPU Architectural Protocol interface\r
174\r
175Returns:\r
176\r
177 Status\r
178 EFI_SUCCESS\r
179\r
180--*/\r
181// TODO: This - add argument and description to function comment\r
182{\r
183 CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
184\r
185 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
186 Private->InterruptState = FALSE;\r
187 return EFI_SUCCESS;\r
188}\r
189\r
190EFI_STATUS\r
191EFIAPI\r
192UnixGetInterruptState (\r
193 IN EFI_CPU_ARCH_PROTOCOL *This,\r
194 OUT BOOLEAN *State\r
195 )\r
196/*++\r
197\r
198Routine Description:\r
199\r
200 This routine provides support for emulation of the interrupt disable of the\r
201 the system. For our purposes, CPU enable is just a BOOLEAN that the Timer\r
202 Architectural Protocol observes in order to defer behaviour while in its\r
203 emulated interrupt, or timer tick.\r
204\r
205Arguments:\r
206\r
207 Pointer to CPU Architectural Protocol interface\r
208\r
209Returns:\r
210\r
211 Status\r
212 EFI_SUCCESS\r
213\r
214--*/\r
215// TODO: This - add argument and description to function comment\r
216// TODO: State - add argument and description to function comment\r
217// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
218{\r
219 CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
220\r
221 if (State == NULL) {\r
222 return EFI_INVALID_PARAMETER;\r
223 }\r
224\r
225 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
226 *State = Private->InterruptState;\r
227 return EFI_SUCCESS;\r
228}\r
229\r
230EFI_STATUS\r
231EFIAPI\r
232UnixInit (\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
263EFI_STATUS\r
264EFIAPI\r
265UnixRegisterInterruptHandler (\r
266 IN EFI_CPU_ARCH_PROTOCOL *This,\r
267 IN EFI_EXCEPTION_TYPE InterruptType,\r
268 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler\r
269 )\r
270/*++\r
271\r
272Routine Description:\r
273\r
274 This routine would support registration of an interrupt handler. At\r
275 present, this code does not provide emulation.\r
276\r
277Arguments:\r
278\r
279 Pointer to CPU Architectural Protocol interface\r
280 Pointer to interrupt handlers\r
281 Interrupt type\r
282\r
283Returns:\r
284\r
285 Status\r
286 EFI_UNSUPPORTED - not yet implemented\r
287\r
288--*/\r
289// TODO: This - add argument and description to function comment\r
290// TODO: InterruptType - add argument and description to function comment\r
291// TODO: InterruptHandler - add argument and description to function comment\r
292{\r
293 CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
294\r
295 //\r
296 // Do parameter checking for EFI spec conformance\r
297 //\r
298 if (InterruptType < 0 || InterruptType > 0xff) {\r
299 return EFI_UNSUPPORTED;\r
300 }\r
301 //\r
302 // Do nothing for Nt32 emulation\r
303 //\r
304 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
305 return EFI_UNSUPPORTED;\r
306}\r
307\r
308EFI_STATUS\r
309EFIAPI\r
310UnixGetTimerValue (\r
311 IN EFI_CPU_ARCH_PROTOCOL *This,\r
312 IN UINT32 TimerIndex,\r
313 OUT UINT64 *TimerValue,\r
314 OUT UINT64 *TimerPeriod OPTIONAL\r
315 )\r
316/*++\r
317\r
318Routine Description:\r
319\r
320 This routine would support querying of an on-CPU timer. At present,\r
321 this code does not provide timer emulation.\r
322\r
323Arguments:\r
324\r
325 This - Pointer to CPU Architectural Protocol interface\r
326 TimerIndex - Index of given CPU timer\r
327 TimerValue - Output of the timer\r
328 TimerPeriod - Output of the timer period\r
329\r
330Returns:\r
331\r
332 EFI_UNSUPPORTED - not yet implemented\r
333 EFI_INVALID_PARAMETER - TimeValue is NULL\r
334\r
335--*/\r
336{\r
337 if (TimerValue == NULL) {\r
338 return EFI_INVALID_PARAMETER;\r
339 }\r
340\r
341 //\r
342 // No timer supported\r
343 //\r
344 return EFI_UNSUPPORTED;\r
345}\r
346\r
347EFI_STATUS\r
348EFIAPI\r
349UnixSetMemoryAttributes (\r
350 IN EFI_CPU_ARCH_PROTOCOL *This,\r
351 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
352 IN UINT64 Length,\r
353 IN UINT64 Attributes\r
354 )\r
355/*++\r
356\r
357Routine Description:\r
358\r
359 This routine would support querying of an on-CPU timer. At present,\r
360 this code does not provide timer emulation.\r
361\r
362Arguments:\r
363\r
364 Pointer to CPU Architectural Protocol interface\r
365 Start address of memory region\r
366 The size in bytes of the memory region\r
367 The bit mask of attributes to set for the memory region\r
368\r
369Returns:\r
370\r
371 Status\r
372 EFI_UNSUPPORTED - not yet implemented\r
373\r
374--*/\r
375// TODO: This - add argument and description to function comment\r
376// TODO: BaseAddress - add argument and description to function comment\r
377// TODO: Length - add argument and description to function comment\r
378// TODO: Attributes - add argument and description to function comment\r
379// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
380{\r
381 CPU_ARCH_PROTOCOL_PRIVATE *Private;\r
382\r
383 //\r
384 // Check for invalid parameter for Spec conformance\r
385 //\r
386 if (Length == 0) {\r
387 return EFI_INVALID_PARAMETER;\r
388 }\r
389\r
390 //\r
391 // Do nothing for Nt32 emulation\r
392 //\r
393 Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);\r
394 return EFI_UNSUPPORTED;\r
395}\r
396\r
aaa2cc19 397\r
398\r
399/**\r
400 Logs SMBIOS record.\r
401\r
402 @param Smbios Pointer to SMBIOS protocol instance.\r
403 @param Buffer Pointer to the data buffer.\r
404\r
405**/\r
804405e7 406VOID\r
aaa2cc19 407LogSmbiosData (\r
408 IN EFI_SMBIOS_PROTOCOL *Smbios,\r
409 IN UINT8 *Buffer\r
410 )\r
411{\r
412 EFI_STATUS Status;\r
413 EFI_SMBIOS_HANDLE SmbiosHandle;\r
414 \r
415 SmbiosHandle = 0;\r
416 Status = Smbios->Add (\r
417 Smbios,\r
418 NULL,\r
419 &SmbiosHandle,\r
420 (EFI_SMBIOS_TABLE_HEADER*)Buffer\r
421 );\r
422 ASSERT_EFI_ERROR (Status);\r
423}\r
424\r
425VOID\r
426CpuUpdateSmbios (\r
804405e7 427 VOID\r
428 )\r
429/*++\r
430\r
431Routine Description:\r
432 This function will log processor version and frequency data to data hub.\r
433\r
434Arguments:\r
435 Event - Event whose notification function is being invoked.\r
436 Context - Pointer to the notification function's context.\r
437\r
438Returns:\r
439 None.\r
440\r
441--*/\r
442{\r
443 EFI_STATUS Status;\r
aaa2cc19 444 EFI_SMBIOS_PROTOCOL *Smbios;\r
804405e7 445 UINT32 TotalSize;\r
804405e7 446 EFI_HII_HANDLE HiiHandle;\r
aaa2cc19 447 STRING_REF Token;\r
448 UINTN CpuVerStrLen;\r
449 EFI_STRING CpuVerStr;\r
450 SMBIOS_TABLE_TYPE4 *SmbiosRecord;\r
451 CHAR8 *OptionalStrStart;\r
804405e7 452\r
453 //\r
aaa2cc19 454 // Locate Smbios protocol.\r
804405e7 455 //\r
aaa2cc19 456 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);\r
457 \r
804405e7 458 if (EFI_ERROR (Status)) {\r
459 return;\r
460 }\r
461\r
804405e7 462 //\r
463 // Initialize strings to HII database\r
464 //\r
cb7d01c0 465 HiiHandle = HiiAddPackages (\r
c2bd20a5 466 &gEfiCallerIdGuid,\r
cb7d01c0 467 NULL,\r
468 CpuStrings,\r
469 NULL\r
470 );\r
471 ASSERT (HiiHandle != NULL);\r
804405e7 472\r
804405e7 473\r
aaa2cc19 474 Token = STRING_TOKEN (STR_INTEL_GENUINE_PROCESSOR);\r
475 CpuVerStr = HiiGetPackageString(&gEfiCallerIdGuid, Token, NULL);\r
476 CpuVerStrLen = StrLen(CpuVerStr);\r
477 ASSERT (CpuVerStrLen <= SMBIOS_STRING_MAX_LENGTH);\r
804405e7 478\r
aaa2cc19 479 TotalSize = sizeof(SMBIOS_TABLE_TYPE4) + CpuVerStrLen + 1 + 1;\r
480 SmbiosRecord = AllocatePool(TotalSize);\r
481 ZeroMem(SmbiosRecord, TotalSize);\r
804405e7 482\r
aaa2cc19 483 SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION;\r
484 SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4);\r
485 //\r
486 // Make handle chosen by smbios protocol.add automatically.\r
487 //\r
488 SmbiosRecord->Hdr.Handle = 0; \r
489 //\r
490 // Processor version is the 1st string.\r
491 //\r
492 SmbiosRecord->ProcessorVersion = 1;\r
804405e7 493 //\r
494 // Store CPU frequency data record to data hub - It's an emulator so make up a value\r
495 //\r
aaa2cc19 496 SmbiosRecord->CurrentSpeed = 1234;\r
497\r
498 OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);\r
499 UnicodeStrToAsciiStr(CpuVerStr, OptionalStrStart);\r
500\r
501 //\r
502 // Now we have got the full smbios record, call smbios protocol to add this record.\r
503 //\r
504 LogSmbiosData(Smbios, (UINT8 *) SmbiosRecord);\r
505 FreePool (SmbiosRecord);\r
804405e7 506}\r
507\r
508EFI_STATUS\r
509EFIAPI\r
510InitializeCpu (\r
511 IN EFI_HANDLE ImageHandle,\r
512 IN EFI_SYSTEM_TABLE *SystemTable\r
513 )\r
514/*++\r
515\r
516Routine Description:\r
517\r
518 Initialize the state information for the CPU Architectural Protocol\r
519\r
520Arguments:\r
521\r
522 ImageHandle of the loaded driver\r
523 Pointer to the System Table\r
524\r
525Returns:\r
526\r
527 Status\r
528\r
529 EFI_SUCCESS - protocol instance can be published\r
530 EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure\r
531 EFI_DEVICE_ERROR - cannot create the thread\r
532\r
533--*/\r
534// TODO: SystemTable - add argument and description to function comment\r
535{\r
536 EFI_STATUS Status;\r
537\r
aaa2cc19 538 CpuUpdateSmbios ();\r
804405e7 539\r
540 Status = gBS->InstallMultipleProtocolInterfaces (\r
541 &mCpuTemplate.Handle,\r
542 &gEfiCpuArchProtocolGuid, &mCpuTemplate.Cpu,\r
5161b24d 543 &gEfiCpuIo2ProtocolGuid, &mCpuTemplate.CpuIo,\r
804405e7 544 NULL\r
545 );\r
546 ASSERT_EFI_ERROR (Status);\r
547\r
548 DEBUG ((EFI_D_ERROR, "CPU Architectural Protocol Loaded\n"));\r
549\r
550 return Status;\r
551}\r