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