mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
acpica: add domain ivar
Specialize acpi bus_get_domain method to read ivar. Execute and cache the _PXM result in the ivar at namespace enumeration time. If there is no _PXM, driver for the child can set the ivar to the value obtained by other means. Move acpi_get_domain() to acpi_pci.c, it now serves pci buses and devices on them. Suggested and reviewed by: jhb Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D47291
This commit is contained in:
parent
6f423295f1
commit
7dd1f0dcd1
3 changed files with 56 additions and 24 deletions
|
|
@ -142,6 +142,7 @@ static bus_child_location_t acpi_child_location_method;
|
|||
static bus_hint_device_unit_t acpi_hint_device_unit;
|
||||
static bus_get_property_t acpi_bus_get_prop;
|
||||
static bus_get_device_path_t acpi_get_device_path;
|
||||
static bus_get_domain_t acpi_get_domain_method;
|
||||
|
||||
static acpi_id_probe_t acpi_device_id_probe;
|
||||
static acpi_evaluate_object_t acpi_device_eval_obj;
|
||||
|
|
@ -219,7 +220,7 @@ static device_method_t acpi_methods[] = {
|
|||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
||||
DEVMETHOD(bus_hint_device_unit, acpi_hint_device_unit),
|
||||
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
|
||||
DEVMETHOD(bus_get_domain, acpi_get_domain),
|
||||
DEVMETHOD(bus_get_domain, acpi_get_domain_method),
|
||||
DEVMETHOD(bus_get_property, acpi_bus_get_prop),
|
||||
DEVMETHOD(bus_get_device_path, acpi_get_device_path),
|
||||
|
||||
|
|
@ -819,6 +820,7 @@ acpi_add_child(device_t bus, u_int order, const char *name, int unit)
|
|||
if ((ad = malloc(sizeof(*ad), M_ACPIDEV, M_NOWAIT | M_ZERO)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
ad->ad_domain = ACPI_DEV_DOMAIN_UNKNOWN;
|
||||
resource_list_init(&ad->ad_rl);
|
||||
|
||||
child = device_add_child_ordered(bus, order, name, unit);
|
||||
|
|
@ -1055,6 +1057,9 @@ acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
|
|||
case ACPI_IVAR_FLAGS:
|
||||
*(int *)result = ad->ad_flags;
|
||||
break;
|
||||
case ACPI_IVAR_DOMAIN:
|
||||
*(int *)result = ad->ad_domain;
|
||||
break;
|
||||
case ISA_IVAR_VENDORID:
|
||||
case ISA_IVAR_SERIAL:
|
||||
case ISA_IVAR_COMPATID:
|
||||
|
|
@ -1099,6 +1104,9 @@ acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
|
|||
case ACPI_IVAR_FLAGS:
|
||||
ad->ad_flags = (int)value;
|
||||
break;
|
||||
case ACPI_IVAR_DOMAIN:
|
||||
ad->ad_domain = (int)value;
|
||||
break;
|
||||
default:
|
||||
panic("bad ivar write request (%d)", index);
|
||||
return (ENOENT);
|
||||
|
|
@ -1297,29 +1305,16 @@ acpi_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the NUMA domain for the given device 'dev'.
|
||||
*
|
||||
* If a device has a _PXM method, map that to a NUMA domain.
|
||||
* Otherwise, pass the request up to the parent.
|
||||
* If there's no matching domain or the domain cannot be
|
||||
* determined, return ENOENT.
|
||||
*/
|
||||
int
|
||||
acpi_get_domain(device_t dev, device_t child, int *domain)
|
||||
static int
|
||||
acpi_get_domain_method(device_t dev, device_t child, int *domain)
|
||||
{
|
||||
int d;
|
||||
int error;
|
||||
|
||||
d = acpi_pxm_parse(child);
|
||||
if (d >= 0) {
|
||||
*domain = d;
|
||||
error = acpi_read_ivar(dev, child, ACPI_IVAR_DOMAIN,
|
||||
(uintptr_t *)domain);
|
||||
if (error == 0 && *domain != ACPI_DEV_DOMAIN_UNKNOWN)
|
||||
return (0);
|
||||
}
|
||||
if (d == -1)
|
||||
return (ENOENT);
|
||||
|
||||
/* No _PXM node; go up a level */
|
||||
return (bus_generic_get_domain(dev, child, domain));
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
static struct rman *
|
||||
|
|
@ -2348,7 +2343,7 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
|
|||
ACPI_HANDLE h;
|
||||
device_t bus, child;
|
||||
char *handle_str;
|
||||
int order;
|
||||
int d, order;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
|
|
@ -2456,6 +2451,10 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
|
|||
}
|
||||
AcpiOsFree(devinfo);
|
||||
}
|
||||
|
||||
d = acpi_pxm_parse(child);
|
||||
if (d >= 0)
|
||||
ad->ad_domain = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ static int acpi_pci_set_powerstate_method(device_t dev, device_t child,
|
|||
int state);
|
||||
static void acpi_pci_update_device(ACPI_HANDLE handle, device_t pci_child);
|
||||
static bus_dma_tag_t acpi_pci_get_dma_tag(device_t bus, device_t child);
|
||||
static int acpi_pci_get_domain(device_t dev, device_t child, int *domain);
|
||||
|
||||
static device_method_t acpi_pci_methods[] = {
|
||||
/* Device interface */
|
||||
|
|
@ -108,7 +109,7 @@ static device_method_t acpi_pci_methods[] = {
|
|||
DEVMETHOD(bus_get_device_path, acpi_pci_get_device_path),
|
||||
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
|
||||
DEVMETHOD(bus_get_dma_tag, acpi_pci_get_dma_tag),
|
||||
DEVMETHOD(bus_get_domain, acpi_get_domain),
|
||||
DEVMETHOD(bus_get_domain, acpi_pci_get_domain),
|
||||
|
||||
/* PCI interface */
|
||||
DEVMETHOD(pci_alloc_devinfo, acpi_pci_alloc_devinfo),
|
||||
|
|
@ -206,6 +207,31 @@ acpi_pci_get_device_path(device_t bus, device_t child, const char *locator, stru
|
|||
return (pci_get_device_path_method(bus, child, locator, sb));
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the NUMA domain for the given device 'dev'.
|
||||
*
|
||||
* If a device has a _PXM method, map that to a NUMA domain.
|
||||
* Otherwise, pass the request up to the parent.
|
||||
* If there's no matching domain or the domain cannot be
|
||||
* determined, return ENOENT.
|
||||
*/
|
||||
static int
|
||||
acpi_pci_get_domain(device_t dev, device_t child, int *domain)
|
||||
{
|
||||
int d;
|
||||
|
||||
d = acpi_pxm_parse(child);
|
||||
if (d >= 0) {
|
||||
*domain = d;
|
||||
return (0);
|
||||
}
|
||||
if (d == -1)
|
||||
return (ENOENT);
|
||||
|
||||
/* No _PXM node; go up a level */
|
||||
return (bus_generic_get_domain(dev, child, domain));
|
||||
}
|
||||
|
||||
/*
|
||||
* PCI power manangement
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ struct acpi_device {
|
|||
void *ad_private;
|
||||
int ad_flags;
|
||||
int ad_cls_class;
|
||||
int ad_domain;
|
||||
|
||||
ACPI_BUFFER dsd; /* Device Specific Data */
|
||||
const ACPI_OBJECT *dsd_pkg;
|
||||
|
|
@ -272,6 +273,12 @@ extern int acpi_override_isa_irq_polarity;
|
|||
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
|
||||
#define ACPI_IVAR_PRIVATE 0x102
|
||||
#define ACPI_IVAR_FLAGS 0x103
|
||||
#define ACPI_IVAR_DOMAIN 0x104
|
||||
|
||||
/*
|
||||
* ad_domain NUMA domain special value.
|
||||
*/
|
||||
#define ACPI_DEV_DOMAIN_UNKNOWN (-1)
|
||||
|
||||
/*
|
||||
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
|
||||
|
|
@ -297,6 +304,7 @@ static __inline void varp ## _set_ ## var(device_t dev, type t) \
|
|||
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
|
||||
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
|
||||
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
|
||||
__ACPI_BUS_ACCESSOR(acpi, domain, ACPI, DOMAIN, int)
|
||||
|
||||
void acpi_fake_objhandler(ACPI_HANDLE h, void *data);
|
||||
static __inline device_t
|
||||
|
|
@ -594,7 +602,6 @@ int acpi_pxm_parse(device_t dev);
|
|||
*/
|
||||
int acpi_map_pxm_to_vm_domainid(int pxm);
|
||||
bus_get_cpus_t acpi_get_cpus;
|
||||
bus_get_domain_t acpi_get_domain;
|
||||
|
||||
#ifdef __aarch64__
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue