summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/CpuInit/Dxe/CpuInitDxeDbgr.h
blob: 86316bb9769211ba8d7d262311a8eca2000a968a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
/** @file
  Private data structures

@copyright
  Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
  This software and associated documentation (if any) is furnished
  under a license and may only be used or copied in accordance
  with the terms of the license. Except as permitted by such
  license, no part of this software or documentation may be
  reproduced, stored in a retrieval system, or transmitted in any
  form or by any means without the express written consent of
  Intel Corporation.

  This file contains an 'Intel Peripheral Driver' and uniquely
  identified as "Intel Reference Module" and is
  licensed for Intel CPUs and chipsets under the terms of your
  license agreement with Intel or your vendor.  This file may
  be modified by the user, subject to additional terms of the
  license agreement

**/
#ifndef _CPU_INIT_DXE_H
#define _CPU_INIT_DXE_H

#include "CpuAccess.h"
#include "MemoryAttribute.h"
#include "RcFviDxeLib.h"
#include "EdkIIGlueBaseLib.h"

#include EFI_PROTOCOL_DEFINITION (CpuPlatformPolicy)
#include EFI_PROTOCOL_CONSUMER (ExitPmAuth)
#include EFI_PROTOCOL_DEFINITION (CpuInfo)

#if (EFI_SPECIFICATION_VERSION >= 0x2000A)
#include "UefiIfrLibrary.h"
#endif

#define INTERRUPT_VECTOR_NUMBER     256
#define INTERRUPT_GATE_ATTRIBUTE    0x8e00
#define NUMBER_OF_MICROCODE_UPDATE  10

extern UINT8 mSmmbaseSwSmiNumber;

//(AMI_CHG+)
#if defined(AMI_PEI_DEBUG_SUPPORT) && AMI_PEI_DEBUG_SUPPORT

#define AMI_DEBUGGER_CPU_PROTOCOL_GUID \
  { 0xab21acc3, 0xba33, 0xee2c, 0x66, 0xbc, 0x12, 0x56, 0x77, 0x11, 0x1a, 0xb2 }
  

typedef struct _AMI_DEBUGGER_CPU_PROTOCOL AMI_DEBUGGER_CPU_PROTOCOL;  

#pragma pack(1)

typedef struct {
  UINT16  Offset15To0;
  UINT16  SegmentSelector;
  UINT16  Attributes;
  UINT16  Offset31To16;
  UINT32  Offset63To32;
  UINT32  Reserved;
} DEBUGGER_INTERRUPT_GATE_DESCRIPTOR;

#pragma pack()

typedef
EFI_STATUS
(EFIAPI *DEBUGGER_GET_APTIO_INT_HANDLER) (
    IN OUT UINT32*   InterruptHandlerHaltAddr  
  );

typedef
EFI_STATUS
(EFIAPI *DEBUGGER_FIXUP_PEI_EXCEPTION_HANDLER) (
  IN DEBUGGER_INTERRUPT_GATE_DESCRIPTOR*   IdtEntry,
  IN UINT32    i  
  );
  
typedef
EFI_STATUS
(EFIAPI *DEBUGGER_SETUP_EXCEPTION_HANDLER) (VOID);

typedef
EFI_STATUS
(EFIAPI *DEBUGGER_IS_DEBUGGER_IRQ_HANDLER) (
  IN EFI_EXCEPTION_TYPE           InterruptType,
  IN EFI_CPU_INTERRUPT_HANDLER    InterruptHandler
  );

typedef struct _AMI_DEBUGGER_CPU_PROTOCOL {
    DEBUGGER_GET_APTIO_INT_HANDLER       DebuggerGetAptioIntHandler;
	DEBUGGER_FIXUP_PEI_EXCEPTION_HANDLER DebuggerFixUpPEIExceptionHandlers;
	DEBUGGER_SETUP_EXCEPTION_HANDLER     DebuggerSetupExceptionHandler;
	DEBUGGER_IS_DEBUGGER_IRQ_HANDLER     DebuggerIsDebuggerIrqHadler;	
};
  
