• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
4 
5 
6   This program and the accompanying materials are licensed and made available under
7 
8   the terms and conditions of the BSD License that accompanies this distribution.
9 
10   The full text of the license may be found at
11 
12   http://opensource.org/licenses/bsd-license.php.
13 
14 
15 
16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 
21 
22 
23 
24 Module Name:
25 
26 
27     SmmScriptSave.c
28 
29 Abstract:
30 
31     ScriptTableSave module at run time
32 
33 --*/
34 
35 #include "SmmScriptSave.h"
36 
37 //
38 // internal functions
39 //
40 
41 EFI_STATUS
42 BootScriptIoWrite  (
43   IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
44   IN VA_LIST                  Marker
45   );
46 
47 EFI_STATUS
48 BootScriptPciCfgWrite  (
49   IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
50   IN VA_LIST                  Marker
51   );
52 
53 VOID
54 SmmCopyMem (
SmmBootScriptWrite(IN OUT EFI_SMM_SCRIPT_TABLE * ScriptTable,IN UINTN Type,IN UINT16 OpCode,...)55   IN  UINT8    *Destination,
56   IN  UINT8    *Source,
57   IN  UINTN    ByteCount
58   );
59 
60 //
61 // Function implementations
62 //
63 EFI_STATUS
64 SmmBootScriptWrite (
65   IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
66   IN UINTN                       Type,
67   IN UINT16                      OpCode,
68   ...
69   )
70 {
71   EFI_STATUS    Status;
72   VA_LIST       Marker;
73 
74   if (ScriptTable == NULL) {
75     return EFI_INVALID_PARAMETER;
76   }
77 
78   //
79   // Build script according to opcode
80   //
81   switch ( OpCode ) {
82 
83     case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
84       VA_START(Marker, OpCode);
85       Status = BootScriptIoWrite (ScriptTable, Marker);
86       VA_END(Marker);
87       break;
88 
89     case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
90       VA_START(Marker, OpCode);
91       Status = BootScriptPciCfgWrite(ScriptTable, Marker);
92       VA_END(Marker);
93       break;
94 
95     default:
SmmBootScriptCreateTable(IN OUT EFI_SMM_SCRIPT_TABLE * ScriptTable,IN UINTN Type)96       Status = EFI_SUCCESS;
97       break;
98   }
99 
100   return Status;
101 }
102 
103 
104 EFI_STATUS
105 SmmBootScriptCreateTable (
106   IN OUT EFI_SMM_SCRIPT_TABLE    *ScriptTable,
107   IN UINTN                       Type
108   )
109 {
110   BOOT_SCRIPT_POINTERS          Script;
111   UINT8                         *Buffer;
112 
113   if (ScriptTable == NULL) {
114     return EFI_INVALID_PARAMETER;
115   }
116 
117   Buffer = (UINT8*) ((UINTN)(*ScriptTable));
118 
119   //
120   // Fill Table Header
121   //
122   Script.Raw = Buffer;
123   Script.TableInfo->OpCode      = EFI_BOOT_SCRIPT_TABLE_OPCODE;
124   Script.TableInfo->Length      = sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
125   Script.TableInfo->TableLength = sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
126 
SmmBootScriptCloseTable(IN EFI_SMM_SCRIPT_TABLE ScriptTableBase,IN EFI_SMM_SCRIPT_TABLE ScriptTablePtr,IN UINTN Type)127   //
128   // Update current table pointer
129   //
130   *ScriptTable = *ScriptTable + sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
131   return EFI_SUCCESS;
132 }
133 
134 
135 EFI_STATUS
136 SmmBootScriptCloseTable (
137   IN EFI_SMM_SCRIPT_TABLE        ScriptTableBase,
138   IN EFI_SMM_SCRIPT_TABLE        ScriptTablePtr,
139   IN UINTN                       Type
140   )
141 {
142   BOOT_SCRIPT_POINTERS    Script;
143 
144   //
145   // Add final "termination" node to script table
146   //
147   Script.Raw               = (UINT8*) ((UINTN)ScriptTablePtr);
148   Script.Terminate->OpCode = EFI_BOOT_SCRIPT_TERMINATE_OPCODE;
149   Script.Terminate->Length = sizeof (EFI_BOOT_SCRIPT_TERMINATE);
150   ScriptTablePtr          += sizeof (EFI_BOOT_SCRIPT_TERMINATE);
151 
152 
153   //
154   // Update Table Header
155   //
156   Script.Raw                    = (UINT8*) ((UINTN)ScriptTableBase);
BootScriptIoWrite(IN EFI_SMM_SCRIPT_TABLE * ScriptTable,IN VA_LIST Marker)157   Script.TableInfo->OpCode      = EFI_BOOT_SCRIPT_TABLE_OPCODE;
158   Script.TableInfo->Length      = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
159   Script.TableInfo->TableLength = (UINT32)(ScriptTablePtr - ScriptTableBase);
160 
161   return EFI_SUCCESS;
162 }
163 
164 
165 EFI_STATUS
166 BootScriptIoWrite  (
167   IN EFI_SMM_SCRIPT_TABLE     *ScriptTable,
168   IN VA_LIST                  Marker
169   )
170 {
171   BOOT_SCRIPT_POINTERS    Script;
172   EFI_BOOT_SCRIPT_WIDTH   Width;
173   UINTN                   Address;
174   UINTN                   Count;
175   UINT8                   *Buffer;
176   UINTN                   NodeLength;
177   UINT8                   WidthInByte;
178 
179   Width     = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
180   Address   = VA_ARG(Marker, UINTN);
181   Count     = VA_ARG(Marker, UINTN);
182   Buffer    = VA_ARG(Marker, UINT8*);
183 
184   WidthInByte = (UINT8)(0x01 << (Width & 0x03));
185   Script.Raw  = (UINT8*) ((UINTN)(*ScriptTable));
186   NodeLength  = sizeof (EFI_BOOT_SCRIPT_IO_WRITE) + (WidthInByte * Count);
187 
188   //
189   // Build script data
190   //
191   Script.IoWrite->OpCode  = EFI_BOOT_SCRIPT_IO_WRITE_OPCODE;
192   Script.IoWrite->Length  = (UINT8)(NodeLength);
193   Script.IoWrite->Width   = Width;
194   Script.IoWrite->Address = Address;
195   Script.IoWrite->Count   = (UINT32)Count;
196   SmmCopyMem (
197     (UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)),
198     Buffer,
199     WidthInByte * Count
200     );
201 
BootScriptPciCfgWrite(IN EFI_SMM_SCRIPT_TABLE * ScriptTable,IN VA_LIST Marker)202   //
203   // Update Script table pointer
204   //
205   *ScriptTable = *ScriptTable + NodeLength;
206   return EFI_SUCCESS;
207 }
208 
209 
210 EFI_STATUS
211 BootScriptPciCfgWrite  (
212   IN EFI_SMM_SCRIPT_TABLE        *ScriptTable,
213   IN VA_LIST                     Marker
214   )
215 {
216   BOOT_SCRIPT_POINTERS    Script;
217   EFI_BOOT_SCRIPT_WIDTH   Width;
218   UINT64                  Address;
219   UINTN                   Count;
220   UINT8                   *Buffer;
221   UINTN                   NodeLength;
222   UINT8                   WidthInByte;
223 
224   Width     = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
225   Address   = VA_ARG(Marker, UINT64);
226   Count     = VA_ARG(Marker, UINTN);
227   Buffer    = VA_ARG(Marker, UINT8*);
228 
229   WidthInByte = (UINT8)(0x01 << (Width & 0x03));
230   Script.Raw  = (UINT8*) ((UINTN)(*ScriptTable));
231   NodeLength  = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count);
232 
233   //
234   // Build script data
235   //
236   Script.PciWrite->OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE;
237   Script.PciWrite->Length  = (UINT8)(NodeLength);
238   Script.PciWrite->Width   = Width;
239   Script.PciWrite->Address = Address;
240   Script.PciWrite->Count   = (UINT32)Count;
241   SmmCopyMem (
242     (UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)),
243     Buffer,
244     WidthInByte * Count
245     );
SmmCopyMem(IN UINT8 * Destination,IN UINT8 * Source,IN UINTN ByteCount)246 
247   //
248   // Update Script table pointer
249   //
250   *ScriptTable = *ScriptTable + NodeLength;
251   return EFI_SUCCESS;
252 }
253 
254 VOID
255 SmmCopyMem (
256   IN  UINT8    *Destination,
257   IN  UINT8    *Source,
258   IN  UINTN    ByteCount
259   )
260 {
261   UINTN   Index;
262 
263   for (Index = 0; Index < ByteCount; Index++, Destination++, Source++) {
264     *Destination = *Source;
265   }
266 }
267