Add two new functions, acpi_match_cpu_info() and acpi_match_cpu_handle(),

which will match a given struct cpu_info with the corresponding ACPI handle,
and vice versa.
This commit is contained in:
jruoho 2011-06-20 15:31:52 +00:00
parent f9d2d0003e
commit 0f056e49c5
2 changed files with 150 additions and 9 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_util.c,v 1.6 2010/11/02 16:45:48 gsutre Exp $ */
/* $NetBSD: acpi_util.c,v 1.7 2011/06/20 15:31:52 jruoho Exp $ */
/*-
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_util.c,v 1.6 2010/11/02 16:45:48 gsutre Exp $");
__KERNEL_RCSID(0, "$NetBSD: acpi_util.c,v 1.7 2011/06/20 15:31:52 jruoho Exp $");
#include <sys/param.h>
@ -77,6 +77,11 @@ ACPI_MODULE_NAME ("acpi_util")
static void acpi_clean_node(ACPI_HANDLE, void *);
static const char * const acpicpu_ids[] = {
"ACPI0007",
NULL
};
/*
* Evaluate an integer object.
*/
@ -367,3 +372,138 @@ acpi_match_hid(ACPI_DEVICE_INFO *ad, const char * const *ids)
return 0;
}
/*
* Match a handle from a cpu_info. Returns NULL on failure.
*
* Note that if also acpi_devnode is needed, a subsequent
* call to acpi_get_node() will work.
*/
ACPI_HANDLE
acpi_match_cpu_info(struct cpu_info *ci)
{
struct acpi_softc *sc = acpi_softc;
struct acpi_devnode *ad;
ACPI_INTEGER val;
ACPI_OBJECT *obj;
ACPI_BUFFER buf;
ACPI_HANDLE hdl;
ACPI_STATUS rv;
if (sc == NULL || acpi_active == 0)
return NULL;
/*
* CPUs are declared in the ACPI namespace
* either as a Processor() or as a Device().
* In both cases the MADT entries are used
* for the match (see ACPI 4.0, section 8.4).
*/
SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
hdl = ad->ad_handle;
switch (ad->ad_type) {
case ACPI_TYPE_DEVICE:
if (acpi_match_hid(ad->ad_devinfo, acpicpu_ids) == 0)
break;
rv = acpi_eval_integer(hdl, "_UID", &val);
if (ACPI_SUCCESS(rv) && val == ci->ci_acpiid)
return hdl;
break;
case ACPI_TYPE_PROCESSOR:
rv = acpi_eval_struct(hdl, NULL, &buf);
if (ACPI_FAILURE(rv))
break;
obj = buf.Pointer;
if (obj->Processor.ProcId == ci->ci_acpiid) {
ACPI_FREE(buf.Pointer);
return hdl;
}
ACPI_FREE(buf.Pointer);
break;
}
}
return NULL;
}
/*
* Match a CPU from a handle. Returns NULL on failure.
*/
struct cpu_info *
acpi_match_cpu_handle(ACPI_HANDLE hdl)
{
struct cpu_info *ci;
ACPI_DEVICE_INFO *di;
CPU_INFO_ITERATOR cii;
ACPI_INTEGER val;
ACPI_OBJECT *obj;
ACPI_BUFFER buf;
ACPI_STATUS rv;
ci = NULL;
di = NULL;
buf.Pointer = NULL;
rv = AcpiGetObjectInfo(hdl, &di);
if (ACPI_FAILURE(rv))
return NULL;
switch (di->Type) {
case ACPI_TYPE_DEVICE:
if (acpi_match_hid(di, acpicpu_ids) == 0)
goto out;
rv = acpi_eval_integer(hdl, "_UID", &val);
if (ACPI_FAILURE(rv))
goto out;
break;
case ACPI_TYPE_PROCESSOR:
rv = acpi_eval_struct(hdl, NULL, &buf);
if (ACPI_FAILURE(rv))
goto out;
obj = buf.Pointer;
val = obj->Processor.ProcId;
break;
default:
goto out;
}
for (CPU_INFO_FOREACH(cii, ci)) {
if (ci->ci_acpiid == val)
goto out;
}
ci = NULL;
out:
if (di != NULL)
ACPI_FREE(di);
if (buf.Pointer != NULL)
ACPI_FREE(buf.Pointer);
return ci;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_util.h,v 1.3 2010/06/07 17:13:52 jruoho Exp $ */
/* $NetBSD: acpi_util.h,v 1.4 2011/06/20 15:31:52 jruoho Exp $ */
/*-
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@ -83,7 +83,8 @@ struct acpi_devnode *acpi_get_node(ACPI_HANDLE handle);
void acpi_set_node(struct acpi_devnode *ad);
const char *acpi_name(ACPI_HANDLE);
int acpi_match_hid(ACPI_DEVICE_INFO *, const char * const *);
ACPI_HANDLE acpi_match_cpu_info(struct cpu_info *);
struct cpu_info *acpi_match_cpu_handle(ACPI_HANDLE);
#endif /* !_SYS_DEV_ACPI_ACPI_UTIL_H */