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