int acpidock_eject(struct acpidock_softc *sc, struct aml_node *node) { struct aml_value cmd; struct aml_value res; int rv; if (node != sc->sc_devnode) aml_notify(node, 3); memset(&cmd, 0, sizeof cmd); cmd.v_integer = 1; cmd.type = AML_OBJTYPE_INTEGER; if (aml_evalname(sc->sc_acpi, node, "_EJ0", 1, &cmd, &res) != 0) { dnprintf(15, "%s: _EJ0 failed\n", DEVNAME(sc)); rv = 0; } else { dnprintf(15, "%s: _EJ0 successful\n", DEVNAME(sc)); rv = 1; } aml_freevalue(&res); return (rv); }
int acpiec_gpehandler(struct acpi_softc *acpi_sc, int gpe, void *arg) { struct acpiec_softc *sc = arg; u_int8_t mask, stat; dnprintf(10, "ACPIEC: got gpe\n"); /* Reset GPE event */ mask = (1L << (gpe & 7)); acpi_write_pmreg(acpi_sc, ACPIREG_GPE_STS, gpe>>3, mask); acpi_write_pmreg(acpi_sc, ACPIREG_GPE_EN, gpe>>3, mask); do { if (sc->sc_gotsci) acpiec_sci_event(sc); stat = acpiec_status(sc); dnprintf(40, "%s: EC interrupt, stat: %b\n", DEVNAME(sc), (int)stat, "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF"); if (stat & EC_STAT_SCI_EVT) sc->sc_gotsci = 1; } while (sc->sc_gotsci); return (0); }
int acpiec_gpehandler(struct acpi_softc *acpi_sc, int gpe, void *arg) { struct acpiec_softc *sc = arg; u_int8_t mask, stat, en; int s; KASSERT(sc->sc_ecbusy == 0); dnprintf(10, "ACPIEC: got gpe\n"); do { if (sc->sc_gotsci) acpiec_sci_event(sc); stat = acpiec_status(sc); dnprintf(40, "%s: EC interrupt, stat: %b\n", DEVNAME(sc), (int)stat, "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF"); if (stat & EC_STAT_SCI_EVT) sc->sc_gotsci = 1; else sc->sc_gotsci = 0; } while (sc->sc_gotsci); /* Unmask the GPE which was blocked at interrupt time */ s = spltty(); mask = (1L << (gpe & 7)); en = acpi_read_pmreg(acpi_sc, ACPIREG_GPE_EN, gpe>>3); acpi_write_pmreg(acpi_sc, ACPIREG_GPE_EN, gpe>>3, en | mask); splx(s); return (0); }
void acpitz_refresh(void *arg) { struct acpitz_softc *sc = arg; int i, trend; extern int acpi_s5; dnprintf(30, "%s: %s: refresh\n", DEVNAME(sc), sc->sc_devnode->parent->name); if (-1 == (sc->sc_tmp = acpitz_getreading(sc, "_TMP"))) { dnprintf(30, "%s: %s: failed to read temp!\n", DEVNAME(sc), sc->sc_devnode->parent->name); sc->sc_tmp = 0; /* XXX */ } if (sc->sc_crt != -1 && sc->sc_crt <= sc->sc_tmp) { /* Do critical shutdown */ printf("%s: Critical temperature, shutting down!\n", DEVNAME(sc)); acpi_s5 = 1; psignal(initproc, SIGUSR1); } if (sc->sc_hot != -1 && sc->sc_hot <= sc->sc_tmp) printf("%s: _HOT temperature\n", DEVNAME(sc)); if (sc->sc_lasttmp != -1 && sc->sc_tc1 != -1 && sc->sc_tc2 != -1 && sc->sc_psv != -1) { if (sc->sc_psv <= sc->sc_tmp) { sc->sc_pse = 1; trend = sc->sc_tc1 * (sc->sc_tmp - sc->sc_lasttmp) + sc->sc_tc2 * (sc->sc_tmp - sc->sc_psv); /* printf("_TZ trend = %d\n", trend); */ } else if (sc->sc_pse) sc->sc_pse = 0; } sc->sc_lasttmp = sc->sc_tmp; for (i = 0; i < ACPITZ_MAX_AC; i++) { if (sc->sc_ac[i] != -1 && sc->sc_ac[i] <= sc->sc_tmp) { /* turn on fan i */ if (sc->sc_ac_stat[i] <= 0) acpitz_setfan(sc, i, "_ON_"); } else if (sc->sc_ac[i] != -1) { /* turn off fan i */ if (sc->sc_ac_stat[i] > 0) acpitz_setfan(sc, i, "_OFF"); } } sc->sc_sens.value = sc->sc_tmp * 100000; }
int acpidock_walkchildren(struct aml_node *node, void *arg) { struct acpidock_softc *sc = arg; struct aml_nodelist *n; if (node && node->value && node->value->type == AML_OBJTYPE_DEVICE) { n = malloc(sizeof *n, M_DEVBUF, M_WAITOK | M_ZERO); n->node = node; dnprintf(10,"%s depends on", aml_nodename(node)); dnprintf(10,"%s\n", aml_nodename(sc->sc_devnode)); TAILQ_INSERT_TAIL(&sc->sc_deps_h, n, entries); } return (0); }
int acpibat_notify(struct aml_node *node, int notify_type, void *arg) { struct acpibat_softc *sc = arg; int64_t sta; dnprintf(10, "acpibat_notify: %.2x %s\n", notify_type, sc->sc_devnode->name); /* Check if installed state of battery has changed */ if (aml_evalinteger(sc->sc_acpi, node, "_STA", 0, NULL, &sta) == 0) { if (sta & STA_BATTERY) sc->sc_bat_present = 1; else sc->sc_bat_present = 0; } switch (notify_type) { case 0x00: /* Poll sensors */ case 0x80: /* _BST changed */ acpibat_getbst(sc); break; case 0x81: /* _BIF changed */ acpibat_getbif(sc); break; default: break; } acpibat_refresh(sc); return (0); }
void acpiec_attach(struct device *parent, struct device *self, void *aux) { struct acpiec_softc *sc = (struct acpiec_softc *)self; struct acpi_attach_args *aa = aux; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; if (acpiec_getcrs(sc, aa)) { printf(": Failed to read resource settings\n"); return; } sc->sc_acpi->sc_ec = sc; if (acpiec_reg(sc)) { printf(": Failed to register address space\n"); return; } acpiec_get_events(sc); dnprintf(10, "%s: GPE: %d\n", DEVNAME(sc), sc->sc_gpe); #ifndef SMALL_KERNEL acpi_set_gpehandler(sc->sc_acpi, sc->sc_gpe, acpiec_gpehandler, sc, 1); #endif printf("\n"); }
struct acpi_cstate * acpicpu_add_cstate(struct acpicpu_softc *sc, int type, int latency, int power, int address) { struct acpi_cstate *cx; dnprintf(10," C%d: latency:.%4x power:%.4x addr:%.8x\n", type, latency, power, address); switch (type) { case ACPI_STATE_C2: if (latency > ACPI_MAX_C2_LATENCY || !address || (sc->sc_flags & FLAGS_NO_C2)) goto bad; break; case ACPI_STATE_C3: if (latency > ACPI_MAX_C3_LATENCY || !address || (sc->sc_flags & FLAGS_NO_C3)) goto bad; break; } cx = malloc(sizeof(struct acpi_cstate), M_DEVBUF, M_WAITOK); memset(cx, 0, sizeof(struct acpi_cstate)); cx->type = type; cx->power = power; cx->latency = latency; cx->address = address; SLIST_INSERT_HEAD(&sc->sc_cstates, cx, link); return cx; bad: printf("acpicpu%d: C%d not supported\n", sc->sc_cpu, type); return NULL; }
void acpiec_write_cmd(struct acpiec_softc *sc, u_int8_t val) { acpiec_wait(sc, EC_STAT_IBF, 0); dnprintf(40, "acpiec: write_cmd -- %d\n", (int)val); bus_space_write_1(sc->sc_cmd_bt, sc->sc_cmd_bh, 0, val); }
u_int8_t acpiec_read_data(struct acpiec_softc *sc) { u_int8_t val; acpiec_wait(sc, EC_STAT_OBF, EC_STAT_OBF); dnprintf(40, "acpiec: read_data\n", (int)val); val = bus_space_read_1(sc->sc_data_bt, sc->sc_data_bh, 0); return (val); }
void acpiec_wait(struct acpiec_softc *sc, u_int8_t mask, u_int8_t val) { u_int8_t stat; dnprintf(40, "%s: EC wait_ns for: %b == %02x\n", DEVNAME(sc), (int)mask, "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF", (int)val); while (((stat = acpiec_status(sc)) & mask) != val) { if (stat & EC_STAT_SCI_EVT) sc->sc_gotsci = 1; if (cold) delay(1); else tsleep(sc, PWAIT, "ecwait", 1); } dnprintf(40, "%s: EC wait_ns, stat: %b\n", DEVNAME(sc), (int)stat, "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF"); }
int acpibat_getbst(struct acpibat_softc *sc) { struct aml_value res; int rv = EINVAL; if (!sc->sc_bat_present) { memset(&sc->sc_bst, 0, sizeof(sc->sc_bst)); return (0); } if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BST", 0, NULL, &res)) { dnprintf(10, "%s: no _BST\n", DEVNAME(sc)); goto out; } if (res.length != 4) { dnprintf(10, "%s: invalid _BST, battery status not saved\n", DEVNAME(sc)); goto out; } sc->sc_bst.bst_state = aml_val2int(res.v_package[0]); sc->sc_bst.bst_rate = aml_val2int(res.v_package[1]); sc->sc_bst.bst_capacity = aml_val2int(res.v_package[2]); sc->sc_bst.bst_voltage = aml_val2int(res.v_package[3]); dnprintf(60, "state: %u rate: %u cap: %u volt: %u ", sc->sc_bst.bst_state, sc->sc_bst.bst_rate, sc->sc_bst.bst_capacity, sc->sc_bst.bst_voltage); rv = 0; out: aml_freevalue(&res); return (rv); }
void acpiec_get_events(struct acpiec_softc *sc) { int idx; char name[16]; memset(sc->sc_events, 0, sizeof(sc->sc_events)); for (idx = 0; idx < ACPIEC_MAX_EVENTS; idx++) { snprintf(name, sizeof(name), "_Q%02X", idx); sc->sc_events[idx].event = aml_searchname(sc->sc_devnode, name); if (sc->sc_events[idx].event != NULL) dnprintf(10, "%s: Found event %s\n", DEVNAME(sc), name); } }
int acpidock_dockctl(struct acpidock_softc *sc, int dock) { struct aml_value cmd; struct aml_value res; int rv; memset(&cmd, 0, sizeof cmd); cmd.v_integer = dock; cmd.type = AML_OBJTYPE_INTEGER; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_DCK", 1, &cmd, &res) != 0) { dnprintf(15, "%s: _DCK %d failed\n", DEVNAME(sc), dock); rv = 0; } else { dnprintf(15, "%s: _DCK %d successful\n", DEVNAME(sc), dock); rv = 1; } aml_freevalue(&res); return (rv); }
void acpiec_write(struct acpiec_softc *sc, u_int8_t addr, int len, u_int8_t *buffer) { int reg; /* * this works because everything runs in the acpi thread context. * at some point add a lock to deal with concurrency so that a * transaction does not get interrupted. */ acpiec_burst_enable(sc); dnprintf(20, "%s: write %d, %d\n", DEVNAME(sc), (int)addr, len); for (reg = 0; reg < len; reg++) acpiec_write_1(sc, addr + reg, buffer[reg]); }
int acpitz_getreading(struct acpitz_softc *sc, char *name) { struct aml_value res; int rv = -1; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, name, 0, NULL, &res)) { dnprintf(10, "%s: no %s\n", DEVNAME(sc), name); goto out; } rv = aml_val2int(&res); out: aml_freevalue(&res); return (rv); }
int acpidock_notify(struct aml_node *node, int notify_type, void *arg) { struct acpidock_softc *sc = arg; struct aml_nodelist *n; dnprintf(5, "%s: acpidock_notify: notify %d\n", DEVNAME(sc), notify_type); switch (notify_type) { case ACPIDOCK_EVENT_INSERT: acpidock_docklock(sc, 1); acpidock_dockctl(sc, 1); TAILQ_FOREACH_REVERSE(n, &sc->sc_deps_h, aml_nodelisth, entries) aml_notify(n->node, 0x00); break; case ACPIDOCK_EVENT_EJECT: case ACPIDOCK_EVENT_DEVCHECK: /* ACPI Spec says eject button press generates * a Notify(Device, 1); */ TAILQ_FOREACH(n, &sc->sc_deps_h, entries) acpidock_eject(sc, n->node); acpidock_dockctl(sc, 0); acpidock_docklock(sc, 0); /* now actually undock */ acpidock_eject(sc, sc->sc_devnode); break; } acpidock_status(sc); sc->sc_sens.value = sc->sc_docked == ACPIDOCK_STATUS_DOCKED; if (sc->sc_docked) strlcpy(sc->sc_sens.desc, "docked", sizeof(sc->sc_sens.desc)); else strlcpy(sc->sc_sens.desc, "not docked", sizeof(sc->sc_sens.desc)); printf("%s: %s\n", DEVNAME(sc), sc->sc_docked == ACPIDOCK_STATUS_DOCKED ? "docked" : "undocked"); return (0); }
void acpibat_attach(struct device *parent, struct device *self, void *aux) { struct acpibat_softc *sc = (struct acpibat_softc *)self; struct acpi_attach_args *aa = aux; struct aml_value res; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &res)) { dnprintf(10, "%s: no _STA\n", DEVNAME(sc)); return; } if ((res.v_integer & STA_BATTERY) != 0) { sc->sc_bat_present = 1; acpibat_getbif(sc); acpibat_getbst(sc); printf(": %s", sc->sc_devnode->name); if (sc->sc_bif.bif_model[0]) printf(" model \"%s\"", sc->sc_bif.bif_model); if (sc->sc_bif.bif_serial[0]) printf(" serial %s", sc->sc_bif.bif_serial); if (sc->sc_bif.bif_type[0]) printf(" type %s", sc->sc_bif.bif_type); if (sc->sc_bif.bif_oem[0]) printf(" oem \"%s\"", sc->sc_bif.bif_oem); printf("\n"); } else { sc->sc_bat_present = 0; printf(": %s not present\n", sc->sc_devnode->name); } aml_freevalue(&res); /* create sensors */ acpibat_monitor(sc); /* populate sensors */ acpibat_refresh(sc); aml_register_notify(sc->sc_devnode, aa->aaa_dev, acpibat_notify, sc, ACPIDEV_POLL); }
void acpiec_sci_event(struct acpiec_softc *sc) { u_int8_t evt; sc->sc_gotsci = 0; acpiec_wait(sc, EC_STAT_IBF, 0); bus_space_write_1(sc->sc_cmd_bt, sc->sc_cmd_bh, 0, EC_CMD_QR); acpiec_wait(sc, EC_STAT_OBF, EC_STAT_OBF); evt = bus_space_read_1(sc->sc_data_bt, sc->sc_data_bh, 0); if (evt) { dnprintf(10, "%s: sci_event: 0x%02x\n", DEVNAME(sc), (int)evt); aml_evalnode(sc->sc_acpi, sc->sc_events[evt].event, 0, NULL, NULL); } }
int acpiec_reg(struct acpiec_softc *sc) { struct aml_value arg[2]; memset(&arg, 0, sizeof(arg)); arg[0].type = AML_OBJTYPE_INTEGER; arg[0].v_integer = REG_TYPE_EC; arg[1].type = AML_OBJTYPE_INTEGER; arg[1].v_integer = 1; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_REG", 2, arg, NULL) != 0) { dnprintf(10, "%s: eval method _REG failed\n", DEVNAME(sc)); return (1); } return (0); }
int acpiec_reg(struct acpiec_softc *sc) { struct aml_value arg[2]; struct aml_node *node; memset(&arg, 0, sizeof(arg)); arg[0].type = AML_OBJTYPE_INTEGER; arg[0].v_integer = REG_TYPE_EC; arg[1].type = AML_OBJTYPE_INTEGER; arg[1].v_integer = 1; node = aml_searchname(sc->sc_devnode, "_REG"); if (node && aml_evalnode(sc->sc_acpi, node, 2, arg, NULL)) { dnprintf(10, "%s: eval method _REG failed\n", DEVNAME(sc)); printf("acpiec _REG failed, broken BIOS\n"); } return (0); }
int acpicpu_notify(struct aml_node *node, int notify_type, void *arg) { struct acpicpu_softc *sc = arg; dnprintf(10, "acpicpu_notify: %.2x %s\n", notify_type, sc->sc_devnode->name); switch (notify_type) { case 0x80: /* _PPC changed, retrieve new values */ acpicpu_getpct(sc); acpicpu_getpss(sc); break; default: printf("%s: unhandled cpu event %x\n", DEVNAME(sc), notify_type); break; } return (0); }
void acpiec_attach(struct device *parent, struct device *self, void *aux) { struct acpiec_softc *sc = (struct acpiec_softc *)self; struct acpi_attach_args *aa = aux; struct aml_value res; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; if (acpiec_getcrs(sc, aa)) { printf(": Failed to read resource settings\n"); return; } sc->sc_acpi->sc_ec = sc; if (acpiec_reg(sc)) { printf(": Failed to register address space\n"); return; } acpiec_get_events(sc); dnprintf(10, "%s: GPE: %d\n", DEVNAME(sc), sc->sc_gpe); #ifndef SMALL_KERNEL acpi_set_gpehandler(sc->sc_acpi, sc->sc_gpe, acpiec_gpehandler, sc, 1); #endif if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_GLK", 0, NULL, &res)) sc->sc_glk = 0; else if (res.type != AML_OBJTYPE_INTEGER) sc->sc_glk = 0; else sc->sc_glk = res.v_integer ? 1 : 0; printf("\n"); }
int acpicpu_getpss(struct acpicpu_softc *sc) { struct aml_value res; int i; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PSS", 0, NULL, &res)) { dnprintf(20, "%s: no _PSS\n", DEVNAME(sc)); return (1); } if (sc->sc_pss) free(sc->sc_pss, M_DEVBUF); sc->sc_pss = malloc(res.length * sizeof *sc->sc_pss, M_DEVBUF, M_WAITOK); memset(sc->sc_pss, 0, res.length * sizeof *sc->sc_pss); for (i = 0; i < res.length; i++) { sc->sc_pss[i].pss_core_freq = aml_val2int( res.v_package[i]->v_package[0]); sc->sc_pss[i].pss_power = aml_val2int( res.v_package[i]->v_package[1]); sc->sc_pss[i].pss_trans_latency = aml_val2int( res.v_package[i]->v_package[2]); sc->sc_pss[i].pss_bus_latency = aml_val2int( res.v_package[i]->v_package[3]); sc->sc_pss[i].pss_ctrl = aml_val2int( res.v_package[i]->v_package[4]); sc->sc_pss[i].pss_status = aml_val2int( res.v_package[i]->v_package[5]); } aml_freevalue(&res); sc->sc_pss_len = res.length; return (0); }
int acpitz_notify(struct aml_node *node, int notify_type, void *arg) { struct acpitz_softc *sc = arg; u_int64_t crt; dnprintf(10, "%s notify: %.2x %s\n", DEVNAME(sc), notify_type, sc->sc_devnode->parent->name); switch (notify_type) { case 0x81: /* Operating Points changed */ sc->sc_psv = acpitz_getreading(sc, "_PSV"); crt = sc->sc_crt; sc->sc_crt = acpitz_getreading(sc, "_CRT"); if (crt != sc->sc_crt) printf("%s: critical temperature: %u degC", DEVNAME(sc), (sc->sc_crt - 2732) / 10); break; default: break; } acpitz_refresh(sc); return (0); }
int acpidock_foundejd(struct aml_node *node, void *arg) { struct acpidock_softc *sc = (struct acpidock_softc *)arg; struct aml_value res; struct aml_node *dock; extern struct aml_node aml_root; dnprintf(15, "%s: %s", DEVNAME(sc), node->name); if (aml_evalnode(sc->sc_acpi, node, 0, NULL, &res) == -1) printf(": error\n"); else { dock = aml_searchname(&aml_root, res.v_string); if (dock == sc->sc_devnode) /* Add all children devices of Device containing _EJD */ aml_walknodes(node->parent, AML_WALK_POST, acpidock_walkchildren, sc); aml_freevalue(&res); } return (0); }
void acpicpu_setperf(int level) { struct acpicpu_softc *sc; struct acpicpu_pss *pss = NULL; int idx; u_int32_t stat_as, ctrl_as, stat_len, ctrl_len; u_int32_t status = 0; sc = acpicpu_sc[cpu_number()]; dnprintf(10, "%s: acpicpu setperf level %d\n", sc->sc_devnode->>name, level); if (level < 0 || level > 100) { dnprintf(10, "%s: acpicpu setperf illegal percentage\n", sc->sc_devnode->name); return; } idx = (sc->sc_pss_len - 1) - (level / (100 / sc->sc_pss_len)); if (idx < 0) idx = 0; /* compensate */ if (idx > sc->sc_pss_len) { /* XXX should never happen */ printf("%s: acpicpu setperf index out of range\n", sc->sc_devnode->name); return; } dnprintf(10, "%s: acpicpu setperf index %d\n", sc->sc_devnode->name, idx); pss = &sc->sc_pss[idx]; /* if not set assume single 32 bit access */ stat_as = sc->sc_pct.pct_status.grd_gas.register_bit_width / 8; if (stat_as == 0) stat_as = 4; ctrl_as = sc->sc_pct.pct_ctrl.grd_gas.register_bit_width / 8; if (ctrl_as == 0) ctrl_as = 4; stat_len = sc->sc_pct.pct_status.grd_gas.access_size; if (stat_len == 0) stat_len = stat_as; ctrl_len = sc->sc_pct.pct_ctrl.grd_gas.access_size; if (ctrl_len == 0) ctrl_len = ctrl_as; #ifdef ACPI_DEBUG /* keep this for now since we will need this for debug in the field */ printf("0 status: %x %llx %u %u ctrl: %x %llx %u %u\n", sc->sc_pct.pct_status.grd_gas.address_space_id, sc->sc_pct.pct_status.grd_gas.address, stat_as, stat_len, sc->sc_pct.pct_ctrl.grd_gas.address_space_id, sc->sc_pct.pct_ctrl.grd_gas.address, ctrl_as, ctrl_len); #endif acpi_gasio(sc->sc_acpi, ACPI_IOREAD, sc->sc_pct.pct_status.grd_gas.address_space_id, sc->sc_pct.pct_status.grd_gas.address, stat_as, stat_len, &status); dnprintf(20, "status: %u <- %u\n", status, pss->pss_status); /* Are we already at the requested frequency? */ if (status == pss->pss_status) return; acpi_gasio(sc->sc_acpi, ACPI_IOWRITE, sc->sc_pct.pct_ctrl.grd_gas.address_space_id, sc->sc_pct.pct_ctrl.grd_gas.address, ctrl_as, ctrl_len, &pss->pss_ctrl); dnprintf(20, "pss_ctrl: %x\n", pss->pss_ctrl); acpi_gasio(sc->sc_acpi, ACPI_IOREAD, sc->sc_pct.pct_status.grd_gas.address_space_id, sc->sc_pct.pct_status.grd_gas.address, stat_as, stat_as, &status); dnprintf(20, "3 status: %d\n", status); /* Did the transition succeed? */ if (status == pss->pss_status) cpuspeed = pss->pss_core_freq; else printf("%s: acpicpu setperf failed to alter frequency\n", sc->sc_devnode->name); }
int acpicpu_getpct(struct acpicpu_softc *sc) { struct aml_value res; int rv = 1; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PPC", 0, NULL, &res)) { dnprintf(20, "%s: no _PPC\n", DEVNAME(sc)); printf("%s: no _PPC\n", DEVNAME(sc)); return (1); } dnprintf(10, "_PPC: %d\n", aml_val2int(&res)); aml_freevalue(&res); if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PCT", 0, NULL, &res)) { printf("%s: no _PCT\n", DEVNAME(sc)); return (1); } if (res.length != 2) { printf("%s: %s: invalid _PCT length\n", DEVNAME(sc), sc->sc_devnode->name); return (1); } memcpy(&sc->sc_pct.pct_ctrl, res.v_package[0]->v_buffer, sizeof sc->sc_pct.pct_ctrl); if (sc->sc_pct.pct_ctrl.grd_gas.address_space_id == GAS_FUNCTIONAL_FIXED) { printf("CTRL GASIO is CPU manufacturer overridden\n"); goto bad; } memcpy(&sc->sc_pct.pct_status, res.v_package[1]->v_buffer, sizeof sc->sc_pct.pct_status); if (sc->sc_pct.pct_status.grd_gas.address_space_id == GAS_FUNCTIONAL_FIXED) { printf("STATUS GASIO is CPU manufacturer overridden\n"); goto bad; } dnprintf(10, "_PCT(ctrl) : %02x %04x %02x %02x %02x %02x %016x\n", sc->sc_pct.pct_ctrl.grd_descriptor, sc->sc_pct.pct_ctrl.grd_length, sc->sc_pct.pct_ctrl.grd_gas.address_space_id, sc->sc_pct.pct_ctrl.grd_gas.register_bit_width, sc->sc_pct.pct_ctrl.grd_gas.register_bit_offset, sc->sc_pct.pct_ctrl.grd_gas.access_size, sc->sc_pct.pct_ctrl.grd_gas.address); dnprintf(10, "_PCT(status): %02x %04x %02x %02x %02x %02x %016x\n", sc->sc_pct.pct_status.grd_descriptor, sc->sc_pct.pct_status.grd_length, sc->sc_pct.pct_status.grd_gas.address_space_id, sc->sc_pct.pct_status.grd_gas.register_bit_width, sc->sc_pct.pct_status.grd_gas.register_bit_offset, sc->sc_pct.pct_status.grd_gas.access_size, sc->sc_pct.pct_status.grd_gas.address); rv = 0; bad: aml_freevalue(&res); return (rv); }
void acpicpu_attach(struct device *parent, struct device *self, void *aux) { struct acpicpu_softc *sc = (struct acpicpu_softc *)self; struct acpi_attach_args *aa = aux; struct aml_value res; int i; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; SLIST_INIT(&sc->sc_cstates); sc->sc_pss = NULL; printf(": %s: ", sc->sc_devnode->name); if (aml_evalnode(sc->sc_acpi, sc->sc_devnode, 0, NULL, &res) == 0) { if (res.type == AML_OBJTYPE_PROCESSOR) { sc->sc_cpu = res.v_processor.proc_id; sc->sc_pblk_addr = res.v_processor.proc_addr; sc->sc_pblk_len = res.v_processor.proc_len; } aml_freevalue(&res); } sc->sc_duty_off = sc->sc_acpi->sc_fadt->duty_offset; sc->sc_duty_wid = sc->sc_acpi->sc_fadt->duty_width; if (!valid_throttle(sc->sc_duty_off, sc->sc_duty_wid, sc->sc_pblk_addr)) sc->sc_flags |= FLAGS_NOTHROTTLE; #ifdef ACPI_DEBUG printf(": %s: ", sc->sc_devnode->name); printf("\n: hdr:%x pblk:%x,%x duty:%x,%x pstate:%x (%d throttling states)\n", sc->sc_acpi->sc_fadt->hdr_revision, sc->sc_pblk_addr, sc->sc_pblk_len, sc->sc_duty_off, sc->sc_duty_wid, sc->sc_acpi->sc_fadt->pstate_cnt, CPU_MAXSTATE(sc)); #endif /* Get C-States from _CST or FADT */ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CST", 0, NULL, &res) == 0) { aml_foreachpkg(&res, 1, acpicpu_add_cstatepkg, sc); aml_freevalue(&res); } else { /* Some systems don't export a full PBLK, reduce functionality */ if (sc->sc_pblk_len < 5) sc->sc_flags |= FLAGS_NO_C2; if (sc->sc_pblk_len < 6) sc->sc_flags |= FLAGS_NO_C3; acpicpu_add_cstate(sc, ACPI_STATE_C2, sc->sc_acpi->sc_fadt->p_lvl2_lat, -1, sc->sc_pblk_addr + 4); acpicpu_add_cstate(sc, ACPI_STATE_C3, sc->sc_acpi->sc_fadt->p_lvl3_lat, -1, sc->sc_pblk_addr + 5); } if (acpicpu_getpss(sc)) { /* XXX not the right test but has to do for now */ sc->sc_flags |= FLAGS_NOPSS; goto nopss; } #ifdef ACPI_DEBUG for (i = 0; i < sc->sc_pss_len; i++) { dnprintf(20, "%d %d %d %d %d %d\n", sc->sc_pss[i].pss_core_freq, sc->sc_pss[i].pss_power, sc->sc_pss[i].pss_trans_latency, sc->sc_pss[i].pss_bus_latency, sc->sc_pss[i].pss_ctrl, sc->sc_pss[i].pss_status); } dnprintf(20, "\n"); #endif /* XXX this needs to be moved to probe routine */ if (acpicpu_getpct(sc)) return; /* Notify BIOS we are handing p-states */ if (sc->sc_acpi->sc_fadt->pstate_cnt) acpi_write_pmreg(sc->sc_acpi, ACPIREG_SMICMD, 0, sc->sc_acpi->sc_fadt->pstate_cnt); for (i = 0; i < sc->sc_pss_len; i++) printf("%d%s", sc->sc_pss[i].pss_core_freq, i < sc->sc_pss_len - 1 ? ", " : " MHz\n"); aml_register_notify(sc->sc_devnode, NULL, acpicpu_notify, sc, ACPIDEV_NOPOLL); if (setperf_prio < 30) { cpu_setperf = acpicpu_setperf; setperf_prio = 30; acpi_hasprocfvs = 1; } acpicpu_sc[sc->sc_dev.dv_unit] = sc; return; nopss: if (sc->sc_flags & FLAGS_NOTHROTTLE) printf("no performance/throttling supported\n"); }
int acpibat_getbif(struct acpibat_softc *sc) { struct aml_value res; int rv = EINVAL; if (!sc->sc_bat_present) { memset(&sc->sc_bif, 0, sizeof(sc->sc_bif)); return (0); } if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BIF", 0, NULL, &res)) { dnprintf(10, "%s: no _BIF\n", DEVNAME(sc)); goto out; } if (res.length != 13) { dnprintf(10, "%s: invalid _BIF, battery info not saved\n", DEVNAME(sc)); goto out; } sc->sc_bif.bif_power_unit = aml_val2int(res.v_package[0]); sc->sc_bif.bif_capacity = aml_val2int(res.v_package[1]); sc->sc_bif.bif_last_capacity = aml_val2int(res.v_package[2]); sc->sc_bif.bif_technology = aml_val2int(res.v_package[3]); sc->sc_bif.bif_voltage = aml_val2int(res.v_package[4]); sc->sc_bif.bif_warning = aml_val2int(res.v_package[5]); sc->sc_bif.bif_low = aml_val2int(res.v_package[6]); sc->sc_bif.bif_cap_granu1 = aml_val2int(res.v_package[7]); sc->sc_bif.bif_cap_granu2 = aml_val2int(res.v_package[8]); strlcpy(sc->sc_bif.bif_model, aml_val_to_string(res.v_package[9]), sizeof(sc->sc_bif.bif_model)); strlcpy(sc->sc_bif.bif_serial, aml_val_to_string(res.v_package[10]), sizeof(sc->sc_bif.bif_serial)); strlcpy(sc->sc_bif.bif_type, aml_val_to_string(res.v_package[11]), sizeof(sc->sc_bif.bif_type)); strlcpy(sc->sc_bif.bif_oem, aml_val_to_string(res.v_package[12]), sizeof(sc->sc_bif.bif_oem)); dnprintf(60, "power_unit: %u capacity: %u last_cap: %u tech: %u " "volt: %u warn: %u low: %u gran1: %u gran2: %d model: %s " "serial: %s type: %s oem: %s\n", sc->sc_bif.bif_power_unit, sc->sc_bif.bif_capacity, sc->sc_bif.bif_last_capacity, sc->sc_bif.bif_technology, sc->sc_bif.bif_voltage, sc->sc_bif.bif_warning, sc->sc_bif.bif_low, sc->sc_bif.bif_cap_granu1, sc->sc_bif.bif_cap_granu2, sc->sc_bif.bif_model, sc->sc_bif.bif_serial, sc->sc_bif.bif_type, sc->sc_bif.bif_oem); rv = 0; out: aml_freevalue(&res); return (rv); }