1/** @file
2Prototypes and defines for the QNC SMM Dispatcher.
3
4Copyright (c) 2013-2015 Intel Corporation.
5
6This program and the accompanying materials
7are licensed and made available under the terms and conditions of the BSD License
8which accompanies this distribution.  The full text of the license may be found at
9http://opensource.org/licenses/bsd-license.php
10
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16#ifndef QNC_SMM_H
17#define QNC_SMM_H
18
19//
20// Include common header file for this module.
21//
22#include "CommonHeader.h"
23
24#include "QNCSmmRegisters.h"
25
26extern EFI_HANDLE  mQNCSmmDispatcherImageHandle;
27
28
29//
30// /////////////////////////////////////////////////////////////////////////////
31// SUPPORTED PROTOCOLS
32//
33
34//
35// Define an enumeration for all the supported protocols
36//
37typedef enum {
38  // UsbType,    DELETE:on QuarkNcSocId, there is no usb smi supported
39  SxType,
40  SwType,
41  GpiType,
42  QNCnType,
43  PowerButtonType,
44  PeriodicTimerType,
45  NUM_PROTOCOLS
46} QNC_SMM_PROTOCOL_TYPE;
47
48//
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.
56//
57// Addresses we need to consider:
58//
59//  Type:                           Required:
60//  I/O                             Yes
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
65//
66typedef enum {
67  //
68  //  IO_ADDR_TYPE, // unimplemented
69  //
70  ACPI_ADDR_TYPE,
71  GPE_ADDR_TYPE,
72  //
73  //  MEMORY_ADDR_TYPE, // unimplemented
74  //
75  MEMORY_MAPPED_IO_ADDRESS_TYPE,
76  PCI_ADDR_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
79} ADDR_TYPE;
80
81//
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.
88//
89typedef UINT16 IO_ADDR;
90typedef IO_ADDR ACPI_ADDR;  // can omit
91typedef IO_ADDR GPE_ADDR;  // can omit
92typedef IO_ADDR TCO_ADDR;   // can omit
93typedef VOID *MEM_ADDR;
94typedef MEM_ADDR MEMORY_MAPPED_IO_ADDRESS;
95typedef union {
96  UINT32  Raw;
97  struct {
98    UINT8 Reg;
99    UINT8 Fnc;
100    UINT8 Dev;
101    UINT8 Bus;
102  } Fields;
103} PCI_ADDR;
104
105typedef struct {
106  ADDR_TYPE Type;
107  union {
108    //
109    // used to initialize during declaration/definition
110    //
111    UINTN                     raw;
112
113    //
114    // used to access useful data
115    //
116    IO_ADDR                   io;
117    ACPI_ADDR                 acpi;
118    GPE_ADDR                  gpe;
119    TCO_ADDR                  tco;
120    MEM_ADDR                  mem;
121    MEMORY_MAPPED_IO_ADDRESS  Mmio;
122    PCI_ADDR                  pci;
123
124  } Data;
125
126} QNC_SMM_ADDRESS;
127//
128// Assumption: total size is 64 bits (32 for type and 32 for data) or 8 bytes
129//
130#define EFI_PCI_ADDRESS_PORT  0xcf8
131#define EFI_PCI_DATA_PORT     0xcfc
132
133//
134// /////////////////////////////////////////////////////////////////////////////
135// SPECIFYING BITS WITHIN A REGISTER
136// Here's a struct that helps us specify a source or enable bit.
137//
138typedef struct {
139  QNC_SMM_ADDRESS Reg;
140  UINT8           SizeInBytes;  // of the register
141  UINT8           Bit;
142} QNC_SMM_BIT_DESC;
143
144//
145// Sometimes, we'll have bit descriptions that are unused.  It'd be great to have a
146// way to easily identify them:
147//
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 \
151  { \
152    { \
153      QNC_SMM_ADDR_TYPE_NULL, \
154      { \
155        0 \
156      } \
157    }, \
158    0, 0 \
159  }
160//
161// I'd like a type to specify the callback's Sts & En bits because they'll
162// be commonly used together:
163//
164#define NUM_EN_BITS   2
165#define NUM_STS_BITS  1
166
167//
168// Flags
169//
170typedef UINT8 QNC_SMM_SOURCE_FLAGS;
171
172//
173// Flags required today
174//
175#define QNC_SMM_NO_FLAGS               0
176#define QNC_SMM_SCI_EN_DEPENDENT      (BIT0)
177#define QNC_SMM_CLEAR_WITH_ZERO       (BIT6)
178
179//
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
183//
184typedef struct {
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;
189//
190// 31 bytes, I think
191//
192#define NULL_SOURCE_DESC_INITIALIZER \
193  { \
194    QNC_SMM_NO_FLAGS, \
195    { \
196      NULL_BIT_DESC_INITIALIZER, NULL_BIT_DESC_INITIALIZER \
197    }, \
198    { \
199      NULL_BIT_DESC_INITIALIZER \
200    } \
201  }
202
203//
204// /////////////////////////////////////////////////////////////////////////////
205// CHILD CONTEXTS
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
212// our internal use:
213//
214typedef union {
215  //
216  // (in no particular order)
217  //
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;
225} QNC_SMM_CONTEXT;
226
227typedef union {
228  //
229  // (in no particular order)
230  //
231  EFI_SMM_SW_CONTEXT                      Sw;
232  EFI_SMM_PERIODIC_TIMER_CONTEXT          PeriodicTimer;
233} QNC_SMM_BUFFER;
234
235//
236// Assumption: PeriodicTimer largest at 3x64-bits or 24 bytes
237//
238typedef struct _DATABASE_RECORD DATABASE_RECORD;
239
240typedef
241VOID
242(EFIAPI *GET_CONTEXT) (
243  IN  DATABASE_RECORD    * Record,
244  OUT QNC_SMM_CONTEXT    * Context
245  );
246//
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
251//
252typedef
253BOOLEAN
254(EFIAPI *CMP_CONTEXT) (
255  IN QNC_SMM_CONTEXT     * Context1,
256  IN QNC_SMM_CONTEXT     * Context2
257  );
258
259/*
260    Returns: True when contexts are equivalent; False otherwise
261*/
262
263//
264// This function is used to get the content of CommBuffer that will be passed
265// to Callback function
266//
267typedef
268VOID
269(EFIAPI *GET_BUFFER) (
270  IN  DATABASE_RECORD     * Record
271  );
272
273//
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.
276//
277typedef struct {
278  GET_CONTEXT GetContext;
279  CMP_CONTEXT CmpContext;
280  GET_BUFFER  GetBuffer;
281} CONTEXT_FUNCTIONS;
282
283extern CONTEXT_FUNCTIONS          ContextFunctions[NUM_PROTOCOLS];
284
285//
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
294// to me.
295// Mapping complex contexts requires a function
296//
297// DELETE:on QuarkNcSocId, there is no usb smi supported
298//EFI_STATUS
299//EFIAPI
300//MapUsbToSrcDesc (
301//  IN  QNC_SMM_CONTEXT                                          *RegisterContext,
302//  OUT QNC_SMM_SOURCE_DESC                                      *SrcDesc
303//  )
304/*++
305
306Routine Description:
307
308  GC_TODO: Add function description
309
310Arguments:
311
312  RegisterContext - GC_TODO: add argument description
313  SrcDesc         - GC_TODO: add argument description
314
315Returns:
316
317  GC_TODO: add return values
318
319--*/
320;
321
322EFI_STATUS
323MapPeriodicTimerToSrcDesc (
324  IN  QNC_SMM_CONTEXT                                          *RegisterContext,
325  OUT QNC_SMM_SOURCE_DESC                                     *SrcDesc
326  )
327/*++
328
329Routine Description:
330
331  GC_TODO: Add function description
332
333Arguments:
334
335  RegisterContext - GC_TODO: add argument description
336  SrcDesc         - GC_TODO: add argument description
337
338Returns:
339
340  GC_TODO: add return values
341
342--*/
343;
344
345//
346// Mapping simple contexts can be done by assignment or lookup table
347//
348extern CONST QNC_SMM_SOURCE_DESC  SW_SOURCE_DESC;
349extern CONST QNC_SMM_SOURCE_DESC  SX_SOURCE_DESC;
350
351//
352// With the changes we've made to the protocols, we can now use table
353// lookups for the following protocols:
354//
355extern CONST QNC_SMM_SOURCE_DESC  GPI_SOURCE_DESC;
356
357extern QNC_SMM_SOURCE_DESC        QNCN_SOURCE_DESCS[NUM_ICHN_TYPES];
358
359
360//
361// For QNCx, APMC is UINT8 port, so the MAX SWI Value is 0xFF.
362//
363#define MAXIMUM_SWI_VALUE   0xFF
364
365
366//
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.
370
371///////////////////////////////////////////////////////////////////////////////
372//
373typedef
374VOID
375(EFIAPI *QNC_SMM_CLEAR_SOURCE) (
376  QNC_SMM_SOURCE_DESC * SrcDesc
377  );
378
379//
380// /////////////////////////////////////////////////////////////////////////////
381// "DATABASE" RECORD
382// Linked list data structures
383//
384#define DATABASE_RECORD_SIGNATURE SIGNATURE_32 ('D', 'B', 'R', 'C')
385
386struct _DATABASE_RECORD {
387  UINT32                Signature;
388  LIST_ENTRY            Link;
389
390  //
391  // Status and Enable bit description
392  //
393  QNC_SMM_SOURCE_DESC   SrcDesc;
394
395  //
396  // Callback function
397  //
398  EFI_SMM_HANDLER_ENTRY_POINT2      Callback;
399  QNC_SMM_CONTEXT       ChildContext;
400  QNC_SMM_BUFFER                     CommBuffer;
401  UINTN                             BufferSize;
402
403  //
404  // Special handling hooks -- init them to NULL if unused/unneeded
405  //
406  QNC_SMM_CLEAR_SOURCE  ClearSource;  // needed for SWSMI timer
407  // Functions required to make callback code general
408  //
409  CONTEXT_FUNCTIONS     ContextFunctions;
410
411  //
412  // The protocol that this record dispatches
413  //
414  QNC_SMM_PROTOCOL_TYPE ProtocolType;
415
416};
417
418#define DATABASE_RECORD_FROM_LINK(_record)  CR (_record, DATABASE_RECORD, Link, DATABASE_RECORD_SIGNATURE)
419#define DATABASE_RECORD_FROM_CONTEXT(_record)  CR (_record, DATABASE_RECORD, ChildContext, DATABASE_RECORD_SIGNATURE)
420
421//
422// /////////////////////////////////////////////////////////////////////////////
423// HOOKING INTO THE ARCHITECTURE
424//
425typedef
426EFI_STATUS
427(EFIAPI *QNC_SMM_GENERIC_REGISTER) (
428  IN  VOID                                    **This,
429  IN  VOID                                    *DispatchFunction,
430  IN  VOID                                    *RegisterContext,
431  OUT EFI_HANDLE                              * DispatchHandle
432  );
433typedef
434EFI_STATUS
435(EFIAPI *QNC_SMM_GENERIC_UNREGISTER) (
436  IN  VOID                                    **This,
437  IN  EFI_HANDLE                              DispatchHandle
438  );
439
440//
441// Define a memory "stamp" equivalent in size and function to most of the protocols
442//
443typedef struct {
444  QNC_SMM_GENERIC_REGISTER    Register;
445  QNC_SMM_GENERIC_UNREGISTER  Unregister;
446  UINTN                       Extra1;
447  UINTN                       Extra2; // may not need this one
448} QNC_SMM_GENERIC_PROTOCOL;
449
450EFI_STATUS
451QNCSmmCoreRegister (
452  IN  QNC_SMM_GENERIC_PROTOCOL                          *This,
453  IN  EFI_SMM_HANDLER_ENTRY_POINT2                      DispatchFunction,
454  IN  QNC_SMM_CONTEXT                                    *RegisterContext,
455  OUT EFI_HANDLE                                        *DispatchHandle
456  )
457/*++
458
459Routine Description:
460
461  GC_TODO: Add function description
462
463Arguments:
464
465  This              - GC_TODO: add argument description
466  DispatchFunction  - GC_TODO: add argument description
467  RegisterContext   - GC_TODO: add argument description
468  DispatchHandle    - GC_TODO: add argument description
469
470Returns:
471
472  GC_TODO: add return values
473
474--*/
475;
476EFI_STATUS
477QNCSmmCoreUnRegister (
478  IN  QNC_SMM_GENERIC_PROTOCOL                         *This,
479  IN EFI_HANDLE                                        DispatchHandle
480  )
481/*++
482
483Routine Description:
484
485  GC_TODO: Add function description
486
487Arguments:
488
489  This            - GC_TODO: add argument description
490  DispatchHandle  - GC_TODO: add argument description
491
492Returns:
493
494  GC_TODO: add return values
495
496--*/
497;
498
499typedef union {
500  QNC_SMM_GENERIC_PROTOCOL                  Generic;
501
502  // EFI_SMM_USB_DISPATCH2_PROTOCOL             Usb;  DELETE:on QuarkNcSocId, there is no usb smi supported
503  EFI_SMM_SX_DISPATCH2_PROTOCOL              Sx;
504  EFI_SMM_SW_DISPATCH2_PROTOCOL              Sw;
505  EFI_SMM_GPI_DISPATCH2_PROTOCOL             Gpi;
506  EFI_SMM_ICHN_DISPATCH2_PROTOCOL            QNCn;
507  EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL    PowerButton;
508  EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL  PeriodicTimer;
509} QNC_SMM_PROTOCOL;
510
511//
512// Define a structure to help us identify the generic protocol
513//
514#define PROTOCOL_SIGNATURE  SIGNATURE_32 ('P', 'R', 'O', 'T')
515
516typedef struct {
517  UINTN                 Signature;
518
519  QNC_SMM_PROTOCOL_TYPE Type;
520  EFI_GUID              *Guid;
521  QNC_SMM_PROTOCOL      Protocols;
522} QNC_SMM_QUALIFIED_PROTOCOL;
523
524#define QUALIFIED_PROTOCOL_FROM_GENERIC(_generic) \
525  CR (_generic, \
526      QNC_SMM_QUALIFIED_PROTOCOL, \
527      Protocols, \
528      PROTOCOL_SIGNATURE \
529      )
530
531//
532// Create private data for the protocols that we'll publish
533//
534typedef struct {
535  LIST_ENTRY                  CallbackDataBase;
536  EFI_HANDLE                  SmiHandle;
537  EFI_HANDLE                  InstallMultProtHandle;
538  QNC_SMM_QUALIFIED_PROTOCOL  Protocols[NUM_PROTOCOLS];
539} PRIVATE_DATA;
540
541extern PRIVATE_DATA           mPrivateData;
542
543//
544// /////////////////////////////////////////////////////////////////////////////
545//
546VOID
547EFIAPI
548SwGetContext (
549  IN  DATABASE_RECORD    *Record,
550  OUT QNC_SMM_CONTEXT    *Context
551  )
552/*++
553
554Routine Description:
555
556  GC_TODO: Add function description
557
558Arguments:
559
560  Record  - GC_TODO: add argument description
561  Context - GC_TODO: add argument description
562
563Returns:
564
565  GC_TODO: add return values
566
567--*/
568;
569
570BOOLEAN
571EFIAPI
572SwCmpContext (
573  IN QNC_SMM_CONTEXT     *Context1,
574  IN QNC_SMM_CONTEXT     *Context2
575  )
576/*++
577
578Routine Description:
579
580  GC_TODO: Add function description
581
582Arguments:
583
584  Context1  - GC_TODO: add argument description
585  Context2  - GC_TODO: add argument description
586
587Returns:
588
589  GC_TODO: add return values
590
591--*/
592;
593
594VOID
595SwGetBuffer (
596  IN  DATABASE_RECORD     * Record
597  )
598/*++
599
600Routine Description:
601
602  GC_TODO: Add function description
603
604Arguments:
605
606  Record  - GC_TODO: add argument description
607
608Returns:
609
610  GC_TODO: add return values
611
612--*/
613;
614
615VOID
616EFIAPI
617SxGetContext (
618  IN  DATABASE_RECORD    *Record,
619  OUT QNC_SMM_CONTEXT    *Context
620  )
621/*++
622
623Routine Description:
624
625  GC_TODO: Add function description
626
627Arguments:
628
629  Record  - GC_TODO: add argument description
630  Context - GC_TODO: add argument description
631
632Returns:
633
634  GC_TODO: add return values
635
636--*/
637;
638
639BOOLEAN
640EFIAPI
641SxCmpContext (
642  IN QNC_SMM_CONTEXT     *Context1,
643  IN QNC_SMM_CONTEXT     *Context2
644  )
645/*++
646
647Routine Description:
648
649  GC_TODO: Add function description
650
651Arguments:
652
653  Context1  - GC_TODO: add argument description
654  Context2  - GC_TODO: add argument description
655
656Returns:
657
658  GC_TODO: add return values
659
660--*/
661;
662
663VOID
664EFIAPI
665PeriodicTimerGetContext (
666  IN  DATABASE_RECORD    *Record,
667  OUT QNC_SMM_CONTEXT    *Context
668  )
669/*++
670
671Routine Description:
672
673  GC_TODO: Add function description
674
675Arguments:
676
677  Record  - GC_TODO: add argument description
678  Context - GC_TODO: add argument description
679
680Returns:
681
682  GC_TODO: add return values
683
684--*/
685;
686
687BOOLEAN
688EFIAPI
689PeriodicTimerCmpContext (
690  IN QNC_SMM_CONTEXT     *Context1,
691  IN QNC_SMM_CONTEXT     *Context2
692  )
693/*++
694
695Routine Description:
696
697  GC_TODO: Add function description
698
699Arguments:
700
701  Context1  - GC_TODO: add argument description
702  Context2  - GC_TODO: add argument description
703
704Returns:
705
706  GC_TODO: add return values
707
708--*/
709;
710
711VOID
712PeriodicTimerGetBuffer (
713  IN  DATABASE_RECORD     * Record
714  )
715/*++
716
717Routine Description:
718
719  GC_TODO: Add function description
720
721Arguments:
722
723  Record  - GC_TODO: add argument description
724
725Returns:
726
727  GC_TODO: add return values
728
729--*/
730;
731
732VOID
733EFIAPI
734PowerButtonGetContext (
735  IN  DATABASE_RECORD    *Record,
736  OUT QNC_SMM_CONTEXT     *Context
737  )
738/*++
739
740Routine Description:
741
742  GC_TODO: Add function description
743
744Arguments:
745
746  Record  - GC_TODO: add argument description
747  Context - GC_TODO: add argument description
748
749Returns:
750
751  GC_TODO: add return values
752
753--*/
754;
755
756BOOLEAN
757EFIAPI
758PowerButtonCmpContext (
759  IN QNC_SMM_CONTEXT     *Context1,
760  IN QNC_SMM_CONTEXT     *Context2
761  )
762/*++
763
764Routine Description:
765
766  GC_TODO: Add function description
767
768Arguments:
769
770  Context1  - GC_TODO: add argument description
771  Context2  - GC_TODO: add argument description
772
773Returns:
774
775  GC_TODO: add return values
776
777--*/
778;
779
780//
781// /////////////////////////////////////////////////////////////////////////////
782//
783VOID
784EFIAPI
785QNCSmmPeriodicTimerClearSource (
786  QNC_SMM_SOURCE_DESC *SrcDesc
787  )
788/*++
789
790Routine Description:
791
792  GC_TODO: Add function description
793
794Arguments:
795
796  SrcDesc - GC_TODO: add argument description
797
798Returns:
799
800  GC_TODO: add return values
801
802--*/
803;
804
805EFI_STATUS
806QNCSmmPeriodicTimerDispatchGetNextShorterInterval (
807  IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL    *This,
808  IN OUT UINT64                                         **SmiTickInterval
809  )
810/*++
811
812Routine Description:
813
814  GC_TODO: Add function description
815
816Arguments:
817
818  This            - GC_TODO: add argument description
819  SmiTickInterval - GC_TODO: add argument description
820
821Returns:
822
823  GC_TODO: add return values
824
825--*/
826;
827
828VOID
829QNCSmmSxGoToSleep (
830  VOID
831  )
832/*++
833
834Routine Description:
835
836  GC_TODO: Add function description
837
838Arguments:
839
840  None
841
842Returns:
843
844  GC_TODO: add return values
845
846--*/
847;
848
849VOID
850EFIAPI
851QNCSmmQNCnClearSource (
852  QNC_SMM_SOURCE_DESC *SrcDesc
853  )
854/*++
855
856Routine Description:
857
858  GC_TODO: Add function description
859
860Arguments:
861
862  SrcDesc - GC_TODO: add argument description
863
864Returns:
865
866  GC_TODO: add return values
867
868--*/
869;
870
871#endif
872