#endif
//<(AMI_CHG+)

#define CPU_FVI_STRING      "Reference Code - CPU"
#define CPU_FVI_SMBIOS_TYPE 0xDD  ///< Default value
#define CPU_FVI_SMBIOS_INSTANCE 0x02
#define UCODE_FVI_STRING    "uCode Version"
#define UCODE_VERSION \
  { \
    0xFF, 0xFF, 0xFF, 0xFFFF \
  }
#define TXT_FVI_STRING          "TXT ACM version"
#define TXT_ACM_MAJOR_VERSION   0x1
#define TXT_ACM_MINOR_VERSION   0x0
#define TXT_ACM_REVERSION       0x0
#define TXT_ACM_BUILD_NUMBER    0x0
#define TXT_VERSION \
  { \
    TXT_ACM_MAJOR_VERSION, TXT_ACM_MINOR_VERSION, TXT_ACM_REVERSION, TXT_ACM_BUILD_NUMBER \
  }
enum {
  CPU_RC_VER= 0,
  UCODE_VER,
  TXT_VER
} CPU_FVI_INDEX;

extern FVI_ELEMENT_AND_FUNCTION      mCpuFviElementsData[];
extern FVI_DATA_HUB_CALLBACK_CONTEXT mCpuFviVersionData;
extern UINTN                         mCpuFviElements;

/**
  Adjust length to a paragraph boundry

  @param[in] MemoryLength  -  Input memory length.

  @retval Returned Maximum length.
**/
UINT64
Power2MaxMemory (
  IN UINT64 MemoryLength
  );

/**
  Disable cache and its mtrr

  @param[in] OldMtrr - To return the Old MTRR value
**/
VOID
EfiDisableCacheMtrr (
  IN UINT64 *OldMtrr
  );

/**
  Recover cache MTRR

  @param[in] EnableMtrr - Whether to enable the MTRR
  @param[in] OldMtrr    - The saved old MTRR value to restore when not to
                          enable the MTRR
**/
VOID
EfiRecoverCacheMtrr (
  IN BOOLEAN EnableMtrr,
  IN UINT64  OldMtrr
  );

typedef struct _ALIGNED_DWORD {
  UINT32 High;
  UINT32 Low;
} ALIGNED_DWORD;

typedef union _ALIGNED {
  UINT64        AlignedQword;
  ALIGNED_DWORD AlignedDword;
} ALIGNED;

/**
  Initialize the state information for the CPU Architectural Protocol

  @param[in] ImageHandle - Image handle of the loaded driver
  @param[in] SystemTable - Pointer to the System Table

  @retval EFI_SUCCESS           - thread can be successfully created
  @retval EFI_OUT_OF_RESOURCES  - cannot allocate protocol data structure
  @retval EFI_DEVICE_ERROR      - cannot create the thread
**/
EFI_STATUS
EFIAPI
InitializeCpu (
  IN EFI_HANDLE       ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  );

/**
  Prepare memory for essential system tables.

  @retval EFI_SUCCESS  - Memory successfully prepared.
**/
EFI_STATUS
PrepareMemory (
  VOID
  );

/**
  Flush CPU data cache. If the instruction cache is fully coherent
  with all DMA operations then function can just return EFI_SUCCESS.

  @param[in] This             - Protocol instance structure
  @param[in] Start            - Physical address to start flushing from.
  @param[in] Length           - Number of bytes to flush. Round up to chipset granularity.
  @param[in] FlushType        - Specifies the type of flush operation to perform.

  @retval EFI_SUCCESS         - If cache was flushed
  @exception EFI_UNSUPPORTED  - If flush type is not supported.
  @retval EFI_DEVICE_ERROR    - If requested range could not be flushed.
**/
EFI_STATUS
EFIAPI
FlushCpuDataCache (
  IN EFI_CPU_ARCH_PROTOCOL *This,
  IN EFI_PHYSICAL_ADDRESS  Start,
  IN UINT64                Length,
  IN EFI_CPU_FLUSH_TYPE    FlushType
  );

