1 /** @file 2 Prototypes and defines for the PCH SMM Dispatcher. 3 4 Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR> 5 SPDX-License-Identifier: BSD-2-Clause-Patent 6 7 **/ 8 #ifndef PCH_SMM_H 9 #define PCH_SMM_H 10 11 #include <Uefi.h> 12 #include <Protocol/PciRootBridgeIo.h> 13 #include <Protocol/LoadedImage.h> 14 #include <Protocol/SmmControl2.h> 15 #include <Protocol/SmmUsbDispatch2.h> 16 #include <Protocol/SmmSxDispatch2.h> 17 #include <Protocol/SmmSwDispatch2.h> 18 #include <Protocol/SmmGpiDispatch2.h> 19 #include <Protocol/SmmPowerButtonDispatch2.h> 20 #include <Protocol/SmmPeriodicTimerDispatch2.h> 21 #include <Library/UefiBootServicesTableLib.h> 22 #include <Library/DxeServicesTableLib.h> 23 #include <Library/DebugLib.h> 24 #include <Library/IoLib.h> 25 #include <Library/BaseLib.h> 26 #include <Library/BaseMemoryLib.h> 27 #include <Library/DevicePathLib.h> 28 #include <Library/SmmServicesTableLib.h> 29 #include <Library/ReportStatusCodeLib.h> 30 #include <Library/PerformanceLib.h> 31 #include <Protocol/SmmReadyToLock.h> 32 #include <IndustryStandard/Pci30.h> 33 #include <PchAccess.h> 34 #include <Library/PchCycleDecodingLib.h> 35 #include <Library/PchPcieRpLib.h> 36 #include <Library/PchPcrLib.h> 37 #include <Library/MmPciLib.h> 38 #include <Library/GpioLib.h> 39 #include <Library/PchInfoLib.h> 40 #include <Library/PchEspiLib.h> 41 #include <Library/GpioPrivateLib.h> 42 #include <Protocol/PchTcoSmiDispatch.h> 43 #include <Protocol/PchPcieSmiDispatch.h> 44 #include <Protocol/PchAcpiSmiDispatch.h> 45 #include <Protocol/PchGpioUnlockSmiDispatch.h> 46 #include <Protocol/PchSmiDispatch.h> 47 #include <Protocol/PchEspiSmiDispatch.h> 48 #include "IoTrap.h" 49 50 #include <Library/SmiHandlerProfileLib.h> 51 52 #define EFI_BAD_POINTER 0xAFAFAFAFAFAFAFAFULL 53 54 extern BOOLEAN mReadyToLock; 55 56 /// 57 /// Define an enumeration for all the supported protocols 58 /// 59 #define PCH_SMM_PROTOCOL_TYPE_MAX 6 60 61 typedef enum { 62 UsbType, 63 SxType, 64 SwType, 65 GpiType, 66 PowerButtonType, 67 PeriodicTimerType, 68 PchSmiDispatchType, 69 PchSmmProtocolTypeMax 70 } PCH_SMM_PROTOCOL_TYPE; 71 72 /// 73 /// Define all the supported types of PCH SMI 74 /// 75 typedef enum { 76 PchTcoSmiMchType, 77 PchTcoSmiTcoTimeoutType, 78 PchTcoSmiOsTcoType, 79 PchTcoSmiNmiType, 80 PchTcoSmiIntruderDetectType, 81 PchTcoSmiSpiBiosWpType, 82 PchTcoSmiLpcBiosWpType, 83 PchTcoSmiNewCenturyType, 84 PchPcieSmiRpHotplugType, 85 PchPcieSmiRpLinkActiveType, 86 PchPcieSmiRpLinkEqType, 87 PchAcpiSmiPmeType, 88 PchAcpiSmiPmeB0Type, 89 PchAcpiSmiRtcAlarmType, 90 PchAcpiSmiTmrOverflowType, 91 PchGpioUnlockSmiType, 92 PchEspiSmiEspiSlaveType, 93 PchSmiSerialIrqType, 94 PchSmiMcSmiType, 95 PchSmiSmBusType, 96 PchSmiSpiAsyncType, 97 PchIoTrapSmiType ///< internal SMI type 98 } PCH_SMI_TYPES; 99 100 /// 101 /// Generic funciton pointer to cover all Pch SMI function pointer types 102 /// 103 typedef 104 VOID 105 (EFIAPI *PCH_SMI_CALLBACK_FUNCTIONS) ( 106 IN EFI_HANDLE DispatchHandle, 107 ... 108 ); 109 110 111 /// 112 /// SPECIFYING A REGISTER 113 /// We want a general way of referring to addresses. For this case, we'll only 114 /// need addresses in the ACPI table (and the TCO entries within the ACPI table). 115 /// However, it's interesting to consider what it would take to support other types 116 /// of addresses. To address Will's concern, I think it prudent to accommodate it 117 /// early on in the design. 118 /// 119 /// Addresses we need to consider: 120 /// 121 /// Type: Required: 122 /// I/O Yes 123 /// ACPI (special case of I/O) Only if we want to 124 /// TCO (special case of I/O) Only if we want to 125 /// GPIO (special case of MMIO) Only if we want to 126 /// Memory (or Memory Mapped I/O) Only if we want to 127 /// PCIE Yes, for BiosWp 128 /// 129 typedef enum { 130 /// 131 /// IO_ADDR_TYPE, /// unimplemented 132 /// 133 ACPI_ADDR_TYPE, 134 TCO_ADDR_TYPE, 135 /// 136 /// MEMORY_ADDR_TYPE, /// unimplemented 137 /// 138 GPIO_ADDR_TYPE, 139 MEMORY_MAPPED_IO_ADDRESS_TYPE, 140 PCIE_ADDR_TYPE, 141 PCR_ADDR_TYPE, 142 NUM_ADDR_TYPES, ///< count of items in this enum 143 PCH_SMM_ADDR_TYPE_NULL = -1 ///< sentinel to indicate NULL or to signal end of arrays 144 } ADDR_TYPE; 145 146 // 147 // Assumption: 32-bits -- enum's evaluate to integer 148 // Assumption: This code will only run on IA-32. Justification: IA-64 doesn't have SMIs. 149 // We don't have to worry about 64-bit addresses. 150 // Typedef the size of addresses in case the numbers I'm using are wrong or in case 151 // this changes. This is a good idea because PCI_ADDR will change, for example, when 152 // we add support for PciExpress. 153 // 154 typedef UINT16 IO_ADDR; 155 typedef IO_ADDR ACPI_ADDR; ///< can omit 156 typedef IO_ADDR TCO_ADDR; ///< can omit 157 typedef UINTN MEM_ADDR; 158 typedef MEM_ADDR *MEMORY_MAPPED_IO_ADDRESS; 159 typedef MEM_ADDR *GPIO_ADDR; 160 typedef union { 161 UINT32 Raw; 162 struct { 163 UINT32 Reg: 16; 164 UINT32 Fnc: 3; 165 UINT32 Dev: 5; 166 UINT32 Bus: 8; 167 } Fields; 168 } PCIE_ADDR; 169 170 typedef union { 171 UINT32 Raw; 172 struct { 173 UINT16 Offset; 174 UINT8 Pid; 175 UINT8 Base; 176 } Fields; 177 } PCR_ADDR; 178 179 typedef struct { 180 ADDR_TYPE Type; 181 union { 182 /// 183 /// used to initialize during declaration/definition 184 /// 185 UINT32 raw; 186 187 /// 188 /// used to access useful data 189 /// 190 IO_ADDR io; 191 ACPI_ADDR acpi; 192 TCO_ADDR tco; 193 GPIO_ADDR gpio; 194 MEM_ADDR mem; 195 MEMORY_MAPPED_IO_ADDRESS Mmio; 196 PCIE_ADDR pcie; 197 PCR_ADDR Pcr; 198 199 } Data; 200 201 } PCH_SMM_ADDRESS; 202 203 /// 204 /// SPECIFYING BITS WITHIN A REGISTER 205 /// Here's a struct that helps us specify a source or enable bit. 206 /// 207 typedef struct { 208 PCH_SMM_ADDRESS Reg; 209 UINT8 SizeInBytes; ///< of the register 210 UINT8 Bit; 211 } PCH_SMM_BIT_DESC; 212 213 // 214 // Sometimes, we'll have bit descriptions that are unused. It'd be great to have a 215 // way to easily identify them: 216 // 217 #define IS_BIT_DESC_NULL(BitDesc) ((BitDesc).Reg.Type == PCH_SMM_ADDR_TYPE_NULL) ///< "returns" true when BitDesc is NULL 218 #define NULL_THIS_BIT_DESC(BitDesc) ((BitDesc).Reg.Type = PCH_SMM_ADDR_TYPE_NULL) ///< will "return" an integer w/ value of 0 219 #define NULL_BIT_DESC_INITIALIZER \ 220 { \ 221 { \ 222 PCH_SMM_ADDR_TYPE_NULL, \ 223 { \ 224 0 \ 225 } \ 226 }, \ 227 0, 0 \ 228 } 229 // 230 // I'd like a type to specify the callback's Sts & En bits because they'll 231 // be commonly used together: 232 // 233 #define NUM_EN_BITS 2 234 #define NUM_STS_BITS 1 235 236 // 237 // Flags 238 // 239 typedef UINT8 PCH_SMM_SOURCE_FLAGS; 240 241 // 242 // Flags required to describe the event source 243 // 244 #define PCH_SMM_NO_FLAGS 0 245 #define PCH_SMM_SCI_EN_DEPENDENT 1 246 247 typedef struct { 248 PCH_SMM_SOURCE_FLAGS Flags; 249 PCH_SMM_BIT_DESC En[NUM_EN_BITS]; ///< Describes the enable bit(s) for the SMI event 250 PCH_SMM_BIT_DESC Sts[NUM_STS_BITS]; ///< Describes the secondary status bit for the SMI event. Might be the same as TopLevelSmi 251 PCH_SMM_BIT_DESC PmcSmiSts; ///< Refereing to the top level status bit in PMC SMI_STS, i.e. R_PCH_SMI_STS 252 } PCH_SMM_SOURCE_DESC; 253 254 /// 255 /// Used to initialize null source descriptor 256 /// 257 #define NULL_SOURCE_DESC_INITIALIZER \ 258 { \ 259 PCH_SMM_NO_FLAGS, \ 260 { \ 261 NULL_BIT_DESC_INITIALIZER, NULL_BIT_DESC_INITIALIZER \ 262 }, \ 263 { \ 264 NULL_BIT_DESC_INITIALIZER \ 265 }, \ 266 NULL_BIT_DESC_INITIALIZER \ 267 } 268 269 /// 270 /// CHILD CONTEXTS 271 /// To keep consistent w/ the architecture, we'll need to provide the context 272 /// to the child when we call its callback function. After talking with Will, 273 /// we agreed that we'll need functions to "dig" the context out of the hardware 274 /// in many cases (Sx, Trap, Gpi, etc), and we'll need a function to compare those 275 /// contexts to prevent unnecessary dispatches. I'd like a general type for these 276 /// "GetContext" functions, so I'll need a union of all the protocol contexts for 277 /// our internal use: 278 /// 279 typedef union { 280 // 281 // (in no particular order) 282 // 283 EFI_SMM_SX_REGISTER_CONTEXT Sx; 284 EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT PeriodicTimer; 285 EFI_SMM_SW_REGISTER_CONTEXT Sw; 286 EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT PowerButton; 287 EFI_SMM_USB_REGISTER_CONTEXT Usb; 288 EFI_SMM_GPI_REGISTER_CONTEXT Gpi; 289 } PCH_SMM_CONTEXT; 290 291 /// 292 /// Misc data for PchDispatcher usage. 293 /// For PeriodicTimer, since the ElapsedTime is removed from EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT of EDKII, 294 /// and PchDispatcher needs it for every record. Thus move it here to support ElapsedTime. 295 /// 296 typedef union { 297 UINTN ElapsedTime; 298 } PCH_SMM_MISC_DATA; 299 300 // 301 // Assumption: PeriodicTimer largest at 3x64-bits or 24 bytes 302 // 303 typedef struct _DATABASE_RECORD DATABASE_RECORD; 304 305 /// 306 /// Assumption: the GET_CONTEXT function will be as small and simple as possible. 307 /// Assumption: We don't need to pass in an enumeration for the protocol because each 308 /// GET_CONTEXT function is written for only one protocol. 309 /// We also need a function to compare contexts to see if the child should be dispatched 310 /// In addition, we need a function to acquire CommBuffer and CommBufferSize for 311 /// dispatch callback function of EDKII native support. 312 /// 313 typedef 314 VOID 315 (EFIAPI *GET_CONTEXT) ( 316 IN DATABASE_RECORD * Record, 317 OUT PCH_SMM_CONTEXT * Context 318 ); 319 320 typedef 321 BOOLEAN 322 (EFIAPI *CMP_CONTEXT) ( 323 IN PCH_SMM_CONTEXT * Context1, 324 IN PCH_SMM_CONTEXT * Context2 325 ); 326 327 typedef 328 VOID 329 (EFIAPI *GET_COMMBUFFER) ( 330 IN DATABASE_RECORD * Record, 331 OUT VOID **CommBuffer, 332 OUT UINTN * CommBufferSize 333 ); 334 335 /// 336 /// Finally, every protocol will require a "Get Context" and "Compare Context" call, so 337 /// we may as well wrap that up in a table, too. 338 /// 339 typedef struct { 340 GET_CONTEXT GetContext; 341 CMP_CONTEXT CmpContext; 342 GET_COMMBUFFER GetCommBuffer; 343 } CONTEXT_FUNCTIONS; 344 345 extern CONTEXT_FUNCTIONS ContextFunctions[PCH_SMM_PROTOCOL_TYPE_MAX]; 346 347 /// 348 /// MAPPING CONTEXT TO BIT DESCRIPTIONS 349 /// I'd like to have a general approach to mapping contexts to bit descriptions. 350 /// Sometimes, we'll find that we can use table lookups or constant assignments; 351 /// other times, we'll find that we'll need to use a function to perform the mapping. 352 /// If we define a macro to mask that process, we'll never have to change the code. 353 /// I don't know if this is desirable or not -- if it isn't, then we can get rid 354 /// of the macros and just use function calls or variable assignments. Doesn't matter 355 /// to me. 356 /// Mapping complex contexts requires a function 357 /// 358 359 /** 360 Maps a USB context to a source description. 361 362 @param[in] Context The context we need to map. Type must be USB. 363 @param[out] SrcDesc The source description that corresponds to the given context. 364 365 **/ 366 VOID 367 MapUsbToSrcDesc ( 368 IN PCH_SMM_CONTEXT *Context, 369 OUT PCH_SMM_SOURCE_DESC *SrcDesc 370 ); 371 372 /** 373 Figure out which timer the child is requesting and 374 send back the source description 375 376 @param[in] DispatchContext The pointer to the Dispatch Context instances 377 @param[out] SrcDesc The pointer to the source description 378 379 **/ 380 VOID 381 MapPeriodicTimerToSrcDesc ( 382 IN PCH_SMM_CONTEXT *DispatchContext, 383 OUT PCH_SMM_SOURCE_DESC *SrcDesc 384 ); 385 386 // 387 // Mapping simple contexts can be done by assignment or lookup table 388 // 389 extern CONST PCH_SMM_SOURCE_DESC SW_SOURCE_DESC; 390 extern CONST PCH_SMM_SOURCE_DESC SX_SOURCE_DESC; 391 extern CONST PCH_SMM_SOURCE_DESC POWER_BUTTON_SOURCE_DESC; 392 393 // 394 // With the changes we've made to the protocols, we can now use table 395 // lookups for the following protocols: 396 // 397 extern CONST PCH_SMM_SOURCE_DESC PCH_GPI_SOURCE_DESC_TEMPLATE; 398 399 /// 400 /// For PCHx, APMC is UINT8 port, so the MAX SWI Value is 0xFF. 401 /// 402 #define MAXIMUM_SWI_VALUE 0xFF 403 /// 404 /// Open: Need to make sure this kind of type cast will actually work. 405 /// May need an intermediate form w/ two VOID* arguments. I'll figure 406 /// that out when I start compiling. 407 /// 408 typedef 409 VOID 410 (EFIAPI *PCH_SMM_CLEAR_SOURCE) ( 411 PCH_SMM_SOURCE_DESC * SrcDesc 412 ); 413 414 /// 415 /// "DATABASE" RECORD 416 /// Linked list data structures 417 /// 418 #define DATABASE_RECORD_SIGNATURE SIGNATURE_32 ('D', 'B', 'R', 'C') 419 420 struct _DATABASE_RECORD { 421 UINT32 Signature; 422 LIST_ENTRY Link; 423 BOOLEAN Processed; 424 /// 425 /// Status and Enable bit description 426 /// 427 PCH_SMM_SOURCE_DESC SrcDesc; 428 429 /// 430 /// Callback function 431 /// 432 EFI_SMM_HANDLER_ENTRY_POINT2 Callback; 433 PCH_SMM_CONTEXT ChildContext; 434 435 /// 436 /// Special handling hooks -- init them to NULL if unused/unneeded 437 /// 438 PCH_SMM_CLEAR_SOURCE ClearSource; ///< needed for SWSMI timer 439 440 /// 441 /// Functions required to make callback code general 442 /// 443 CONTEXT_FUNCTIONS ContextFunctions; 444 445 /// 446 /// The protocol that this record dispatches 447 /// 448 PCH_SMM_PROTOCOL_TYPE ProtocolType; 449 EFI_GUID *ProtocolGuid; 450 451 /// 452 /// Misc data for private usage 453 /// 454 PCH_SMM_MISC_DATA MiscData; 455 456 /// 457 /// PCH SMI callback function 458 /// 459 PCH_SMI_CALLBACK_FUNCTIONS PchSmiCallback; 460 /// 461 /// Indicate the PCH SMI types. 462 /// 463 PCH_SMI_TYPES PchSmiType; 464 }; 465 466 #define DATABASE_RECORD_FROM_LINK(_record) CR (_record, DATABASE_RECORD, Link, DATABASE_RECORD_SIGNATURE) 467 #define DATABASE_RECORD_FROM_CHILDCONTEXT(_record) CR (_record, DATABASE_RECORD, ChildContext, DATABASE_RECORD_SIGNATURE) 468 469 /// 470 /// HOOKING INTO THE ARCHITECTURE 471 /// 472 typedef 473 EFI_STATUS 474 (EFIAPI *PCH_SMM_GENERIC_REGISTER) ( 475 IN VOID **This, 476 IN VOID *DispatchFunction, 477 IN VOID *DispatchContext, 478 OUT EFI_HANDLE *DispatchHandle 479 ); 480 typedef 481 EFI_STATUS 482 (EFIAPI *PCH_SMM_GENERIC_UNREGISTER) ( 483 IN VOID **This, 484 IN EFI_HANDLE DispatchHandle 485 ); 486 487 /// 488 /// Define a memory "stamp" equivalent in size and function to most of the protocols 489 /// 490 typedef struct { 491 PCH_SMM_GENERIC_REGISTER Register; 492 PCH_SMM_GENERIC_UNREGISTER Unregister; 493 UINTN Extra1; 494 UINTN Extra2; ///< may not need this one 495 } PCH_SMM_GENERIC_PROTOCOL; 496 497 /** 498 Register a child SMI dispatch function with a parent SMM driver. 499 500 @param[in] This Pointer to the PCH_SMM_GENERIC_PROTOCOL instance. 501 @param[in] DispatchFunction Pointer to dispatch function to be invoked for this SMI source. 502 @param[in] DispatchContext Pointer to the dispatch function's context. 503 @param[out] DispatchHandle Handle of dispatch function, for when interfacing 504 with the parent SMM driver, will be the address of linked 505 list link in the call back record. 506 507 @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database record 508 @retval EFI_INVALID_PARAMETER The input parameter is invalid 509 @retval EFI_SUCCESS The dispatch function has been successfully 510 registered and the SMI source has been enabled. 511 **/ 512 EFI_STATUS 513 EFIAPI 514 PchSmmCoreRegister ( 515 IN PCH_SMM_GENERIC_PROTOCOL *This, 516 IN EFI_SMM_HANDLER_ENTRY_POINT2 DispatchFunction, 517 IN PCH_SMM_CONTEXT *DispatchContext, 518 OUT EFI_HANDLE *DispatchHandle 519 ); 520 521 /** 522 Unregister a child SMI source dispatch function with a parent SMM driver. 523 524 @param[in] This Pointer to the PCH_SMM_GENERIC_PROTOCOL instance. 525 @param[in] DispatchHandle Handle of dispatch function to deregister. 526 527 @retval EFI_SUCCESS The dispatch function has been successfully 528 unregistered and the SMI source has been disabled 529 if there are no other registered child dispatch 530 functions for this SMI source. 531 @retval EFI_INVALID_PARAMETER Handle is invalid. 532 **/ 533 EFI_STATUS 534 EFIAPI 535 PchSmmCoreUnRegister ( 536 IN PCH_SMM_GENERIC_PROTOCOL *This, 537 IN EFI_HANDLE *DispatchHandle 538 ); 539 540 typedef union { 541 PCH_SMM_GENERIC_PROTOCOL Generic; 542 EFI_SMM_USB_DISPATCH2_PROTOCOL Usb; 543 EFI_SMM_SX_DISPATCH2_PROTOCOL Sx; 544 EFI_SMM_SW_DISPATCH2_PROTOCOL Sw; 545 EFI_SMM_GPI_DISPATCH2_PROTOCOL Gpi; 546 EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL PowerButton; 547 EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL PeriodicTimer; 548 } PCH_SMM_PROTOCOL; 549 550 /// 551 /// Define a structure to help us identify the generic protocol 552 /// 553 #define PROTOCOL_SIGNATURE SIGNATURE_32 ('P', 'R', 'O', 'T') 554 555 typedef struct { 556 UINTN Signature; 557 558 PCH_SMM_PROTOCOL_TYPE Type; 559 EFI_GUID *Guid; 560 PCH_SMM_PROTOCOL Protocols; 561 } PCH_SMM_QUALIFIED_PROTOCOL; 562 563 #define QUALIFIED_PROTOCOL_FROM_GENERIC(_generic) \ 564 CR ( \ 565 _generic, \ 566 PCH_SMM_QUALIFIED_PROTOCOL, \ 567 Protocols, \ 568 PROTOCOL_SIGNATURE \ 569 ) 570 571 /// 572 /// Create private data for the protocols that we'll publish 573 /// 574 typedef struct { 575 LIST_ENTRY CallbackDataBase; 576 EFI_HANDLE SmiHandle; 577 EFI_HANDLE InstallMultProtHandle; 578 PCH_SMM_QUALIFIED_PROTOCOL Protocols[PCH_SMM_PROTOCOL_TYPE_MAX]; 579 } PRIVATE_DATA; 580 581 extern PRIVATE_DATA mPrivateData; 582 extern UINT16 mAcpiBaseAddr; 583 extern UINT16 mTcoBaseAddr; 584 /** 585 Get the Software Smi value 586 587 @param[in] Record No use 588 @param[out] Context The context that includes Software Smi value to be filled 589 590 **/ 591 VOID 592 EFIAPI 593 SwGetContext ( 594 IN DATABASE_RECORD *Record, 595 OUT PCH_SMM_CONTEXT *Context 596 ); 597 598 /** 599 Check whether software SMI value of two contexts match 600 601 @param[in] Context1 Context 1 that includes software SMI value 1 602 @param[in] Context2 Context 2 that includes software SMI value 2 603 604 @retval FALSE Software SMI value match 605 @retval TRUE Software SMI value don't match 606 **/ 607 BOOLEAN 608 EFIAPI 609 SwCmpContext ( 610 IN PCH_SMM_CONTEXT *Context1, 611 IN PCH_SMM_CONTEXT *Context2 612 ); 613 614 /** 615 Gather the CommBuffer information of SmmSwDispatch2. 616 617 @param[in] Record No use 618 @param[out] CommBuffer Point to the CommBuffer structure 619 @param[out] CommBufferSize Point to the Size of CommBuffer structure 620 621 **/ 622 VOID 623 EFIAPI 624 SwGetCommBuffer ( 625 IN DATABASE_RECORD *Record, 626 OUT VOID **CommBuffer, 627 OUT UINTN *CommBufferSize 628 ); 629 630 /** 631 Get the Sleep type 632 633 @param[in] Record No use 634 @param[out] Context The context that includes SLP_TYP bits to be filled 635 636 **/ 637 VOID 638 EFIAPI 639 SxGetContext ( 640 IN DATABASE_RECORD *Record, 641 OUT PCH_SMM_CONTEXT *Context 642 ); 643 644 /** 645 Init required protocol for Pch Sw Dispatch protocol. 646 647 648 **/ 649 VOID 650 PchSwDispatchInit ( 651 VOID 652 ); 653 654 /** 655 Check whether sleep type of two contexts match 656 657 @param[in] Context1 Context 1 that includes sleep type 1 658 @param[in] Context2 Context 2 that includes sleep type 2 659 660 @retval FALSE Sleep types match 661 @retval TRUE Sleep types don't match 662 **/ 663 BOOLEAN 664 EFIAPI 665 SxCmpContext ( 666 IN PCH_SMM_CONTEXT *Context1, 667 IN PCH_SMM_CONTEXT *Context2 668 ); 669 670 /** 671 Update the elapsed time from the Interval data of DATABASE_RECORD 672 673 @param[in] Record The pointer to the DATABASE_RECORD. 674 @param[out] HwContext The Context to be updated. 675 676 **/ 677 VOID 678 EFIAPI 679 PeriodicTimerGetContext ( 680 IN DATABASE_RECORD *Record, 681 OUT PCH_SMM_CONTEXT *Context 682 ); 683 684 /** 685 Check whether Periodic Timer of two contexts match 686 687 @param[in] Context1 Context 1 that includes Periodic Timer 1 688 @param[in] Context2 Context 2 that includes Periodic Timer 2 689 690 @retval FALSE Periodic Timer match 691 @retval TRUE Periodic Timer don't match 692 **/ 693 BOOLEAN 694 EFIAPI 695 PeriodicTimerCmpContext ( 696 IN PCH_SMM_CONTEXT *Context1, 697 IN PCH_SMM_CONTEXT *Context2 698 ); 699 700 /** 701 Gather the CommBuffer information of SmmPeriodicTimerDispatch2. 702 703 @param[in] Record No use 704 @param[out] CommBuffer Point to the CommBuffer structure 705 @param[out] CommBufferSize Point to the Size of CommBuffer structure 706 707 **/ 708 VOID 709 EFIAPI 710 PeriodicTimerGetCommBuffer ( 711 IN DATABASE_RECORD *Record, 712 OUT VOID **CommBuffer, 713 OUT UINTN *CommBufferSize 714 ); 715 716 /** 717 Get the power button status. 718 719 @param[in] Record The pointer to the DATABASE_RECORD. 720 @param[out] Context Calling context from the hardware, will be updated with the current power button status. 721 722 **/ 723 VOID 724 EFIAPI 725 PowerButtonGetContext ( 726 IN DATABASE_RECORD *Record, 727 OUT PCH_SMM_CONTEXT *Context 728 ); 729 730 /** 731 Check whether Power Button status of two contexts match 732 733 @param[in] Context1 Context 1 that includes Power Button status 1 734 @param[in] Context2 Context 2 that includes Power Button status 2 735 736 @retval FALSE Power Button status match 737 @retval TRUE Power Button status don't match 738 **/ 739 BOOLEAN 740 EFIAPI 741 PowerButtonCmpContext ( 742 IN PCH_SMM_CONTEXT *Context1, 743 IN PCH_SMM_CONTEXT *Context2 744 ); 745 746 /** 747 This function is responsible for calculating and enabling any timers that are required 748 to dispatch messages to children. The SrcDesc argument isn't acutally used. 749 750 @param[in] SrcDesc Pointer to the PCH_SMM_SOURCE_DESC instance. 751 752 **/ 753 VOID 754 EFIAPI 755 PchSmmPeriodicTimerClearSource ( 756 IN PCH_SMM_SOURCE_DESC *SrcDesc 757 ); 758 759 /** 760 This services returns the next SMI tick period that is supported by the chipset. 761 The order returned is from longest to shortest interval period. 762 763 @param[in] This Pointer to the EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL instance. 764 @param[in, out] SmiTickInterval Pointer to pointer of the next shorter SMI interval period that is supported by the child. 765 766 @retval EFI_SUCCESS The service returned successfully. 767 @retval EFI_INVALID_PARAMETER The parameter SmiTickInterval is invalid. 768 **/ 769 EFI_STATUS 770 PchSmmPeriodicTimerDispatchGetNextShorterInterval ( 771 IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL *This, 772 IN OUT UINT64 **SmiTickInterval 773 ); 774 775 /** 776 Install PCH SMM periodic timer control protocol 777 778 @param[in] Handle handle for this driver 779 780 @retval EFI_SUCCESS Driver initialization completed successfully 781 **/ 782 EFI_STATUS 783 EFIAPI 784 InstallPchSmmPeriodicTimerControlProtocol ( 785 IN EFI_HANDLE Handle 786 ); 787 788 /** 789 When we get an SMI that indicates that we are transitioning to a sleep state, 790 we need to actually transition to that state. We do this by disabling the 791 "SMI on sleep enable" feature, which generates an SMI when the operating system 792 tries to put the system to sleep, and then physically putting the system to sleep. 793 **/ 794 VOID 795 PchSmmSxGoToSleep ( 796 VOID 797 ); 798 799 /** 800 Check and clear NEWCENTURY_STS. 801 It will clear the SMI status once it happens. 802 803 @param[in] SrcDesc Pointer to the PCH SMI source description table 804 **/ 805 VOID 806 EFIAPI 807 PchTcoClearNewCenturySts ( 808 PCH_SMM_SOURCE_DESC *SrcDesc 809 ); 810 811 /** 812 Install protocols of PCH specifics SMI types, including 813 PCH TCO SMI types, PCH PCIE SMI types, PCH ACPI SMI types, PCH MISC SMI types. 814 815 @retval the result of protocol installation 816 **/ 817 EFI_STATUS 818 InstallPchSmiDispatchProtocols ( 819 VOID 820 ); 821 822 /** 823 The function to dispatch all callback function of PCH SMI types. 824 825 @retval EFI_SUCCESS Function successfully completed 826 @retval EFI_UNSUPPORTED no 827 **/ 828 EFI_STATUS 829 PchSmiTypeCallbackDispatcher ( 830 IN DATABASE_RECORD *Record 831 ); 832 833 /** 834 The register function used to register SMI handler of IoTrap event. 835 This is internal function and only used by Iotrap module. 836 837 @param[in] DispatchFunction Pointer to dispatch function to be invoked for this SMI source 838 @param[in] IoTrapIndex Index number of IOTRAP register 839 @param[out] DispatchHandle Handle of dispatch function to register. 840 841 @retval EFI_INVALID_PARAMETER Error with NULL SMI source description 842 @retval EFI_OUT_OF_RESOURCES Fail to allocate pool for database record 843 @retval EFI_SUCCESS The database record is created successfully. 844 **/ 845 EFI_STATUS 846 PchInternalIoTrapSmiRegister ( 847 IN PCH_SMI_DISPATCH_CALLBACK DispatchFunction, 848 IN UINTN IoTrapIndex, 849 OUT EFI_HANDLE *DispatchHandle 850 ); 851 852 /** 853 Unregister a child SMI source dispatch function with a parent SMM driver 854 855 @param[in] DispatchHandle Handle of dispatch function to deregister. 856 857 @retval EFI_SUCCESS The dispatch function has been successfully 858 unregistered and the SMI source has been disabled 859 if there are no other registered child dispatch 860 functions for this SMI source. 861 @retval EFI_INVALID_PARAMETER Handle is invalid. 862 **/ 863 EFI_STATUS 864 PchInternalIoTrapSmiUnRegister ( 865 IN EFI_HANDLE DispatchHandle 866 ); 867 868 /** 869 Register an eSPI SMI handler based on the type 870 871 @param[in] DispatchFunction Callback in an event of eSPI SMI 872 @param[in] PchSmiTypes The eSPI type published by PchSmiDispatch 873 @param[out] DispatchHandle The callback handle 874 875 @retval EFI_INVALID_PARAMETER Error with NULL SMI source description 876 @retval EFI_OUT_OF_RESOURCES Fail to allocate pool for database record 877 @retval EFI_SUCCESS Registration is successful. 878 **/ 879 EFI_STATUS 880 PchInternalEspiSmiRegister ( 881 IN PCH_SMI_DISPATCH_CALLBACK DispatchFunction, 882 IN PCH_SMI_TYPES PchSmiTypes, 883 OUT EFI_HANDLE *DispatchHandle 884 ); 885 886 /** 887 Unregister an eSPI SMI handler 888 889 @param[in] DispatchHandle Handle of dispatch function to deregister. 890 891 @retval EFI_SUCCESS The dispatch function has been successfully 892 unregistered and the SMI source has been disabled 893 if there are no other registered child dispatch 894 functions for this SMI source. 895 @retval EFI_INVALID_PARAMETER Handle is invalid. 896 **/ 897 EFI_STATUS 898 PchInternalEspiSmiUnRegister ( 899 IN EFI_HANDLE DispatchHandle 900 ); 901 902 /** 903 The internal function used to create and insert a database record 904 for SMI record of Pch Smi types. 905 906 @param[in] SrcDesc The pointer to the SMI source description 907 @param[in] DispatchFunction Pointer to dispatch function to be invoked for this SMI source 908 @param[in] PchSmiType Specific SMI type of PCH SMI 909 @param[out] DispatchHandle Handle of dispatch function to register. 910 911 @retval EFI_INVALID_PARAMETER Error with NULL SMI source description 912 @retval EFI_OUT_OF_RESOURCES Fail to allocate pool for database record 913 @retval EFI_SUCCESS The database record is created successfully. 914 **/ 915 EFI_STATUS 916 PchSmiRecordInsert ( 917 IN EFI_GUID *ProtocolGuid, 918 IN PCH_SMM_SOURCE_DESC *SrcDesc, 919 IN PCH_SMI_CALLBACK_FUNCTIONS DispatchFunction, 920 IN PCH_SMI_TYPES PchSmiType, 921 OUT EFI_HANDLE *DispatchHandle 922 ); 923 924 extern PCH_SMM_SOURCE_DESC mSrcDescSerialIrq; 925 926 /** 927 Clear the TCO SMI status bit after the SMI handling is done 928 929 @param[in] SrcDesc Pointer to the PCH SMI source description table 930 931 **/ 932 VOID 933 EFIAPI 934 PchTcoSmiClearSource ( 935 PCH_SMM_SOURCE_DESC *SrcDesc 936 ); 937 938 /** 939 Initialize Source descriptor structure 940 941 @param[in] SrcDesc Pointer to the PCH SMI source description table 942 943 **/ 944 VOID 945 NullInitSourceDesc ( 946 PCH_SMM_SOURCE_DESC *SrcDesc 947 ); 948 949 #endif 950