Add UEFI locator for bus_get_device_path, pci acpi

Add a UEFI locator type. It prints the UEFI device names for a FreeBSD
device_t name. It works with PCI and ACPI device nodes. USB forthcoming.

Sponsored by:		Netflix
Reviewed by:		jhb
Differential Revision:	https://reviews.freebsd.org/D32749
This commit is contained in:
Warner Losh 2022-02-28 14:27:48 -07:00
parent cae7d9ec83
commit d0a20e401e
5 changed files with 70 additions and 3 deletions

View File

@ -958,6 +958,52 @@ acpi_get_device_path(device_t bus, device_t child, const char *locator, struct s
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0)
return (acpi_get_acpi_device_path(bus, child, locator, sb));
if (strcmp(locator, BUS_LOCATOR_UEFI) == 0) {
ACPI_DEVICE_INFO *adinfo;
if (!ACPI_FAILURE(AcpiGetObjectInfo(dinfo->ad_handle, &adinfo)) &&
dinfo->ad_handle != 0 && (adinfo->Valid & ACPI_VALID_HID)) {
const char *hid = adinfo->HardwareId.String;
u_long uid = (adinfo->Valid & ACPI_VALID_UID) ?
strtoul(adinfo->UniqueId.String, NULL, 10) : 0UL;
u_long hidval;
/*
* In UEFI Stanard Version 2.6, Section 9.6.1.6 Text
* Device Node Reference, there's an insanely long table
* 98. This implements the relevant bits from that
* table. Newer versions appear to have not required
* anything new. The EDK2 firmware presents both PciRoot
* and PcieRoot as PciRoot. Follow the EDK2 standard.
*/
if (strncmp("PNP", hid, 3) != 0)
goto nomatch;
hidval = strtoul(hid + 3, NULL, 16);
switch (hidval) {
case 0x0301:
sbuf_printf(sb, "Keyboard(0x%lx)", uid);
break;
case 0x0401:
sbuf_printf(sb, "ParallelPort(0x%lx)", uid);
break;
case 0x0501:
sbuf_printf(sb, "Serial(0x%lx)", uid);
break;
case 0x0604:
sbuf_printf(sb, "Floppy(0x%lx)", uid);
break;
case 0x0a03:
case 0x0a08:
sbuf_printf(sb, "PciRoot(0x%lx)", uid);
break;
default: /* Everything else gets a generic encode */
nomatch:
sbuf_printf(sb, "Acpi(%s,0x%lx)", hid, uid);
break;
}
}
/* Not handled: AcpiAdr... unsure how to know it's one */
}
/* For the rest, punt to the default handler */
return (bus_generic_get_device_path(bus, child, locator, sb));
}

View File

@ -206,8 +206,8 @@ acpi_pci_get_device_path(device_t bus, device_t child, const char *locator, stru
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0)
return (acpi_get_acpi_device_path(bus, child, locator, sb));
/* For the rest, punt to the default handler */
return (bus_generic_get_device_path(bus, child, locator, sb));
/* Otherwise follow base class' actions */
return (pci_get_device_path_method(bus, child, locator, sb));
}
/*

View File

@ -138,7 +138,6 @@ static int pci_reset_child(device_t dev, device_t child,
static int pci_get_id_method(device_t dev, device_t child,
enum pci_id_type type, uintptr_t *rid);
static struct pci_devinfo * pci_fill_devinfo(device_t pcib, device_t bus, int d,
int b, int s, int f, uint16_t vid, uint16_t did);
@ -177,6 +176,7 @@ static device_method_t pci_methods[] = {
DEVMETHOD(bus_child_detached, pci_child_detached),
DEVMETHOD(bus_child_pnpinfo, pci_child_pnpinfo_method),
DEVMETHOD(bus_child_location, pci_child_location_method),
DEVMETHOD(bus_get_device_path, pci_get_device_path_method),
DEVMETHOD(bus_hint_device_unit, pci_hint_device_unit),
DEVMETHOD(bus_remap_intr, pci_remap_intr_method),
DEVMETHOD(bus_suspend_child, pci_suspend_child),
@ -5917,6 +5917,24 @@ pci_child_pnpinfo_method(device_t dev, device_t child, struct sbuf *sb)
return (0);
}
int
pci_get_device_path_method(device_t bus, device_t child, const char *locator,
struct sbuf *sb)
{
device_t parent = device_get_parent(bus);
int rv;
if (strcmp(locator, BUS_LOCATOR_UEFI) == 0) {
rv = bus_generic_get_device_path(parent, bus, locator, sb);
if (rv == 0) {
sbuf_printf(sb, "/Pci(0x%x,0x%x)", pci_get_slot(child),
pci_get_function(child));
}
return (0);
}
return (bus_generic_get_device_path(bus, child, locator, sb));
}
int
pci_assign_interrupt_method(device_t dev, device_t child)
{

View File

@ -138,6 +138,8 @@ int pci_child_location_method(device_t cbdev, device_t child,
struct sbuf *sb);
int pci_child_pnpinfo_method(device_t cbdev, device_t child,
struct sbuf *sb);
int pci_get_device_path_method(device_t dev, device_t child,
const char *locator, struct sbuf *sb);
int pci_assign_interrupt_method(device_t dev, device_t child);
int pci_resume(device_t dev);
int pci_resume_child(device_t dev, device_t child);

View File

@ -739,6 +739,7 @@ void bus_data_generation_update(void);
#define BUS_LOCATOR_ACPI "ACPI"
#define BUS_LOCATOR_FREEBSD "FreeBSD"
#define BUS_LOCATOR_UEFI "UEFI"
extern int bus_current_pass;