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