/**
  Enables CPU interrupts.

  @param[in] This            - Protocol instance structure

  @retval EFI_SUCCESS        - If interrupts were enabled in the CPU
  @retval EFI_DEVICE_ERROR   - If interrupts could not be enabled on the CPU.
**/
EFI_STATUS
EFIAPI
EnableInterrupt (
  IN EFI_CPU_ARCH_PROTOCOL *This
  );

/**
  Disables CPU interrupts.

  @param[in] This           - Protocol instance structure

  @retval EFI_SUCCESS       - If interrupts were disabled in the CPU.
  @retval EFI_DEVICE_ERROR  - If interrupts could not be disabled on the CPU.
**/
EFI_STATUS
EFIAPI
DisableInterrupt (
  IN EFI_CPU_ARCH_PROTOCOL *This
  );

/**
  Return the state of interrupts.

  @param[in] This                - Protocol instance structure
  @param[in] State               - Pointer to the CPU's current interrupt state

  @retval EFI_SUCCESS            - If interrupts were disabled in the CPU.
  @retval EFI_INVALID_PARAMETER  - State is NULL.
**/
EFI_STATUS
EFIAPI
CpuGetInterruptState (
  IN EFI_CPU_ARCH_PROTOCOL *This,
  OUT BOOLEAN              *State
  );

/**
  Generates an INIT to the CPU

  @param[in] This             - Protocol instance structure
  @param[in] InitType         - Type of CPU INIT to perform

  @retval EFI_SUCCESS         - If CPU INIT occurred. This value should never be seen.
  @retval EFI_DEVICE_ERROR    - If CPU INIT failed.
  @exception EFI_UNSUPPORTED  - Requested type of CPU INIT not supported.
**/
EFI_STATUS
EFIAPI
Init (
  IN EFI_CPU_ARCH_PROTOCOL *This,
  IN EFI_CPU_INIT_TYPE     InitType
  );

/**
  Registers a function to be called from the CPU interrupt handler.

  @param[in] This                - Protocol instance structure
  @param[in] InterruptType       - Defines which interrupt to hook.
                                   IA-32 valid range is 0x00 through 0xFF
  @param[in] InterruptHandler    - A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER
                                   that is called when a processor interrupt occurs.
                                   A null pointer is an error condition.

  @retval EFI_SUCCESS            - If handler installed or uninstalled.
  @retval EFI_ALREADY_STARTED    - InterruptHandler is not NULL, and a handler for
                                   InterruptType was previously installed
  @retval EFI_INVALID_PARAMETER  - InterruptHandler is NULL, and a handler for
                                   InterruptType was not previously installed.
  @exception EFI_UNSUPPORTED     - The interrupt specified by InterruptType is not supported.
**/
EFI_STATUS
EFIAPI
RegisterInterruptHandler (
  IN EFI_CPU_ARCH_PROTOCOL     *This,
  IN EFI_EXCEPTION_TYPE        InterruptType,
  IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
  );

/**
  Returns a timer value from one of the CPU's internal timers. There is no
  inherent time interval between ticks but is a function of the CPU frequency.

  @param[in] This                - Protocol instance structure.
  @param[in] TimerIndex          - Specifies which CPU timer is requested.
  @param[in] TimerValue          - Pointer to the returned timer value.
  @param[in] TimerPeriod         - A pointer to the amount of time that passes in femtoseconds (10-15) for each
                                   increment of TimerValue. If TimerValue does not increment at a predictable
                                   rate, then 0 is returned. The amount of time that has passed between two calls to
                                   GetTimerValue() can be calculated with the formula
                                   (TimerValue2 - TimerValue1) * TimerPeriod. This parameter is optional and may be NULL.

  @retval EFI_SUCCESS            - If the CPU timer count was returned.
  @exception EFI_UNSUPPORTED     - If the CPU does not have any readable timers.
  @retval EFI_DEVICE_ERROR       - If an error occurred while reading the timer.
  @retval EFI_INVALID_PARAMETER  - TimerIndex is not valid or TimerValue is NULL.
**/
EFI_STATUS
EFIAPI
GetTimerValue (
  IN EFI_CPU_ARCH_PROTOCOL *This,
  IN UINT32                TimerIndex,
  OUT UINT64               *TimerValue,
  OUT UINT64 *TimerPeriod  OPTIONAL
  );

