1530d68baSNigel Croxon /*++
2530d68baSNigel Croxon
3530d68baSNigel Croxon Copyright (c) 1998 Intel Corporation
4530d68baSNigel Croxon
5530d68baSNigel Croxon Module Name:
6530d68baSNigel Croxon
7530d68baSNigel Croxon dpath.c
8530d68baSNigel Croxon
9530d68baSNigel Croxon Abstract:
10530d68baSNigel Croxon MBR & Device Path functions
11530d68baSNigel Croxon
12530d68baSNigel Croxon
13530d68baSNigel Croxon
14530d68baSNigel Croxon Revision History
15530d68baSNigel Croxon
16530d68baSNigel Croxon 2014/04 B.Burette - updated device path text representation, conforming to
17530d68baSNigel Croxon UEFI specification 2.4 (dec. 2013). More specifically:
18530d68baSNigel Croxon - § 9.3.5: added some media types ie. Sata()
19530d68baSNigel Croxon - § 9.6.1.2: Acpi(PNP0A03,0) makes more sense when displayed as PciRoot(0)
20530d68baSNigel Croxon - § 9.6.1.5: use commas (instead of '|') between option specific parameters
21530d68baSNigel Croxon - § 9.6.1.6: hex values in device paths must be preceded by "0x" or "0X"
22530d68baSNigel Croxon
23530d68baSNigel Croxon --*/
24530d68baSNigel Croxon
25530d68baSNigel Croxon #include "lib.h"
26530d68baSNigel Croxon
27530d68baSNigel Croxon #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
28530d68baSNigel Croxon
29530d68baSNigel Croxon
30530d68baSNigel Croxon
31530d68baSNigel Croxon EFI_DEVICE_PATH *
DevicePathFromHandle(IN EFI_HANDLE Handle)32530d68baSNigel Croxon DevicePathFromHandle (
33530d68baSNigel Croxon IN EFI_HANDLE Handle
34530d68baSNigel Croxon )
35530d68baSNigel Croxon {
36530d68baSNigel Croxon EFI_STATUS Status;
37530d68baSNigel Croxon EFI_DEVICE_PATH *DevicePath;
38530d68baSNigel Croxon
39530d68baSNigel Croxon Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath);
40530d68baSNigel Croxon if (EFI_ERROR(Status)) {
41530d68baSNigel Croxon DevicePath = NULL;
42530d68baSNigel Croxon }
43530d68baSNigel Croxon
44530d68baSNigel Croxon return DevicePath;
45530d68baSNigel Croxon }
46530d68baSNigel Croxon
47530d68baSNigel Croxon
48530d68baSNigel Croxon EFI_DEVICE_PATH *
DevicePathInstance(IN OUT EFI_DEVICE_PATH ** DevicePath,OUT UINTN * Size)49530d68baSNigel Croxon DevicePathInstance (
50530d68baSNigel Croxon IN OUT EFI_DEVICE_PATH **DevicePath,
51530d68baSNigel Croxon OUT UINTN *Size
52530d68baSNigel Croxon )
53530d68baSNigel Croxon {
54530d68baSNigel Croxon EFI_DEVICE_PATH *Start, *Next, *DevPath;
55530d68baSNigel Croxon UINTN Count;
56530d68baSNigel Croxon
57530d68baSNigel Croxon DevPath = *DevicePath;
58530d68baSNigel Croxon Start = DevPath;
59530d68baSNigel Croxon
60530d68baSNigel Croxon if (!DevPath) {
61530d68baSNigel Croxon return NULL;
62530d68baSNigel Croxon }
63530d68baSNigel Croxon
64530d68baSNigel Croxon //
65530d68baSNigel Croxon // Check for end of device path type
66530d68baSNigel Croxon //
67530d68baSNigel Croxon
68530d68baSNigel Croxon for (Count = 0; ; Count++) {
69530d68baSNigel Croxon Next = NextDevicePathNode(DevPath);
70530d68baSNigel Croxon
71530d68baSNigel Croxon if (IsDevicePathEndType(DevPath)) {
72530d68baSNigel Croxon break;
73530d68baSNigel Croxon }
74530d68baSNigel Croxon
75530d68baSNigel Croxon if (Count > 01000) {
76530d68baSNigel Croxon //
77530d68baSNigel Croxon // BugBug: Debug code to catch bogus device paths
78530d68baSNigel Croxon //
79530d68baSNigel Croxon DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
80530d68baSNigel Croxon DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
81530d68baSNigel Croxon break;
82530d68baSNigel Croxon }
83530d68baSNigel Croxon
84530d68baSNigel Croxon DevPath = Next;
85530d68baSNigel Croxon }
86530d68baSNigel Croxon
87530d68baSNigel Croxon ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
88530d68baSNigel Croxon DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
89530d68baSNigel Croxon
90530d68baSNigel Croxon //
91530d68baSNigel Croxon // Set next position
92530d68baSNigel Croxon //
93530d68baSNigel Croxon
94530d68baSNigel Croxon if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
95530d68baSNigel Croxon Next = NULL;
96530d68baSNigel Croxon }
97530d68baSNigel Croxon
98530d68baSNigel Croxon *DevicePath = Next;
99530d68baSNigel Croxon
100530d68baSNigel Croxon //
101530d68baSNigel Croxon // Return size and start of device path instance
102530d68baSNigel Croxon //
103530d68baSNigel Croxon
104530d68baSNigel Croxon *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start);
105530d68baSNigel Croxon return Start;
106530d68baSNigel Croxon }
107530d68baSNigel Croxon
108530d68baSNigel Croxon UINTN
DevicePathInstanceCount(IN EFI_DEVICE_PATH * DevicePath)109530d68baSNigel Croxon DevicePathInstanceCount (
110530d68baSNigel Croxon IN EFI_DEVICE_PATH *DevicePath
111530d68baSNigel Croxon )
112530d68baSNigel Croxon {
113530d68baSNigel Croxon UINTN Count, Size;
114530d68baSNigel Croxon
115530d68baSNigel Croxon Count = 0;
116530d68baSNigel Croxon while (DevicePathInstance(&DevicePath, &Size)) {
117530d68baSNigel Croxon Count += 1;
118530d68baSNigel Croxon }
119530d68baSNigel Croxon
120530d68baSNigel Croxon return Count;
121530d68baSNigel Croxon }
122530d68baSNigel Croxon
123530d68baSNigel Croxon
124530d68baSNigel Croxon EFI_DEVICE_PATH *
AppendDevicePath(IN EFI_DEVICE_PATH * Src1,IN EFI_DEVICE_PATH * Src2)125530d68baSNigel Croxon AppendDevicePath (
126530d68baSNigel Croxon IN EFI_DEVICE_PATH *Src1,
127530d68baSNigel Croxon IN EFI_DEVICE_PATH *Src2
128530d68baSNigel Croxon )
129530d68baSNigel Croxon // Src1 may have multiple "instances" and each instance is appended
130530d68baSNigel Croxon // Src2 is appended to each instance is Src1. (E.g., it's possible
131530d68baSNigel Croxon // to append a new instance to the complete device path by passing
132530d68baSNigel Croxon // it in Src2)
133530d68baSNigel Croxon {
134530d68baSNigel Croxon UINTN Src1Size, Src1Inst, Src2Size, Size;
135530d68baSNigel Croxon EFI_DEVICE_PATH *Dst, *Inst;
136530d68baSNigel Croxon UINT8 *DstPos;
137530d68baSNigel Croxon
138530d68baSNigel Croxon //
139530d68baSNigel Croxon // If there's only 1 path, just duplicate it
140530d68baSNigel Croxon //
141530d68baSNigel Croxon
142530d68baSNigel Croxon if (!Src1) {
143530d68baSNigel Croxon ASSERT (!IsDevicePathUnpacked (Src2));
144530d68baSNigel Croxon return DuplicateDevicePath (Src2);
145530d68baSNigel Croxon }
146530d68baSNigel Croxon
147530d68baSNigel Croxon if (!Src2) {
148530d68baSNigel Croxon ASSERT (!IsDevicePathUnpacked (Src1));
149530d68baSNigel Croxon return DuplicateDevicePath (Src1);
150530d68baSNigel Croxon }
151530d68baSNigel Croxon
152530d68baSNigel Croxon //
153530d68baSNigel Croxon // Verify we're not working with unpacked paths
154530d68baSNigel Croxon //
155530d68baSNigel Croxon
156530d68baSNigel Croxon // ASSERT (!IsDevicePathUnpacked (Src1));
157530d68baSNigel Croxon // ASSERT (!IsDevicePathUnpacked (Src2));
158530d68baSNigel Croxon
159530d68baSNigel Croxon //
160530d68baSNigel Croxon // Append Src2 to every instance in Src1
161530d68baSNigel Croxon //
162530d68baSNigel Croxon
163530d68baSNigel Croxon Src1Size = DevicePathSize(Src1);
164530d68baSNigel Croxon Src1Inst = DevicePathInstanceCount(Src1);
165530d68baSNigel Croxon Src2Size = DevicePathSize(Src2);
166530d68baSNigel Croxon Size = Src1Size * Src1Inst + Src2Size;
167530d68baSNigel Croxon
168530d68baSNigel Croxon Dst = AllocatePool (Size);
169530d68baSNigel Croxon if (Dst) {
170530d68baSNigel Croxon DstPos = (UINT8 *) Dst;
171530d68baSNigel Croxon
172530d68baSNigel Croxon //
173530d68baSNigel Croxon // Copy all device path instances
174530d68baSNigel Croxon //
175530d68baSNigel Croxon
176530d68baSNigel Croxon while ((Inst = DevicePathInstance (&Src1, &Size))) {
177530d68baSNigel Croxon
178530d68baSNigel Croxon CopyMem(DstPos, Inst, Size);
179530d68baSNigel Croxon DstPos += Size;
180530d68baSNigel Croxon
181530d68baSNigel Croxon CopyMem(DstPos, Src2, Src2Size);
182530d68baSNigel Croxon DstPos += Src2Size;
183530d68baSNigel Croxon
184530d68baSNigel Croxon CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH));
185530d68baSNigel Croxon DstPos += sizeof(EFI_DEVICE_PATH);
186530d68baSNigel Croxon }
187530d68baSNigel Croxon
188530d68baSNigel Croxon // Change last end marker
189530d68baSNigel Croxon DstPos -= sizeof(EFI_DEVICE_PATH);
190530d68baSNigel Croxon CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH));
191530d68baSNigel Croxon }
192530d68baSNigel Croxon
193530d68baSNigel Croxon return Dst;
194530d68baSNigel Croxon }
195530d68baSNigel Croxon
196530d68baSNigel Croxon
197530d68baSNigel Croxon EFI_DEVICE_PATH *
AppendDevicePathNode(IN EFI_DEVICE_PATH * Src1,IN EFI_DEVICE_PATH * Src2)198530d68baSNigel Croxon AppendDevicePathNode (
199530d68baSNigel Croxon IN EFI_DEVICE_PATH *Src1,
200530d68baSNigel Croxon IN EFI_DEVICE_PATH *Src2
201530d68baSNigel Croxon )
202530d68baSNigel Croxon // Src1 may have multiple "instances" and each instance is appended
203530d68baSNigel Croxon // Src2 is a signal device path node (without a terminator) that is
204530d68baSNigel Croxon // appended to each instance is Src1.
205530d68baSNigel Croxon {
206530d68baSNigel Croxon EFI_DEVICE_PATH *Temp, *Eop;
207530d68baSNigel Croxon UINTN Length;
208530d68baSNigel Croxon
209530d68baSNigel Croxon //
210530d68baSNigel Croxon // Build a Src2 that has a terminator on it
211530d68baSNigel Croxon //
212530d68baSNigel Croxon
213530d68baSNigel Croxon Length = DevicePathNodeLength(Src2);
214530d68baSNigel Croxon Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH));
215530d68baSNigel Croxon if (!Temp) {
216530d68baSNigel Croxon return NULL;
217530d68baSNigel Croxon }
218530d68baSNigel Croxon
219530d68baSNigel Croxon CopyMem (Temp, Src2, Length);
220530d68baSNigel Croxon Eop = NextDevicePathNode(Temp);
221530d68baSNigel Croxon SetDevicePathEndNode(Eop);
222530d68baSNigel Croxon
223530d68baSNigel Croxon //
224530d68baSNigel Croxon // Append device paths
225530d68baSNigel Croxon //
226530d68baSNigel Croxon
227530d68baSNigel Croxon Src1 = AppendDevicePath (Src1, Temp);
228530d68baSNigel Croxon FreePool (Temp);
229530d68baSNigel Croxon return Src1;
230530d68baSNigel Croxon }
231530d68baSNigel Croxon
232530d68baSNigel Croxon
233530d68baSNigel Croxon EFI_DEVICE_PATH *
FileDevicePath(IN EFI_HANDLE Device OPTIONAL,IN CHAR16 * FileName)234530d68baSNigel Croxon FileDevicePath (
235530d68baSNigel Croxon IN EFI_HANDLE Device OPTIONAL,
236530d68baSNigel Croxon IN CHAR16 *FileName
237530d68baSNigel Croxon )
238530d68baSNigel Croxon /*++
239530d68baSNigel Croxon
240530d68baSNigel Croxon N.B. Results are allocated from pool. The caller must FreePool
241530d68baSNigel Croxon the resulting device path structure
242530d68baSNigel Croxon
243530d68baSNigel Croxon --*/
244530d68baSNigel Croxon {
245530d68baSNigel Croxon UINTN Size;
246530d68baSNigel Croxon FILEPATH_DEVICE_PATH *FilePath;
247530d68baSNigel Croxon EFI_DEVICE_PATH *Eop, *DevicePath;
248530d68baSNigel Croxon
249530d68baSNigel Croxon Size = StrSize(FileName);
250530d68baSNigel Croxon FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH));
251530d68baSNigel Croxon DevicePath = NULL;
252530d68baSNigel Croxon
253530d68baSNigel Croxon if (FilePath) {
254530d68baSNigel Croxon
255530d68baSNigel Croxon //
256530d68baSNigel Croxon // Build a file path
257530d68baSNigel Croxon //
258530d68baSNigel Croxon
259530d68baSNigel Croxon FilePath->Header.Type = MEDIA_DEVICE_PATH;
260530d68baSNigel Croxon FilePath->Header.SubType = MEDIA_FILEPATH_DP;
261530d68baSNigel Croxon SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
262530d68baSNigel Croxon CopyMem (FilePath->PathName, FileName, Size);
263530d68baSNigel Croxon Eop = NextDevicePathNode(&FilePath->Header);
264530d68baSNigel Croxon SetDevicePathEndNode(Eop);
265530d68baSNigel Croxon
266530d68baSNigel Croxon //
267530d68baSNigel Croxon // Append file path to device's device path
268530d68baSNigel Croxon //
269530d68baSNigel Croxon
270530d68baSNigel Croxon DevicePath = (EFI_DEVICE_PATH *) FilePath;
271530d68baSNigel Croxon if (Device) {
272530d68baSNigel Croxon DevicePath = AppendDevicePath (
273530d68baSNigel Croxon DevicePathFromHandle(Device),
274530d68baSNigel Croxon DevicePath
275530d68baSNigel Croxon );
276530d68baSNigel Croxon
277530d68baSNigel Croxon FreePool(FilePath);
278530d68baSNigel Croxon }
279530d68baSNigel Croxon }
280530d68baSNigel Croxon
281530d68baSNigel Croxon return DevicePath;
282530d68baSNigel Croxon }
283530d68baSNigel Croxon
284530d68baSNigel Croxon
285530d68baSNigel Croxon
286530d68baSNigel Croxon UINTN
DevicePathSize(IN EFI_DEVICE_PATH * DevPath)287530d68baSNigel Croxon DevicePathSize (
288530d68baSNigel Croxon IN EFI_DEVICE_PATH *DevPath
289530d68baSNigel Croxon )
290530d68baSNigel Croxon {
291530d68baSNigel Croxon EFI_DEVICE_PATH *Start;
292530d68baSNigel Croxon
293530d68baSNigel Croxon //
294530d68baSNigel Croxon // Search for the end of the device path structure
295530d68baSNigel Croxon //
296530d68baSNigel Croxon
297530d68baSNigel Croxon Start = DevPath;
298530d68baSNigel Croxon while (!IsDevicePathEnd(DevPath)) {
299530d68baSNigel Croxon DevPath = NextDevicePathNode(DevPath);
300530d68baSNigel Croxon }
301530d68baSNigel Croxon
302530d68baSNigel Croxon //
303530d68baSNigel Croxon // Compute the size
304530d68baSNigel Croxon //
305530d68baSNigel Croxon
306530d68baSNigel Croxon return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH);
307530d68baSNigel Croxon }
308530d68baSNigel Croxon
309530d68baSNigel Croxon EFI_DEVICE_PATH *
DuplicateDevicePath(IN EFI_DEVICE_PATH * DevPath)310530d68baSNigel Croxon DuplicateDevicePath (
311530d68baSNigel Croxon IN EFI_DEVICE_PATH *DevPath
312530d68baSNigel Croxon )
313530d68baSNigel Croxon {
314530d68baSNigel Croxon EFI_DEVICE_PATH *NewDevPath;
315530d68baSNigel Croxon UINTN Size;
316530d68baSNigel Croxon
317530d68baSNigel Croxon
318530d68baSNigel Croxon //
319530d68baSNigel Croxon // Compute the size
320530d68baSNigel Croxon //
321530d68baSNigel Croxon
322530d68baSNigel Croxon Size = DevicePathSize (DevPath);
323530d68baSNigel Croxon
324530d68baSNigel Croxon //
325530d68baSNigel Croxon // Make a copy
326530d68baSNigel Croxon //
327530d68baSNigel Croxon
328530d68baSNigel Croxon NewDevPath = AllocatePool (Size);
329530d68baSNigel Croxon if (NewDevPath) {
330530d68baSNigel Croxon CopyMem (NewDevPath, DevPath, Size);
331530d68baSNigel Croxon }
332530d68baSNigel Croxon
333530d68baSNigel Croxon return NewDevPath;
334530d68baSNigel Croxon }
335530d68baSNigel Croxon
336530d68baSNigel Croxon EFI_DEVICE_PATH *
UnpackDevicePath(IN EFI_DEVICE_PATH * DevPath)337530d68baSNigel Croxon UnpackDevicePath (
338530d68baSNigel Croxon IN EFI_DEVICE_PATH *DevPath
339530d68baSNigel Croxon )
340530d68baSNigel Croxon {
341530d68baSNigel Croxon EFI_DEVICE_PATH *Src, *Dest, *NewPath;
342530d68baSNigel Croxon UINTN Size;
343530d68baSNigel Croxon
344530d68baSNigel Croxon //
345530d68baSNigel Croxon // Walk device path and round sizes to valid boundries
346530d68baSNigel Croxon //
347530d68baSNigel Croxon
348530d68baSNigel Croxon Src = DevPath;
349530d68baSNigel Croxon Size = 0;
350530d68baSNigel Croxon for (; ;) {
351530d68baSNigel Croxon Size += DevicePathNodeLength(Src);
352530d68baSNigel Croxon Size += ALIGN_SIZE(Size);
353530d68baSNigel Croxon
354530d68baSNigel Croxon if (IsDevicePathEnd(Src)) {
355530d68baSNigel Croxon break;
356530d68baSNigel Croxon }
357530d68baSNigel Croxon
358530d68baSNigel Croxon Src = NextDevicePathNode(Src);
359530d68baSNigel Croxon }
360530d68baSNigel Croxon
361530d68baSNigel Croxon
362530d68baSNigel Croxon //
363530d68baSNigel Croxon // Allocate space for the unpacked path
364530d68baSNigel Croxon //
365530d68baSNigel Croxon
366530d68baSNigel Croxon NewPath = AllocateZeroPool (Size);
367530d68baSNigel Croxon if (NewPath) {
368530d68baSNigel Croxon
369530d68baSNigel Croxon ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0);
370530d68baSNigel Croxon
371530d68baSNigel Croxon //
372530d68baSNigel Croxon // Copy each node
373530d68baSNigel Croxon //
374530d68baSNigel Croxon
375530d68baSNigel Croxon Src = DevPath;
376530d68baSNigel Croxon Dest = NewPath;
377530d68baSNigel Croxon for (; ;) {
378530d68baSNigel Croxon Size = DevicePathNodeLength(Src);
379530d68baSNigel Croxon CopyMem (Dest, Src, Size);
380530d68baSNigel Croxon Size += ALIGN_SIZE(Size);
381530d68baSNigel Croxon SetDevicePathNodeLength (Dest, Size);
382530d68baSNigel Croxon Dest->Type |= EFI_DP_TYPE_UNPACKED;
383530d68baSNigel Croxon Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size);
384530d68baSNigel Croxon
385530d68baSNigel Croxon if (IsDevicePathEnd(Src)) {
386530d68baSNigel Croxon break;
387530d68baSNigel Croxon }
388530d68baSNigel Croxon
389530d68baSNigel Croxon Src = NextDevicePathNode(Src);
390530d68baSNigel Croxon }
391530d68baSNigel Croxon }
392530d68baSNigel Croxon
393530d68baSNigel Croxon return NewPath;
394530d68baSNigel Croxon }
395530d68baSNigel Croxon
396530d68baSNigel Croxon
397530d68baSNigel Croxon EFI_DEVICE_PATH*
AppendDevicePathInstance(IN EFI_DEVICE_PATH * Src,IN EFI_DEVICE_PATH * Instance)398530d68baSNigel Croxon AppendDevicePathInstance (
399530d68baSNigel Croxon IN EFI_DEVICE_PATH *Src,
400530d68baSNigel Croxon IN EFI_DEVICE_PATH *Instance
401530d68baSNigel Croxon )
402530d68baSNigel Croxon {
403530d68baSNigel Croxon UINT8 *Ptr;
404530d68baSNigel Croxon EFI_DEVICE_PATH *DevPath;
405530d68baSNigel Croxon UINTN SrcSize;
406530d68baSNigel Croxon UINTN InstanceSize;
407530d68baSNigel Croxon
408530d68baSNigel Croxon if (Src == NULL) {
409530d68baSNigel Croxon return DuplicateDevicePath (Instance);
410530d68baSNigel Croxon }
411530d68baSNigel Croxon SrcSize = DevicePathSize(Src);
412530d68baSNigel Croxon InstanceSize = DevicePathSize(Instance);
413530d68baSNigel Croxon Ptr = AllocatePool (SrcSize + InstanceSize);
414530d68baSNigel Croxon DevPath = (EFI_DEVICE_PATH *)Ptr;
415530d68baSNigel Croxon ASSERT(DevPath);
416530d68baSNigel Croxon
417530d68baSNigel Croxon CopyMem (Ptr, Src, SrcSize);
418530d68baSNigel Croxon // FreePool (Src);
419530d68baSNigel Croxon
420530d68baSNigel Croxon while (!IsDevicePathEnd(DevPath)) {
421530d68baSNigel Croxon DevPath = NextDevicePathNode(DevPath);
422530d68baSNigel Croxon }
423530d68baSNigel Croxon //
424530d68baSNigel Croxon // Convert the End to an End Instance, since we are
425530d68baSNigel Croxon // appending another instacne after this one its a good
426530d68baSNigel Croxon // idea.
427530d68baSNigel Croxon //
428530d68baSNigel Croxon DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
429530d68baSNigel Croxon
430530d68baSNigel Croxon DevPath = NextDevicePathNode(DevPath);
431530d68baSNigel Croxon CopyMem (DevPath, Instance, InstanceSize);
432530d68baSNigel Croxon return (EFI_DEVICE_PATH *)Ptr;
433530d68baSNigel Croxon }
434530d68baSNigel Croxon
435530d68baSNigel Croxon EFI_STATUS
LibDevicePathToInterface(IN EFI_GUID * Protocol,IN EFI_DEVICE_PATH * FilePath,OUT VOID ** Interface)436530d68baSNigel Croxon LibDevicePathToInterface (
437530d68baSNigel Croxon IN EFI_GUID *Protocol,
438530d68baSNigel Croxon IN EFI_DEVICE_PATH *FilePath,
439530d68baSNigel Croxon OUT VOID **Interface
440530d68baSNigel Croxon )
441530d68baSNigel Croxon {
442530d68baSNigel Croxon EFI_STATUS Status;
443530d68baSNigel Croxon EFI_HANDLE Device;
444530d68baSNigel Croxon
445530d68baSNigel Croxon Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device);
446530d68baSNigel Croxon
447530d68baSNigel Croxon if (!EFI_ERROR(Status)) {
448530d68baSNigel Croxon
449530d68baSNigel Croxon // If we didn't get a direct match return not found
450530d68baSNigel Croxon Status = EFI_NOT_FOUND;
451530d68baSNigel Croxon
452530d68baSNigel Croxon if (IsDevicePathEnd(FilePath)) {
453530d68baSNigel Croxon
454530d68baSNigel Croxon //
455530d68baSNigel Croxon // It was a direct match, lookup the protocol interface
456530d68baSNigel Croxon //
457530d68baSNigel Croxon
458530d68baSNigel Croxon Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface);
459530d68baSNigel Croxon }
460530d68baSNigel Croxon }
461530d68baSNigel Croxon
462530d68baSNigel Croxon //
463530d68baSNigel Croxon // If there was an error, do not return an interface
464530d68baSNigel Croxon //
465530d68baSNigel Croxon
466530d68baSNigel Croxon if (EFI_ERROR(Status)) {
467530d68baSNigel Croxon *Interface = NULL;
468530d68baSNigel Croxon }
469530d68baSNigel Croxon
470530d68baSNigel Croxon return Status;
471530d68baSNigel Croxon }
472530d68baSNigel Croxon
473530d68baSNigel Croxon static VOID
_DevPathPci(IN OUT POOL_PRINT * Str,IN VOID * DevPath)474530d68baSNigel Croxon _DevPathPci (
475530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
476530d68baSNigel Croxon IN VOID *DevPath
477530d68baSNigel Croxon )
478530d68baSNigel Croxon {
479530d68baSNigel Croxon PCI_DEVICE_PATH *Pci;
480530d68baSNigel Croxon
481530d68baSNigel Croxon Pci = DevPath;
482530d68baSNigel Croxon CatPrint(Str, L"Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
483530d68baSNigel Croxon }
484530d68baSNigel Croxon
485530d68baSNigel Croxon static VOID
_DevPathPccard(IN OUT POOL_PRINT * Str,IN VOID * DevPath)486530d68baSNigel Croxon _DevPathPccard (
487530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
488530d68baSNigel Croxon IN VOID *DevPath
489530d68baSNigel Croxon )
490530d68baSNigel Croxon {
491530d68baSNigel Croxon PCCARD_DEVICE_PATH *Pccard;
492530d68baSNigel Croxon
493530d68baSNigel Croxon Pccard = DevPath;
494530d68baSNigel Croxon CatPrint(Str, L"Pccard(0x%x)", Pccard-> FunctionNumber );
495530d68baSNigel Croxon }
496530d68baSNigel Croxon
497530d68baSNigel Croxon static VOID
_DevPathMemMap(IN OUT POOL_PRINT * Str,IN VOID * DevPath)498530d68baSNigel Croxon _DevPathMemMap (
499530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
500530d68baSNigel Croxon IN VOID *DevPath
501530d68baSNigel Croxon )
502530d68baSNigel Croxon {
503530d68baSNigel Croxon MEMMAP_DEVICE_PATH *MemMap;
504530d68baSNigel Croxon
505530d68baSNigel Croxon MemMap = DevPath;
506530d68baSNigel Croxon CatPrint(Str, L"MemMap(%d,0x%x,0x%x)",
507530d68baSNigel Croxon MemMap->MemoryType,
508530d68baSNigel Croxon MemMap->StartingAddress,
509530d68baSNigel Croxon MemMap->EndingAddress
510530d68baSNigel Croxon );
511530d68baSNigel Croxon }
512530d68baSNigel Croxon
513530d68baSNigel Croxon static VOID
_DevPathController(IN OUT POOL_PRINT * Str,IN VOID * DevPath)514530d68baSNigel Croxon _DevPathController (
515530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
516530d68baSNigel Croxon IN VOID *DevPath
517530d68baSNigel Croxon )
518530d68baSNigel Croxon {
519530d68baSNigel Croxon CONTROLLER_DEVICE_PATH *Controller;
520530d68baSNigel Croxon
521530d68baSNigel Croxon Controller = DevPath;
522530d68baSNigel Croxon CatPrint(Str, L"Ctrl(%d)",
523530d68baSNigel Croxon Controller->Controller
524530d68baSNigel Croxon );
525530d68baSNigel Croxon }
526530d68baSNigel Croxon
527530d68baSNigel Croxon static VOID
_DevPathVendor(IN OUT POOL_PRINT * Str,IN VOID * DevPath)528530d68baSNigel Croxon _DevPathVendor (
529530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
530530d68baSNigel Croxon IN VOID *DevPath
531530d68baSNigel Croxon )
532530d68baSNigel Croxon {
533530d68baSNigel Croxon VENDOR_DEVICE_PATH *Vendor;
534530d68baSNigel Croxon CHAR16 *Type;
535530d68baSNigel Croxon UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath;
536530d68baSNigel Croxon
537530d68baSNigel Croxon Vendor = DevPath;
538530d68baSNigel Croxon switch (DevicePathType(&Vendor->Header)) {
539530d68baSNigel Croxon case HARDWARE_DEVICE_PATH: Type = L"Hw"; break;
540530d68baSNigel Croxon case MESSAGING_DEVICE_PATH: Type = L"Msg"; break;
541530d68baSNigel Croxon case MEDIA_DEVICE_PATH: Type = L"Media"; break;
542530d68baSNigel Croxon default: Type = L"?"; break;
543530d68baSNigel Croxon }
544530d68baSNigel Croxon
545530d68baSNigel Croxon CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid);
546530d68baSNigel Croxon if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) {
547530d68baSNigel Croxon //
548530d68baSNigel Croxon // GUID used by EFI to enumerate an EDD 1.1 device
549530d68baSNigel Croxon //
550530d68baSNigel Croxon UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor;
551530d68baSNigel Croxon CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
552530d68baSNigel Croxon } else {
553530d68baSNigel Croxon CatPrint(Str, L")");
554530d68baSNigel Croxon }
555530d68baSNigel Croxon }
556530d68baSNigel Croxon
557530d68baSNigel Croxon
558530d68baSNigel Croxon /*
559530d68baSNigel Croxon Type: 2 (ACPI Device Path) SubType: 1 (ACPI Device Path)
560530d68baSNigel Croxon */
561530d68baSNigel Croxon static VOID
_DevPathAcpi(IN OUT POOL_PRINT * Str,IN VOID * DevPath)562530d68baSNigel Croxon _DevPathAcpi (
563530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
564530d68baSNigel Croxon IN VOID *DevPath
565530d68baSNigel Croxon )
566530d68baSNigel Croxon {
567530d68baSNigel Croxon ACPI_HID_DEVICE_PATH *Acpi;
568530d68baSNigel Croxon
569530d68baSNigel Croxon Acpi = DevPath;
570530d68baSNigel Croxon if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
571530d68baSNigel Croxon switch ( EISA_ID_TO_NUM( Acpi-> HID ) ) {
572530d68baSNigel Croxon case 0x301 : {
573530d68baSNigel Croxon CatPrint( Str , L"Keyboard(%d)" , Acpi-> UID ) ;
574530d68baSNigel Croxon break ;
575530d68baSNigel Croxon }
576530d68baSNigel Croxon case 0x401 : {
577530d68baSNigel Croxon CatPrint( Str , L"ParallelPort(%d)" , Acpi-> UID ) ;
578530d68baSNigel Croxon break ;
579530d68baSNigel Croxon }
580530d68baSNigel Croxon case 0x501 : {
581530d68baSNigel Croxon CatPrint( Str , L"Serial(%d)" , Acpi-> UID ) ;
582530d68baSNigel Croxon break ;
583530d68baSNigel Croxon }
584530d68baSNigel Croxon case 0x604 : {
585530d68baSNigel Croxon CatPrint( Str , L"Floppy(%d)" , Acpi-> UID ) ;
586530d68baSNigel Croxon break ;
587530d68baSNigel Croxon }
588530d68baSNigel Croxon case 0xa03 : {
589530d68baSNigel Croxon CatPrint( Str , L"PciRoot(%d)" , Acpi-> UID ) ;
590530d68baSNigel Croxon break ;
591530d68baSNigel Croxon }
592530d68baSNigel Croxon case 0xa08 : {
593530d68baSNigel Croxon CatPrint( Str , L"PcieRoot(%d)" , Acpi-> UID ) ;
594530d68baSNigel Croxon break ;
595530d68baSNigel Croxon }
596530d68baSNigel Croxon default : {
597530d68baSNigel Croxon CatPrint( Str , L"Acpi(PNP%04x" , EISA_ID_TO_NUM( Acpi-> HID ) ) ;
598530d68baSNigel Croxon if ( Acpi-> UID ) CatPrint( Str , L",%d" , Acpi-> UID ) ;
599530d68baSNigel Croxon CatPrint( Str , L")" ) ;
600530d68baSNigel Croxon break ;
601530d68baSNigel Croxon }
602530d68baSNigel Croxon }
603530d68baSNigel Croxon } else {
604530d68baSNigel Croxon CatPrint( Str , L"Acpi(0x%X" , Acpi-> HID ) ;
605530d68baSNigel Croxon if ( Acpi-> UID ) CatPrint( Str , L",%d" , Acpi-> UID ) ;
606530d68baSNigel Croxon CatPrint( Str , L")" , Acpi-> HID , Acpi-> UID ) ;
607530d68baSNigel Croxon }
608530d68baSNigel Croxon }
609530d68baSNigel Croxon
610530d68baSNigel Croxon
611530d68baSNigel Croxon static VOID
_DevPathAtapi(IN OUT POOL_PRINT * Str,IN VOID * DevPath)612530d68baSNigel Croxon _DevPathAtapi (
613530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
614530d68baSNigel Croxon IN VOID *DevPath
615530d68baSNigel Croxon )
616530d68baSNigel Croxon {
617530d68baSNigel Croxon ATAPI_DEVICE_PATH *Atapi;
618530d68baSNigel Croxon
619530d68baSNigel Croxon Atapi = DevPath;
620530d68baSNigel Croxon CatPrint(Str, L"Ata(%s,%s)",
621530d68baSNigel Croxon Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
622530d68baSNigel Croxon Atapi->SlaveMaster ? L"Slave" : L"Master"
623530d68baSNigel Croxon );
624530d68baSNigel Croxon }
625530d68baSNigel Croxon
626530d68baSNigel Croxon static VOID
_DevPathScsi(IN OUT POOL_PRINT * Str,IN VOID * DevPath)627530d68baSNigel Croxon _DevPathScsi (
628530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
629530d68baSNigel Croxon IN VOID *DevPath
630530d68baSNigel Croxon )
631530d68baSNigel Croxon {
632530d68baSNigel Croxon SCSI_DEVICE_PATH *Scsi;
633530d68baSNigel Croxon
634530d68baSNigel Croxon Scsi = DevPath;
635530d68baSNigel Croxon CatPrint(Str, L"Scsi(%d,%d)", Scsi->Pun, Scsi->Lun);
636530d68baSNigel Croxon }
637530d68baSNigel Croxon
638530d68baSNigel Croxon
639530d68baSNigel Croxon static VOID
_DevPathFibre(IN OUT POOL_PRINT * Str,IN VOID * DevPath)640530d68baSNigel Croxon _DevPathFibre (
641530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
642530d68baSNigel Croxon IN VOID *DevPath
643530d68baSNigel Croxon )
644530d68baSNigel Croxon {
645530d68baSNigel Croxon FIBRECHANNEL_DEVICE_PATH *Fibre;
646530d68baSNigel Croxon
647530d68baSNigel Croxon Fibre = DevPath;
648530d68baSNigel Croxon CatPrint( Str , L"Fibre%s(0x%016lx,0x%016lx)" ,
649530d68baSNigel Croxon DevicePathType( & Fibre-> Header ) == MSG_FIBRECHANNEL_DP ? L"" : L"Ex" ,
650530d68baSNigel Croxon Fibre-> WWN , Fibre-> Lun ) ;
651530d68baSNigel Croxon }
652530d68baSNigel Croxon
653530d68baSNigel Croxon static VOID
_DevPath1394(IN OUT POOL_PRINT * Str,IN VOID * DevPath)654530d68baSNigel Croxon _DevPath1394 (
655530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
656530d68baSNigel Croxon IN VOID *DevPath
657530d68baSNigel Croxon )
658530d68baSNigel Croxon {
659530d68baSNigel Croxon F1394_DEVICE_PATH *F1394;
660530d68baSNigel Croxon
661530d68baSNigel Croxon F1394 = DevPath;
662d34132e6SNigel Croxon // Guid has format of IEEE-EUI64
663d34132e6SNigel Croxon CatPrint(Str, L"I1394(%016lx)", F1394->Guid);
664530d68baSNigel Croxon }
665530d68baSNigel Croxon
666530d68baSNigel Croxon
667530d68baSNigel Croxon
668530d68baSNigel Croxon static VOID
_DevPathUsb(IN OUT POOL_PRINT * Str,IN VOID * DevPath)669530d68baSNigel Croxon _DevPathUsb (
670530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
671530d68baSNigel Croxon IN VOID *DevPath
672530d68baSNigel Croxon )
673530d68baSNigel Croxon {
674530d68baSNigel Croxon USB_DEVICE_PATH *Usb;
675530d68baSNigel Croxon
676530d68baSNigel Croxon Usb = DevPath;
677530d68baSNigel Croxon CatPrint( Str , L"Usb(0x%x,0x%x)" , Usb-> Port , Usb-> Endpoint ) ;
678530d68baSNigel Croxon }
679530d68baSNigel Croxon
680530d68baSNigel Croxon
681530d68baSNigel Croxon static VOID
_DevPathI2O(IN OUT POOL_PRINT * Str,IN VOID * DevPath)682530d68baSNigel Croxon _DevPathI2O (
683530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
684530d68baSNigel Croxon IN VOID *DevPath
685530d68baSNigel Croxon )
686530d68baSNigel Croxon {
687530d68baSNigel Croxon I2O_DEVICE_PATH *I2O;
688530d68baSNigel Croxon
689530d68baSNigel Croxon I2O = DevPath;
690530d68baSNigel Croxon CatPrint(Str, L"I2O(0x%X)", I2O->Tid);
691530d68baSNigel Croxon }
692530d68baSNigel Croxon
693530d68baSNigel Croxon static VOID
_DevPathMacAddr(IN OUT POOL_PRINT * Str,IN VOID * DevPath)694530d68baSNigel Croxon _DevPathMacAddr (
695530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
696530d68baSNigel Croxon IN VOID *DevPath
697530d68baSNigel Croxon )
698530d68baSNigel Croxon {
699530d68baSNigel Croxon MAC_ADDR_DEVICE_PATH *MAC;
700530d68baSNigel Croxon UINTN HwAddressSize;
701530d68baSNigel Croxon UINTN Index;
702530d68baSNigel Croxon
703530d68baSNigel Croxon MAC = DevPath;
704530d68baSNigel Croxon
705530d68baSNigel Croxon /* HwAddressSize = sizeof(EFI_MAC_ADDRESS); */
706530d68baSNigel Croxon HwAddressSize = DevicePathNodeLength( & MAC-> Header ) ;
707530d68baSNigel Croxon HwAddressSize -= sizeof( MAC-> Header ) ;
708530d68baSNigel Croxon HwAddressSize -= sizeof( MAC-> IfType ) ;
709530d68baSNigel Croxon if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
710530d68baSNigel Croxon HwAddressSize = 6;
711530d68baSNigel Croxon }
712530d68baSNigel Croxon
713530d68baSNigel Croxon CatPrint(Str, L"Mac(");
714530d68baSNigel Croxon
715530d68baSNigel Croxon for(Index = 0; Index < HwAddressSize; Index++) {
716530d68baSNigel Croxon CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
717530d68baSNigel Croxon }
718530d68baSNigel Croxon if ( MAC-> IfType != 0 ) {
719530d68baSNigel Croxon CatPrint(Str, L",%d" , MAC-> IfType ) ;
720530d68baSNigel Croxon }
721530d68baSNigel Croxon CatPrint(Str, L")");
722530d68baSNigel Croxon }
723530d68baSNigel Croxon
724530d68baSNigel Croxon static VOID
CatPrintIPv4(IN OUT POOL_PRINT * Str,IN EFI_IPv4_ADDRESS * Address)725530d68baSNigel Croxon CatPrintIPv4(
726530d68baSNigel Croxon IN OUT POOL_PRINT * Str ,
727530d68baSNigel Croxon IN EFI_IPv4_ADDRESS * Address
728530d68baSNigel Croxon )
729530d68baSNigel Croxon {
730530d68baSNigel Croxon CatPrint( Str , L"%d.%d.%d.%d" , Address-> Addr[ 0 ] , Address-> Addr[ 1 ] ,
731530d68baSNigel Croxon Address-> Addr[ 2 ] , Address-> Addr[ 3 ] ) ;
732530d68baSNigel Croxon }
733530d68baSNigel Croxon
734530d68baSNigel Croxon static BOOLEAN
IsNotNullIPv4(IN EFI_IPv4_ADDRESS * Address)735530d68baSNigel Croxon IsNotNullIPv4(
736530d68baSNigel Croxon IN EFI_IPv4_ADDRESS * Address
737530d68baSNigel Croxon )
738530d68baSNigel Croxon {
739530d68baSNigel Croxon UINT8 val ;
740530d68baSNigel Croxon val = Address-> Addr[ 0 ] | Address-> Addr[ 1 ] ;
741530d68baSNigel Croxon val |= Address-> Addr[ 2 ] | Address-> Addr[ 3 ] ;
742530d68baSNigel Croxon return val != 0 ;
743530d68baSNigel Croxon }
744530d68baSNigel Croxon
745530d68baSNigel Croxon static VOID
CatPrintNetworkProtocol(IN OUT POOL_PRINT * Str,IN UINT16 Proto)746530d68baSNigel Croxon CatPrintNetworkProtocol(
747530d68baSNigel Croxon IN OUT POOL_PRINT * Str ,
748530d68baSNigel Croxon IN UINT16 Proto
749530d68baSNigel Croxon )
750530d68baSNigel Croxon {
751530d68baSNigel Croxon if ( Proto == 6 ) {
752530d68baSNigel Croxon CatPrint( Str , L"TCP" ) ;
753530d68baSNigel Croxon } else if ( Proto == 17 ) {
754530d68baSNigel Croxon CatPrint( Str , L"UDP" ) ;
755530d68baSNigel Croxon } else {
756530d68baSNigel Croxon CatPrint( Str , L"%d" , Proto ) ;
757530d68baSNigel Croxon }
758530d68baSNigel Croxon }
759530d68baSNigel Croxon
760530d68baSNigel Croxon static VOID
_DevPathIPv4(IN OUT POOL_PRINT * Str,IN VOID * DevPath)761530d68baSNigel Croxon _DevPathIPv4 (
762530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
763530d68baSNigel Croxon IN VOID *DevPath
764530d68baSNigel Croxon )
765530d68baSNigel Croxon {
766530d68baSNigel Croxon IPv4_DEVICE_PATH *IP;
767530d68baSNigel Croxon BOOLEAN show ;
768530d68baSNigel Croxon
769530d68baSNigel Croxon IP = DevPath;
770530d68baSNigel Croxon CatPrint( Str , L"IPv4(") ;
771530d68baSNigel Croxon CatPrintIPv4( Str , & IP-> RemoteIpAddress ) ;
772530d68baSNigel Croxon CatPrint( Str , L",") ;
773530d68baSNigel Croxon CatPrintNetworkProtocol( Str , IP-> Protocol ) ;
774530d68baSNigel Croxon CatPrint( Str , L",%s" , IP-> StaticIpAddress ? L"Static" : L"DHCP" ) ;
775530d68baSNigel Croxon show = IsNotNullIPv4( & IP-> LocalIpAddress ) ;
776530d68baSNigel Croxon if ( ! show && DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) {
777530d68baSNigel Croxon /* only version 2 includes gateway and netmask */
778530d68baSNigel Croxon show |= IsNotNullIPv4( & IP-> GatewayIpAddress ) ;
779530d68baSNigel Croxon show |= IsNotNullIPv4( & IP-> SubnetMask ) ;
780530d68baSNigel Croxon }
781530d68baSNigel Croxon if ( show ) {
782530d68baSNigel Croxon CatPrint( Str , L"," ) ;
783530d68baSNigel Croxon CatPrintIPv4( Str , & IP-> LocalIpAddress ) ;
784530d68baSNigel Croxon if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) {
785530d68baSNigel Croxon /* only version 2 includes gateway and netmask */
786530d68baSNigel Croxon show = IsNotNullIPv4( & IP-> GatewayIpAddress ) ;
787530d68baSNigel Croxon show |= IsNotNullIPv4( & IP-> SubnetMask ) ;
788530d68baSNigel Croxon if ( show ) {
789530d68baSNigel Croxon CatPrint( Str , L",") ;
790530d68baSNigel Croxon CatPrintIPv4( Str , & IP-> GatewayIpAddress ) ;
791530d68baSNigel Croxon if ( IsNotNullIPv4( & IP-> SubnetMask ) ) {
792530d68baSNigel Croxon CatPrint( Str , L",") ;
793530d68baSNigel Croxon CatPrintIPv4( Str , & IP-> SubnetMask ) ;
794530d68baSNigel Croxon }
795530d68baSNigel Croxon }
796530d68baSNigel Croxon }
797530d68baSNigel Croxon }
798530d68baSNigel Croxon CatPrint( Str , L")") ;
799530d68baSNigel Croxon }
800530d68baSNigel Croxon
801530d68baSNigel Croxon #define CatPrintIPv6_ADD( x , y ) ( ( (UINT16) ( x ) ) << 8 | ( y ) )
802530d68baSNigel Croxon static VOID
CatPrintIPv6(IN OUT POOL_PRINT * Str,IN EFI_IPv6_ADDRESS * Address)803530d68baSNigel Croxon CatPrintIPv6(
804530d68baSNigel Croxon IN OUT POOL_PRINT * Str ,
805530d68baSNigel Croxon IN EFI_IPv6_ADDRESS * Address
806530d68baSNigel Croxon )
807530d68baSNigel Croxon {
808530d68baSNigel Croxon CatPrint( Str , L"%x:%x:%x:%x:%x:%x:%x:%x" ,
809530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 0 ] , Address-> Addr[ 1 ] ) ,
810530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 2 ] , Address-> Addr[ 3 ] ) ,
811530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 4 ] , Address-> Addr[ 5 ] ) ,
812530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 6 ] , Address-> Addr[ 7 ] ) ,
813530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 8 ] , Address-> Addr[ 9 ] ) ,
814530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 10 ] , Address-> Addr[ 11 ] ) ,
815530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 12 ] , Address-> Addr[ 13 ] ) ,
816530d68baSNigel Croxon CatPrintIPv6_ADD( Address-> Addr[ 14 ] , Address-> Addr[ 15 ] ) ) ;
817530d68baSNigel Croxon }
818530d68baSNigel Croxon
819530d68baSNigel Croxon static VOID
_DevPathIPv6(IN OUT POOL_PRINT * Str,IN VOID * DevPath)820530d68baSNigel Croxon _DevPathIPv6 (
821530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
822530d68baSNigel Croxon IN VOID *DevPath
823530d68baSNigel Croxon )
824530d68baSNigel Croxon {
825530d68baSNigel Croxon IPv6_DEVICE_PATH *IP;
826530d68baSNigel Croxon
827530d68baSNigel Croxon IP = DevPath;
828530d68baSNigel Croxon CatPrint( Str , L"IPv6(") ;
829530d68baSNigel Croxon CatPrintIPv6( Str , & IP-> RemoteIpAddress ) ;
830530d68baSNigel Croxon CatPrint( Str , L",") ;
831530d68baSNigel Croxon CatPrintNetworkProtocol( Str, IP-> Protocol ) ;
832530d68baSNigel Croxon CatPrint( Str , L",%s," , IP-> IPAddressOrigin ?
833530d68baSNigel Croxon ( IP-> IPAddressOrigin == 1 ? L"StatelessAutoConfigure" :
834530d68baSNigel Croxon L"StatefulAutoConfigure" ) : L"Static" ) ;
835530d68baSNigel Croxon CatPrintIPv6( Str , & IP-> LocalIpAddress ) ;
836530d68baSNigel Croxon if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv6_DEVICE_PATH ) ) {
837530d68baSNigel Croxon CatPrint( Str , L",") ;
838530d68baSNigel Croxon CatPrintIPv6( Str , & IP-> GatewayIpAddress ) ;
839530d68baSNigel Croxon CatPrint( Str , L",") ;
840530d68baSNigel Croxon CatPrint( Str , L"%d" , & IP-> PrefixLength ) ;
841530d68baSNigel Croxon }
842530d68baSNigel Croxon CatPrint( Str , L")") ;
843530d68baSNigel Croxon }
844530d68baSNigel Croxon
845530d68baSNigel Croxon static VOID
_DevPathUri(IN OUT POOL_PRINT * Str,IN VOID * DevPath)846ad7f0d4bSNigel Croxon _DevPathUri (
847ad7f0d4bSNigel Croxon IN OUT POOL_PRINT *Str,
848ad7f0d4bSNigel Croxon IN VOID *DevPath
849ad7f0d4bSNigel Croxon )
850ad7f0d4bSNigel Croxon {
851ad7f0d4bSNigel Croxon URI_DEVICE_PATH *Uri;
852ad7f0d4bSNigel Croxon
853ad7f0d4bSNigel Croxon Uri = DevPath;
854ad7f0d4bSNigel Croxon
855ad7f0d4bSNigel Croxon CatPrint( Str, L"Uri(%a)", Uri->Uri );
856ad7f0d4bSNigel Croxon }
857ad7f0d4bSNigel Croxon
858ad7f0d4bSNigel Croxon static VOID
_DevPathInfiniBand(IN OUT POOL_PRINT * Str,IN VOID * DevPath)859530d68baSNigel Croxon _DevPathInfiniBand (
860530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
861530d68baSNigel Croxon IN VOID *DevPath
862530d68baSNigel Croxon )
863530d68baSNigel Croxon {
864530d68baSNigel Croxon INFINIBAND_DEVICE_PATH *InfiniBand;
865530d68baSNigel Croxon
866530d68baSNigel Croxon InfiniBand = DevPath;
867530d68baSNigel Croxon CatPrint(Str, L"Infiniband(0x%x,%g,0x%lx,0x%lx,0x%lx)",
868530d68baSNigel Croxon InfiniBand->ResourceFlags, InfiniBand->PortGid, InfiniBand->ServiceId,
869530d68baSNigel Croxon InfiniBand->TargetPortId, InfiniBand->DeviceId);
870530d68baSNigel Croxon }
871530d68baSNigel Croxon
872530d68baSNigel Croxon static VOID
_DevPathUart(IN OUT POOL_PRINT * Str,IN VOID * DevPath)873530d68baSNigel Croxon _DevPathUart (
874530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
875530d68baSNigel Croxon IN VOID *DevPath
876530d68baSNigel Croxon )
877530d68baSNigel Croxon {
878530d68baSNigel Croxon UART_DEVICE_PATH *Uart;
879530d68baSNigel Croxon CHAR8 Parity;
880530d68baSNigel Croxon
881530d68baSNigel Croxon Uart = DevPath;
882530d68baSNigel Croxon switch (Uart->Parity) {
883530d68baSNigel Croxon case 0 : Parity = 'D'; break;
884530d68baSNigel Croxon case 1 : Parity = 'N'; break;
885530d68baSNigel Croxon case 2 : Parity = 'E'; break;
886530d68baSNigel Croxon case 3 : Parity = 'O'; break;
887530d68baSNigel Croxon case 4 : Parity = 'M'; break;
888530d68baSNigel Croxon case 5 : Parity = 'S'; break;
889530d68baSNigel Croxon default : Parity = 'x'; break;
890530d68baSNigel Croxon }
891530d68baSNigel Croxon
892530d68baSNigel Croxon if (Uart->BaudRate == 0) {
893d34132e6SNigel Croxon CatPrint(Str, L"Uart(DEFAULT,");
894530d68baSNigel Croxon } else {
895d34132e6SNigel Croxon CatPrint(Str, L"Uart(%ld,", Uart->BaudRate);
896530d68baSNigel Croxon }
897530d68baSNigel Croxon
898530d68baSNigel Croxon if (Uart->DataBits == 0) {
899d34132e6SNigel Croxon CatPrint(Str, L"DEFAULT,");
900530d68baSNigel Croxon } else {
901d34132e6SNigel Croxon CatPrint(Str, L"%d,", Uart->DataBits);
902530d68baSNigel Croxon }
903530d68baSNigel Croxon
904d34132e6SNigel Croxon CatPrint(Str, L"%c,", Parity);
905d34132e6SNigel Croxon
906530d68baSNigel Croxon switch (Uart->StopBits) {
907530d68baSNigel Croxon case 0 : CatPrint(Str, L"D)"); break;
908530d68baSNigel Croxon case 1 : CatPrint(Str, L"1)"); break;
909530d68baSNigel Croxon case 2 : CatPrint(Str, L"1.5)"); break;
910530d68baSNigel Croxon case 3 : CatPrint(Str, L"2)"); break;
911530d68baSNigel Croxon default : CatPrint(Str, L"x)"); break;
912530d68baSNigel Croxon }
913530d68baSNigel Croxon }
914530d68baSNigel Croxon
915530d68baSNigel Croxon static VOID
_DevPathSata(IN OUT POOL_PRINT * Str,IN VOID * DevPath)916530d68baSNigel Croxon _DevPathSata (
917530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
918530d68baSNigel Croxon IN VOID *DevPath
919530d68baSNigel Croxon )
920530d68baSNigel Croxon {
921530d68baSNigel Croxon SATA_DEVICE_PATH * Sata ;
922530d68baSNigel Croxon
923530d68baSNigel Croxon Sata = DevPath;
924530d68baSNigel Croxon CatPrint( Str , L"Sata(0x%x,0x%x,0x%x)" , Sata-> HBAPortNumber ,
925530d68baSNigel Croxon Sata-> PortMultiplierPortNumber , Sata-> Lun ) ;
926530d68baSNigel Croxon }
927530d68baSNigel Croxon
928530d68baSNigel Croxon static VOID
_DevPathHardDrive(IN OUT POOL_PRINT * Str,IN VOID * DevPath)929530d68baSNigel Croxon _DevPathHardDrive (
930530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
931530d68baSNigel Croxon IN VOID *DevPath
932530d68baSNigel Croxon )
933530d68baSNigel Croxon {
934530d68baSNigel Croxon HARDDRIVE_DEVICE_PATH *Hd;
935530d68baSNigel Croxon
936530d68baSNigel Croxon Hd = DevPath;
937530d68baSNigel Croxon switch (Hd->SignatureType) {
938530d68baSNigel Croxon case SIGNATURE_TYPE_MBR:
939d34132e6SNigel Croxon CatPrint(Str, L"HD(%d,MBR,0x%08x)",
940530d68baSNigel Croxon Hd->PartitionNumber,
941530d68baSNigel Croxon *((UINT32 *)(&(Hd->Signature[0])))
942530d68baSNigel Croxon );
943530d68baSNigel Croxon break;
944530d68baSNigel Croxon case SIGNATURE_TYPE_GUID:
945d34132e6SNigel Croxon CatPrint(Str, L"HD(%d,GPT,%g)",
946530d68baSNigel Croxon Hd->PartitionNumber,
947530d68baSNigel Croxon (EFI_GUID *) &(Hd->Signature[0])
948530d68baSNigel Croxon );
949530d68baSNigel Croxon break;
950530d68baSNigel Croxon default:
951d34132e6SNigel Croxon CatPrint(Str, L"HD(%d,%d,0)",
952530d68baSNigel Croxon Hd->PartitionNumber,
953530d68baSNigel Croxon Hd->SignatureType
954530d68baSNigel Croxon );
955530d68baSNigel Croxon break;
956530d68baSNigel Croxon }
957530d68baSNigel Croxon }
958530d68baSNigel Croxon
959530d68baSNigel Croxon static VOID
_DevPathCDROM(IN OUT POOL_PRINT * Str,IN VOID * DevPath)960530d68baSNigel Croxon _DevPathCDROM (
961530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
962530d68baSNigel Croxon IN VOID *DevPath
963530d68baSNigel Croxon )
964530d68baSNigel Croxon {
965530d68baSNigel Croxon CDROM_DEVICE_PATH *Cd;
966530d68baSNigel Croxon
967530d68baSNigel Croxon Cd = DevPath;
968530d68baSNigel Croxon CatPrint( Str , L"CDROM(0x%x)" , Cd-> BootEntry ) ;
969530d68baSNigel Croxon }
970530d68baSNigel Croxon
971530d68baSNigel Croxon static VOID
_DevPathFilePath(IN OUT POOL_PRINT * Str,IN VOID * DevPath)972530d68baSNigel Croxon _DevPathFilePath (
973530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
974530d68baSNigel Croxon IN VOID *DevPath
975530d68baSNigel Croxon )
976530d68baSNigel Croxon {
977530d68baSNigel Croxon FILEPATH_DEVICE_PATH *Fp;
978530d68baSNigel Croxon
979530d68baSNigel Croxon Fp = DevPath;
980530d68baSNigel Croxon CatPrint(Str, L"%s", Fp->PathName);
981530d68baSNigel Croxon }
982530d68baSNigel Croxon
983530d68baSNigel Croxon static VOID
_DevPathMediaProtocol(IN OUT POOL_PRINT * Str,IN VOID * DevPath)984530d68baSNigel Croxon _DevPathMediaProtocol (
985530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
986530d68baSNigel Croxon IN VOID *DevPath
987530d68baSNigel Croxon )
988530d68baSNigel Croxon {
989530d68baSNigel Croxon MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
990530d68baSNigel Croxon
991530d68baSNigel Croxon MediaProt = DevPath;
992530d68baSNigel Croxon CatPrint(Str, L"%g", &MediaProt->Protocol);
993530d68baSNigel Croxon }
994530d68baSNigel Croxon
995530d68baSNigel Croxon static VOID
_DevPathBssBss(IN OUT POOL_PRINT * Str,IN VOID * DevPath)996530d68baSNigel Croxon _DevPathBssBss (
997530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
998530d68baSNigel Croxon IN VOID *DevPath
999530d68baSNigel Croxon )
1000530d68baSNigel Croxon {
1001530d68baSNigel Croxon BBS_BBS_DEVICE_PATH *Bss;
1002530d68baSNigel Croxon CHAR16 *Type;
1003530d68baSNigel Croxon
1004530d68baSNigel Croxon Bss = DevPath;
1005530d68baSNigel Croxon switch (Bss->DeviceType) {
1006530d68baSNigel Croxon case BBS_TYPE_FLOPPY: Type = L"Floppy"; break;
1007530d68baSNigel Croxon case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break;
1008530d68baSNigel Croxon case BBS_TYPE_CDROM: Type = L"CDROM"; break;
1009530d68baSNigel Croxon case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break;
1010530d68baSNigel Croxon case BBS_TYPE_USB: Type = L"Usb"; break;
1011530d68baSNigel Croxon case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break;
1012530d68baSNigel Croxon default: Type = L"?"; break;
1013530d68baSNigel Croxon }
1014530d68baSNigel Croxon
1015530d68baSNigel Croxon CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String);
1016530d68baSNigel Croxon }
1017530d68baSNigel Croxon
1018530d68baSNigel Croxon
1019530d68baSNigel Croxon static VOID
_DevPathEndInstance(IN OUT POOL_PRINT * Str,IN VOID * DevPath EFI_UNUSED)1020530d68baSNigel Croxon _DevPathEndInstance (
1021530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
10225ff74ecaSNigel Croxon IN VOID *DevPath EFI_UNUSED
1023530d68baSNigel Croxon )
1024530d68baSNigel Croxon {
1025530d68baSNigel Croxon CatPrint(Str, L",");
1026530d68baSNigel Croxon }
1027530d68baSNigel Croxon
1028530d68baSNigel Croxon /**
1029530d68baSNigel Croxon * Print unknown device node.
1030530d68baSNigel Croxon * UEFI 2.4 § 9.6.1.6 table 89.
1031530d68baSNigel Croxon */
1032530d68baSNigel Croxon
1033530d68baSNigel Croxon static VOID
_DevPathNodeUnknown(IN OUT POOL_PRINT * Str,IN VOID * DevPath)1034530d68baSNigel Croxon _DevPathNodeUnknown (
1035530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
1036530d68baSNigel Croxon IN VOID *DevPath
1037530d68baSNigel Croxon )
1038530d68baSNigel Croxon {
1039530d68baSNigel Croxon EFI_DEVICE_PATH * Path ;
1040530d68baSNigel Croxon UINT8 * value ;
1041530d68baSNigel Croxon int length , index ;
1042530d68baSNigel Croxon Path = DevPath ;
1043530d68baSNigel Croxon value = DevPath ;
1044530d68baSNigel Croxon value += 4 ;
1045530d68baSNigel Croxon switch ( Path-> Type ) {
1046530d68baSNigel Croxon case HARDWARE_DEVICE_PATH : { /* Unknown Hardware Device Path */
1047530d68baSNigel Croxon CatPrint( Str , L"HardwarePath(%d" , Path-> SubType ) ;
1048530d68baSNigel Croxon break ;
1049530d68baSNigel Croxon }
1050530d68baSNigel Croxon case ACPI_DEVICE_PATH : { /* Unknown ACPI Device Path */
1051530d68baSNigel Croxon CatPrint( Str , L"AcpiPath(%d" , Path-> SubType ) ;
1052530d68baSNigel Croxon break ;
1053530d68baSNigel Croxon }
1054530d68baSNigel Croxon case MESSAGING_DEVICE_PATH : { /* Unknown Messaging Device Path */
1055530d68baSNigel Croxon CatPrint( Str , L"Msg(%d" , Path-> SubType ) ;
1056530d68baSNigel Croxon break ;
1057530d68baSNigel Croxon }
1058530d68baSNigel Croxon case MEDIA_DEVICE_PATH : { /* Unknown Media Device Path */
1059530d68baSNigel Croxon CatPrint( Str , L"MediaPath(%d" , Path-> SubType ) ;
1060530d68baSNigel Croxon break ;
1061530d68baSNigel Croxon }
1062530d68baSNigel Croxon case BBS_DEVICE_PATH : { /* Unknown BIOS Boot Specification Device Path */
1063530d68baSNigel Croxon CatPrint( Str , L"BbsPath(%d" , Path-> SubType ) ;
1064530d68baSNigel Croxon break ;
1065530d68baSNigel Croxon }
1066530d68baSNigel Croxon default : { /* Unknown Device Path */
1067530d68baSNigel Croxon CatPrint( Str , L"Path(%d,%d" , Path-> Type , Path-> SubType ) ;
1068530d68baSNigel Croxon break ;
1069530d68baSNigel Croxon }
1070530d68baSNigel Croxon }
1071530d68baSNigel Croxon length = DevicePathNodeLength( Path ) ;
1072530d68baSNigel Croxon for ( index = 0 ; index < length ; index ++ ) {
1073530d68baSNigel Croxon if ( index == 0 ) CatPrint( Str , L",0x" ) ;
1074530d68baSNigel Croxon CatPrint( Str , L"%02x" , * value ) ;
1075530d68baSNigel Croxon value ++ ;
1076530d68baSNigel Croxon }
1077530d68baSNigel Croxon CatPrint( Str , L")" ) ;
1078530d68baSNigel Croxon }
1079530d68baSNigel Croxon
1080530d68baSNigel Croxon
1081530d68baSNigel Croxon /*
1082530d68baSNigel Croxon * Table to convert "Type" and "SubType" to a "convert to text" function/
1083530d68baSNigel Croxon * Entries hold "Type" and "SubType" for know values.
1084530d68baSNigel Croxon * Special "SubType" 0 is used as default for known type with unknown subtype.
1085530d68baSNigel Croxon */
1086*99730f29SCallum Farmer typedef struct {
1087530d68baSNigel Croxon UINT8 Type;
1088530d68baSNigel Croxon UINT8 SubType;
1089530d68baSNigel Croxon VOID (*Function)(POOL_PRINT *, VOID *);
1090*99730f29SCallum Farmer } DevPathTable_Type;
1091*99730f29SCallum Farmer DevPathTable_Type DevPathTable[] = {
1092530d68baSNigel Croxon { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci},
1093530d68baSNigel Croxon { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard},
1094530d68baSNigel Croxon { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap},
1095530d68baSNigel Croxon { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor},
1096530d68baSNigel Croxon { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController},
1097530d68baSNigel Croxon { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi},
1098530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi},
1099530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi},
1100530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre},
1101530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394},
1102530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb},
1103530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O},
1104530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr},
1105530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4},
1106530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6},
1107ad7f0d4bSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_URI_DP, _DevPathUri},
1108530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand},
1109530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart},
1110530d68baSNigel Croxon { MESSAGING_DEVICE_PATH , MSG_SATA_DP , _DevPathSata } ,
1111530d68baSNigel Croxon { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor},
1112530d68baSNigel Croxon { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive},
1113530d68baSNigel Croxon { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM},
1114530d68baSNigel Croxon { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor},
1115530d68baSNigel Croxon { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath},
1116530d68baSNigel Croxon { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol},
1117530d68baSNigel Croxon { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss},
1118530d68baSNigel Croxon { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance},
1119530d68baSNigel Croxon { 0, 0, NULL}
1120530d68baSNigel Croxon };
1121530d68baSNigel Croxon
1122530d68baSNigel Croxon
1123530d68baSNigel Croxon CHAR16 *
DevicePathToStr(EFI_DEVICE_PATH * DevPath)1124530d68baSNigel Croxon DevicePathToStr (
1125530d68baSNigel Croxon EFI_DEVICE_PATH *DevPath
1126530d68baSNigel Croxon )
1127530d68baSNigel Croxon /*++
1128530d68baSNigel Croxon
1129530d68baSNigel Croxon Turns the Device Path into a printable string. Allcoates
1130530d68baSNigel Croxon the string from pool. The caller must FreePool the returned
1131530d68baSNigel Croxon string.
1132530d68baSNigel Croxon
1133530d68baSNigel Croxon --*/
1134530d68baSNigel Croxon {
1135530d68baSNigel Croxon POOL_PRINT Str;
1136530d68baSNigel Croxon EFI_DEVICE_PATH *DevPathNode;
1137530d68baSNigel Croxon VOID (*DumpNode)(POOL_PRINT *, VOID *);
1138530d68baSNigel Croxon UINTN Index, NewSize;
1139530d68baSNigel Croxon
1140530d68baSNigel Croxon ZeroMem(&Str, sizeof(Str));
1141530d68baSNigel Croxon
1142530d68baSNigel Croxon //
1143530d68baSNigel Croxon // Unpacked the device path
1144530d68baSNigel Croxon //
1145530d68baSNigel Croxon
1146530d68baSNigel Croxon DevPath = UnpackDevicePath(DevPath);
1147530d68baSNigel Croxon ASSERT (DevPath);
1148530d68baSNigel Croxon
1149530d68baSNigel Croxon
1150530d68baSNigel Croxon //
1151530d68baSNigel Croxon // Process each device path node
1152530d68baSNigel Croxon //
1153530d68baSNigel Croxon
1154530d68baSNigel Croxon DevPathNode = DevPath;
1155530d68baSNigel Croxon while (!IsDevicePathEnd(DevPathNode)) {
1156530d68baSNigel Croxon //
1157530d68baSNigel Croxon // Find the handler to dump this device path node
1158530d68baSNigel Croxon //
1159530d68baSNigel Croxon
1160530d68baSNigel Croxon DumpNode = NULL;
1161530d68baSNigel Croxon for (Index = 0; DevPathTable[Index].Function; Index += 1) {
1162530d68baSNigel Croxon
1163530d68baSNigel Croxon if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
1164530d68baSNigel Croxon DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
1165530d68baSNigel Croxon DumpNode = DevPathTable[Index].Function;
1166530d68baSNigel Croxon break;
1167530d68baSNigel Croxon }
1168530d68baSNigel Croxon }
1169530d68baSNigel Croxon
1170530d68baSNigel Croxon //
1171530d68baSNigel Croxon // If not found, use a generic function
1172530d68baSNigel Croxon //
1173530d68baSNigel Croxon
1174530d68baSNigel Croxon if (!DumpNode) {
1175530d68baSNigel Croxon DumpNode = _DevPathNodeUnknown;
1176530d68baSNigel Croxon }
1177530d68baSNigel Croxon
1178530d68baSNigel Croxon //
1179530d68baSNigel Croxon // Put a path seperator in if needed
1180530d68baSNigel Croxon //
1181530d68baSNigel Croxon
1182530d68baSNigel Croxon if (Str.len && DumpNode != _DevPathEndInstance) {
1183530d68baSNigel Croxon CatPrint (&Str, L"/");
1184530d68baSNigel Croxon }
1185530d68baSNigel Croxon
1186530d68baSNigel Croxon //
1187530d68baSNigel Croxon // Print this node of the device path
1188530d68baSNigel Croxon //
1189530d68baSNigel Croxon
1190530d68baSNigel Croxon DumpNode (&Str, DevPathNode);
1191530d68baSNigel Croxon
1192530d68baSNigel Croxon //
1193530d68baSNigel Croxon // Next device path node
1194530d68baSNigel Croxon //
1195530d68baSNigel Croxon
1196530d68baSNigel Croxon DevPathNode = NextDevicePathNode(DevPathNode);
1197530d68baSNigel Croxon }
1198530d68baSNigel Croxon
1199530d68baSNigel Croxon //
1200530d68baSNigel Croxon // Shrink pool used for string allocation
1201530d68baSNigel Croxon //
1202530d68baSNigel Croxon
1203530d68baSNigel Croxon FreePool (DevPath);
1204530d68baSNigel Croxon NewSize = (Str.len + 1) * sizeof(CHAR16);
1205530d68baSNigel Croxon Str.str = ReallocatePool (Str.str, NewSize, NewSize);
1206530d68baSNigel Croxon Str.str[Str.len] = 0;
1207530d68baSNigel Croxon return Str.str;
1208530d68baSNigel Croxon }
1209530d68baSNigel Croxon
1210530d68baSNigel Croxon BOOLEAN
LibMatchDevicePaths(IN EFI_DEVICE_PATH * Multi,IN EFI_DEVICE_PATH * Single)1211530d68baSNigel Croxon LibMatchDevicePaths (
1212530d68baSNigel Croxon IN EFI_DEVICE_PATH *Multi,
1213530d68baSNigel Croxon IN EFI_DEVICE_PATH *Single
1214530d68baSNigel Croxon )
1215530d68baSNigel Croxon {
1216530d68baSNigel Croxon EFI_DEVICE_PATH *DevicePath, *DevicePathInst;
1217530d68baSNigel Croxon UINTN Size;
1218530d68baSNigel Croxon
1219530d68baSNigel Croxon if (!Multi || !Single) {
1220530d68baSNigel Croxon return FALSE;
1221530d68baSNigel Croxon }
1222530d68baSNigel Croxon
1223530d68baSNigel Croxon DevicePath = Multi;
1224530d68baSNigel Croxon while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) {
1225530d68baSNigel Croxon if (CompareMem (Single, DevicePathInst, Size) == 0) {
1226530d68baSNigel Croxon return TRUE;
1227530d68baSNigel Croxon }
1228530d68baSNigel Croxon }
1229530d68baSNigel Croxon return FALSE;
1230530d68baSNigel Croxon }
1231530d68baSNigel Croxon
1232530d68baSNigel Croxon EFI_DEVICE_PATH *
LibDuplicateDevicePathInstance(IN EFI_DEVICE_PATH * DevPath)1233530d68baSNigel Croxon LibDuplicateDevicePathInstance (
1234530d68baSNigel Croxon IN EFI_DEVICE_PATH *DevPath
1235530d68baSNigel Croxon )
1236530d68baSNigel Croxon {
1237530d68baSNigel Croxon EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp;
1238530d68baSNigel Croxon UINTN Size = 0;
1239530d68baSNigel Croxon
1240530d68baSNigel Croxon //
1241530d68baSNigel Croxon // get the size of an instance from the input
1242530d68baSNigel Croxon //
1243530d68baSNigel Croxon
1244530d68baSNigel Croxon Temp = DevPath;
1245530d68baSNigel Croxon DevicePathInst = DevicePathInstance (&Temp, &Size);
1246530d68baSNigel Croxon
1247530d68baSNigel Croxon //
1248530d68baSNigel Croxon // Make a copy and set proper end type
1249530d68baSNigel Croxon //
1250530d68baSNigel Croxon NewDevPath = NULL;
1251530d68baSNigel Croxon if (Size) {
1252530d68baSNigel Croxon NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
1253530d68baSNigel Croxon }
1254530d68baSNigel Croxon
1255530d68baSNigel Croxon if (NewDevPath) {
1256530d68baSNigel Croxon CopyMem (NewDevPath, DevicePathInst, Size);
1257530d68baSNigel Croxon Temp = NextDevicePathNode(NewDevPath);
1258530d68baSNigel Croxon SetDevicePathEndNode(Temp);
1259530d68baSNigel Croxon }
1260530d68baSNigel Croxon
1261530d68baSNigel Croxon return NewDevPath;
1262530d68baSNigel Croxon }
1263530d68baSNigel Croxon
1264