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