/* * Query ACPI processor ID by evaluating ACPI _MAT, _UID, and PROCESSOR * objects. */ static ACPI_STATUS acpidev_cpu_get_procid(acpidev_walk_info_t *infop, uint32_t *idp) { int id; ACPI_HANDLE hdl; struct acpidev_cpu_MAT_arg mat; if (infop->awi_info->Type != ACPI_TYPE_PROCESSOR && infop->awi_info->Type != ACPI_TYPE_DEVICE) { ACPIDEV_DEBUG(CE_WARN, "!acpidev: object %s is not PROCESSOR or DEVICE.", infop->awi_name); return (AE_BAD_PARAMETER); } hdl = infop->awi_hdl; /* * First try to evaluate _MAT. * According to the ACPI Spec3.0b, it's legal for ACPI PROCESSOR objects * to have ACPI method objects. */ bzero(&mat, sizeof (mat)); (void) acpidev_walk_apic(NULL, hdl, ACPIDEV_METHOD_NAME_MAT, acpidev_cpu_query_MAT, &mat); if (mat.found) { *idp = mat.proc_id; return (AE_OK); } /* Then evalute PROCESSOR object. */ if (infop->awi_info->Type == ACPI_TYPE_PROCESSOR) { ACPI_BUFFER rb; rb.Pointer = NULL; rb.Length = ACPI_ALLOCATE_BUFFER; if (ACPI_SUCCESS(AcpiEvaluateObjectTyped(hdl, NULL, NULL, &rb, ACPI_TYPE_PROCESSOR))) { *idp = ((ACPI_OBJECT *)rb.Pointer)->Processor.ProcId; AcpiOsFree(rb.Pointer); return (AE_OK); } else { ACPIDEV_DEBUG(CE_WARN, "!acpidev: failed to evaluate ACPI object %s.", infop->awi_name); } } /* * Finally, try to evalute the _UID method. * According to the ACPI Spec3.0b, it's legal for ACPI PROCESSOR objects * to have ACPI method objects. * The CPU _UID method should return Processor Id as an integer on x86. */ if (ACPI_SUCCESS(acpica_eval_int(hdl, METHOD_NAME__UID, &id))) { *idp = id; return (AE_OK); } return (AE_NOT_FOUND); }
ACPI_STATUS sony_acpi_eval_set_integer(ACPI_HANDLE handle, const char *path, ACPI_INTEGER val, ACPI_INTEGER *valp) { ACPI_STATUS rv; ACPI_BUFFER buf; ACPI_OBJECT param, ret_val; ACPI_OBJECT_LIST params; if (handle == NULL) handle = ACPI_ROOT_OBJECT; params.Count = 1; params.Pointer = ¶m; param.Type = ACPI_TYPE_INTEGER; param.Integer.Value = val; buf.Pointer = &ret_val; buf.Length = sizeof(ret_val); rv = AcpiEvaluateObjectTyped(handle, path, ¶ms, &buf, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS(rv) && valp) *valp = ret_val.Integer.Value; return rv; }
/* * HCI/SCI operation */ static ACPI_STATUS hci_op(struct valz_acpi_softc *sc, uint32_t *input, uint32_t *output) { ACPI_STATUS rv; ACPI_OBJECT Arg[HCI_WORDS]; ACPI_OBJECT_LIST ArgList; ACPI_OBJECT *param, *PrtElement; ACPI_BUFFER buf; int i; for (i = 0; i < HCI_WORDS; i++) { Arg[i].Type = ACPI_TYPE_INTEGER; Arg[i].Integer.Value = 0; } for (i = 0; i < HCI_WORDS; i++) { Arg[i].Integer.Value = input[i]; } ArgList.Count = HCI_WORDS; ArgList.Pointer = Arg; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; rv = AcpiEvaluateObjectTyped(sc->sc_node->ad_handle, METHOD_HCI, &ArgList, &buf, ACPI_TYPE_PACKAGE); if (ACPI_FAILURE(rv)) { aprint_error_dev(sc->sc_dev, "failed to evaluate GHCI: %s\n", AcpiFormatException(rv)); return rv; } for (i = 0; i < HCI_WORDS; i++) { output[i] = 0; } param = (ACPI_OBJECT *)buf.Pointer; PrtElement = param->Package.Elements; for (i = 0; i < HCI_WORDS; i++) { if (PrtElement->Type == ACPI_TYPE_INTEGER) output[i] = PrtElement->Integer.Value; PrtElement++; } if (buf.Pointer) ACPI_FREE(buf.Pointer); return rv; }
PRIVATE ACPI_STATUS device_get_int(ACPI_HANDLE handle, char * name, ACPI_INTEGER * val) { ACPI_STATUS status; char buff[sizeof(ACPI_OBJECT)]; ACPI_BUFFER abuff; abuff.Length = sizeof(buff); abuff.Pointer = buff; status = AcpiEvaluateObjectTyped(handle, name, NULL, &abuff, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS(status)) { *val = ((ACPI_OBJECT *)abuff.Pointer)->Integer.Value; } return status; }
status_t get_object_typed(const char* path, acpi_object_type** _returnValue, uint32 objectType) { ACPI_HANDLE handle; ACPI_BUFFER buffer; ACPI_STATUS status; status = AcpiGetHandle(NULL, (ACPI_STRING)path, &handle); if (status != AE_OK) return B_ENTRY_NOT_FOUND; buffer.Pointer = NULL; buffer.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObjectTyped(handle, NULL, NULL, &buffer, objectType); *_returnValue = (acpi_object_type*)buffer.Pointer; return status == AE_OK ? B_OK : B_ERROR; }
static int aibs_sysctl(SYSCTL_HANDLER_ARGS) { struct aibs_softc *sc = arg1; enum aibs_type st = arg2; int i = oidp->oid_number; ACPI_STATUS rs; ACPI_OBJECT p, *bp; ACPI_OBJECT_LIST mp; ACPI_BUFFER b; char *name; struct aibs_sensor *as; ACPI_INTEGER v, l, h; int so[3]; switch (st) { case AIBS_VOLT: name = "RVLT"; as = sc->sc_asens_volt; break; case AIBS_TEMP: name = "RTMP"; as = sc->sc_asens_temp; break; case AIBS_FAN: name = "RFAN"; as = sc->sc_asens_fan; break; default: return ENOENT; } if (as == NULL) return ENOENT; l = as[i].l; h = as[i].h; p.Type = ACPI_TYPE_INTEGER; p.Integer.Value = as[i].i; mp.Count = 1; mp.Pointer = &p; b.Length = ACPI_ALLOCATE_BUFFER; ACPI_SERIAL_BEGIN(aibs); rs = AcpiEvaluateObjectTyped(sc->sc_ah, name, &mp, &b, ACPI_TYPE_INTEGER); if (ACPI_FAILURE(rs)) { ddevice_printf(sc->sc_dev, "%s: %i: evaluation failed\n", name, i); ACPI_SERIAL_END(aibs); return EIO; } bp = b.Pointer; v = bp->Integer.Value; AcpiOsFree(b.Pointer); ACPI_SERIAL_END(aibs); switch (st) { case AIBS_VOLT: break; case AIBS_TEMP: v += 2731; l += 2731; h += 2731; break; case AIBS_FAN: break; } so[0] = v; so[1] = l; so[2] = h; return sysctl_handle_opaque(oidp, &so, sizeof(so), req); }
static void aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st) { ACPI_STATUS s; ACPI_BUFFER b; ACPI_OBJECT *bp, *o; int i, n; const char *node; char name[] = "?SIF"; struct aibs_sensor *as; struct sysctl_oid *so; switch (st) { case AIBS_VOLT: node = "volt"; name[0] = 'V'; break; case AIBS_TEMP: node = "temp"; name[0] = 'T'; break; case AIBS_FAN: node = "fan"; name[0] = 'F'; break; default: return; } b.Length = ACPI_ALLOCATE_BUFFER; s = AcpiEvaluateObjectTyped(sc->sc_ah, name, NULL, &b, ACPI_TYPE_PACKAGE); if (ACPI_FAILURE(s)) { device_printf(sc->sc_dev, "%s not found\n", name); return; } bp = b.Pointer; o = bp->Package.Elements; if (o[0].Type != ACPI_TYPE_INTEGER) { device_printf(sc->sc_dev, "%s[0]: invalid type\n", name); AcpiOsFree(b.Pointer); return; } n = o[0].Integer.Value; if (bp->Package.Count - 1 < n) { device_printf(sc->sc_dev, "%s: invalid package\n", name); AcpiOsFree(b.Pointer); return; } else if (bp->Package.Count - 1 > n) { int on = n; #ifdef AIBS_MORE_SENSORS n = bp->Package.Count - 1; #endif device_printf(sc->sc_dev, "%s: malformed package: %i/%i" ", assume %i\n", name, on, bp->Package.Count - 1, n); } if (n < 1) { device_printf(sc->sc_dev, "%s: no members in the package\n", name); AcpiOsFree(b.Pointer); return; } as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO); if (as == NULL) { device_printf(sc->sc_dev, "%s: malloc fail\n", name); AcpiOsFree(b.Pointer); return; } switch (st) { case AIBS_VOLT: sc->sc_asens_volt = as; break; case AIBS_TEMP: sc->sc_asens_temp = as; break; case AIBS_FAN: sc->sc_asens_fan = as; break; } /* sysctl subtree for sensors of this type */ so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev), SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), st, node, CTLFLAG_RD, NULL, NULL); for (i = 0, o++; i < n; i++, o++) { ACPI_OBJECT *oi; char si[3]; const char *desc; /* acpica5 automatically evaluates the referenced package */ if (o[0].Type != ACPI_TYPE_PACKAGE) { device_printf(sc->sc_dev, "%s: %i: not a package: %i type\n", name, i, o[0].Type); continue; } oi = o[0].Package.Elements; if (o[0].Package.Count != 5 || oi[0].Type != ACPI_TYPE_INTEGER || oi[1].Type != ACPI_TYPE_STRING || oi[2].Type != ACPI_TYPE_INTEGER || oi[3].Type != ACPI_TYPE_INTEGER || oi[4].Type != ACPI_TYPE_INTEGER) { device_printf(sc->sc_dev, "%s: %i: invalid package\n", name, i); continue; } as[i].i = oi[0].Integer.Value; desc = oi[1].String.Pointer; as[i].l = oi[2].Integer.Value; as[i].h = oi[3].Integer.Value; as[i].t = st; #ifdef AIBS_VERBOSE device_printf(sc->sc_dev, "%c%i: " "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64" " "0x%"PRIx64"\n", name[0], i, (uint64_t)as[i].i, desc, (int64_t)as[i].l, (int64_t)as[i].h, (uint64_t)oi[4].Integer.Value); #endif snprintf(si, sizeof(si), "%i", i); SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev), SYSCTL_CHILDREN(so), i, si, CTLTYPE_INT | CTLFLAG_RD, sc, st, aibs_sysctl, st == AIBS_TEMP ? "IK" : "I", desc); } AcpiOsFree(b.Pointer); }
static void aibs_refresh_r(struct aibs_softc *sc, enum sensor_type st) { ACPI_STATUS rs; ACPI_HANDLE rh; int i, n = sc->sc_sensordev.maxnumt[st]; char *name; struct aibs_sensor *as; switch (st) { case SENSOR_TEMP: name = "RTMP"; as = sc->sc_asens_temp; break; case SENSOR_FANRPM: name = "RFAN"; as = sc->sc_asens_fan; break; case SENSOR_VOLTS_DC: name = "RVLT"; as = sc->sc_asens_volt; break; default: return; } if (as == NULL) return; rs = AcpiGetHandle(sc->sc_ah, name, &rh); if (ACPI_FAILURE(rs)) { ddevice_printf(sc->sc_dev, "%s: method handle not found\n", name); for (i = 0; i < n; i++) as[i].s.flags |= SENSOR_FINVALID; return; } for (i = 0; i < n; i++) { ACPI_OBJECT p, *bp; ACPI_OBJECT_LIST mp; ACPI_BUFFER b; UINT64 v; struct ksensor *s = &as[i].s; const UINT64 l = as[i].l, h = as[i].h; p.Type = ACPI_TYPE_INTEGER; p.Integer.Value = as[i].i; mp.Count = 1; mp.Pointer = &p; b.Length = ACPI_ALLOCATE_BUFFER; rs = AcpiEvaluateObjectTyped(rh, NULL, &mp, &b, ACPI_TYPE_INTEGER); if (ACPI_FAILURE(rs)) { ddevice_printf(sc->sc_dev, "%s: %i: evaluation failed\n", name, i); s->flags |= SENSOR_FINVALID; continue; } bp = b.Pointer; v = bp->Integer.Value; AcpiOsFree(b.Pointer); switch (st) { case SENSOR_TEMP: s->value = v * 100 * 1000 + 273150000; if (v == 0) { s->status = SENSOR_S_UNKNOWN; s->flags |= SENSOR_FINVALID; } else { if (v > h) s->status = SENSOR_S_CRIT; else if (v > l) s->status = SENSOR_S_WARN; else s->status = SENSOR_S_OK; s->flags &= ~SENSOR_FINVALID; } break; case SENSOR_FANRPM: s->value = v; /* some boards have strange limits for fans */ if ((l != 0 && l < v && v < h) || (l == 0 && v > h)) s->status = SENSOR_S_OK; else s->status = SENSOR_S_WARN; s->flags &= ~SENSOR_FINVALID; break; case SENSOR_VOLTS_DC: s->value = v * 1000; if (l < v && v < h) s->status = SENSOR_S_OK; else s->status = SENSOR_S_WARN; s->flags &= ~SENSOR_FINVALID; break; default: /* NOTREACHED */ break; } } return; }
static void aibs_attach_sif(struct aibs_softc *sc, enum sensor_type st) { ACPI_STATUS s; ACPI_BUFFER b; ACPI_OBJECT *bp, *o; int i, n; char name[] = "?SIF"; struct aibs_sensor *as; switch (st) { case SENSOR_TEMP: name[0] = 'T'; break; case SENSOR_FANRPM: name[0] = 'F'; break; case SENSOR_VOLTS_DC: name[0] = 'V'; break; default: return; } b.Length = ACPI_ALLOCATE_BUFFER; s = AcpiEvaluateObjectTyped(sc->sc_ah, name, NULL, &b, ACPI_TYPE_PACKAGE); if (ACPI_FAILURE(s)) { device_printf(sc->sc_dev, "%s not found\n", name); return; } bp = b.Pointer; o = bp->Package.Elements; if (o[0].Type != ACPI_TYPE_INTEGER) { device_printf(sc->sc_dev, "%s[0]: invalid type\n", name); AcpiOsFree(b.Pointer); return; } n = o[0].Integer.Value; if (bp->Package.Count - 1 < n) { device_printf(sc->sc_dev, "%s: invalid package\n", name); AcpiOsFree(b.Pointer); return; } else if (bp->Package.Count - 1 > n) { int on = n; #ifdef AIBS_MORE_SENSORS n = bp->Package.Count - 1; #endif device_printf(sc->sc_dev, "%s: malformed package: %i/%i" ", assume %i\n", name, on, bp->Package.Count - 1, n); } if (n < 1) { device_printf(sc->sc_dev, "%s: no members in the package\n", name); AcpiOsFree(b.Pointer); return; } as = kmalloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO); if (as == NULL) { device_printf(sc->sc_dev, "%s: malloc fail\n", name); AcpiOsFree(b.Pointer); return; } switch (st) { case SENSOR_TEMP: sc->sc_asens_temp = as; break; case SENSOR_FANRPM: sc->sc_asens_fan = as; break; case SENSOR_VOLTS_DC: sc->sc_asens_volt = as; break; default: /* NOTREACHED */ return; } for (i = 0, o++; i < n; i++, o++) { ACPI_OBJECT *oi; /* acpica automatically evaluates the referenced package */ if (o[0].Type != ACPI_TYPE_PACKAGE) { device_printf(sc->sc_dev, "%s: %i: not a package: %i type\n", name, i, o[0].Type); continue; } oi = o[0].Package.Elements; if (o[0].Package.Count != 5 || oi[0].Type != ACPI_TYPE_INTEGER || oi[1].Type != ACPI_TYPE_STRING || oi[2].Type != ACPI_TYPE_INTEGER || oi[3].Type != ACPI_TYPE_INTEGER || oi[4].Type != ACPI_TYPE_INTEGER) { device_printf(sc->sc_dev, "%s: %i: invalid package\n", name, i); continue; } as[i].i = oi[0].Integer.Value; strlcpy(as[i].s.desc, oi[1].String.Pointer, sizeof(as[i].s.desc)); as[i].l = oi[2].Integer.Value; as[i].h = oi[3].Integer.Value; as[i].s.type = st; #ifdef AIBS_VERBOSE device_printf(sc->sc_dev, "%c%i: " "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64" " "0x%"PRIx64"\n", name[0], i, as[i].i, as[i].s.desc, (int64_t)as[i].l, (int64_t)as[i].h, oi[4].Integer.Value); #endif sensor_attach(&sc->sc_sensordev, &as[i].s); } AcpiOsFree(b.Pointer); return; }
ACPI_STATUS DisplayOneDevice (ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **RetVal) { ACPI_STATUS Status; ACPI_DEVICE_INFO *Info; ACPI_BUFFER Path; ACPI_BUFFER Result; ACPI_OBJECT Obj; char Buffer[256]; uint8 prt_buf[1024]; ACPI_BUFFER Prt = { .Length = sizeof (prt_buf), .Pointer = prt_buf }; ACPI_PCI_ROUTING_TABLE *prtd; uint32 addr=0; uint32 fun = 0; bool pcibus=FALSE; u8 busnum; Path.Length = sizeof (Buffer); Path.Pointer = Buffer; Status = AcpiGetName (ObjHandle, ACPI_FULL_PATHNAME, &Path); if (ACPI_SUCCESS (Status)) { DLOG_COM1 ("%s: \n", Path.Pointer); } Status = AcpiGetObjectInfo (ObjHandle, &Info); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" "); if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) { DLOG_COM1 (" PCI_ROOT"); busnum = 0; pcibus = TRUE; } if (Info->Valid & ACPI_VALID_STA) DLOG_COM1 (" STA %.8X", Info->CurrentStatus); if (Info->Valid & ACPI_VALID_ADR) { DLOG_COM1 (" ADR %.8X", Info->Address); addr = Info->Address >> 16; fun = Info->Address & 0x7; } if (Info->Valid & ACPI_VALID_HID) DLOG_COM1 (" HID %s", Info->HardwareId.String); if (Info->Valid & ACPI_VALID_UID) DLOG_COM1 (" UID %s", Info->UniqueId.String); if (Info->Valid & ACPI_VALID_CID) DLOG_COM1 (" CID"); ACPI_FREE (Info); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_DDN", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" DDN=%s", Obj.String.Pointer); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_STR", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" STR=%s", Obj.String.Pointer); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_MLS", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" MLS=%s", Obj.String.Pointer); } Status = AcpiEvaluateObjectTyped (ObjHandle, "_BBN", NULL, &Result, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" BBN=%d", Obj.Integer.Value); } else if (Status != AE_NOT_FOUND) DLOG_COM1 (" bbnERR=%d", Status); Status = AcpiEvaluateObjectTyped (ObjHandle, "_PXM", NULL, &Result, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" PXM=%d", Obj.Integer.Value); } else if (Status != AE_NOT_FOUND) DLOG_COM1 (" pxmERR=%d", Status); DLOG_COM1 ("\n"); for (;;) { Status = AcpiGetIrqRoutingTable (ObjHandle, &Prt); if (ACPI_FAILURE (Status)) { if (Status == AE_BUFFER_OVERFLOW) { DLOG_COM1 ("AcpiGetIrqRoutingTable failed: BUFFER OVERFLOW\n"); } break; } else break; } if (ACPI_SUCCESS (Status)) { int i; /* Check if ObjHandle refers to a non-root PCI bus */ if (READ (0, addr, fun, 0, dword) != 0xFFFFFFFF) { u8 hdrtype = READ (0, addr, fun, 0x0E, byte); if ((hdrtype & 0x7F) == 1) { /* PCI-to-PCI bridge headerType == 1 */ busnum = READ (0, addr, fun, 0x19, byte); //busnum = READ (0, addr, fun, 0x1A, byte); DLOG_COM1 (" bus=0x%.02X\n", busnum); pcibus = TRUE; } } for (i=0;i<sizeof(prt_buf);) { pci_irq_t irq; prtd = (ACPI_PCI_ROUTING_TABLE *)(&prt_buf[i]); if (prtd->Length == 0) break; if (pcibus) { irq.pin = prtd->Pin + 1; /* ACPI numbers pins from 0 */ irq.gsi = 0; } if (prtd->Source[0]) { DLOG_COM1 (" PRT entry: len=%d pin=%d addr=%p srcidx=0x%x src=%s\n", prtd->Length, prtd->Pin, (uint32)prtd->Address, prtd->SourceIndex, &prtd->Source[0]); GetLnkInfo (&prtd->Source[0], &irq); } else { DLOG_COM1 (" PRT entry: len=%d pin=%d addr=%p fixed IRQ=0x%x\n", prtd->Length, prtd->Pin, (uint32)prtd->Address, prtd->SourceIndex); irq.gsi = prtd->SourceIndex; irq.polarity = POLARITY_DEFAULT; irq.trigger = TRIGGER_DEFAULT; } if (pcibus && irq.gsi != 0) pci_irq_register (&irq); i+=prtd->Length; } } #if 0 ACPI_STATUS DisplayResource (ACPI_RESOURCE *Resource, void *Context); DLOG_COM1 (" _PRS:\n"); AcpiWalkResources (ObjHandle, "_PRS", DisplayResource, NULL); DLOG_COM1 (" _CRS:\n"); AcpiWalkResources (ObjHandle, "_CRS", DisplayResource, NULL); #endif return AE_OK; }