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