]> code.delx.au - refind/blob - EfiLib/BdsTianoCore.c
2163b99218061c8d5c46794ab1ef6143072268bd
[refind] / EfiLib / BdsTianoCore.c
1 /** @file
2 BDS Lib functions which relate with create or process the boot option.
3
4 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "../include/tiano_includes.h"
16
17 /**
18 Build the boot#### or driver#### option from the VariableName, the
19 build boot#### or driver#### will also be linked to BdsCommonOptionList.
20
21 @param BdsCommonOptionList The header of the boot#### or driver#### option
22 link list
23 @param VariableName EFI Variable name indicate if it is boot#### or
24 driver####
25
26 @retval BDS_COMMON_OPTION Get the option just been created
27 @retval NULL Failed to get the new option
28
29 **/
30 BDS_COMMON_OPTION *
31 EFIAPI
32 BdsLibVariableToOption (
33 IN OUT LIST_ENTRY *BdsCommonOptionList,
34 IN CHAR16 *VariableName
35 )
36 {
37 UINT32 Attribute;
38 UINT16 FilePathSize;
39 UINT8 *Variable;
40 UINT8 *TempPtr;
41 UINTN VariableSize;
42 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
43 BDS_COMMON_OPTION *Option;
44 VOID *LoadOptions;
45 UINT32 LoadOptionsSize;
46 CHAR16 *Description;
47 UINT8 NumOff;
48 EFI_GUID EfiGlobalVariableGuid = { 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }};
49
50 //
51 // Read the variable. We will never free this data.
52 //
53 Variable = BdsLibGetVariableAndSize (
54 VariableName,
55 &EfiGlobalVariableGuid,
56 &VariableSize
57 );
58 if (Variable == NULL) {
59 return NULL;
60 }
61 //
62 // Notes: careful defined the variable of Boot#### or
63 // Driver####, consider use some macro to abstract the code
64 //
65 //
66 // Get the option attribute
67 //
68 TempPtr = Variable;
69 Attribute = *(UINT32 *) Variable;
70 TempPtr += sizeof (UINT32);
71
72 //
73 // Get the option's device path size
74 //
75 FilePathSize = *(UINT16 *) TempPtr;
76 TempPtr += sizeof (UINT16);
77
78 //
79 // Get the option's description string
80 //
81 Description = (CHAR16 *) TempPtr;
82
83 //
84 // Get the option's description string size
85 //
86 TempPtr += StrSize ((CHAR16 *) TempPtr);
87
88 //
89 // Get the option's device path
90 //
91 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
92 TempPtr += FilePathSize;
93
94 LoadOptions = TempPtr;
95 LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
96
97 //
98 // The Console variables may have multiple device paths, so make
99 // an Entry for each one.
100 //
101 Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));
102 if (Option == NULL) {
103 return NULL;
104 }
105
106 Option->Signature = BDS_LOAD_OPTION_SIGNATURE;
107 Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));
108 ASSERT(Option->DevicePath != NULL);
109 CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
110
111 Option->Attribute = Attribute;
112 Option->Description = AllocateZeroPool (StrSize (Description));
113 ASSERT(Option->Description != NULL);
114 CopyMem (Option->Description, Description, StrSize (Description));
115
116 Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
117 ASSERT(Option->LoadOptions != NULL);
118 CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
119 Option->LoadOptionsSize = LoadOptionsSize;
120
121 //
122 // Get the value from VariableName Unicode string
123 // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this
124 // Unicode stream to ASCII without any loss in meaning.
125 //
126 if (*VariableName == 'B') {
127 NumOff = (UINT8) (sizeof (L"Boot") / sizeof(CHAR16) - 1);
128 Option->BootCurrent = (UINT16) ((VariableName[NumOff] -'0') * 0x1000);
129 Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+1]-'0') * 0x100));
130 Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+2]-'0') * 0x10));
131 Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+3]-'0')));
132 }
133 //
134 // Insert active entry to BdsDeviceList
135 //
136 if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {
137 InsertTailList (BdsCommonOptionList, &Option->Link);
138 FreePool (Variable);
139 return Option;
140 }
141
142 FreePool (Variable);
143 FreePool (Option);
144 return NULL;
145
146 }
147
148
149 /**
150 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
151 buffer, and the size of the buffer. If failure return NULL.
152
153 @param Name String part of EFI variable name
154 @param VendorGuid GUID part of EFI variable name
155 @param VariableSize Returns the size of the EFI variable that was read
156
157 @return Dynamically allocated memory that contains a copy of the EFI variable
158 Caller is responsible freeing the buffer.
159 @retval NULL Variable was not read
160
161 **/
162 VOID *
163 EFIAPI
164 BdsLibGetVariableAndSize (
165 IN CHAR16 *Name,
166 IN EFI_GUID *VendorGuid,
167 OUT UINTN *VariableSize
168 )
169 {
170 EFI_STATUS Status;
171 UINTN BufferSize;
172 VOID *Buffer;
173
174 Buffer = NULL;
175
176 //
177 // Pass in a zero size buffer to find the required buffer size.
178 //
179 BufferSize = 0;
180 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
181 if (Status == EFI_BUFFER_TOO_SMALL) {
182 //
183 // Allocate the buffer to return
184 //
185 Buffer = AllocateZeroPool (BufferSize);
186 if (Buffer == NULL) {
187 return NULL;
188 }
189 //
190 // Read variable into the allocated buffer.
191 //
192 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
193 if (EFI_ERROR (Status)) {
194 BufferSize = 0;
195 }
196 }
197
198 *VariableSize = BufferSize;
199 return Buffer;
200 }
201