dpath.c revision 1.1.1.1.10.3 1 1.1.1.1.10.2 tls /* $NetBSD: dpath.c,v 1.1.1.1.10.3 2017/12/03 11:38:02 jdolecek Exp $ */
2 1.1.1.1.10.2 tls
3 1.1.1.1.10.2 tls /*++
4 1.1.1.1.10.2 tls
5 1.1.1.1.10.2 tls Copyright (c) 1998 Intel Corporation
6 1.1.1.1.10.2 tls
7 1.1.1.1.10.2 tls Module Name:
8 1.1.1.1.10.2 tls
9 1.1.1.1.10.2 tls dpath.c
10 1.1.1.1.10.2 tls
11 1.1.1.1.10.2 tls Abstract:
12 1.1.1.1.10.2 tls MBR & Device Path functions
13 1.1.1.1.10.2 tls
14 1.1.1.1.10.2 tls
15 1.1.1.1.10.2 tls
16 1.1.1.1.10.2 tls Revision History
17 1.1.1.1.10.2 tls
18 1.1.1.1.10.2 tls --*/
19 1.1.1.1.10.2 tls
20 1.1.1.1.10.2 tls #include "lib.h"
21 1.1.1.1.10.2 tls
22 1.1.1.1.10.2 tls #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
23 1.1.1.1.10.2 tls
24 1.1.1.1.10.2 tls
25 1.1.1.1.10.2 tls
26 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
27 1.1.1.1.10.2 tls DevicePathFromHandle (
28 1.1.1.1.10.2 tls IN EFI_HANDLE Handle
29 1.1.1.1.10.2 tls )
30 1.1.1.1.10.2 tls {
31 1.1.1.1.10.2 tls EFI_STATUS Status;
32 1.1.1.1.10.2 tls EFI_DEVICE_PATH *DevicePath;
33 1.1.1.1.10.2 tls
34 1.1.1.1.10.2 tls Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath);
35 1.1.1.1.10.2 tls if (EFI_ERROR(Status)) {
36 1.1.1.1.10.2 tls DevicePath = NULL;
37 1.1.1.1.10.2 tls }
38 1.1.1.1.10.2 tls
39 1.1.1.1.10.2 tls return DevicePath;
40 1.1.1.1.10.2 tls }
41 1.1.1.1.10.2 tls
42 1.1.1.1.10.2 tls
43 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
44 1.1.1.1.10.2 tls DevicePathInstance (
45 1.1.1.1.10.2 tls IN OUT EFI_DEVICE_PATH **DevicePath,
46 1.1.1.1.10.2 tls OUT UINTN *Size
47 1.1.1.1.10.2 tls )
48 1.1.1.1.10.2 tls {
49 1.1.1.1.10.2 tls EFI_DEVICE_PATH *Start, *Next, *DevPath;
50 1.1.1.1.10.2 tls UINTN Count;
51 1.1.1.1.10.2 tls
52 1.1.1.1.10.2 tls DevPath = *DevicePath;
53 1.1.1.1.10.2 tls Start = DevPath;
54 1.1.1.1.10.2 tls
55 1.1.1.1.10.2 tls if (!DevPath) {
56 1.1.1.1.10.2 tls return NULL;
57 1.1.1.1.10.2 tls }
58 1.1.1.1.10.2 tls
59 1.1.1.1.10.2 tls //
60 1.1.1.1.10.2 tls // Check for end of device path type
61 1.1.1.1.10.2 tls //
62 1.1.1.1.10.2 tls
63 1.1.1.1.10.2 tls for (Count = 0; ; Count++) {
64 1.1.1.1.10.2 tls Next = NextDevicePathNode(DevPath);
65 1.1.1.1.10.2 tls
66 1.1.1.1.10.2 tls if (IsDevicePathEndType(DevPath)) {
67 1.1.1.1.10.2 tls break;
68 1.1.1.1.10.2 tls }
69 1.1.1.1.10.2 tls
70 1.1.1.1.10.2 tls if (Count > 01000) {
71 1.1.1.1.10.2 tls //
72 1.1.1.1.10.2 tls // BugBug: Debug code to catch bogus device paths
73 1.1.1.1.10.2 tls //
74 1.1.1.1.10.2 tls DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
75 1.1.1.1.10.2 tls DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
76 1.1.1.1.10.2 tls break;
77 1.1.1.1.10.2 tls }
78 1.1.1.1.10.2 tls
79 1.1.1.1.10.2 tls DevPath = Next;
80 1.1.1.1.10.2 tls }
81 1.1.1.1.10.2 tls
82 1.1.1.1.10.2 tls ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
83 1.1.1.1.10.2 tls DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
84 1.1.1.1.10.2 tls
85 1.1.1.1.10.2 tls //
86 1.1.1.1.10.2 tls // Set next position
87 1.1.1.1.10.2 tls //
88 1.1.1.1.10.2 tls
89 1.1.1.1.10.2 tls if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
90 1.1.1.1.10.2 tls Next = NULL;
91 1.1.1.1.10.2 tls }
92 1.1.1.1.10.2 tls
93 1.1.1.1.10.2 tls *DevicePath = Next;
94 1.1.1.1.10.2 tls
95 1.1.1.1.10.2 tls //
96 1.1.1.1.10.2 tls // Return size and start of device path instance
97 1.1.1.1.10.2 tls //
98 1.1.1.1.10.2 tls
99 1.1.1.1.10.2 tls *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start);
100 1.1.1.1.10.2 tls return Start;
101 1.1.1.1.10.2 tls }
102 1.1.1.1.10.2 tls
103 1.1.1.1.10.2 tls UINTN
104 1.1.1.1.10.2 tls DevicePathInstanceCount (
105 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *DevicePath
106 1.1.1.1.10.2 tls )
107 1.1.1.1.10.2 tls {
108 1.1.1.1.10.2 tls UINTN Count, Size;
109 1.1.1.1.10.2 tls
110 1.1.1.1.10.2 tls Count = 0;
111 1.1.1.1.10.2 tls while (DevicePathInstance(&DevicePath, &Size)) {
112 1.1.1.1.10.2 tls Count += 1;
113 1.1.1.1.10.2 tls }
114 1.1.1.1.10.2 tls
115 1.1.1.1.10.2 tls return Count;
116 1.1.1.1.10.2 tls }
117 1.1.1.1.10.2 tls
118 1.1.1.1.10.2 tls
119 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
120 1.1.1.1.10.2 tls AppendDevicePath (
121 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Src1,
122 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Src2
123 1.1.1.1.10.2 tls )
124 1.1.1.1.10.2 tls // Src1 may have multiple "instances" and each instance is appended
125 1.1.1.1.10.2 tls // Src2 is appended to each instance is Src1. (E.g., it's possible
126 1.1.1.1.10.2 tls // to append a new instance to the complete device path by passing
127 1.1.1.1.10.2 tls // it in Src2)
128 1.1.1.1.10.2 tls {
129 1.1.1.1.10.2 tls UINTN Src1Size, Src1Inst, Src2Size, Size;
130 1.1.1.1.10.2 tls EFI_DEVICE_PATH *Dst, *Inst;
131 1.1.1.1.10.2 tls UINT8 *DstPos;
132 1.1.1.1.10.2 tls
133 1.1.1.1.10.2 tls //
134 1.1.1.1.10.2 tls // If there's only 1 path, just duplicate it
135 1.1.1.1.10.2 tls //
136 1.1.1.1.10.2 tls
137 1.1.1.1.10.2 tls if (!Src1) {
138 1.1.1.1.10.2 tls ASSERT (!IsDevicePathUnpacked (Src2));
139 1.1.1.1.10.2 tls return DuplicateDevicePath (Src2);
140 1.1.1.1.10.2 tls }
141 1.1.1.1.10.2 tls
142 1.1.1.1.10.2 tls if (!Src2) {
143 1.1.1.1.10.2 tls ASSERT (!IsDevicePathUnpacked (Src1));
144 1.1.1.1.10.2 tls return DuplicateDevicePath (Src1);
145 1.1.1.1.10.2 tls }
146 1.1.1.1.10.2 tls
147 1.1.1.1.10.2 tls //
148 1.1.1.1.10.2 tls // Verify we're not working with unpacked paths
149 1.1.1.1.10.2 tls //
150 1.1.1.1.10.2 tls
151 1.1.1.1.10.2 tls // ASSERT (!IsDevicePathUnpacked (Src1));
152 1.1.1.1.10.2 tls // ASSERT (!IsDevicePathUnpacked (Src2));
153 1.1.1.1.10.2 tls
154 1.1.1.1.10.2 tls //
155 1.1.1.1.10.2 tls // Append Src2 to every instance in Src1
156 1.1.1.1.10.2 tls //
157 1.1.1.1.10.2 tls
158 1.1.1.1.10.2 tls Src1Size = DevicePathSize(Src1);
159 1.1.1.1.10.2 tls Src1Inst = DevicePathInstanceCount(Src1);
160 1.1.1.1.10.2 tls Src2Size = DevicePathSize(Src2);
161 1.1.1.1.10.2 tls Size = Src1Size * Src1Inst + Src2Size;
162 1.1.1.1.10.2 tls
163 1.1.1.1.10.2 tls Dst = AllocatePool (Size);
164 1.1.1.1.10.2 tls if (Dst) {
165 1.1.1.1.10.2 tls DstPos = (UINT8 *) Dst;
166 1.1.1.1.10.2 tls
167 1.1.1.1.10.2 tls //
168 1.1.1.1.10.2 tls // Copy all device path instances
169 1.1.1.1.10.2 tls //
170 1.1.1.1.10.2 tls
171 1.1.1.1.10.2 tls while ((Inst = DevicePathInstance (&Src1, &Size))) {
172 1.1.1.1.10.2 tls
173 1.1.1.1.10.2 tls CopyMem(DstPos, Inst, Size);
174 1.1.1.1.10.2 tls DstPos += Size;
175 1.1.1.1.10.2 tls
176 1.1.1.1.10.2 tls CopyMem(DstPos, Src2, Src2Size);
177 1.1.1.1.10.2 tls DstPos += Src2Size;
178 1.1.1.1.10.2 tls
179 1.1.1.1.10.2 tls CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH));
180 1.1.1.1.10.2 tls DstPos += sizeof(EFI_DEVICE_PATH);
181 1.1.1.1.10.2 tls }
182 1.1.1.1.10.2 tls
183 1.1.1.1.10.2 tls // Change last end marker
184 1.1.1.1.10.2 tls DstPos -= sizeof(EFI_DEVICE_PATH);
185 1.1.1.1.10.2 tls CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH));
186 1.1.1.1.10.2 tls }
187 1.1.1.1.10.2 tls
188 1.1.1.1.10.2 tls return Dst;
189 1.1.1.1.10.2 tls }
190 1.1.1.1.10.2 tls
191 1.1.1.1.10.2 tls
192 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
193 1.1.1.1.10.2 tls AppendDevicePathNode (
194 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Src1,
195 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Src2
196 1.1.1.1.10.2 tls )
197 1.1.1.1.10.2 tls // Src1 may have multiple "instances" and each instance is appended
198 1.1.1.1.10.2 tls // Src2 is a signal device path node (without a terminator) that is
199 1.1.1.1.10.2 tls // appended to each instance is Src1.
200 1.1.1.1.10.2 tls {
201 1.1.1.1.10.2 tls EFI_DEVICE_PATH *Temp, *Eop;
202 1.1.1.1.10.2 tls UINTN Length;
203 1.1.1.1.10.2 tls
204 1.1.1.1.10.2 tls //
205 1.1.1.1.10.2 tls // Build a Src2 that has a terminator on it
206 1.1.1.1.10.2 tls //
207 1.1.1.1.10.2 tls
208 1.1.1.1.10.2 tls Length = DevicePathNodeLength(Src2);
209 1.1.1.1.10.2 tls Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH));
210 1.1.1.1.10.2 tls if (!Temp) {
211 1.1.1.1.10.2 tls return NULL;
212 1.1.1.1.10.2 tls }
213 1.1.1.1.10.2 tls
214 1.1.1.1.10.2 tls CopyMem (Temp, Src2, Length);
215 1.1.1.1.10.2 tls Eop = NextDevicePathNode(Temp);
216 1.1.1.1.10.2 tls SetDevicePathEndNode(Eop);
217 1.1.1.1.10.2 tls
218 1.1.1.1.10.2 tls //
219 1.1.1.1.10.2 tls // Append device paths
220 1.1.1.1.10.2 tls //
221 1.1.1.1.10.2 tls
222 1.1.1.1.10.2 tls Src1 = AppendDevicePath (Src1, Temp);
223 1.1.1.1.10.2 tls FreePool (Temp);
224 1.1.1.1.10.2 tls return Src1;
225 1.1.1.1.10.2 tls }
226 1.1.1.1.10.2 tls
227 1.1.1.1.10.2 tls
228 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
229 1.1.1.1.10.2 tls FileDevicePath (
230 1.1.1.1.10.2 tls IN EFI_HANDLE Device OPTIONAL,
231 1.1.1.1.10.2 tls IN CHAR16 *FileName
232 1.1.1.1.10.2 tls )
233 1.1.1.1.10.2 tls /*++
234 1.1.1.1.10.2 tls
235 1.1.1.1.10.2 tls N.B. Results are allocated from pool. The caller must FreePool
236 1.1.1.1.10.2 tls the resulting device path structure
237 1.1.1.1.10.2 tls
238 1.1.1.1.10.2 tls --*/
239 1.1.1.1.10.2 tls {
240 1.1.1.1.10.2 tls UINTN Size;
241 1.1.1.1.10.2 tls FILEPATH_DEVICE_PATH *FilePath;
242 1.1.1.1.10.2 tls EFI_DEVICE_PATH *Eop, *DevicePath;
243 1.1.1.1.10.2 tls
244 1.1.1.1.10.2 tls Size = StrSize(FileName);
245 1.1.1.1.10.2 tls FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH));
246 1.1.1.1.10.2 tls DevicePath = NULL;
247 1.1.1.1.10.2 tls
248 1.1.1.1.10.2 tls if (FilePath) {
249 1.1.1.1.10.2 tls
250 1.1.1.1.10.2 tls //
251 1.1.1.1.10.2 tls // Build a file path
252 1.1.1.1.10.2 tls //
253 1.1.1.1.10.2 tls
254 1.1.1.1.10.2 tls FilePath->Header.Type = MEDIA_DEVICE_PATH;
255 1.1.1.1.10.2 tls FilePath->Header.SubType = MEDIA_FILEPATH_DP;
256 1.1.1.1.10.2 tls SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
257 1.1.1.1.10.2 tls CopyMem (FilePath->PathName, FileName, Size);
258 1.1.1.1.10.2 tls Eop = NextDevicePathNode(&FilePath->Header);
259 1.1.1.1.10.2 tls SetDevicePathEndNode(Eop);
260 1.1.1.1.10.2 tls
261 1.1.1.1.10.2 tls //
262 1.1.1.1.10.2 tls // Append file path to device's device path
263 1.1.1.1.10.2 tls //
264 1.1.1.1.10.2 tls
265 1.1.1.1.10.2 tls DevicePath = (EFI_DEVICE_PATH *) FilePath;
266 1.1.1.1.10.2 tls if (Device) {
267 1.1.1.1.10.2 tls DevicePath = AppendDevicePath (
268 1.1.1.1.10.2 tls DevicePathFromHandle(Device),
269 1.1.1.1.10.2 tls DevicePath
270 1.1.1.1.10.2 tls );
271 1.1.1.1.10.2 tls
272 1.1.1.1.10.2 tls FreePool(FilePath);
273 1.1.1.1.10.2 tls }
274 1.1.1.1.10.2 tls }
275 1.1.1.1.10.2 tls
276 1.1.1.1.10.2 tls return DevicePath;
277 1.1.1.1.10.2 tls }
278 1.1.1.1.10.2 tls
279 1.1.1.1.10.2 tls
280 1.1.1.1.10.2 tls
281 1.1.1.1.10.2 tls UINTN
282 1.1.1.1.10.2 tls DevicePathSize (
283 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *DevPath
284 1.1.1.1.10.2 tls )
285 1.1.1.1.10.2 tls {
286 1.1.1.1.10.2 tls EFI_DEVICE_PATH *Start;
287 1.1.1.1.10.2 tls
288 1.1.1.1.10.2 tls //
289 1.1.1.1.10.2 tls // Search for the end of the device path structure
290 1.1.1.1.10.2 tls //
291 1.1.1.1.10.2 tls
292 1.1.1.1.10.2 tls Start = DevPath;
293 1.1.1.1.10.2 tls while (!IsDevicePathEnd(DevPath)) {
294 1.1.1.1.10.2 tls DevPath = NextDevicePathNode(DevPath);
295 1.1.1.1.10.2 tls }
296 1.1.1.1.10.2 tls
297 1.1.1.1.10.2 tls //
298 1.1.1.1.10.2 tls // Compute the size
299 1.1.1.1.10.2 tls //
300 1.1.1.1.10.2 tls
301 1.1.1.1.10.2 tls return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH);
302 1.1.1.1.10.2 tls }
303 1.1.1.1.10.2 tls
304 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
305 1.1.1.1.10.2 tls DuplicateDevicePath (
306 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *DevPath
307 1.1.1.1.10.2 tls )
308 1.1.1.1.10.2 tls {
309 1.1.1.1.10.2 tls EFI_DEVICE_PATH *NewDevPath;
310 1.1.1.1.10.2 tls UINTN Size;
311 1.1.1.1.10.2 tls
312 1.1.1.1.10.2 tls
313 1.1.1.1.10.2 tls //
314 1.1.1.1.10.2 tls // Compute the size
315 1.1.1.1.10.2 tls //
316 1.1.1.1.10.2 tls
317 1.1.1.1.10.2 tls Size = DevicePathSize (DevPath);
318 1.1.1.1.10.2 tls
319 1.1.1.1.10.2 tls //
320 1.1.1.1.10.2 tls // Make a copy
321 1.1.1.1.10.2 tls //
322 1.1.1.1.10.2 tls
323 1.1.1.1.10.2 tls NewDevPath = AllocatePool (Size);
324 1.1.1.1.10.2 tls if (NewDevPath) {
325 1.1.1.1.10.2 tls CopyMem (NewDevPath, DevPath, Size);
326 1.1.1.1.10.2 tls }
327 1.1.1.1.10.2 tls
328 1.1.1.1.10.2 tls return NewDevPath;
329 1.1.1.1.10.2 tls }
330 1.1.1.1.10.2 tls
331 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
332 1.1.1.1.10.2 tls UnpackDevicePath (
333 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *DevPath
334 1.1.1.1.10.2 tls )
335 1.1.1.1.10.2 tls {
336 1.1.1.1.10.2 tls EFI_DEVICE_PATH *Src, *Dest, *NewPath;
337 1.1.1.1.10.2 tls UINTN Size;
338 1.1.1.1.10.2 tls
339 1.1.1.1.10.2 tls //
340 1.1.1.1.10.2 tls // Walk device path and round sizes to valid boundries
341 1.1.1.1.10.2 tls //
342 1.1.1.1.10.2 tls
343 1.1.1.1.10.2 tls Src = DevPath;
344 1.1.1.1.10.2 tls Size = 0;
345 1.1.1.1.10.2 tls for (; ;) {
346 1.1.1.1.10.2 tls Size += DevicePathNodeLength(Src);
347 1.1.1.1.10.2 tls Size += ALIGN_SIZE(Size);
348 1.1.1.1.10.2 tls
349 1.1.1.1.10.2 tls if (IsDevicePathEnd(Src)) {
350 1.1.1.1.10.2 tls break;
351 1.1.1.1.10.2 tls }
352 1.1.1.1.10.2 tls
353 1.1.1.1.10.2 tls Src = NextDevicePathNode(Src);
354 1.1.1.1.10.2 tls }
355 1.1.1.1.10.2 tls
356 1.1.1.1.10.2 tls
357 1.1.1.1.10.2 tls //
358 1.1.1.1.10.2 tls // Allocate space for the unpacked path
359 1.1.1.1.10.2 tls //
360 1.1.1.1.10.2 tls
361 1.1.1.1.10.2 tls NewPath = AllocateZeroPool (Size);
362 1.1.1.1.10.2 tls if (NewPath) {
363 1.1.1.1.10.2 tls
364 1.1.1.1.10.2 tls ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0);
365 1.1.1.1.10.2 tls
366 1.1.1.1.10.2 tls //
367 1.1.1.1.10.2 tls // Copy each node
368 1.1.1.1.10.2 tls //
369 1.1.1.1.10.2 tls
370 1.1.1.1.10.2 tls Src = DevPath;
371 1.1.1.1.10.2 tls Dest = NewPath;
372 1.1.1.1.10.2 tls for (; ;) {
373 1.1.1.1.10.2 tls Size = DevicePathNodeLength(Src);
374 1.1.1.1.10.2 tls CopyMem (Dest, Src, Size);
375 1.1.1.1.10.2 tls Size += ALIGN_SIZE(Size);
376 1.1.1.1.10.2 tls SetDevicePathNodeLength (Dest, Size);
377 1.1.1.1.10.2 tls Dest->Type |= EFI_DP_TYPE_UNPACKED;
378 1.1.1.1.10.2 tls Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size);
379 1.1.1.1.10.2 tls
380 1.1.1.1.10.2 tls if (IsDevicePathEnd(Src)) {
381 1.1.1.1.10.2 tls break;
382 1.1.1.1.10.2 tls }
383 1.1.1.1.10.2 tls
384 1.1.1.1.10.2 tls Src = NextDevicePathNode(Src);
385 1.1.1.1.10.2 tls }
386 1.1.1.1.10.2 tls }
387 1.1.1.1.10.2 tls
388 1.1.1.1.10.2 tls return NewPath;
389 1.1.1.1.10.2 tls }
390 1.1.1.1.10.2 tls
391 1.1.1.1.10.2 tls
392 1.1.1.1.10.2 tls EFI_DEVICE_PATH*
393 1.1.1.1.10.2 tls AppendDevicePathInstance (
394 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Src,
395 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Instance
396 1.1.1.1.10.2 tls )
397 1.1.1.1.10.2 tls {
398 1.1.1.1.10.2 tls UINT8 *Ptr;
399 1.1.1.1.10.2 tls EFI_DEVICE_PATH *DevPath;
400 1.1.1.1.10.2 tls UINTN SrcSize;
401 1.1.1.1.10.2 tls UINTN InstanceSize;
402 1.1.1.1.10.2 tls
403 1.1.1.1.10.2 tls if (Src == NULL) {
404 1.1.1.1.10.2 tls return DuplicateDevicePath (Instance);
405 1.1.1.1.10.2 tls }
406 1.1.1.1.10.2 tls SrcSize = DevicePathSize(Src);
407 1.1.1.1.10.2 tls InstanceSize = DevicePathSize(Instance);
408 1.1.1.1.10.2 tls Ptr = AllocatePool (SrcSize + InstanceSize);
409 1.1.1.1.10.2 tls DevPath = (EFI_DEVICE_PATH *)Ptr;
410 1.1.1.1.10.2 tls ASSERT(DevPath);
411 1.1.1.1.10.2 tls
412 1.1.1.1.10.2 tls CopyMem (Ptr, Src, SrcSize);
413 1.1.1.1.10.2 tls // FreePool (Src);
414 1.1.1.1.10.2 tls
415 1.1.1.1.10.2 tls while (!IsDevicePathEnd(DevPath)) {
416 1.1.1.1.10.2 tls DevPath = NextDevicePathNode(DevPath);
417 1.1.1.1.10.2 tls }
418 1.1.1.1.10.2 tls //
419 1.1.1.1.10.2 tls // Convert the End to an End Instance, since we are
420 1.1.1.1.10.2 tls // appending another instacne after this one its a good
421 1.1.1.1.10.2 tls // idea.
422 1.1.1.1.10.2 tls //
423 1.1.1.1.10.2 tls DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
424 1.1.1.1.10.2 tls
425 1.1.1.1.10.2 tls DevPath = NextDevicePathNode(DevPath);
426 1.1.1.1.10.2 tls CopyMem (DevPath, Instance, InstanceSize);
427 1.1.1.1.10.2 tls return (EFI_DEVICE_PATH *)Ptr;
428 1.1.1.1.10.2 tls }
429 1.1.1.1.10.2 tls
430 1.1.1.1.10.2 tls EFI_STATUS
431 1.1.1.1.10.2 tls LibDevicePathToInterface (
432 1.1.1.1.10.2 tls IN EFI_GUID *Protocol,
433 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *FilePath,
434 1.1.1.1.10.2 tls OUT VOID **Interface
435 1.1.1.1.10.2 tls )
436 1.1.1.1.10.2 tls {
437 1.1.1.1.10.2 tls EFI_STATUS Status;
438 1.1.1.1.10.2 tls EFI_HANDLE Device;
439 1.1.1.1.10.2 tls
440 1.1.1.1.10.2 tls Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device);
441 1.1.1.1.10.2 tls
442 1.1.1.1.10.2 tls if (!EFI_ERROR(Status)) {
443 1.1.1.1.10.2 tls
444 1.1.1.1.10.2 tls // If we didn't get a direct match return not found
445 1.1.1.1.10.2 tls Status = EFI_NOT_FOUND;
446 1.1.1.1.10.2 tls
447 1.1.1.1.10.2 tls if (IsDevicePathEnd(FilePath)) {
448 1.1.1.1.10.2 tls
449 1.1.1.1.10.2 tls //
450 1.1.1.1.10.2 tls // It was a direct match, lookup the protocol interface
451 1.1.1.1.10.2 tls //
452 1.1.1.1.10.2 tls
453 1.1.1.1.10.2 tls Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface);
454 1.1.1.1.10.2 tls }
455 1.1.1.1.10.2 tls }
456 1.1.1.1.10.2 tls
457 1.1.1.1.10.2 tls //
458 1.1.1.1.10.2 tls // If there was an error, do not return an interface
459 1.1.1.1.10.2 tls //
460 1.1.1.1.10.2 tls
461 1.1.1.1.10.2 tls if (EFI_ERROR(Status)) {
462 1.1.1.1.10.2 tls *Interface = NULL;
463 1.1.1.1.10.2 tls }
464 1.1.1.1.10.2 tls
465 1.1.1.1.10.2 tls return Status;
466 1.1.1.1.10.2 tls }
467 1.1.1.1.10.2 tls
468 1.1.1.1.10.2 tls VOID
469 1.1.1.1.10.2 tls _DevPathPci (
470 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
471 1.1.1.1.10.2 tls IN VOID *DevPath
472 1.1.1.1.10.2 tls )
473 1.1.1.1.10.2 tls {
474 1.1.1.1.10.2 tls PCI_DEVICE_PATH *Pci;
475 1.1.1.1.10.2 tls
476 1.1.1.1.10.2 tls Pci = DevPath;
477 1.1.1.1.10.2 tls CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);
478 1.1.1.1.10.2 tls }
479 1.1.1.1.10.2 tls
480 1.1.1.1.10.2 tls VOID
481 1.1.1.1.10.2 tls _DevPathPccard (
482 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
483 1.1.1.1.10.2 tls IN VOID *DevPath
484 1.1.1.1.10.2 tls )
485 1.1.1.1.10.2 tls {
486 1.1.1.1.10.2 tls PCCARD_DEVICE_PATH *Pccard;
487 1.1.1.1.10.2 tls
488 1.1.1.1.10.2 tls Pccard = DevPath;
489 1.1.1.1.10.2 tls CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber);
490 1.1.1.1.10.2 tls }
491 1.1.1.1.10.2 tls
492 1.1.1.1.10.2 tls VOID
493 1.1.1.1.10.2 tls _DevPathMemMap (
494 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
495 1.1.1.1.10.2 tls IN VOID *DevPath
496 1.1.1.1.10.2 tls )
497 1.1.1.1.10.2 tls {
498 1.1.1.1.10.2 tls MEMMAP_DEVICE_PATH *MemMap;
499 1.1.1.1.10.2 tls
500 1.1.1.1.10.2 tls MemMap = DevPath;
501 1.1.1.1.10.2 tls CatPrint(Str, L"MemMap(%d:%x-%x)",
502 1.1.1.1.10.2 tls MemMap->MemoryType,
503 1.1.1.1.10.2 tls MemMap->StartingAddress,
504 1.1.1.1.10.2 tls MemMap->EndingAddress
505 1.1.1.1.10.2 tls );
506 1.1.1.1.10.2 tls }
507 1.1.1.1.10.2 tls
508 1.1.1.1.10.2 tls VOID
509 1.1.1.1.10.2 tls _DevPathController (
510 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
511 1.1.1.1.10.2 tls IN VOID *DevPath
512 1.1.1.1.10.2 tls )
513 1.1.1.1.10.2 tls {
514 1.1.1.1.10.2 tls CONTROLLER_DEVICE_PATH *Controller;
515 1.1.1.1.10.2 tls
516 1.1.1.1.10.2 tls Controller = DevPath;
517 1.1.1.1.10.2 tls CatPrint(Str, L"Ctrl(%d)",
518 1.1.1.1.10.2 tls Controller->Controller
519 1.1.1.1.10.2 tls );
520 1.1.1.1.10.2 tls }
521 1.1.1.1.10.2 tls
522 1.1.1.1.10.2 tls VOID
523 1.1.1.1.10.2 tls _DevPathVendor (
524 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
525 1.1.1.1.10.2 tls IN VOID *DevPath
526 1.1.1.1.10.2 tls )
527 1.1.1.1.10.2 tls {
528 1.1.1.1.10.2 tls VENDOR_DEVICE_PATH *Vendor;
529 1.1.1.1.10.2 tls CHAR16 *Type;
530 1.1.1.1.10.2 tls UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath;
531 1.1.1.1.10.2 tls
532 1.1.1.1.10.2 tls Vendor = DevPath;
533 1.1.1.1.10.2 tls switch (DevicePathType(&Vendor->Header)) {
534 1.1.1.1.10.2 tls case HARDWARE_DEVICE_PATH: Type = L"Hw"; break;
535 1.1.1.1.10.2 tls case MESSAGING_DEVICE_PATH: Type = L"Msg"; break;
536 1.1.1.1.10.2 tls case MEDIA_DEVICE_PATH: Type = L"Media"; break;
537 1.1.1.1.10.2 tls default: Type = L"?"; break;
538 1.1.1.1.10.2 tls }
539 1.1.1.1.10.2 tls
540 1.1.1.1.10.2 tls CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid);
541 1.1.1.1.10.2 tls if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) {
542 1.1.1.1.10.2 tls //
543 1.1.1.1.10.2 tls // GUID used by EFI to enumerate an EDD 1.1 device
544 1.1.1.1.10.2 tls //
545 1.1.1.1.10.2 tls UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor;
546 1.1.1.1.10.2 tls CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
547 1.1.1.1.10.2 tls } else {
548 1.1.1.1.10.2 tls CatPrint(Str, L")");
549 1.1.1.1.10.2 tls }
550 1.1.1.1.10.2 tls }
551 1.1.1.1.10.2 tls
552 1.1.1.1.10.2 tls
553 1.1.1.1.10.2 tls VOID
554 1.1.1.1.10.2 tls _DevPathAcpi (
555 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
556 1.1.1.1.10.2 tls IN VOID *DevPath
557 1.1.1.1.10.2 tls )
558 1.1.1.1.10.2 tls {
559 1.1.1.1.10.2 tls ACPI_HID_DEVICE_PATH *Acpi;
560 1.1.1.1.10.2 tls
561 1.1.1.1.10.2 tls Acpi = DevPath;
562 1.1.1.1.10.2 tls if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
563 1.1.1.1.10.2 tls CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
564 1.1.1.1.10.2 tls } else {
565 1.1.1.1.10.2 tls CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
566 1.1.1.1.10.2 tls }
567 1.1.1.1.10.2 tls }
568 1.1.1.1.10.2 tls
569 1.1.1.1.10.2 tls
570 1.1.1.1.10.2 tls VOID
571 1.1.1.1.10.2 tls _DevPathAtapi (
572 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
573 1.1.1.1.10.2 tls IN VOID *DevPath
574 1.1.1.1.10.2 tls )
575 1.1.1.1.10.2 tls {
576 1.1.1.1.10.2 tls ATAPI_DEVICE_PATH *Atapi;
577 1.1.1.1.10.2 tls
578 1.1.1.1.10.2 tls Atapi = DevPath;
579 1.1.1.1.10.2 tls CatPrint(Str, L"Ata(%s,%s)",
580 1.1.1.1.10.2 tls Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
581 1.1.1.1.10.2 tls Atapi->SlaveMaster ? L"Slave" : L"Master"
582 1.1.1.1.10.2 tls );
583 1.1.1.1.10.2 tls }
584 1.1.1.1.10.2 tls
585 1.1.1.1.10.2 tls VOID
586 1.1.1.1.10.2 tls _DevPathScsi (
587 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
588 1.1.1.1.10.2 tls IN VOID *DevPath
589 1.1.1.1.10.2 tls )
590 1.1.1.1.10.2 tls {
591 1.1.1.1.10.2 tls SCSI_DEVICE_PATH *Scsi;
592 1.1.1.1.10.2 tls
593 1.1.1.1.10.2 tls Scsi = DevPath;
594 1.1.1.1.10.2 tls CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);
595 1.1.1.1.10.2 tls }
596 1.1.1.1.10.2 tls
597 1.1.1.1.10.2 tls
598 1.1.1.1.10.2 tls VOID
599 1.1.1.1.10.2 tls _DevPathFibre (
600 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
601 1.1.1.1.10.2 tls IN VOID *DevPath
602 1.1.1.1.10.2 tls )
603 1.1.1.1.10.2 tls {
604 1.1.1.1.10.2 tls FIBRECHANNEL_DEVICE_PATH *Fibre;
605 1.1.1.1.10.2 tls
606 1.1.1.1.10.2 tls Fibre = DevPath;
607 1.1.1.1.10.2 tls CatPrint(Str, L"Fibre(%lx)", Fibre->WWN);
608 1.1.1.1.10.2 tls }
609 1.1.1.1.10.2 tls
610 1.1.1.1.10.2 tls VOID
611 1.1.1.1.10.2 tls _DevPath1394 (
612 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
613 1.1.1.1.10.2 tls IN VOID *DevPath
614 1.1.1.1.10.2 tls )
615 1.1.1.1.10.2 tls {
616 1.1.1.1.10.2 tls F1394_DEVICE_PATH *F1394;
617 1.1.1.1.10.2 tls
618 1.1.1.1.10.2 tls F1394 = DevPath;
619 1.1.1.1.10.2 tls CatPrint(Str, L"1394(%g)", &F1394->Guid);
620 1.1.1.1.10.2 tls }
621 1.1.1.1.10.2 tls
622 1.1.1.1.10.2 tls
623 1.1.1.1.10.2 tls
624 1.1.1.1.10.2 tls VOID
625 1.1.1.1.10.2 tls _DevPathUsb (
626 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
627 1.1.1.1.10.2 tls IN VOID *DevPath
628 1.1.1.1.10.2 tls )
629 1.1.1.1.10.2 tls {
630 1.1.1.1.10.2 tls USB_DEVICE_PATH *Usb;
631 1.1.1.1.10.2 tls
632 1.1.1.1.10.2 tls Usb = DevPath;
633 1.1.1.1.10.2 tls CatPrint(Str, L"Usb(%x)", Usb->Port);
634 1.1.1.1.10.2 tls }
635 1.1.1.1.10.2 tls
636 1.1.1.1.10.2 tls
637 1.1.1.1.10.2 tls VOID
638 1.1.1.1.10.2 tls _DevPathI2O (
639 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
640 1.1.1.1.10.2 tls IN VOID *DevPath
641 1.1.1.1.10.2 tls )
642 1.1.1.1.10.2 tls {
643 1.1.1.1.10.2 tls I2O_DEVICE_PATH *I2O;
644 1.1.1.1.10.2 tls
645 1.1.1.1.10.2 tls I2O = DevPath;
646 1.1.1.1.10.2 tls CatPrint(Str, L"I2O(%x)", I2O->Tid);
647 1.1.1.1.10.2 tls }
648 1.1.1.1.10.2 tls
649 1.1.1.1.10.2 tls VOID
650 1.1.1.1.10.2 tls _DevPathMacAddr (
651 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
652 1.1.1.1.10.2 tls IN VOID *DevPath
653 1.1.1.1.10.2 tls )
654 1.1.1.1.10.2 tls {
655 1.1.1.1.10.2 tls MAC_ADDR_DEVICE_PATH *MAC;
656 1.1.1.1.10.2 tls UINTN HwAddressSize;
657 1.1.1.1.10.2 tls UINTN Index;
658 1.1.1.1.10.2 tls
659 1.1.1.1.10.2 tls MAC = DevPath;
660 1.1.1.1.10.2 tls
661 1.1.1.1.10.2 tls HwAddressSize = sizeof(EFI_MAC_ADDRESS);
662 1.1.1.1.10.2 tls if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
663 1.1.1.1.10.2 tls HwAddressSize = 6;
664 1.1.1.1.10.2 tls }
665 1.1.1.1.10.2 tls
666 1.1.1.1.10.2 tls CatPrint(Str, L"Mac(");
667 1.1.1.1.10.2 tls
668 1.1.1.1.10.2 tls for(Index = 0; Index < HwAddressSize; Index++) {
669 1.1.1.1.10.2 tls CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
670 1.1.1.1.10.2 tls }
671 1.1.1.1.10.2 tls CatPrint(Str, L")");
672 1.1.1.1.10.2 tls }
673 1.1.1.1.10.2 tls
674 1.1.1.1.10.2 tls VOID
675 1.1.1.1.10.2 tls _DevPathIPv4 (
676 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
677 1.1.1.1.10.2 tls IN VOID *DevPath
678 1.1.1.1.10.2 tls )
679 1.1.1.1.10.2 tls {
680 1.1.1.1.10.3 jdolecek IPv4_DEVICE_PATH *IP __unused;
681 1.1.1.1.10.2 tls
682 1.1.1.1.10.2 tls IP = DevPath;
683 1.1.1.1.10.2 tls CatPrint(Str, L"IPv4(not-done)");
684 1.1.1.1.10.2 tls }
685 1.1.1.1.10.2 tls
686 1.1.1.1.10.2 tls VOID
687 1.1.1.1.10.2 tls _DevPathIPv6 (
688 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
689 1.1.1.1.10.2 tls IN VOID *DevPath
690 1.1.1.1.10.2 tls )
691 1.1.1.1.10.2 tls {
692 1.1.1.1.10.3 jdolecek IPv6_DEVICE_PATH *IP __unused;
693 1.1.1.1.10.2 tls
694 1.1.1.1.10.2 tls IP = DevPath;
695 1.1.1.1.10.2 tls CatPrint(Str, L"IP-v6(not-done)");
696 1.1.1.1.10.2 tls }
697 1.1.1.1.10.2 tls
698 1.1.1.1.10.2 tls VOID
699 1.1.1.1.10.2 tls _DevPathInfiniBand (
700 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
701 1.1.1.1.10.2 tls IN VOID *DevPath
702 1.1.1.1.10.2 tls )
703 1.1.1.1.10.2 tls {
704 1.1.1.1.10.3 jdolecek INFINIBAND_DEVICE_PATH *InfiniBand __unused;
705 1.1.1.1.10.2 tls
706 1.1.1.1.10.2 tls InfiniBand = DevPath;
707 1.1.1.1.10.2 tls CatPrint(Str, L"InfiniBand(not-done)");
708 1.1.1.1.10.2 tls }
709 1.1.1.1.10.2 tls
710 1.1.1.1.10.2 tls VOID
711 1.1.1.1.10.2 tls _DevPathUart (
712 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
713 1.1.1.1.10.2 tls IN VOID *DevPath
714 1.1.1.1.10.2 tls )
715 1.1.1.1.10.2 tls {
716 1.1.1.1.10.2 tls UART_DEVICE_PATH *Uart;
717 1.1.1.1.10.2 tls CHAR8 Parity;
718 1.1.1.1.10.2 tls
719 1.1.1.1.10.2 tls Uart = DevPath;
720 1.1.1.1.10.2 tls switch (Uart->Parity) {
721 1.1.1.1.10.2 tls case 0 : Parity = 'D'; break;
722 1.1.1.1.10.2 tls case 1 : Parity = 'N'; break;
723 1.1.1.1.10.2 tls case 2 : Parity = 'E'; break;
724 1.1.1.1.10.2 tls case 3 : Parity = 'O'; break;
725 1.1.1.1.10.2 tls case 4 : Parity = 'M'; break;
726 1.1.1.1.10.2 tls case 5 : Parity = 'S'; break;
727 1.1.1.1.10.2 tls default : Parity = 'x'; break;
728 1.1.1.1.10.2 tls }
729 1.1.1.1.10.2 tls
730 1.1.1.1.10.2 tls if (Uart->BaudRate == 0) {
731 1.1.1.1.10.2 tls CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity);
732 1.1.1.1.10.2 tls } else {
733 1.1.1.1.10.2 tls CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity);
734 1.1.1.1.10.2 tls }
735 1.1.1.1.10.2 tls
736 1.1.1.1.10.2 tls if (Uart->DataBits == 0) {
737 1.1.1.1.10.2 tls CatPrint(Str, L"D");
738 1.1.1.1.10.2 tls } else {
739 1.1.1.1.10.2 tls CatPrint(Str, L"%d",Uart->DataBits);
740 1.1.1.1.10.2 tls }
741 1.1.1.1.10.2 tls
742 1.1.1.1.10.2 tls switch (Uart->StopBits) {
743 1.1.1.1.10.2 tls case 0 : CatPrint(Str, L"D)"); break;
744 1.1.1.1.10.2 tls case 1 : CatPrint(Str, L"1)"); break;
745 1.1.1.1.10.2 tls case 2 : CatPrint(Str, L"1.5)"); break;
746 1.1.1.1.10.2 tls case 3 : CatPrint(Str, L"2)"); break;
747 1.1.1.1.10.2 tls default : CatPrint(Str, L"x)"); break;
748 1.1.1.1.10.2 tls }
749 1.1.1.1.10.2 tls }
750 1.1.1.1.10.2 tls
751 1.1.1.1.10.2 tls
752 1.1.1.1.10.2 tls VOID
753 1.1.1.1.10.2 tls _DevPathHardDrive (
754 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
755 1.1.1.1.10.2 tls IN VOID *DevPath
756 1.1.1.1.10.2 tls )
757 1.1.1.1.10.2 tls {
758 1.1.1.1.10.2 tls HARDDRIVE_DEVICE_PATH *Hd;
759 1.1.1.1.10.2 tls
760 1.1.1.1.10.2 tls Hd = DevPath;
761 1.1.1.1.10.2 tls switch (Hd->SignatureType) {
762 1.1.1.1.10.2 tls case SIGNATURE_TYPE_MBR:
763 1.1.1.1.10.2 tls CatPrint(Str, L"HD(Part%d,Sig%08X)",
764 1.1.1.1.10.2 tls Hd->PartitionNumber,
765 1.1.1.1.10.2 tls *((UINT32 *)(&(Hd->Signature[0])))
766 1.1.1.1.10.2 tls );
767 1.1.1.1.10.2 tls break;
768 1.1.1.1.10.2 tls case SIGNATURE_TYPE_GUID:
769 1.1.1.1.10.2 tls CatPrint(Str, L"HD(Part%d,Sig%g)",
770 1.1.1.1.10.2 tls Hd->PartitionNumber,
771 1.1.1.1.10.2 tls (EFI_GUID *) &(Hd->Signature[0])
772 1.1.1.1.10.2 tls );
773 1.1.1.1.10.2 tls break;
774 1.1.1.1.10.2 tls default:
775 1.1.1.1.10.2 tls CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)",
776 1.1.1.1.10.2 tls Hd->PartitionNumber,
777 1.1.1.1.10.2 tls Hd->MBRType,
778 1.1.1.1.10.2 tls Hd->SignatureType
779 1.1.1.1.10.2 tls );
780 1.1.1.1.10.2 tls break;
781 1.1.1.1.10.2 tls }
782 1.1.1.1.10.2 tls }
783 1.1.1.1.10.2 tls
784 1.1.1.1.10.2 tls VOID
785 1.1.1.1.10.2 tls _DevPathCDROM (
786 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
787 1.1.1.1.10.2 tls IN VOID *DevPath
788 1.1.1.1.10.2 tls )
789 1.1.1.1.10.2 tls {
790 1.1.1.1.10.2 tls CDROM_DEVICE_PATH *Cd;
791 1.1.1.1.10.2 tls
792 1.1.1.1.10.2 tls Cd = DevPath;
793 1.1.1.1.10.2 tls CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry);
794 1.1.1.1.10.2 tls }
795 1.1.1.1.10.2 tls
796 1.1.1.1.10.2 tls VOID
797 1.1.1.1.10.2 tls _DevPathFilePath (
798 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
799 1.1.1.1.10.2 tls IN VOID *DevPath
800 1.1.1.1.10.2 tls )
801 1.1.1.1.10.2 tls {
802 1.1.1.1.10.2 tls FILEPATH_DEVICE_PATH *Fp;
803 1.1.1.1.10.2 tls
804 1.1.1.1.10.2 tls Fp = DevPath;
805 1.1.1.1.10.2 tls CatPrint(Str, L"%s", Fp->PathName);
806 1.1.1.1.10.2 tls }
807 1.1.1.1.10.2 tls
808 1.1.1.1.10.2 tls VOID
809 1.1.1.1.10.2 tls _DevPathMediaProtocol (
810 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
811 1.1.1.1.10.2 tls IN VOID *DevPath
812 1.1.1.1.10.2 tls )
813 1.1.1.1.10.2 tls {
814 1.1.1.1.10.2 tls MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
815 1.1.1.1.10.2 tls
816 1.1.1.1.10.2 tls MediaProt = DevPath;
817 1.1.1.1.10.2 tls CatPrint(Str, L"%g", &MediaProt->Protocol);
818 1.1.1.1.10.2 tls }
819 1.1.1.1.10.2 tls
820 1.1.1.1.10.2 tls VOID
821 1.1.1.1.10.2 tls _DevPathBssBss (
822 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
823 1.1.1.1.10.2 tls IN VOID *DevPath
824 1.1.1.1.10.2 tls )
825 1.1.1.1.10.2 tls {
826 1.1.1.1.10.2 tls BBS_BBS_DEVICE_PATH *Bss;
827 1.1.1.1.10.2 tls CHAR16 *Type;
828 1.1.1.1.10.2 tls
829 1.1.1.1.10.2 tls Bss = DevPath;
830 1.1.1.1.10.2 tls switch (Bss->DeviceType) {
831 1.1.1.1.10.2 tls case BBS_TYPE_FLOPPY: Type = L"Floppy"; break;
832 1.1.1.1.10.2 tls case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break;
833 1.1.1.1.10.2 tls case BBS_TYPE_CDROM: Type = L"CDROM"; break;
834 1.1.1.1.10.2 tls case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break;
835 1.1.1.1.10.2 tls case BBS_TYPE_USB: Type = L"Usb"; break;
836 1.1.1.1.10.2 tls case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break;
837 1.1.1.1.10.2 tls default: Type = L"?"; break;
838 1.1.1.1.10.2 tls }
839 1.1.1.1.10.2 tls
840 1.1.1.1.10.2 tls CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String);
841 1.1.1.1.10.2 tls }
842 1.1.1.1.10.2 tls
843 1.1.1.1.10.2 tls
844 1.1.1.1.10.2 tls VOID
845 1.1.1.1.10.2 tls _DevPathEndInstance (
846 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
847 1.1.1.1.10.2 tls IN VOID *DevPath
848 1.1.1.1.10.2 tls )
849 1.1.1.1.10.2 tls {
850 1.1.1.1.10.2 tls CatPrint(Str, L",");
851 1.1.1.1.10.2 tls }
852 1.1.1.1.10.2 tls
853 1.1.1.1.10.2 tls VOID
854 1.1.1.1.10.2 tls _DevPathNodeUnknown (
855 1.1.1.1.10.2 tls IN OUT POOL_PRINT *Str,
856 1.1.1.1.10.2 tls IN VOID *DevPath
857 1.1.1.1.10.2 tls )
858 1.1.1.1.10.2 tls {
859 1.1.1.1.10.2 tls CatPrint(Str, L"?");
860 1.1.1.1.10.2 tls }
861 1.1.1.1.10.2 tls
862 1.1.1.1.10.2 tls
863 1.1.1.1.10.2 tls struct {
864 1.1.1.1.10.2 tls UINT8 Type;
865 1.1.1.1.10.2 tls UINT8 SubType;
866 1.1.1.1.10.2 tls VOID (*Function)(POOL_PRINT *, VOID *);
867 1.1.1.1.10.2 tls } DevPathTable[] = {
868 1.1.1.1.10.2 tls { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci},
869 1.1.1.1.10.2 tls { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard},
870 1.1.1.1.10.2 tls { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap},
871 1.1.1.1.10.2 tls { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor},
872 1.1.1.1.10.2 tls { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController},
873 1.1.1.1.10.2 tls { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi},
874 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi},
875 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi},
876 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre},
877 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394},
878 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb},
879 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O},
880 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr},
881 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4},
882 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6},
883 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand},
884 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart},
885 1.1.1.1.10.2 tls { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor},
886 1.1.1.1.10.2 tls { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive},
887 1.1.1.1.10.2 tls { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM},
888 1.1.1.1.10.2 tls { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor},
889 1.1.1.1.10.2 tls { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath},
890 1.1.1.1.10.2 tls { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol},
891 1.1.1.1.10.2 tls { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss},
892 1.1.1.1.10.2 tls { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance},
893 1.1.1.1.10.2 tls { 0, 0, NULL}
894 1.1.1.1.10.2 tls };
895 1.1.1.1.10.2 tls
896 1.1.1.1.10.2 tls
897 1.1.1.1.10.2 tls CHAR16 *
898 1.1.1.1.10.2 tls DevicePathToStr (
899 1.1.1.1.10.2 tls EFI_DEVICE_PATH *DevPath
900 1.1.1.1.10.2 tls )
901 1.1.1.1.10.2 tls /*++
902 1.1.1.1.10.2 tls
903 1.1.1.1.10.2 tls Turns the Device Path into a printable string. Allcoates
904 1.1.1.1.10.2 tls the string from pool. The caller must FreePool the returned
905 1.1.1.1.10.2 tls string.
906 1.1.1.1.10.2 tls
907 1.1.1.1.10.2 tls --*/
908 1.1.1.1.10.2 tls {
909 1.1.1.1.10.2 tls POOL_PRINT Str;
910 1.1.1.1.10.2 tls EFI_DEVICE_PATH *DevPathNode;
911 1.1.1.1.10.2 tls VOID (*DumpNode)(POOL_PRINT *, VOID *);
912 1.1.1.1.10.2 tls UINTN Index, NewSize;
913 1.1.1.1.10.2 tls
914 1.1.1.1.10.2 tls ZeroMem(&Str, sizeof(Str));
915 1.1.1.1.10.2 tls
916 1.1.1.1.10.2 tls //
917 1.1.1.1.10.2 tls // Unpacked the device path
918 1.1.1.1.10.2 tls //
919 1.1.1.1.10.2 tls
920 1.1.1.1.10.2 tls DevPath = UnpackDevicePath(DevPath);
921 1.1.1.1.10.2 tls ASSERT (DevPath);
922 1.1.1.1.10.2 tls
923 1.1.1.1.10.2 tls
924 1.1.1.1.10.2 tls //
925 1.1.1.1.10.2 tls // Process each device path node
926 1.1.1.1.10.2 tls //
927 1.1.1.1.10.2 tls
928 1.1.1.1.10.2 tls DevPathNode = DevPath;
929 1.1.1.1.10.2 tls while (!IsDevicePathEnd(DevPathNode)) {
930 1.1.1.1.10.2 tls //
931 1.1.1.1.10.2 tls // Find the handler to dump this device path node
932 1.1.1.1.10.2 tls //
933 1.1.1.1.10.2 tls
934 1.1.1.1.10.2 tls DumpNode = NULL;
935 1.1.1.1.10.2 tls for (Index = 0; DevPathTable[Index].Function; Index += 1) {
936 1.1.1.1.10.2 tls
937 1.1.1.1.10.2 tls if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
938 1.1.1.1.10.2 tls DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
939 1.1.1.1.10.2 tls DumpNode = DevPathTable[Index].Function;
940 1.1.1.1.10.2 tls break;
941 1.1.1.1.10.2 tls }
942 1.1.1.1.10.2 tls }
943 1.1.1.1.10.2 tls
944 1.1.1.1.10.2 tls //
945 1.1.1.1.10.2 tls // If not found, use a generic function
946 1.1.1.1.10.2 tls //
947 1.1.1.1.10.2 tls
948 1.1.1.1.10.2 tls if (!DumpNode) {
949 1.1.1.1.10.2 tls DumpNode = _DevPathNodeUnknown;
950 1.1.1.1.10.2 tls }
951 1.1.1.1.10.2 tls
952 1.1.1.1.10.2 tls //
953 1.1.1.1.10.2 tls // Put a path seperator in if needed
954 1.1.1.1.10.2 tls //
955 1.1.1.1.10.2 tls
956 1.1.1.1.10.2 tls if (Str.len && DumpNode != _DevPathEndInstance) {
957 1.1.1.1.10.2 tls CatPrint (&Str, L"/");
958 1.1.1.1.10.2 tls }
959 1.1.1.1.10.2 tls
960 1.1.1.1.10.2 tls //
961 1.1.1.1.10.2 tls // Print this node of the device path
962 1.1.1.1.10.2 tls //
963 1.1.1.1.10.2 tls
964 1.1.1.1.10.2 tls DumpNode (&Str, DevPathNode);
965 1.1.1.1.10.2 tls
966 1.1.1.1.10.2 tls //
967 1.1.1.1.10.2 tls // Next device path node
968 1.1.1.1.10.2 tls //
969 1.1.1.1.10.2 tls
970 1.1.1.1.10.2 tls DevPathNode = NextDevicePathNode(DevPathNode);
971 1.1.1.1.10.2 tls }
972 1.1.1.1.10.2 tls
973 1.1.1.1.10.2 tls //
974 1.1.1.1.10.2 tls // Shrink pool used for string allocation
975 1.1.1.1.10.2 tls //
976 1.1.1.1.10.2 tls
977 1.1.1.1.10.2 tls FreePool (DevPath);
978 1.1.1.1.10.2 tls NewSize = (Str.len + 1) * sizeof(CHAR16);
979 1.1.1.1.10.2 tls Str.str = ReallocatePool (Str.str, NewSize, NewSize);
980 1.1.1.1.10.2 tls Str.str[Str.len] = 0;
981 1.1.1.1.10.2 tls return Str.str;
982 1.1.1.1.10.2 tls }
983 1.1.1.1.10.2 tls
984 1.1.1.1.10.2 tls BOOLEAN
985 1.1.1.1.10.2 tls LibMatchDevicePaths (
986 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Multi,
987 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *Single
988 1.1.1.1.10.2 tls )
989 1.1.1.1.10.2 tls {
990 1.1.1.1.10.2 tls EFI_DEVICE_PATH *DevicePath, *DevicePathInst;
991 1.1.1.1.10.2 tls UINTN Size;
992 1.1.1.1.10.2 tls
993 1.1.1.1.10.2 tls if (!Multi || !Single) {
994 1.1.1.1.10.2 tls return FALSE;
995 1.1.1.1.10.2 tls }
996 1.1.1.1.10.2 tls
997 1.1.1.1.10.2 tls DevicePath = Multi;
998 1.1.1.1.10.2 tls while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) {
999 1.1.1.1.10.2 tls if (CompareMem (Single, DevicePathInst, Size) == 0) {
1000 1.1.1.1.10.2 tls return TRUE;
1001 1.1.1.1.10.2 tls }
1002 1.1.1.1.10.2 tls }
1003 1.1.1.1.10.2 tls return FALSE;
1004 1.1.1.1.10.2 tls }
1005 1.1.1.1.10.2 tls
1006 1.1.1.1.10.2 tls EFI_DEVICE_PATH *
1007 1.1.1.1.10.2 tls LibDuplicateDevicePathInstance (
1008 1.1.1.1.10.2 tls IN EFI_DEVICE_PATH *DevPath
1009 1.1.1.1.10.2 tls )
1010 1.1.1.1.10.2 tls {
1011 1.1.1.1.10.2 tls EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp;
1012 1.1.1.1.10.2 tls UINTN Size;
1013 1.1.1.1.10.2 tls
1014 1.1.1.1.10.2 tls //
1015 1.1.1.1.10.2 tls // get the size of an instance from the input
1016 1.1.1.1.10.2 tls //
1017 1.1.1.1.10.2 tls
1018 1.1.1.1.10.2 tls Temp = DevPath;
1019 1.1.1.1.10.2 tls DevicePathInst = DevicePathInstance (&Temp, &Size);
1020 1.1.1.1.10.2 tls
1021 1.1.1.1.10.2 tls //
1022 1.1.1.1.10.2 tls // Make a copy and set proper end type
1023 1.1.1.1.10.2 tls //
1024 1.1.1.1.10.2 tls NewDevPath = NULL;
1025 1.1.1.1.10.2 tls if (Size) {
1026 1.1.1.1.10.2 tls NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
1027 1.1.1.1.10.2 tls }
1028 1.1.1.1.10.2 tls
1029 1.1.1.1.10.2 tls if (NewDevPath) {
1030 1.1.1.1.10.2 tls CopyMem (NewDevPath, DevicePathInst, Size);
1031 1.1.1.1.10.2 tls Temp = NextDevicePathNode(NewDevPath);
1032 1.1.1.1.10.2 tls SetDevicePathEndNode(Temp);
1033 1.1.1.1.10.2 tls }
1034 1.1.1.1.10.2 tls
1035 1.1.1.1.10.2 tls return NewDevPath;
1036 1.1.1.1.10.2 tls }
1037 1.1.1.1.10.2 tls
1038