2 Prototypes and defines for the QNC SMM Dispatcher.
4 Copyright (c) 2013-2016 Intel Corporation.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 // Include common header file for this module.
22 #include "CommonHeader.h"
24 #include "QNCSmmRegisters.h"
26 extern EFI_HANDLE mQNCSmmDispatcherImageHandle
;
30 // /////////////////////////////////////////////////////////////////////////////
31 // SUPPORTED PROTOCOLS
35 // Define an enumeration for all the supported protocols
38 // UsbType, DELETE:on QuarkNcSocId, there is no usb smi supported
46 } QNC_SMM_PROTOCOL_TYPE
;
49 // /////////////////////////////////////////////////////////////////////////////
50 // SPECIFYING A REGISTER
51 // We want a general way of referring to addresses. For this case, we'll only
52 // need addresses in the ACPI table (and the TCO entries within the ACPI table).
53 // However, it's interesting to consider what it would take to support other types
54 // of addresses. To address Will's concern, I think it prudent to accommodate it
55 // early on in the design.
57 // Addresses we need to consider:
61 // ACPI (special case of I/O) Only if we want to
62 // TCO (special case of ACPI) Only if we want to
63 // Memory (or Memory Mapped I/O) Only if we want to
64 // PCI Yes, for BiosWp
68 // IO_ADDR_TYPE, // unimplemented
73 // MEMORY_ADDR_TYPE, // unimplemented
75 MEMORY_MAPPED_IO_ADDRESS_TYPE
,
77 NUM_ADDR_TYPES
, // count of items in this enum
78 QNC_SMM_ADDR_TYPE_NULL
= -1 // sentinel to indicate NULL or to signal end of arrays
82 // Assumption: 32-bits -- enum's evaluate to integer
83 // Assumption: This code will only run on IA-32. Justification: IA-64 doesn't have SMIs.
84 // We don't have to worry about 64-bit addresses.
85 // Typedef the size of addresses in case the numbers I'm using are wrong or in case
86 // this changes. This is a good idea because PCI_ADDR will change, for example, when
87 // we add support for PciExpress.
89 typedef UINT16 IO_ADDR
;
90 typedef IO_ADDR ACPI_ADDR
; // can omit
91 typedef IO_ADDR GPE_ADDR
; // can omit
92 typedef IO_ADDR TCO_ADDR
; // can omit
93 typedef VOID
*MEM_ADDR
;
94 typedef MEM_ADDR MEMORY_MAPPED_IO_ADDRESS
;
109 // used to initialize during declaration/definition
114 // used to access useful data
121 MEMORY_MAPPED_IO_ADDRESS Mmio
;
128 // Assumption: total size is 64 bits (32 for type and 32 for data) or 8 bytes
130 #define EFI_PCI_ADDRESS_PORT 0xcf8
131 #define EFI_PCI_DATA_PORT 0xcfc
134 // /////////////////////////////////////////////////////////////////////////////
135 // SPECIFYING BITS WITHIN A REGISTER
136 // Here's a struct that helps us specify a source or enable bit.
140 UINT8 SizeInBytes
; // of the register
145 // Sometimes, we'll have bit descriptions that are unused. It'd be great to have a
146 // way to easily identify them:
148 #define IS_BIT_DESC_NULL(BitDesc) ((BitDesc).Reg.Type == QNC_SMM_ADDR_TYPE_NULL) // "returns" true when BitDesc is NULL
149 #define NULL_THIS_BIT_DESC(BitDesc) ((BitDesc).Reg.Type = QNC_SMM_ADDR_TYPE_NULL) // will "return" an integer w/ value of 0
150 #define NULL_BIT_DESC_INITIALIZER \
153 QNC_SMM_ADDR_TYPE_NULL, \
161 // I'd like a type to specify the callback's Sts & En bits because they'll
162 // be commonly used together:
164 #define NUM_EN_BITS 2
165 #define NUM_STS_BITS 1
170 typedef UINT8 QNC_SMM_SOURCE_FLAGS
;
173 // Flags required today
175 #define QNC_SMM_NO_FLAGS 0
176 #define QNC_SMM_SCI_EN_DEPENDENT (BIT0)
177 #define QNC_SMM_CLEAR_WITH_ZERO (BIT6)
180 // Flags that might be required tomorrow
181 // #define QNC_SMM_CLEAR_WITH_ONE 2 // may need to support bits that clear by writing 0
182 // #define QNC_SMM_MULTIBIT_FIELD 3 // may need to support status/enable fields 2 bits wide
185 QNC_SMM_SOURCE_FLAGS Flags
;
186 QNC_SMM_BIT_DESC En
[NUM_EN_BITS
];
187 QNC_SMM_BIT_DESC Sts
[NUM_STS_BITS
];
188 } QNC_SMM_SOURCE_DESC
;
192 #define NULL_SOURCE_DESC_INITIALIZER \
196 NULL_BIT_DESC_INITIALIZER, NULL_BIT_DESC_INITIALIZER \
199 NULL_BIT_DESC_INITIALIZER \
204 // /////////////////////////////////////////////////////////////////////////////
206 // To keep consistent w/ the architecture, we'll need to provide the context
207 // to the child when we call its callback function. After talking with Will,
208 // we agreed that we'll need functions to "dig" the context out of the hardware
209 // in many cases (Sx, Trap, Gpi, etc), and we'll need a function to compare those
210 // contexts to prevent unnecessary dispatches. I'd like a general type for these
211 // "GetContext" functions, so I'll need a union of all the protocol contexts for
216 // (in no particular order)
218 EFI_SMM_ICHN_REGISTER_CONTEXT QNCn
;
219 EFI_SMM_SX_REGISTER_CONTEXT Sx
;
220 EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT PeriodicTimer
;
221 EFI_SMM_SW_REGISTER_CONTEXT Sw
;
222 EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT PowerButton
;
223 // EFI_SMM_USB_REGISTER_CONTEXT Usb; DELETE:on QuarkNcSocId, there is no usb smi supported
224 EFI_SMM_GPI_REGISTER_CONTEXT Gpi
;
229 // (in no particular order)
231 EFI_SMM_SW_CONTEXT Sw
;
232 EFI_SMM_PERIODIC_TIMER_CONTEXT PeriodicTimer
;
236 // Assumption: PeriodicTimer largest at 3x64-bits or 24 bytes
238 typedef struct _DATABASE_RECORD DATABASE_RECORD
;
242 (EFIAPI
*GET_CONTEXT
) (
243 IN DATABASE_RECORD
* Record
,
244 OUT QNC_SMM_CONTEXT
* Context
247 // Assumption: the GET_CONTEXT function will be as small and simple as possible.
248 // Assumption: We don't need to pass in an enumeration for the protocol because each
249 // GET_CONTEXT function is written for only one protocol.
250 // We also need a function to compare contexts to see if the child should be dispatched
254 (EFIAPI
*CMP_CONTEXT
) (
255 IN QNC_SMM_CONTEXT
* Context1
,
256 IN QNC_SMM_CONTEXT
* Context2
260 Returns: True when contexts are equivalent; False otherwise
264 // This function is used to get the content of CommBuffer that will be passed
265 // to Callback function
269 (EFIAPI
*GET_BUFFER
) (
270 IN DATABASE_RECORD
* Record
274 // Finally, every protocol will require a "Get Context", "Compare Context"
275 // and "Get CommBuffer" call, so we may as well wrap that up in a table, too.
278 GET_CONTEXT GetContext
;
279 CMP_CONTEXT CmpContext
;
280 GET_BUFFER GetBuffer
;
283 extern CONTEXT_FUNCTIONS ContextFunctions
[NUM_PROTOCOLS
];
286 // /////////////////////////////////////////////////////////////////////////////
287 // MAPPING CONTEXT TO BIT DESCRIPTIONS
288 // I'd like to have a general approach to mapping contexts to bit descriptions.
289 // Sometimes, we'll find that we can use table lookups or CONSTant assignments;
290 // other times, we'll find that we'll need to use a function to perform the mapping.
291 // If we define a macro to mask that process, we'll never have to change the code.
292 // I don't know if this is desirable or not -- if it isn't, then we can get rid
293 // of the macros and just use function calls or variable assignments. Doesn't matter
295 // Mapping complex contexts requires a function
297 // DELETE:on QuarkNcSocId, there is no usb smi supported
301 // IN QNC_SMM_CONTEXT *RegisterContext,
302 // OUT QNC_SMM_SOURCE_DESC *SrcDesc
308 GC_TODO: Add function description
312 RegisterContext - GC_TODO: add argument description
313 SrcDesc - GC_TODO: add argument description
317 GC_TODO: add return values
323 MapPeriodicTimerToSrcDesc (
324 IN QNC_SMM_CONTEXT
*RegisterContext
,
325 OUT QNC_SMM_SOURCE_DESC
*SrcDesc
331 GC_TODO: Add function description
335 RegisterContext - GC_TODO: add argument description
336 SrcDesc - GC_TODO: add argument description
340 GC_TODO: add return values
346 // Mapping simple contexts can be done by assignment or lookup table
348 extern CONST QNC_SMM_SOURCE_DESC SW_SOURCE_DESC
;
349 extern CONST QNC_SMM_SOURCE_DESC SX_SOURCE_DESC
;
352 // With the changes we've made to the protocols, we can now use table
353 // lookups for the following protocols:
355 extern CONST QNC_SMM_SOURCE_DESC GPI_SOURCE_DESC
;
357 extern QNC_SMM_SOURCE_DESC QNCN_SOURCE_DESCS
[NUM_ICHN_TYPES
];
361 // For QNCx, APMC is UINT8 port, so the MAX SWI Value is 0xFF.
363 #define MAXIMUM_SWI_VALUE 0xFF
367 // Open: Need to make sure this kind of type cast will actually work.
368 // May need an intermediate form w/ two VOID* arguments. I'll figure
369 // that out when I start compiling.
371 ///////////////////////////////////////////////////////////////////////////////
375 (EFIAPI
*QNC_SMM_CLEAR_SOURCE
) (
376 QNC_SMM_SOURCE_DESC
* SrcDesc
380 // /////////////////////////////////////////////////////////////////////////////
382 // Linked list data structures
384 #define DATABASE_RECORD_SIGNATURE SIGNATURE_32 ('D', 'B', 'R', 'C')
386 struct _DATABASE_RECORD
{
391 // Status and Enable bit description
393 QNC_SMM_SOURCE_DESC SrcDesc
;
398 EFI_SMM_HANDLER_ENTRY_POINT2 Callback
;
399 QNC_SMM_CONTEXT ChildContext
;
400 VOID
*CallbackContext
;
401 QNC_SMM_BUFFER CommBuffer
;
405 // Special handling hooks -- init them to NULL if unused/unneeded
407 QNC_SMM_CLEAR_SOURCE ClearSource
; // needed for SWSMI timer
408 // Functions required to make callback code general
410 CONTEXT_FUNCTIONS ContextFunctions
;
413 // The protocol that this record dispatches
415 QNC_SMM_PROTOCOL_TYPE ProtocolType
;
419 #define DATABASE_RECORD_FROM_LINK(_record) CR (_record, DATABASE_RECORD, Link, DATABASE_RECORD_SIGNATURE)
420 #define DATABASE_RECORD_FROM_CONTEXT(_record) CR (_record, DATABASE_RECORD, ChildContext, DATABASE_RECORD_SIGNATURE)
423 // /////////////////////////////////////////////////////////////////////////////
424 // HOOKING INTO THE ARCHITECTURE
428 (EFIAPI
*QNC_SMM_GENERIC_REGISTER
) (
430 IN VOID
*DispatchFunction
,
431 IN VOID
*RegisterContext
,
432 OUT EFI_HANDLE
* DispatchHandle
436 (EFIAPI
*QNC_SMM_GENERIC_UNREGISTER
) (
438 IN EFI_HANDLE DispatchHandle
442 // Define a memory "stamp" equivalent in size and function to most of the protocols
445 QNC_SMM_GENERIC_REGISTER Register
;
446 QNC_SMM_GENERIC_UNREGISTER Unregister
;
448 UINTN Extra2
; // may not need this one
449 } QNC_SMM_GENERIC_PROTOCOL
;
453 IN QNC_SMM_GENERIC_PROTOCOL
*This
,
454 IN EFI_SMM_HANDLER_ENTRY_POINT2 DispatchFunction
,
455 IN QNC_SMM_CONTEXT
*RegisterContext
,
456 OUT EFI_HANDLE
*DispatchHandle
462 GC_TODO: Add function description
466 This - GC_TODO: add argument description
467 DispatchFunction - GC_TODO: add argument description
468 RegisterContext - GC_TODO: add argument description
469 DispatchHandle - GC_TODO: add argument description
473 GC_TODO: add return values
478 QNCSmmCoreUnRegister (
479 IN QNC_SMM_GENERIC_PROTOCOL
*This
,
480 IN EFI_HANDLE DispatchHandle
486 GC_TODO: Add function description
490 This - GC_TODO: add argument description
491 DispatchHandle - GC_TODO: add argument description
495 GC_TODO: add return values
501 QNC_SMM_GENERIC_PROTOCOL Generic
;
503 // EFI_SMM_USB_DISPATCH2_PROTOCOL Usb; DELETE:on QuarkNcSocId, there is no usb smi supported
504 EFI_SMM_SX_DISPATCH2_PROTOCOL Sx
;
505 EFI_SMM_SW_DISPATCH2_PROTOCOL Sw
;
506 EFI_SMM_GPI_DISPATCH2_PROTOCOL Gpi
;
507 EFI_SMM_ICHN_DISPATCH2_PROTOCOL QNCn
;
508 EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL PowerButton
;
509 EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL PeriodicTimer
;
513 // Define a structure to help us identify the generic protocol
515 #define PROTOCOL_SIGNATURE SIGNATURE_32 ('P', 'R', 'O', 'T')
520 QNC_SMM_PROTOCOL_TYPE Type
;
522 QNC_SMM_PROTOCOL Protocols
;
523 } QNC_SMM_QUALIFIED_PROTOCOL
;
525 #define QUALIFIED_PROTOCOL_FROM_GENERIC(_generic) \
527 QNC_SMM_QUALIFIED_PROTOCOL, \
533 // Create private data for the protocols that we'll publish
536 LIST_ENTRY CallbackDataBase
;
537 EFI_HANDLE SmiHandle
;
538 EFI_HANDLE InstallMultProtHandle
;
539 QNC_SMM_QUALIFIED_PROTOCOL Protocols
[NUM_PROTOCOLS
];
542 extern PRIVATE_DATA mPrivateData
;
545 // /////////////////////////////////////////////////////////////////////////////
550 IN DATABASE_RECORD
*Record
,
551 OUT QNC_SMM_CONTEXT
*Context
557 GC_TODO: Add function description
561 Record - GC_TODO: add argument description
562 Context - GC_TODO: add argument description
566 GC_TODO: add return values
574 IN QNC_SMM_CONTEXT
*Context1
,
575 IN QNC_SMM_CONTEXT
*Context2
581 GC_TODO: Add function description
585 Context1 - GC_TODO: add argument description
586 Context2 - GC_TODO: add argument description
590 GC_TODO: add return values
597 IN DATABASE_RECORD
* Record
603 GC_TODO: Add function description
607 Record - GC_TODO: add argument description
611 GC_TODO: add return values
619 IN DATABASE_RECORD
*Record
,
620 OUT QNC_SMM_CONTEXT
*Context
626 GC_TODO: Add function description
630 Record - GC_TODO: add argument description
631 Context - GC_TODO: add argument description
635 GC_TODO: add return values
643 IN QNC_SMM_CONTEXT
*Context1
,
644 IN QNC_SMM_CONTEXT
*Context2
650 GC_TODO: Add function description
654 Context1 - GC_TODO: add argument description
655 Context2 - GC_TODO: add argument description
659 GC_TODO: add return values
666 PeriodicTimerGetContext (
667 IN DATABASE_RECORD
*Record
,
668 OUT QNC_SMM_CONTEXT
*Context
674 GC_TODO: Add function description
678 Record - GC_TODO: add argument description
679 Context - GC_TODO: add argument description
683 GC_TODO: add return values
690 PeriodicTimerCmpContext (
691 IN QNC_SMM_CONTEXT
*Context1
,
692 IN QNC_SMM_CONTEXT
*Context2
698 GC_TODO: Add function description
702 Context1 - GC_TODO: add argument description
703 Context2 - GC_TODO: add argument description
707 GC_TODO: add return values
713 PeriodicTimerGetBuffer (
714 IN DATABASE_RECORD
* Record
720 GC_TODO: Add function description
724 Record - GC_TODO: add argument description
728 GC_TODO: add return values
735 PowerButtonGetContext (
736 IN DATABASE_RECORD
*Record
,
737 OUT QNC_SMM_CONTEXT
*Context
743 GC_TODO: Add function description
747 Record - GC_TODO: add argument description
748 Context - GC_TODO: add argument description
752 GC_TODO: add return values
759 PowerButtonCmpContext (
760 IN QNC_SMM_CONTEXT
*Context1
,
761 IN QNC_SMM_CONTEXT
*Context2
767 GC_TODO: Add function description
771 Context1 - GC_TODO: add argument description
772 Context2 - GC_TODO: add argument description
776 GC_TODO: add return values
782 // /////////////////////////////////////////////////////////////////////////////
786 QNCSmmPeriodicTimerClearSource (
787 QNC_SMM_SOURCE_DESC
*SrcDesc
793 GC_TODO: Add function description
797 SrcDesc - GC_TODO: add argument description
801 GC_TODO: add return values
807 QNCSmmPeriodicTimerDispatchGetNextShorterInterval (
808 IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL
*This
,
809 IN OUT UINT64
**SmiTickInterval
815 GC_TODO: Add function description
819 This - GC_TODO: add argument description
820 SmiTickInterval - GC_TODO: add argument description
824 GC_TODO: add return values
837 GC_TODO: Add function description
845 GC_TODO: add return values
852 QNCSmmQNCnClearSource (
853 QNC_SMM_SOURCE_DESC
*SrcDesc
859 GC_TODO: Add function description
863 SrcDesc - GC_TODO: add argument description
867 GC_TODO: add return values