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