4 Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #define __STDC_FORMAT_MACROS
29 #include <netinet/in.h>
32 #include "unparse_path.h"
35 /* Avoid unaligned access warnings */
36 #define get(buf, obj) *(typeof(obj) *)memcpy(buf, &obj, sizeof(obj))
40 dump_raw_data(void *data, uint64_t length)
42 char buffer1[80], buffer2[80], *b1, *b2, c;
43 unsigned char *p = data;
44 unsigned long column=0;
45 uint64_t length_printed = 0;
46 const char maxcolumn = 16;
47 while (length_printed < length) {
51 column < maxcolumn && length_printed < length;
53 b1 += sprintf(b1, "%02x ",(unsigned int) *p);
54 if (*p < 32 || *p > 126) c = '.';
56 b2 += sprintf(b2, "%c", c);
60 /* pad out the line */
61 for (; column < maxcolumn; column++)
63 b1 += sprintf(b1, " ");
64 b2 += sprintf(b2, " ");
67 printf("%s\t%s\n", buffer1, buffer2);
74 unparse_raw(char *buffer, uint8_t *p, uint64_t length)
79 for (i=0; i<length; i++) {
80 q += sprintf(q, "%02x", get(a, p[i]));
86 unparse_raw_text(char *buffer, uint8_t *p, uint64_t length)
88 uint64_t i; unsigned char c;
90 for (i=0; i<length; i++) {
92 if (c < 32 || c > 127) c = '.';
93 q += sprintf(q, "%c", c);
99 unparse_ipv4_port(char *buffer, uint32_t ipaddr, uint16_t port)
102 // ipaddr = nltoh(ipaddr);
103 // port = nstoh(port);
104 ip = (unsigned char *)&ipaddr;
105 return sprintf(buffer, "%hhu.%hhu.%hhu.%hhu:%hu",
106 ip[0], ip[1], ip[2], ip[3],
112 unparse_acpi_path(char *buffer, EFI_DEVICE_PATH *path)
114 ACPI_DEVICE_PATH *acpi = (ACPI_DEVICE_PATH *)path;
117 switch (path->subtype) {
119 return sprintf(buffer, "ACPI(%x,%x)", get(a, acpi->_HID), get(b, acpi->_UID));
122 return unparse_raw(buffer, (uint8_t *)path, path->length);
129 unparse_vendor_path(char *buffer, VENDOR_DEVICE_PATH *path)
131 char text_guid[40], *p = buffer;
132 unsigned char *q = (uint8_t *)path + 20;
133 efi_guid_unparse(&path->vendor_guid, text_guid);
134 p += sprintf(p, "Vendor(%s,", text_guid);
135 p += unparse_raw(p, q, path->length - 20);
136 p += sprintf(p, ")");
141 unparse_hardware_path(char *buffer, EFI_DEVICE_PATH *path)
143 PCI_DEVICE_PATH *pci = (PCI_DEVICE_PATH *)path;
144 PCCARD_DEVICE_PATH *pccard = (PCCARD_DEVICE_PATH *)path;
145 MEMORY_MAPPED_DEVICE_PATH *mm = (MEMORY_MAPPED_DEVICE_PATH *)path;
146 CONTROLLER_DEVICE_PATH *ctlr = (CONTROLLER_DEVICE_PATH *)path;
147 char a[16], b[16], c[16];
149 switch (path->subtype) {
151 return sprintf(buffer, "PCI(%x,%x)", get(a, pci->device), get(b, pci->function));
154 return sprintf(buffer, "PCCARD(%x)", get(a, pccard->socket));
157 return sprintf(buffer, "MM(%x,%" PRIx64 ",%" PRIx64 ")",
158 get(a, mm->memory_type),
163 return unparse_vendor_path(buffer, (VENDOR_DEVICE_PATH *)path);
167 return sprintf(buffer, "Controller(%x)", get(a, ctlr->controller));
171 return unparse_raw(buffer, (uint8_t *)path, path->length);
178 unparse_messaging_path(char *buffer, EFI_DEVICE_PATH *path)
180 ATAPI_DEVICE_PATH *atapi = (ATAPI_DEVICE_PATH *)path;
181 SCSI_DEVICE_PATH *scsi = (SCSI_DEVICE_PATH *)path;
182 FIBRE_CHANNEL_DEVICE_PATH *fc = (FIBRE_CHANNEL_DEVICE_PATH *)path;
183 I1394_DEVICE_PATH *i1394 = (I1394_DEVICE_PATH *)path;
184 USB_DEVICE_PATH *usb = (USB_DEVICE_PATH *)path;
185 MAC_ADDR_DEVICE_PATH *mac = (MAC_ADDR_DEVICE_PATH *)path;
186 USB_CLASS_DEVICE_PATH *usbclass = (USB_CLASS_DEVICE_PATH *)path;
187 I2O_DEVICE_PATH *i2o = (I2O_DEVICE_PATH *)path;
188 IPv4_DEVICE_PATH *ipv4 = (IPv4_DEVICE_PATH *)path;
189 /* IPv6_DEVICE_PATH *ipv6 = (IPv6_DEVICE_PATH *)path; */
191 char a[16], b[16], c[16], d[16], e[16];
193 switch (path->subtype) {
195 return sprintf(buffer, "ATAPI(%x,%x,%x)",
196 get(a, atapi->primary_secondary),
197 get(b, atapi->slave_master),
201 return sprintf(buffer, "SCSI(%x,%x)", get(a, scsi->id), get(b, scsi->lun));
205 return sprintf(buffer, "FC(%" PRIx64 ",%" PRIx64 ")", get(a, fc->wwn), get(b, fc->lun));
208 return sprintf(buffer, "1394(%" PRIx64 ")", get(a, i1394->guid));
211 return sprintf(buffer, "USB(%x,%x)", get(a, usb->port), get(b, usb->endpoint));
214 return sprintf(buffer, "I2O(%x)", get(a, i2o->tid));
217 p += sprintf(p, "MAC(");
218 p += unparse_raw(p, mac->macaddr, 6);
219 p += sprintf(p, ",%hhx)", get(a, mac->iftype));
220 return (int) (p - buffer);
223 p += sprintf(p, "IPv4(");
224 p += unparse_ipv4_port(p, ipv4->local_ip, ipv4->local_port);
225 p += sprintf(p, "<->");
226 p += unparse_ipv4_port(p, ipv4->remote_ip, ipv4->remote_port);
227 p += sprintf(p, ",%hx, %hhx", get(a, ipv4->protocol), get(b, ipv4->static_addr));
228 return (int) (p - buffer);
232 return sprintf(buffer, "USBClass(%hx,%hx,%hhx,%hhx,%hhx)",
233 get(a, usbclass->vendor), get(b, usbclass->product),
234 get(c, usbclass->class), get(d, usbclass->subclass),
235 get(e, usbclass->protocol));
238 return unparse_raw(buffer, (uint8_t *)path, path->length);
245 unparse_media_hard_drive_path(char *buffer, EFI_DEVICE_PATH *path)
247 HARDDRIVE_DEVICE_PATH *hd = (HARDDRIVE_DEVICE_PATH *)path;
248 char text_uuid[40], *sig=text_uuid;
249 char a[16], b[16], c[16];
251 switch (hd->signature_type) {
253 sprintf(sig, "None");
256 sprintf(sig, "%08x", *(uint32_t *)memcpy(a, &hd->signature,
257 sizeof(hd->signature)));
260 efi_guid_unparse((efi_guid_t *)hd->signature, sig);
266 return sprintf(buffer, "HD(%x,%" PRIx64 ",%" PRIx64 ",%s)",
267 get(a, hd->part_num),
276 unparse_media_path(char *buffer, EFI_DEVICE_PATH *path)
279 CDROM_DEVICE_PATH *cdrom = (CDROM_DEVICE_PATH *)path;
280 MEDIA_PROTOCOL_DEVICE_PATH *media = (MEDIA_PROTOCOL_DEVICE_PATH *)path;
281 FILE_PATH_DEVICE_PATH *file = (FILE_PATH_DEVICE_PATH *)path;
282 char text_guid[40], *p = buffer;
284 memset(file_name, 0, sizeof(file_name));
285 char a[16], b[16], c[16];
287 switch (path->subtype) {
289 return unparse_media_hard_drive_path(buffer, path);
292 return sprintf(buffer, "CD-ROM(%x,%" PRIx64 ",%" PRIx64 ")",
293 get(a, cdrom->boot_entry), get(b, cdrom->start), get(c, cdrom->size));
296 return unparse_vendor_path(buffer, (VENDOR_DEVICE_PATH *)path);
299 efichar_to_char(file_name, file->path_name, 80);
300 return sprintf(p, "File(%s)", file_name);
303 efi_guid_unparse(&media->guid, text_guid);
304 return sprintf(buffer, "Media(%s)", text_guid);
313 unparse_bios_path(char *buffer, EFI_DEVICE_PATH *path)
315 BIOS_BOOT_SPEC_DEVICE_PATH *bios = (BIOS_BOOT_SPEC_DEVICE_PATH *)path;
317 unsigned char *q = (uint8_t *)path + 8;
319 p += sprintf(p, "BIOS(%x,%x,",
320 get(a, bios->device_type), get(b, bios->status_flag));
321 p += unparse_raw(p, q, path->length - 8);
322 p += sprintf(p, ")");
328 unparse_path(char *buffer, EFI_DEVICE_PATH *path, uint16_t pathsize)
330 uint16_t parsed_length = 0;
334 while (parsed_length < pathsize && !exit_now) {
335 switch (path->type) {
337 p += unparse_hardware_path(p, path);
340 p += unparse_acpi_path(p, path);
343 p += unparse_messaging_path(p, path);
346 p += unparse_media_path(p, path);
349 p += unparse_bios_path(p, path);
358 printf("\nwierd path");
359 dump_raw_data(path, 4);
362 // p += sprintf(p, "\\");
363 parsed_length += path->length;
364 path = (EFI_DEVICE_PATH *) ((uint8_t *)path + path->length);
373 unparse_var(efi_variable_t *var)
376 memset(buffer, 0, sizeof(buffer));
378 unparse_path(buffer, (EFI_DEVICE_PATH *)var->Data, var->DataSize);
379 printf("%s\n", buffer);
383 compare_hardware_path_pci(EFI_DEVICE_PATH *path,
384 int device, int func)
386 uint8_t *p = ((void *)path) + OFFSET_OF(EFI_DEVICE_PATH, data);
387 uint8_t path_device, path_func;
389 switch (path->subtype) {
392 path_func = *(uint8_t *)p;
393 path_device = *(uint8_t *)(p+1);
395 return !(path_func == func && path_device == device);
405 compare_hardware_path_scsi(EFI_DEVICE_PATH *path, int id, int lun)
407 uint8_t *p = ((void *)path) + OFFSET_OF(EFI_DEVICE_PATH, data);
408 uint16_t path_id, path_lun;
410 switch (path->subtype) {
413 path_id = *(uint16_t *)p;
414 path_lun = *(uint16_t *)(p+2);
416 return !(path_id == id && path_lun == lun);
425 compare_hardware_path_acpi(EFI_DEVICE_PATH *path, int bus)
427 uint8_t *p = ((void *)path) + OFFSET_OF(EFI_DEVICE_PATH, data);
430 switch (path->subtype) {
433 _HID = *(uint32_t *)p;
434 _UID = *(uint32_t *)(p+4);
436 /* FIXME: Need to convert _HID and _UID to bus number */
447 compare_media_path_harddrive(EFI_DEVICE_PATH *path, uint32_t num,
448 uint64_t start, uint64_t size)
450 HARDDRIVE_DEVICE_PATH *p = (HARDDRIVE_DEVICE_PATH *)path;
453 switch (path->subtype) {
456 return !(p->part_num == num
469 compare_pci_scsi_disk_blk(efi_variable_t *var,
470 int bus, int device, int func,
471 int host, int channel, int id, int lun,
472 uint64_t start, uint64_t size)
475 EFI_DEVICE_PATH *path = (EFI_DEVICE_PATH *) var->Data;
476 uint64_t parsed_length = 0;
480 while (parsed_length < var->DataSize && !exit_now && !rc) {
481 switch (path->type) {
484 rc = compare_hardware_path_pci(path, device, func);
488 rc = compare_hardware_path_acpi(path, bus);
491 /* Messaging (SCSI) */
492 rc = compare_messaging_path_scsi(path, id, lun);
495 /* Media (Hard Drive) */
496 rc = compare_media_path_harddrive(path, 0,
503 case 0x05: /* BIOS */
507 parsed_length += path->length;
508 path = var->Data + parsed_length;
530 printf("Usage: dumppath filename\n");
531 printf("\t where filename is a blkXXXX EFI variable from /proc/efi/vars\n");
535 main(int argc, char **argv)
547 fd = open(argv[1], O_RDONLY);
549 perror("Failed to open file.");
552 size = read(fd, &var, sizeof(var));
553 if (size == -1 || size < sizeof(var)) {
554 perror("Failed to read file.");