/**
  Set memory cacheability attributes for given range of memeory

  @param[in] This                - Protocol instance structure
  @param[in] BaseAddress         - Specifies the start address of the memory range
  @param[in] Length              - Specifies the length of the memory range
  @param[in] Attributes          - The memory cacheability for the memory range

  @retval EFI_SUCCESS            - If the cacheability of that memory range is set successfully
  @exception EFI_UNSUPPORTED     - If the desired operation cannot be done
  @retval EFI_INVALID_PARAMETER  - The input parameter is not correct, such as Length = 0
**/
EFI_STATUS
EFIAPI
SetMemoryAttributes (
  IN EFI_CPU_ARCH_PROTOCOL *This,
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN UINT64                Attributes
  );

/**
  Init Global Descriptor table
**/
VOID
InitializeSelectors (
  VOID
  );

typedef struct {
  VOID  *Start;
  UINTN Size;
  UINTN FixOffset;
} INTERRUPT_HANDLER_TEMPLATE_MAP;

typedef union {
  EFI_CPU_DATA_RECORD *DataRecord;
  UINT8               *Raw;
} EFI_CPU_DATA_RECORD_BUFFER;

///
/// This constant defines the maximum length of the CPU brand string. According to the
/// IA manual, the brand string is in EAX through EDX (thus 16 bytes) after executing
/// the CPUID instructions with EAX as 80000002, 80000003, 80000004.
///
#define MAXIMUM_CPU_BRAND_STRING_LENGTH 48

typedef struct {
  BOOLEAN                    StringValid;
  CHAR16                     BrandString[MAXIMUM_CPU_BRAND_STRING_LENGTH + 1];
  EFI_PROCESSOR_VERSION_DATA StringRef;
} PROCESSOR_VERSION_INFORMATION;

///
/// The constant defines how many times the Cpuid instruction should be executed
/// in order to get all the cache information. For Pentium 4 processor, 1 is enough
///
#define CPU_CPUID_EXECTION_COUNT  2

typedef struct {
  UINT64                                 IntendCoreFrequency;
  UINT64                                 IntendFsbFrequency;
  PROCESSOR_VERSION_INFORMATION          Version;
  EFI_PROCESSOR_MANUFACTURER_DATA        Manufacturer;
  EFI_PROCESSOR_ID_DATA                  CpuidData;
  EFI_PROCESSOR_FAMILY_DATA              Family;
  INT16                                  Voltage;
  EFI_PROCESSOR_APIC_BASE_ADDRESS_DATA   ApicBase;
  EFI_PROCESSOR_APIC_ID_DATA             ApicID;
  EFI_PROCESSOR_APIC_VERSION_NUMBER_DATA ApicVersion;
  UINT32                                 MicrocodeRevision;
  EFI_PROCESSOR_STATUS_DATA              Status; ///< Need to update this field before report
  CPU_PHYSICAL_LOCATION                  Location;
  EFI_MP_HEALTH_FLAGS                    Health;
  EFI_CPUID_REGISTER                     CacheInformation[CPU_CPUID_EXECTION_COUNT];
} CPU_DATA_FOR_DATAHUB;

///
/// Type, FamilyId and Model values for the different processors
/// [0:7]   - Model
/// [8:23]  - FamilyId
/// [24:31] - Type
///
#define RESERVED  0x00

/**
  This will locate a processor microcode and if it finds a newer revision, it will
  load it to the processor.

  @param[in] MicrocodePointerBuffer  - The Array of pointers which each points to 1 microcode update binary (in memory)
  @param[in] FailedRevision          - The microcode revision that fails to be loaded

  @retval EFI_SUCCESS                - A new microcode update is loaded
  @retval Other                      - Due to some reason, no new microcode update is loaded
**/
EFI_STATUS
InitializeMicrocode (
  IN EFI_CPU_MICROCODE_HEADER **MicrocodePointerBuffer,
  OUT UINT32                  *FailedRevision
  );

