2 Prototypes and defines for the QNC SMM Dispatcher.
4 Copyright (c) 2013-2016 Intel Corporation.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
14 // Include common header file for this module.
16 #include "CommonHeader.h"
18 #include "QNCSmmRegisters.h"
20 extern EFI_HANDLE mQNCSmmDispatcherImageHandle
;
24 // /////////////////////////////////////////////////////////////////////////////
25 // SUPPORTED PROTOCOLS
29 // Define an enumeration for all the supported protocols
32 // UsbType, DELETE:on QuarkNcSocId, there is no usb smi supported
40 } QNC_SMM_PROTOCOL_TYPE
;
43 // /////////////////////////////////////////////////////////////////////////////
44 // SPECIFYING A REGISTER
45 // We want a general way of referring to addresses. For this case, we'll only
46 // need addresses in the ACPI table (and the TCO entries within the ACPI table).
47 // However, it's interesting to consider what it would take to support other types
48 // of addresses. To address Will's concern, I think it prudent to accommodate it
49 // early on in the design.
51 // Addresses we need to consider:
55 // ACPI (special case of I/O) Only if we want to
56 // TCO (special case of ACPI) Only if we want to
57 // Memory (or Memory Mapped I/O) Only if we want to
58 // PCI Yes, for BiosWp
62 // IO_ADDR_TYPE, // unimplemented
67 // MEMORY_ADDR_TYPE, // unimplemented
69 MEMORY_MAPPED_IO_ADDRESS_TYPE
,
71 NUM_ADDR_TYPES
, // count of items in this enum
72 QNC_SMM_ADDR_TYPE_NULL
= -1 // sentinel to indicate NULL or to signal end of arrays
76 // Assumption: 32-bits -- enum's evaluate to integer
77 // Assumption: This code will only run on IA-32. Justification: IA-64 doesn't have SMIs.
78 // We don't have to worry about 64-bit addresses.
79 // Typedef the size of addresses in case the numbers I'm using are wrong or in case
80 // this changes. This is a good idea because PCI_ADDR will change, for example, when
81 // we add support for PciExpress.
83 typedef UINT16 IO_ADDR
;
84 typedef IO_ADDR ACPI_ADDR
; // can omit
85 typedef IO_ADDR GPE_ADDR
; // can omit
86 typedef IO_ADDR TCO_ADDR
; // can omit
87 typedef VOID
*MEM_ADDR
;
88 typedef MEM_ADDR MEMORY_MAPPED_IO_ADDRESS
;
103 // used to initialize during declaration/definition
108 // used to access useful data
115 MEMORY_MAPPED_IO_ADDRESS Mmio
;
122 // Assumption: total size is 64 bits (32 for type and 32 for data) or 8 bytes
124 #define EFI_PCI_ADDRESS_PORT 0xcf8
125 #define EFI_PCI_DATA_PORT 0xcfc
128 // /////////////////////////////////////////////////////////////////////////////
129 // SPECIFYING BITS WITHIN A REGISTER
130 // Here's a struct that helps us specify a source or enable bit.
134 UINT8 SizeInBytes
; // of the register
139 // Sometimes, we'll have bit descriptions that are unused. It'd be great to have a
140 // way to easily identify them:
142 #define IS_BIT_DESC_NULL(BitDesc) ((BitDesc).Reg.Type == QNC_SMM_ADDR_TYPE_NULL) // "returns" true when BitDesc is NULL
143 #define NULL_THIS_BIT_DESC(BitDesc) ((BitDesc).Reg.Type = QNC_SMM_ADDR_TYPE_NULL) // will "return" an integer w/ value of 0
144 #define NULL_BIT_DESC_INITIALIZER \
147 QNC_SMM_ADDR_TYPE_NULL, \
155 // I'd like a type to specify the callback's Sts & En bits because they'll
156 // be commonly used together:
158 #define NUM_EN_BITS 2
159 #define NUM_STS_BITS 1
164 typedef UINT8 QNC_SMM_SOURCE_FLAGS
;
167 // Flags required today
169 #define QNC_SMM_NO_FLAGS 0
170 #define QNC_SMM_SCI_EN_DEPENDENT (BIT0)
171 #define QNC_SMM_CLEAR_WITH_ZERO (BIT6)
174 // Flags that might be required tomorrow
175 // #define QNC_SMM_CLEAR_WITH_ONE 2 // may need to support bits that clear by writing 0
176 // #define QNC_SMM_MULTIBIT_FIELD 3 // may need to support status/enable fields 2 bits wide
179 QNC_SMM_SOURCE_FLAGS Flags
;
180 QNC_SMM_BIT_DESC En
[NUM_EN_BITS
];
181 QNC_SMM_BIT_DESC Sts
[NUM_STS_BITS
];
182 } QNC_SMM_SOURCE_DESC
;
186 #define NULL_SOURCE_DESC_INITIALIZER \
190 NULL_BIT_DESC_INITIALIZER, NULL_BIT_DESC_INITIALIZER \
193 NULL_BIT_DESC_INITIALIZER \
198 // /////////////////////////////////////////////////////////////////////////////
200 // To keep consistent w/ the architecture, we'll need to provide the context
201 // to the child when we call its callback function. After talking with Will,
202 // we agreed that we'll need functions to "dig" the context out of the hardware
203 // in many cases (Sx, Trap, Gpi, etc), and we'll need a function to compare those
204 // contexts to prevent unnecessary dispatches. I'd like a general type for these
205 // "GetContext" functions, so I'll need a union of all the protocol contexts for
210 // (in no particular order)
212 EFI_SMM_ICHN_REGISTER_CONTEXT QNCn
;
213 EFI_SMM_SX_REGISTER_CONTEXT Sx
;
214 EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT PeriodicTimer
;
215 EFI_SMM_SW_REGISTER_CONTEXT Sw
;
216 EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT PowerButton
;
217 // EFI_SMM_USB_REGISTER_CONTEXT Usb; DELETE:on QuarkNcSocId, there is no usb smi supported
218 EFI_SMM_GPI_REGISTER_CONTEXT Gpi
;
223 // (in no particular order)
225 EFI_SMM_SW_CONTEXT Sw
;
226 EFI_SMM_PERIODIC_TIMER_CONTEXT PeriodicTimer
;
230 // Assumption: PeriodicTimer largest at 3x64-bits or 24 bytes
232 typedef struct _DATABASE_RECORD DATABASE_RECORD
;
236 (EFIAPI
*GET_CONTEXT
) (
237 IN DATABASE_RECORD
* Record
,
238 OUT QNC_SMM_CONTEXT
* Context
241 // Assumption: the GET_CONTEXT function will be as small and simple as possible.
242 // Assumption: We don't need to pass in an enumeration for the protocol because each
243 // GET_CONTEXT function is written for only one protocol.
244 // We also need a function to compare contexts to see if the child should be dispatched
248 (EFIAPI
*CMP_CONTEXT
) (
249 IN QNC_SMM_CONTEXT
* Context1
,
250 IN QNC_SMM_CONTEXT
* Context2
254 Returns: True when contexts are equivalent; False otherwise
258 // This function is used to get the content of CommBuffer that will be passed
259 // to Callback function
263 (EFIAPI
*GET_BUFFER
) (
264 IN DATABASE_RECORD
* Record
268 // Finally, every protocol will require a "Get Context", "Compare Context"
269 // and "Get CommBuffer" call, so we may as well wrap that up in a table, too.
272 GET_CONTEXT GetContext
;
273 CMP_CONTEXT CmpContext
;
274 GET_BUFFER GetBuffer
;
277 extern CONTEXT_FUNCTIONS ContextFunctions
[NUM_PROTOCOLS
];
280 // /////////////////////////////////////////////////////////////////////////////
281 // MAPPING CONTEXT TO BIT DESCRIPTIONS
282 // I'd like to have a general approach to mapping contexts to bit descriptions.
283 // Sometimes, we'll find that we can use table lookups or CONSTant assignments;
284 // other times, we'll find that we'll need to use a function to perform the mapping.
285 // If we define a macro to mask that process, we'll never have to change the code.
286 // I don't know if this is desirable or not -- if it isn't, then we can get rid
287 // of the macros and just use function calls or variable assignments. Doesn't matter
289 // Mapping complex contexts requires a function
291 // DELETE:on QuarkNcSocId, there is no usb smi supported
295 // IN QNC_SMM_CONTEXT *RegisterContext,
296 // OUT QNC_SMM_SOURCE_DESC *SrcDesc
302 GC_TODO: Add function description
306 RegisterContext - GC_TODO: add argument description
307 SrcDesc - GC_TODO: add argument description
311 GC_TODO: add return values
317 MapPeriodicTimerToSrcDesc (
318 IN QNC_SMM_CONTEXT
*RegisterContext
,
319 OUT QNC_SMM_SOURCE_DESC
*SrcDesc
325 GC_TODO: Add function description
329 RegisterContext - GC_TODO: add argument description
330 SrcDesc - GC_TODO: add argument description
334 GC_TODO: add return values
340 // Mapping simple contexts can be done by assignment or lookup table
342 extern CONST QNC_SMM_SOURCE_DESC SW_SOURCE_DESC
;
343 extern CONST QNC_SMM_SOURCE_DESC SX_SOURCE_DESC
;
346 // With the changes we've made to the protocols, we can now use table
347 // lookups for the following protocols:
349 extern CONST QNC_SMM_SOURCE_DESC GPI_SOURCE_DESC
;
351 extern QNC_SMM_SOURCE_DESC QNCN_SOURCE_DESCS
[NUM_ICHN_TYPES
];
355 // For QNCx, APMC is UINT8 port, so the MAX SWI Value is 0xFF.
357 #define MAXIMUM_SWI_VALUE 0xFF
361 // Open: Need to make sure this kind of type cast will actually work.
362 // May need an intermediate form w/ two VOID* arguments. I'll figure
363 // that out when I start compiling.
365 ///////////////////////////////////////////////////////////////////////////////
369 (EFIAPI
*QNC_SMM_CLEAR_SOURCE
) (
370 QNC_SMM_SOURCE_DESC
* SrcDesc
374 // /////////////////////////////////////////////////////////////////////////////
376 // Linked list data structures
378 #define DATABASE_RECORD_SIGNATURE SIGNATURE_32 ('D', 'B', 'R', 'C')
380 struct _DATABASE_RECORD
{
387 // Status and Enable bit description
389 QNC_SMM_SOURCE_DESC SrcDesc
;
394 EFI_SMM_HANDLER_ENTRY_POINT2 Callback
;
395 QNC_SMM_CONTEXT ChildContext
;
396 VOID
*CallbackContext
;
397 QNC_SMM_BUFFER CommBuffer
;
401 // Special handling hooks -- init them to NULL if unused/unneeded
403 QNC_SMM_CLEAR_SOURCE ClearSource
; // needed for SWSMI timer
404 // Functions required to make callback code general
406 CONTEXT_FUNCTIONS ContextFunctions
;
409 // The protocol that this record dispatches
411 QNC_SMM_PROTOCOL_TYPE ProtocolType
;
415 #define DATABASE_RECORD_FROM_LINK(_record) CR (_record, DATABASE_RECORD, Link, DATABASE_RECORD_SIGNATURE)
416 #define DATABASE_RECORD_FROM_CONTEXT(_record) CR (_record, DATABASE_RECORD, ChildContext, DATABASE_RECORD_SIGNATURE)
419 // /////////////////////////////////////////////////////////////////////////////
420 // HOOKING INTO THE ARCHITECTURE
424 (EFIAPI
*QNC_SMM_GENERIC_REGISTER
) (
426 IN VOID
*DispatchFunction
,
427 IN VOID
*RegisterContext
,
428 OUT EFI_HANDLE
* DispatchHandle
432 (EFIAPI
*QNC_SMM_GENERIC_UNREGISTER
) (
434 IN EFI_HANDLE DispatchHandle
438 // Define a memory "stamp" equivalent in size and function to most of the protocols
441 QNC_SMM_GENERIC_REGISTER Register
;
442 QNC_SMM_GENERIC_UNREGISTER Unregister
;
444 UINTN Extra2
; // may not need this one
445 } QNC_SMM_GENERIC_PROTOCOL
;
449 IN QNC_SMM_GENERIC_PROTOCOL
*This
,
450 IN EFI_SMM_HANDLER_ENTRY_POINT2 DispatchFunction
,
451 IN QNC_SMM_CONTEXT
*RegisterContext
,
452 OUT EFI_HANDLE
*DispatchHandle
458 GC_TODO: Add function description
462 This - GC_TODO: add argument description
463 DispatchFunction - GC_TODO: add argument description
464 RegisterContext - GC_TODO: add argument description
465 DispatchHandle - GC_TODO: add argument description
469 GC_TODO: add return values
474 QNCSmmCoreUnRegister (
475 IN QNC_SMM_GENERIC_PROTOCOL
*This
,
476 IN EFI_HANDLE DispatchHandle
482 GC_TODO: Add function description
486 This - GC_TODO: add argument description
487 DispatchHandle - GC_TODO: add argument description
491 GC_TODO: add return values
497 QNC_SMM_GENERIC_PROTOCOL Generic
;
499 // EFI_SMM_USB_DISPATCH2_PROTOCOL Usb; DELETE:on QuarkNcSocId, there is no usb smi supported
500 EFI_SMM_SX_DISPATCH2_PROTOCOL Sx
;
501 EFI_SMM_SW_DISPATCH2_PROTOCOL Sw
;
502 EFI_SMM_GPI_DISPATCH2_PROTOCOL Gpi
;
503 EFI_SMM_ICHN_DISPATCH2_PROTOCOL QNCn
;
504 EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL PowerButton
;
505 EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL PeriodicTimer
;
509 // Define a structure to help us identify the generic protocol
511 #define PROTOCOL_SIGNATURE SIGNATURE_32 ('P', 'R', 'O', 'T')
516 QNC_SMM_PROTOCOL_TYPE Type
;
518 QNC_SMM_PROTOCOL Protocols
;
519 } QNC_SMM_QUALIFIED_PROTOCOL
;
521 #define QUALIFIED_PROTOCOL_FROM_GENERIC(_generic) \
523 QNC_SMM_QUALIFIED_PROTOCOL, \
529 // Create private data for the protocols that we'll publish
532 LIST_ENTRY CallbackDataBase
;
533 EFI_HANDLE SmiHandle
;
534 EFI_HANDLE InstallMultProtHandle
;
535 QNC_SMM_QUALIFIED_PROTOCOL Protocols
[NUM_PROTOCOLS
];
538 extern PRIVATE_DATA mPrivateData
;
541 // /////////////////////////////////////////////////////////////////////////////
546 IN DATABASE_RECORD
*Record
,
547 OUT QNC_SMM_CONTEXT
*Context
553 GC_TODO: Add function description
557 Record - GC_TODO: add argument description
558 Context - GC_TODO: add argument description
562 GC_TODO: add return values
570 IN QNC_SMM_CONTEXT
*Context1
,
571 IN QNC_SMM_CONTEXT
*Context2
577 GC_TODO: Add function description
581 Context1 - GC_TODO: add argument description
582 Context2 - GC_TODO: add argument description
586 GC_TODO: add return values
593 IN DATABASE_RECORD
* Record
599 GC_TODO: Add function description
603 Record - GC_TODO: add argument description
607 GC_TODO: add return values
615 IN DATABASE_RECORD
*Record
,
616 OUT QNC_SMM_CONTEXT
*Context
622 GC_TODO: Add function description
626 Record - GC_TODO: add argument description
627 Context - GC_TODO: add argument description
631 GC_TODO: add return values
639 IN QNC_SMM_CONTEXT
*Context1
,
640 IN QNC_SMM_CONTEXT
*Context2
646 GC_TODO: Add function description
650 Context1 - GC_TODO: add argument description
651 Context2 - GC_TODO: add argument description
655 GC_TODO: add return values
662 PeriodicTimerGetContext (
663 IN DATABASE_RECORD
*Record
,
664 OUT QNC_SMM_CONTEXT
*Context
670 GC_TODO: Add function description
674 Record - GC_TODO: add argument description
675 Context - GC_TODO: add argument description
679 GC_TODO: add return values
686 PeriodicTimerCmpContext (
687 IN QNC_SMM_CONTEXT
*Context1
,
688 IN QNC_SMM_CONTEXT
*Context2
694 GC_TODO: Add function description
698 Context1 - GC_TODO: add argument description
699 Context2 - GC_TODO: add argument description
703 GC_TODO: add return values
709 PeriodicTimerGetBuffer (
710 IN DATABASE_RECORD
* Record
716 GC_TODO: Add function description
720 Record - GC_TODO: add argument description
724 GC_TODO: add return values
731 PowerButtonGetContext (
732 IN DATABASE_RECORD
*Record
,
733 OUT QNC_SMM_CONTEXT
*Context
739 GC_TODO: Add function description
743 Record - GC_TODO: add argument description
744 Context - GC_TODO: add argument description
748 GC_TODO: add return values
755 PowerButtonCmpContext (
756 IN QNC_SMM_CONTEXT
*Context1
,
757 IN QNC_SMM_CONTEXT
*Context2
763 GC_TODO: Add function description
767 Context1 - GC_TODO: add argument description
768 Context2 - GC_TODO: add argument description
772 GC_TODO: add return values
778 // /////////////////////////////////////////////////////////////////////////////
782 QNCSmmPeriodicTimerClearSource (
783 QNC_SMM_SOURCE_DESC
*SrcDesc
789 GC_TODO: Add function description
793 SrcDesc - GC_TODO: add argument description
797 GC_TODO: add return values
803 QNCSmmPeriodicTimerDispatchGetNextShorterInterval (
804 IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL
*This
,
805 IN OUT UINT64
**SmiTickInterval
811 GC_TODO: Add function description
815 This - GC_TODO: add argument description
816 SmiTickInterval - GC_TODO: add argument description
820 GC_TODO: add return values
833 GC_TODO: Add function description
841 GC_TODO: add return values
848 QNCSmmQNCnClearSource (
849 QNC_SMM_SOURCE_DESC
*SrcDesc
855 GC_TODO: Add function description
859 SrcDesc - GC_TODO: add argument description
863 GC_TODO: add return values