Please test this ecpecially if your system was one of those that had
problems with this patch when it was in the tree before 4.5 release.
Index: sys/dev/acpi/acpicpu.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpicpu.c,v
retrieving revision 1.53
diff -N -u -p -u -p sys/dev/acpi/acpicpu.c
--- sys/dev/acpi/acpicpu.c 24 Feb 2009 13:20:02 -0000 1.53
+++ sys/dev/acpi/acpicpu.c 1 Jun 2009 05:40:07 -0000
@@ -41,12 +41,29 @@ int acpicpu_match(struct device *, void *, void *);
void acpicpu_attach(struct device *, struct device *, void *);
int acpicpu_notify(struct aml_node *, int, void *);
void acpicpu_setperf(int);
+void acpicpu_setperf_ppc_change(struct acpicpu_pss *, int);
#define ACPI_STATE_C0 0x00
#define ACPI_STATE_C1 0x01
#define ACPI_STATE_C2 0x02
#define ACPI_STATE_C3 0x03
+#define ACPI_PDC_REVID 0x1
+#define ACPI_PDC_SMP 0xa
+#define ACPI_PDC_MSR 0x1
+
+/* _PDC Intel capabilities flags from linux */
+#define ACPI_PDC_P_FFH 0x0001
+#define ACPI_PDC_C_C1_HALT 0x0002
+#define ACPI_PDC_T_FFH 0x0004
+#define ACPI_PDC_SMP_C1PT 0x0008
+#define ACPI_PDC_SMP_C2C3 0x0010
+#define ACPI_PDC_SMP_P_SWCOORD 0x0020
+#define ACPI_PDC_SMP_C_SWCOORD 0x0040
+#define ACPI_PDC_SMP_T_SWCOORD 0x0080
+#define ACPI_PDC_C_C1_FFH 0x0100
+#define ACPI_PDC_C_C2C3_FFH 0x0200
+
#define FLAGS_NO_C2 0x01
#define FLAGS_NO_C3 0x02
#define FLAGS_BMCHECK 0x04
@@ -121,6 +138,8 @@ int acpicpu_getpct(struct acpicpu_softc *);
int acpicpu_getpss(struct acpicpu_softc *);
struct acpi_cstate *acpicpu_add_cstate(struct acpicpu_softc *, int, int, int,
int);
+void acpicpu_set_pdc(struct acpicpu_softc *);
+
#if 0
void acpicpu_set_throttle(struct acpicpu_softc *, int);
struct acpi_cstate *acpicpu_find_cstate(struct acpicpu_softc *, int);
@@ -170,6 +189,66 @@ acpicpu_find_cstate(struct acpicpu_softc *sc, int type
}
#endif
+
+void
+acpicpu_set_pdc(struct acpicpu_softc *sc) {
+ struct aml_value cmd, osc_cmd[4];
+ struct aml_value res;
+ uint32_t buf[3];
+ int errcode;
+
+ /* 4077A616-290C-47BE-9EBD-D87058713953 */
+ static uint8_t cpu_oscuuid[16] = { 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29,
+ 0xBE, 0x47, 0x9E, 0xBD, 0xD8, 0x70,
+ 0x58, 0x71, 0x39, 0x53 };
+ /* Evaluate _PDC */
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.type = AML_OBJTYPE_BUFFER;
+ cmd.v_buffer = (uint8_t *)&buf;
+ cmd.length = sizeof(buf);
+
+ buf[0] = ACPI_PDC_REVID;
+ buf[1] = 1;
+ buf[2] = ACPI_PDC_C_C1_HALT | ACPI_PDC_P_FFH | ACPI_PDC_C_C1_FFH
+ | ACPI_PDC_C_C2C3_FFH | ACPI_PDC_SMP_P_SWCOORD | ACPI_PDC_SMP_C2C3
+ | ACPI_PDC_SMP_C1PT;
+
+ errcode = aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PDC", 1, &cmd,
&res);
+
+ if (errcode != 0) {
+ printf("Failed to evaulate _PDC");
+ } else {
+ printf("_PDC evaluation success");
+ }
+
+ /* Evalualte _OSC */
+ memset(&osc_cmd, 0, sizeof(cmd) * 4);
+ osc_cmd[0].type = AML_OBJTYPE_BUFFER;
+ osc_cmd[0].v_buffer = (uint8_t *)&cpu_oscuuid;
+ osc_cmd[0].length = sizeof(cpu_oscuuid);
+
+ osc_cmd[1].type = AML_OBJTYPE_INTEGER;
+ osc_cmd[1].v_integer = 1;
+ osc_cmd[1].length = 1;
+
+ osc_cmd[2].type = AML_OBJTYPE_INTEGER;
+ osc_cmd[2].v_integer = 1;
+ osc_cmd[2].length = 1;
+
+ buf[0] = 0;
+ osc_cmd[3].type = AML_OBJTYPE_BUFFER;
+ osc_cmd[3].v_buffer = (int8_t *)&buf;
+ osc_cmd[3].length = sizeof(buf);
+
+ errcode = aml_evalname(sc->sc_acpi, sc->sc_devnode, "_OSC", 4, osc_cmd,
&res);
+ if (errcode != 0) {
+ printf("Failed to evaulate _OSC");
+ } else {
+ printf("_OSC evaluation success");
+ }
+}
+
+
struct acpi_cstate *
acpicpu_add_cstate(struct acpicpu_softc *sc, int type, int latency, int power,
int address)
@@ -268,6 +347,13 @@ acpicpu_attach(struct device *parent, struct device *s
}
sc->sc_duty_off = sc->sc_acpi->sc_fadt->duty_offset;
sc->sc_duty_wid = sc->sc_acpi->sc_fadt->duty_width;
+
+#if defined(amd64)
+ if (strcmp(cpu_vendor, "GenuineIntel") == 0)
+ if (cpu_ecxfeature & CPUIDECX_EST)
+ acpicpu_set_pdc(sc);
+#endif
+
if (!valid_throttle(sc->sc_duty_off, sc->sc_duty_wid, sc->sc_pblk_addr))
sc->sc_flags |= FLAGS_NOTHROTTLE;
#ifdef ACPI_DEBUG
@@ -342,6 +428,7 @@ acpicpu_attach(struct device *parent, struct device *s
DEVNAME(sc), status, sc->sc_level);
if (setperf_prio < 30) {
cpu_setperf = acpicpu_setperf;
+ acpicpu_set_notify(acpicpu_setperf_ppc_change);
setperf_prio = 30;
acpi_hasprocfvs = 1;
}
@@ -535,8 +622,6 @@ acpicpu_fetch_pss(struct acpicpu_pss **pss)
* XXX: According to the ACPI spec in an SMP system all processors
* are supposed to support the same states. For now we pray
* the bios ensures this...
- * XXX part deux: this needs to account for _PPC as well
- * when AC is removed the nr of _PSS entries can go down
*/
sc = acpicpu_sc[0];
@@ -562,9 +647,6 @@ acpicpu_notify(struct aml_node *node, int notify_type,
if (sc->sc_notify)
sc->sc_notify(sc->sc_pss, sc->sc_pss_len);
- /* reset performance to current percentage */
- /* XXX will fail for amd64 for now */
- cpu_setperf(sc->sc_level);
break;
default:
printf("%s: unhandled cpu event %x\n", DEVNAME(sc),
@@ -582,6 +664,16 @@ acpicpu_set_notify(void (*func)(struct acpicpu_pss *,
sc = acpicpu_sc[0];
if (sc != NULL)
sc->sc_notify = func;
+}
+
+void
+acpicpu_setperf_ppc_change(struct acpicpu_pss *pss, int npss) {
+ struct acpicpu_softc *sc;
+
+ sc = acpicpu_sc[0];
+
+ if (sc != NULL)
+ cpu_setperf(sc->sc_level);
}
void
Index: sys/dev/acpi/dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.149
diff -N -u -p -u -p sys/dev/acpi/dsdt.c
--- sys/dev/acpi/dsdt.c 30 May 2009 22:49:56 -0000 1.149
+++ sys/dev/acpi/dsdt.c 1 Jun 2009 05:40:07 -0000
@@ -4049,9 +4049,11 @@ aml_xparse(struct aml_scope *scope, int ret_type, cons
case AMLOP_LOADTABLE:
/* LoadTable(Sig:Str, OEMID:Str, OEMTable:Str, [RootPath:Str],
[ParmPath:Str],
[ParmData:DataRefObj]) => DDBHandle */
+ printf("We should have done something here\n");
aml_die("LoadTable");
break;
case AMLOP_LOAD:
+ printf("Evaluating AMLOP_LOAD");
/* Load(Object:NameString, DDBHandle:SuperName) */
rv = opargs[0];
if (rv->type != AML_OBJTYPE_OPREGION ||
@@ -4065,7 +4067,7 @@ aml_xparse(struct aml_scope *scope, int ret_type, cons
aml_xgasio(rv->v_opregion.iospace, rv->v_opregion.iobase,
rv->v_opregion.iolen,
opargs[1]->v_buffer, ACPI_IOREAD, 8, "");
-
+
/* Validate that this is a SSDT */
if (!valid_acpihdr(opargs[1]->v_buffer, opargs[1]->length,
"SSDT")) {