/**
  To indicate the first microcode load is done
**/
VOID
McuFirstLoadDone (
  VOID
  );

/**
  Initializes MP support in the system.

  @retval EFI_SUCCESS           - Multiple processors are initialized successfully.
  @retval EFI_NOT_FOUND         - The ACPI variable is not found in S3 boot path.
  @retval EFI_OUT_OF_RESOURCES  - No enough resoruces (such as out of memory).
**/
EFI_STATUS
InitializeMpSupport (
  VOID
  );

/**
  Save the MTRR registers to global variables
**/
VOID
ReadMtrrRegisters (
  VOID
  );

/**
  Synch up the MTRR values for all processors
**/
VOID
EFIAPI
MpMtrrSynchUp (
  IN VOID *Buffer
  );

/**
  Copy Global MTRR data to S3
**/
VOID
SaveBspMtrrForS3 (
  VOID
  );

/**
  Load all microcode updates to memory. Since in S3 resume boot path, CPUs should be
  patched again, these microcode updates are copied to OS reserved memory.

  @retval EFI_SUCCESS           - All microcode updates are loaded to memory successfully
  @retval EFI_OUT_OF_RESOURCES  - Not enough memory to accomodate all the microcode updates
**/
EFI_STATUS
LoadAllMicrocodeUpdates (
  VOID
  );

/**
  Returns the actual CPU core frequency in MHz.

  @param[in] Metronome           - Metronome protocol
  @param[in] Frequency           - Pointer to the CPU core frequency

  @retval EFI_SUCCESS            - If the frequency is returned successfully
  @retval EFI_INVALID_PARAMETER  - If the input parameter is wrong
**/
EFI_STATUS
GetActualFrequency (
  IN EFI_METRONOME_ARCH_PROTOCOL *Metronome,
  OUT UINT64                     *Frequency
  );

/**
  Dump RC CPU and PPM platform policies
**/
VOID
CpuDxePolicyDump (
  VOID
  );

/**
  Initialize the global DataHub pointer

  @param[in] DataHub   - Pointer to the DataHub protocol as output

  @retval EFI_SUCCESS  - If the DataHub pointer is initialized successfully
**/
EFI_STATUS
InitializeDataHubPtr (
  OUT EFI_DATA_HUB_PROTOCOL **DataHub
  );

/**
  Check if loading microcode update fails, if so, report proper status code

  @param[in] CpuNumber       - The CPU number
  @param[in] Status          - The return value of InitializeMicrocode()
  @param[in] FailedRevision  - The revision of the microcode update that failed to be loaded

  @retval EFI_SUCCESS        - The status is check and proper status code is reported
**/
EFI_STATUS
CheckMicrocodeUpdate (
  IN UINTN      CpuNumber,
  IN EFI_STATUS Status,
  IN UINT32     FailedRevision
  );

/**
  Enable Cpu Interrupt
**/
VOID
CpuEnableInterrupt (
  VOID
  );

/**
  Disable Cpu Interrupt
**/
VOID
CpuDisableInterrupt (
  VOID
  );

/**
  Get code segment

  @retval Code segmnet value
**/
UINT16
GetCodeSegment (
  VOID
  );

/**
  Initialize Cpu float point unit
**/
VOID
CpuInitFloatPointUnit (
  VOID
  );

/**
  Drop into SMM to register IOTRAP handler for pfat tools interface

  @param[in] Event     - A pointer to the Event that triggered the callback.
  @param[in] Context   - A pointer to private data registered with the callback function.
**/
VOID
InitializePfatToolsIntCallback (
  IN EFI_EVENT Event,
  IN VOID      *Context
  );

/**
  Register callback function for Boot Guard revocation flow.

  @param[in] Event     - A pointer to the Event that triggered the callback.
  @param[in] Context   - A pointer to private data registered with the callback function.
**/
VOID
EFIAPI
BootGuardRevocationCallback (
  IN EFI_EVENT Event,
  IN VOID      *Context
  );

#endif