/** * radeon_atpx_call - call an ATPX method * * @handle: acpi handle * @function: the ATPX function to execute * @params: ATPX function params * * Executes the requested ATPX function (all asics). * Returns a pointer to the acpi output buffer. */ static ACPI_OBJECT *radeon_atpx_call(ACPI_HANDLE handle, int function, ACPI_BUFFER *params) { ACPI_STATUS status; ACPI_OBJECT atpx_arg_elements[2]; ACPI_OBJECT_LIST atpx_arg; ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL }; atpx_arg.Count = 2; atpx_arg.Pointer = &atpx_arg_elements[0]; atpx_arg_elements[0].Type = ACPI_TYPE_INTEGER; atpx_arg_elements[0].Integer.Value = function; if (params) { atpx_arg_elements[1].Type = ACPI_TYPE_BUFFER; atpx_arg_elements[1].Buffer.Length = params->Length; atpx_arg_elements[1].Buffer.Pointer = params->Pointer; } else { /* We need a second fake parameter */ atpx_arg_elements[1].Type = ACPI_TYPE_INTEGER; atpx_arg_elements[1].Integer.Value = 0; } status = AcpiEvaluateObject(handle, NULL, &atpx_arg, &buffer); /* Fail only if calling the method fails and ATPX is supported */ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { DRM_ERROR("failed to evaluate ATPX got %s\n", AcpiFormatException(status)); AcpiOsFree(buffer.Pointer); return NULL; } return buffer.Pointer; }
void * AcpiUtAllocateAndTrack ( ACPI_SIZE Size, UINT32 Component, const char *Module, UINT32 Line) { ACPI_DEBUG_MEM_BLOCK *Allocation; ACPI_STATUS Status; Allocation = AcpiUtAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER), Component, Module, Line); if (!Allocation) { return (NULL); } Status = AcpiUtTrackAllocation (Allocation, Size, ACPI_MEM_MALLOC, Component, Module, Line); if (ACPI_FAILURE (Status)) { AcpiOsFree (Allocation); return (NULL); } AcpiGbl_GlobalList->TotalAllocated++; AcpiGbl_GlobalList->TotalSize += (UINT32) Size; AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; if (AcpiGbl_GlobalList->CurrentTotalSize > AcpiGbl_GlobalList->MaxOccupied) { AcpiGbl_GlobalList->MaxOccupied = AcpiGbl_GlobalList->CurrentTotalSize; } return ((void *) &Allocation->UserSpace); }
static int acpi_panasonic_hkey_event(struct acpi_panasonic_softc *sc, ACPI_HANDLE h, UINT32 *arg) { ACPI_BUFFER buf; ACPI_OBJECT *res; ACPI_INTEGER val; int status; ACPI_SERIAL_ASSERT(panasonic); status = ENXIO; buf.Length = ACPI_ALLOCATE_BUFFER; buf.Pointer = NULL; AcpiEvaluateObject(h, "HINF", NULL, &buf); res = (ACPI_OBJECT *)buf.Pointer; if (res->Type != ACPI_TYPE_INTEGER) { device_printf(sc->dev, "HINF returned non-integer\n"); goto end; } val = res->Integer.Value; #ifdef ACPI_PANASONIC_DEBUG device_printf(sc->dev, "%s button Fn+F%d\n", (val & 0x80) ? "Pressed" : "Released", (int)(val & 0x7f)); #endif if ((val & 0x7f) > 0 && (val & 0x7f) < 11) { *arg = val; status = 0; } end: if (buf.Pointer) AcpiOsFree(buf.Pointer); return (status); }
static ACPI_STATUS AeExceptionHandler ( ACPI_STATUS AmlStatus, ACPI_NAME Name, UINT16 Opcode, UINT32 AmlOffset, void *Context) { ACPI_STATUS NewAmlStatus = AmlStatus; ACPI_STATUS Status; ACPI_BUFFER ReturnObj; ACPI_OBJECT_LIST ArgList; ACPI_OBJECT Arg[3]; const char *Exception; Exception = AcpiFormatException (AmlStatus); AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception); if (Name) { AcpiOsPrintf ("of method [%4.4s]", (char *) &Name); } else { AcpiOsPrintf ("at module level (table load)"); } AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset); /* * Invoke the _ERR method if present * * Setup parameter object */ ArgList.Count = 3; ArgList.Pointer = Arg; Arg[0].Type = ACPI_TYPE_INTEGER; Arg[0].Integer.Value = AmlStatus; Arg[1].Type = ACPI_TYPE_STRING; Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception); Arg[1].String.Length = ACPI_STRLEN (Exception); Arg[2].Type = ACPI_TYPE_INTEGER; Arg[2].Integer.Value = AcpiOsGetThreadId(); /* Setup return buffer */ ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj); if (ACPI_SUCCESS (Status)) { if (ReturnObj.Pointer) { /* Override original status */ NewAmlStatus = (ACPI_STATUS) ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value; /* Free a buffer created via ACPI_ALLOCATE_BUFFER */ AcpiOsFree (ReturnObj.Pointer); } } else if (Status != AE_NOT_FOUND) { AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n", AcpiFormatException (Status)); } /* Global override */ if (AcpiGbl_IgnoreErrors) { NewAmlStatus = AE_OK; } if (NewAmlStatus != AmlStatus) { AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n", AcpiFormatException (NewAmlStatus)); } return (NewAmlStatus); }
void AcpiDbAddToHistory ( char *CommandLine) { UINT16 CmdLen; UINT16 BufferLen; /* Put command into the next available slot */ CmdLen = (UINT16) strlen (CommandLine); if (!CmdLen) { return; } if (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command != NULL) { BufferLen = (UINT16) strlen ( AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command); if (CmdLen > BufferLen) { AcpiOsFree (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex]. Command); AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command = AcpiOsAllocate (CmdLen + 1); } } else { AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command = AcpiOsAllocate (CmdLen + 1); } strcpy (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command, CommandLine); AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].CmdNum = AcpiGbl_NextCmdNum; /* Adjust indexes */ if ((AcpiGbl_NumHistory == HISTORY_SIZE) && (AcpiGbl_NextHistoryIndex == AcpiGbl_LoHistory)) { AcpiGbl_LoHistory++; if (AcpiGbl_LoHistory >= HISTORY_SIZE) { AcpiGbl_LoHistory = 0; } } AcpiGbl_NextHistoryIndex++; if (AcpiGbl_NextHistoryIndex >= HISTORY_SIZE) { AcpiGbl_NextHistoryIndex = 0; } AcpiGbl_NextCmdNum++; if (AcpiGbl_NumHistory < HISTORY_SIZE) { AcpiGbl_NumHistory++; } }
void AeMiscellaneousTests ( void) { ACPI_BUFFER ReturnBuf; char Buffer[32]; ACPI_STATUS Status; ACPI_STATISTICS Stats; ACPI_HANDLE Handle; #if (!ACPI_REDUCED_HARDWARE) UINT32 LockHandle1; UINT32 LockHandle2; ACPI_VENDOR_UUID Uuid = {0, {ACPI_INIT_UUID (0,0,0,0,0,0,0,0,0,0,0)}}; #endif /* !ACPI_REDUCED_HARDWARE */ Status = AcpiGetHandle (NULL, "\\", &Handle); ACPI_CHECK_OK (AcpiGetHandle, Status); if (AcpiGbl_DoInterfaceTests) { /* * Tests for AcpiLoadTable and AcpiUnloadParentTable */ /* Attempt unload of DSDT, should fail */ Status = AcpiGetHandle (NULL, "\\_SB_", &Handle); ACPI_CHECK_OK (AcpiGetHandle, Status); Status = AcpiUnloadParentTable (Handle); ACPI_CHECK_STATUS (AcpiUnloadParentTable, Status, AE_TYPE); /* Load and unload SSDT4 */ Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt4Code); ACPI_CHECK_OK (AcpiLoadTable, Status); Status = AcpiGetHandle (NULL, "\\_T96", &Handle); ACPI_CHECK_OK (AcpiGetHandle, Status); Status = AcpiUnloadParentTable (Handle); ACPI_CHECK_OK (AcpiUnloadParentTable, Status); /* Re-load SSDT4 */ Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt4Code); ACPI_CHECK_OK (AcpiLoadTable, Status); /* Unload and re-load SSDT2 (SSDT2 is in the XSDT) */ Status = AcpiGetHandle (NULL, "\\_T99", &Handle); ACPI_CHECK_OK (AcpiGetHandle, Status); Status = AcpiUnloadParentTable (Handle); ACPI_CHECK_OK (AcpiUnloadParentTable, Status); Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt2Code); ACPI_CHECK_OK (AcpiLoadTable, Status); /* Load OEM9 table (causes table override) */ Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt3Code); ACPI_CHECK_OK (AcpiLoadTable, Status); } AeHardwareInterfaces (); AeGenericRegisters (); AeSetupConfiguration (Ssdt3Code); AeTestBufferArgument(); AeTestPackageArgument (); AeMutexInterfaces (); AeTestSleepData (); /* Test _OSI install/remove */ Status = AcpiInstallInterface (""); ACPI_CHECK_STATUS (AcpiInstallInterface, Status, AE_BAD_PARAMETER); Status = AcpiInstallInterface ("TestString"); ACPI_CHECK_OK (AcpiInstallInterface, Status); Status = AcpiInstallInterface ("TestString"); ACPI_CHECK_STATUS (AcpiInstallInterface, Status, AE_ALREADY_EXISTS); Status = AcpiRemoveInterface ("Windows 2006"); ACPI_CHECK_OK (AcpiRemoveInterface, Status); Status = AcpiRemoveInterface ("TestString"); ACPI_CHECK_OK (AcpiRemoveInterface, Status); Status = AcpiRemoveInterface ("XXXXXX"); ACPI_CHECK_STATUS (AcpiRemoveInterface, Status, AE_NOT_EXIST); Status = AcpiInstallInterface ("AnotherTestString"); ACPI_CHECK_OK (AcpiInstallInterface, Status); /* Test _OSI execution */ Status = ExecuteOSI ("Extended Address Space Descriptor", ACPI_UINT64_MAX); ACPI_CHECK_OK (ExecuteOSI, Status); Status = ExecuteOSI ("Windows 2001", ACPI_UINT64_MAX); ACPI_CHECK_OK (ExecuteOSI, Status); Status = ExecuteOSI ("MichiganTerminalSystem", 0); ACPI_CHECK_OK (ExecuteOSI, Status); ReturnBuf.Length = 32; ReturnBuf.Pointer = Buffer; Status = AcpiGetName (ACPI_ROOT_OBJECT, ACPI_FULL_PATHNAME_NO_TRAILING, &ReturnBuf); ACPI_CHECK_OK (AcpiGetName, Status); /* Get Devices */ Status = AcpiGetDevices (NULL, AeGetDevices, NULL, NULL); ACPI_CHECK_OK (AcpiGetDevices, Status); Status = AcpiGetStatistics (&Stats); ACPI_CHECK_OK (AcpiGetStatistics, Status); #if (!ACPI_REDUCED_HARDWARE) Status = AcpiInstallGlobalEventHandler (AeGlobalEventHandler, NULL); ACPI_CHECK_OK (AcpiInstallGlobalEventHandler, Status); /* If Hardware Reduced flag is set, we are all done */ if (AcpiGbl_ReducedHardware) { return; } Status = AcpiEnableEvent (ACPI_EVENT_GLOBAL, 0); ACPI_CHECK_OK (AcpiEnableEvent, Status); /* * GPEs: Handlers, enable/disable, etc. */ Status = AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0); ACPI_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiRemoveGpeHandler (NULL, 0, AeGpeHandler); ACPI_CHECK_OK (AcpiRemoveGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0); ACPI_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiSetGpe (NULL, 0, ACPI_GPE_DISABLE); ACPI_CHECK_OK (AcpiSetGpe, Status); Status = AcpiSetGpe (NULL, 0, ACPI_GPE_ENABLE); ACPI_CHECK_OK (AcpiSetGpe, Status); Status = AcpiInstallGpeHandler (NULL, 1, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 1); ACPI_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiInstallGpeHandler (NULL, 2, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 2); ACPI_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiInstallGpeHandler (NULL, 3, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 4, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 5, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiGetHandle (NULL, "\\_SB", &Handle); ACPI_CHECK_OK (AcpiGetHandle, Status); Status = AcpiSetupGpeForWake (Handle, NULL, 5); ACPI_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiSetGpeWakeMask (NULL, 5, ACPI_GPE_ENABLE); ACPI_CHECK_OK (AcpiSetGpeWakeMask, Status); Status = AcpiSetupGpeForWake (Handle, NULL, 6); ACPI_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiSetupGpeForWake (ACPI_ROOT_OBJECT, NULL, 6); ACPI_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiSetupGpeForWake (Handle, NULL, 9); ACPI_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiInstallGpeHandler (NULL, 0x19, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0x19); ACPI_CHECK_OK (AcpiEnableGpe, Status); /* GPE block 1 */ Status = AcpiInstallGpeHandler (NULL, 101, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 101); ACPI_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiDisableGpe (NULL, 101); ACPI_CHECK_OK (AcpiDisableGpe, Status); AfInstallGpeBlock (); /* Here is where the GPEs are actually "enabled" */ Status = AcpiUpdateAllGpes (); ACPI_CHECK_OK (AcpiUpdateAllGpes, Status); Status = AcpiGetHandle (NULL, "RSRC", &Handle); if (ACPI_SUCCESS (Status)) { ReturnBuf.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiGetVendorResource (Handle, "_CRS", &Uuid, &ReturnBuf); if (ACPI_SUCCESS (Status)) { AcpiOsFree (ReturnBuf.Pointer); } } /* Test global lock */ Status = AcpiAcquireGlobalLock (0xFFFF, &LockHandle1); ACPI_CHECK_OK (AcpiAcquireGlobalLock, Status); Status = AcpiAcquireGlobalLock (0x5, &LockHandle2); ACPI_CHECK_OK (AcpiAcquireGlobalLock, Status); Status = AcpiReleaseGlobalLock (LockHandle1); ACPI_CHECK_OK (AcpiReleaseGlobalLock, Status); Status = AcpiReleaseGlobalLock (LockHandle2); ACPI_CHECK_OK (AcpiReleaseGlobalLock, Status); #endif /* !ACPI_REDUCED_HARDWARE */ }
static int acpi_ec_probe(device_t dev) { ACPI_BUFFER buf; ACPI_HANDLE h; ACPI_OBJECT *obj; ACPI_STATUS status; device_t peer; char desc[64]; int ecdt; int ret; struct acpi_ec_params *params; static char *ec_ids[] = { "PNP0C09", NULL }; /* Check that this is a device and that EC is not disabled. */ if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("ec")) return (ENXIO); /* * If probed via ECDT, set description and continue. Otherwise, * we can access the namespace and make sure this is not a * duplicate probe. */ ret = ENXIO; ecdt = 0; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; params = acpi_get_private(dev); if (params != NULL) { ecdt = 1; ret = 0; } else if (ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) { params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO); h = acpi_get_handle(dev); /* * Read the unit ID to check for duplicate attach and the * global lock value to see if we should acquire it when * accessing the EC. */ status = acpi_GetInteger(h, "_UID", ¶ms->uid); if (ACPI_FAILURE(status)) params->uid = 0; status = acpi_GetInteger(h, "_GLK", ¶ms->glk); if (ACPI_FAILURE(status)) params->glk = 0; /* * Evaluate the _GPE method to find the GPE bit used by the EC to * signal status (SCI). If it's a package, it contains a reference * and GPE bit, similar to _PRW. */ status = AcpiEvaluateObject(h, "_GPE", NULL, &buf); if (ACPI_FAILURE(status)) { device_printf(dev, "can't evaluate _GPE - %s\n", AcpiFormatException(status)); goto out; } obj = (ACPI_OBJECT *)buf.Pointer; if (obj == NULL) goto out; switch (obj->Type) { case ACPI_TYPE_INTEGER: params->gpe_handle = NULL; params->gpe_bit = obj->Integer.Value; break; case ACPI_TYPE_PACKAGE: if (!ACPI_PKG_VALID(obj, 2)) goto out; params->gpe_handle = acpi_GetReference(NULL, &obj->Package.Elements[0]); if (params->gpe_handle == NULL || acpi_PkgInt32(obj, 1, ¶ms->gpe_bit) != 0) goto out; break; default: device_printf(dev, "_GPE has invalid type %d\n", obj->Type); goto out; } /* Store the values we got from the namespace for attach. */ acpi_set_private(dev, params); /* * Check for a duplicate probe. This can happen when a probe * via ECDT succeeded already. If this is a duplicate, disable * this device. */ peer = devclass_get_device(acpi_ec_devclass, params->uid); if (peer == NULL || !device_is_alive(peer)) ret = 0; else device_disable(dev); } out: if (ret == 0) { ksnprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s", params->gpe_bit, (params->glk) ? ", GLK" : "", ecdt ? ", ECDT" : ""); device_set_desc_copy(dev, desc); } if (ret > 0 && params) kfree(params, M_TEMP); if (buf.Pointer) AcpiOsFree(buf.Pointer); return (ret); }
static ACPI_STATUS AcGetOneTableFromFile ( char *Filename, FILE *File, UINT8 GetOnlyAmlTables, ACPI_TABLE_HEADER **ReturnTable) { ACPI_STATUS Status = AE_OK; ACPI_TABLE_HEADER TableHeader; ACPI_TABLE_HEADER *Table; INT32 Count; long TableOffset; *ReturnTable = NULL; /* Get the table header to examine signature and length */ TableOffset = ftell (File); Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File); if (Count != sizeof (ACPI_TABLE_HEADER)) { return (AE_CTRL_TERMINATE); } /* Validate the table signature/header (limited ASCII chars) */ Status = AcValidateTableHeader (File, TableOffset); if (ACPI_FAILURE (Status)) { return (Status); } if (GetOnlyAmlTables) { /* * Table must be an AML table (DSDT/SSDT). * Used for iASL -e option only. */ if (!AcpiUtIsAmlTable (&TableHeader)) { fprintf (stderr, " %s: Table [%4.4s] is not an AML table - ignoring\n", Filename, TableHeader.Signature); return (AE_TYPE); } } /* Allocate a buffer for the entire table */ Table = AcpiOsAllocate ((ACPI_SIZE) TableHeader.Length); if (!Table) { return (AE_NO_MEMORY); } /* Read the entire ACPI table, including header */ fseek (File, TableOffset, SEEK_SET); Count = fread (Table, 1, TableHeader.Length, File); if (Count != (INT32) TableHeader.Length) { Status = AE_ERROR; goto ErrorExit; } /* Validate the checksum (just issue a warning) */ Status = AcpiTbVerifyChecksum (Table, TableHeader.Length); if (ACPI_FAILURE (Status)) { Status = AcCheckTextModeCorruption (Table); if (ACPI_FAILURE (Status)) { goto ErrorExit; } } *ReturnTable = Table; return (AE_OK); ErrorExit: AcpiOsFree (Table); return (Status); }
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 ACPI_STATUS AcpiDbReadFromObject ( ACPI_NAMESPACE_NODE *Node, ACPI_OBJECT_TYPE ExpectedType, ACPI_OBJECT **Value) { ACPI_OBJECT *RetValue; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[2]; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE; Params[0].Reference.ActualType = Node->Type; Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node); ParamObjects.Count = 1; ParamObjects.Pointer = Params; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (ReadHandle, NULL, &ParamObjects, &ReturnObj); AcpiGbl_MethodExecuting = FALSE; if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not read from object, %s", AcpiFormatException (Status)); return (Status); } RetValue = (ACPI_OBJECT *) ReturnObj.Pointer; switch (RetValue->Type) { case ACPI_TYPE_INTEGER: case ACPI_TYPE_BUFFER: case ACPI_TYPE_STRING: /* * Did we receive the type we wanted? Most important for the * Integer/Buffer case (when a field is larger than an Integer, * it should return a Buffer). */ if (RetValue->Type != ExpectedType) { AcpiOsPrintf (" Type mismatch: Expected %s, Received %s", AcpiUtGetTypeName (ExpectedType), AcpiUtGetTypeName (RetValue->Type)); return (AE_TYPE); } *Value = RetValue; break; default: AcpiOsPrintf (" Unsupported return object type, %s", AcpiUtGetTypeName (RetValue->Type)); AcpiOsFree (ReturnObj.Pointer); return (AE_TYPE); } return (Status); }
static ACPI_STATUS AcpiDbTestStringType ( ACPI_NAMESPACE_NODE *Node, UINT32 ByteLength) { ACPI_OBJECT *Temp1 = NULL; ACPI_OBJECT *Temp2 = NULL; ACPI_OBJECT *Temp3 = NULL; char *ValueToWrite = "Test String from AML Debugger"; ACPI_OBJECT WriteValue; ACPI_STATUS Status; /* Read the original value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1); if (ACPI_FAILURE (Status)) { return (Status); } AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8), Temp1->String.Length, Temp1->String.Pointer); /* Write a new value */ WriteValue.Type = ACPI_TYPE_STRING; WriteValue.String.Length = strlen (ValueToWrite); WriteValue.String.Pointer = ValueToWrite; Status = AcpiDbWriteToObject (Node, &WriteValue); if (ACPI_FAILURE (Status)) { goto Exit; } /* Ensure that we can read back the new value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2); if (ACPI_FAILURE (Status)) { goto Exit; } if (strcmp (Temp2->String.Pointer, ValueToWrite)) { AcpiOsPrintf (" MISMATCH 2: %s, expecting %s", Temp2->String.Pointer, ValueToWrite); } /* Write back the original value */ WriteValue.String.Length = strlen (Temp1->String.Pointer); WriteValue.String.Pointer = Temp1->String.Pointer; Status = AcpiDbWriteToObject (Node, &WriteValue); if (ACPI_FAILURE (Status)) { goto Exit; } /* Ensure that we can read back the original value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3); if (ACPI_FAILURE (Status)) { goto Exit; } if (strcmp (Temp1->String.Pointer, Temp3->String.Pointer)) { AcpiOsPrintf (" MISMATCH 3: %s, expecting %s", Temp3->String.Pointer, Temp1->String.Pointer); } Exit: if (Temp1) {AcpiOsFree (Temp1);} if (Temp2) {AcpiOsFree (Temp2);} if (Temp3) {AcpiOsFree (Temp3);} return (Status); }
static ACPI_STATUS AcpiDbTestBufferType ( ACPI_NAMESPACE_NODE *Node, UINT32 BitLength) { ACPI_OBJECT *Temp1 = NULL; ACPI_OBJECT *Temp2 = NULL; ACPI_OBJECT *Temp3 = NULL; UINT8 *Buffer; ACPI_OBJECT WriteValue; ACPI_STATUS Status; UINT32 ByteLength; UINT32 i; UINT8 ExtraBits; ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength); if (ByteLength == 0) { AcpiOsPrintf (" Ignoring zero length buffer"); return (AE_OK); } /* Allocate a local buffer */ Buffer = ACPI_ALLOCATE_ZEROED (ByteLength); if (!Buffer) { return (AE_NO_MEMORY); } /* Read the original value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1); if (ACPI_FAILURE (Status)) { goto Exit; } /* Emit a few bytes of the buffer */ AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length); for (i = 0; ((i < 4) && (i < ByteLength)); i++) { AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]); } AcpiOsPrintf ("... "); /* * Write a new value. * * Handle possible extra bits at the end of the buffer. Can * happen for FieldUnits larger than an integer, but the bit * count is not an integral number of bytes. Zero out the * unused bits. */ memset (Buffer, BUFFER_FILL_VALUE, ByteLength); ExtraBits = BitLength % 8; if (ExtraBits) { Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits); } WriteValue.Type = ACPI_TYPE_BUFFER; WriteValue.Buffer.Length = ByteLength; WriteValue.Buffer.Pointer = Buffer; Status = AcpiDbWriteToObject (Node, &WriteValue); if (ACPI_FAILURE (Status)) { goto Exit; } /* Ensure that we can read back the new value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2); if (ACPI_FAILURE (Status)) { goto Exit; } if (memcmp (Temp2->Buffer.Pointer, Buffer, ByteLength)) { AcpiOsPrintf (" MISMATCH 2: New buffer value"); } /* Write back the original value */ WriteValue.Buffer.Length = ByteLength; WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer; Status = AcpiDbWriteToObject (Node, &WriteValue); if (ACPI_FAILURE (Status)) { goto Exit; } /* Ensure that we can read back the original value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3); if (ACPI_FAILURE (Status)) { goto Exit; } if (memcmp (Temp1->Buffer.Pointer, Temp3->Buffer.Pointer, ByteLength)) { AcpiOsPrintf (" MISMATCH 3: While restoring original buffer"); } Exit: ACPI_FREE (Buffer); if (Temp1) {AcpiOsFree (Temp1);} if (Temp2) {AcpiOsFree (Temp2);} if (Temp3) {AcpiOsFree (Temp3);} return (Status); }
static ACPI_STATUS AcpiDbTestIntegerType ( ACPI_NAMESPACE_NODE *Node, UINT32 BitLength) { ACPI_OBJECT *Temp1 = NULL; ACPI_OBJECT *Temp2 = NULL; ACPI_OBJECT *Temp3 = NULL; ACPI_OBJECT WriteValue; UINT64 ValueToWrite; ACPI_STATUS Status; if (BitLength > 64) { AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength); return (AE_OK); } /* Read the original value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1); if (ACPI_FAILURE (Status)) { return (Status); } AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X", BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength), ACPI_FORMAT_UINT64 (Temp1->Integer.Value)); ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength); if (Temp1->Integer.Value == ValueToWrite) { ValueToWrite = 0; } /* Write a new value */ WriteValue.Type = ACPI_TYPE_INTEGER; WriteValue.Integer.Value = ValueToWrite; Status = AcpiDbWriteToObject (Node, &WriteValue); if (ACPI_FAILURE (Status)) { goto Exit; } /* Ensure that we can read back the new value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2); if (ACPI_FAILURE (Status)) { goto Exit; } if (Temp2->Integer.Value != ValueToWrite) { AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X", ACPI_FORMAT_UINT64 (Temp2->Integer.Value), ACPI_FORMAT_UINT64 (ValueToWrite)); } /* Write back the original value */ WriteValue.Integer.Value = Temp1->Integer.Value; Status = AcpiDbWriteToObject (Node, &WriteValue); if (ACPI_FAILURE (Status)) { goto Exit; } /* Ensure that we can read back the original value */ Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3); if (ACPI_FAILURE (Status)) { goto Exit; } if (Temp3->Integer.Value != Temp1->Integer.Value) { AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X", ACPI_FORMAT_UINT64 (Temp3->Integer.Value), ACPI_FORMAT_UINT64 (Temp1->Integer.Value)); } Exit: if (Temp1) {AcpiOsFree (Temp1);} if (Temp2) {AcpiOsFree (Temp2);} if (Temp3) {AcpiOsFree (Temp3);} return (AE_OK); }
/* * Parse the current state of this thermal zone and set up to use it. * * Note that we may have previous state, which will have to be discarded. */ static int acpi_tz_establish(struct acpi_tz_softc *sc) { ACPI_OBJECT *obj; int i; char nbuf[8]; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); /* Erase any existing state. */ for (i = 0; i < TZ_NUMLEVELS; i++) if (sc->tz_zone.al[i].Pointer != NULL) AcpiOsFree(sc->tz_zone.al[i].Pointer); if (sc->tz_zone.psl.Pointer != NULL) AcpiOsFree(sc->tz_zone.psl.Pointer); /* * XXX: We initialize only ACPI_BUFFER to avoid race condition * with passive cooling thread which refers psv, tc1, tc2 and tsp. */ bzero(sc->tz_zone.ac, sizeof(sc->tz_zone.ac)); bzero(sc->tz_zone.al, sizeof(sc->tz_zone.al)); bzero(&sc->tz_zone.psl, sizeof(sc->tz_zone.psl)); /* Evaluate thermal zone parameters. */ for (i = 0; i < TZ_NUMLEVELS; i++) { sprintf(nbuf, "_AC%d", i); acpi_tz_getparam(sc, nbuf, &sc->tz_zone.ac[i]); sprintf(nbuf, "_AL%d", i); sc->tz_zone.al[i].Length = ACPI_ALLOCATE_BUFFER; sc->tz_zone.al[i].Pointer = NULL; AcpiEvaluateObject(sc->tz_handle, nbuf, NULL, &sc->tz_zone.al[i]); obj = (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer; if (obj != NULL) { /* Should be a package containing a list of power objects */ if (obj->Type != ACPI_TYPE_PACKAGE) { device_printf(sc->tz_dev, "%s has unknown type %d, rejecting\n", nbuf, obj->Type); return_VALUE (ENXIO); } } } acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt); acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot); sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER; sc->tz_zone.psl.Pointer = NULL; AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl); acpi_tz_getparam(sc, "_PSV", &sc->tz_zone.psv); acpi_tz_getparam(sc, "_TC1", &sc->tz_zone.tc1); acpi_tz_getparam(sc, "_TC2", &sc->tz_zone.tc2); acpi_tz_getparam(sc, "_TSP", &sc->tz_zone.tsp); acpi_tz_getparam(sc, "_TZP", &sc->tz_zone.tzp); /* * Sanity-check the values we've been given. * * XXX what do we do about systems that give us the same value for * more than one of these setpoints? */ acpi_tz_sanity(sc, &sc->tz_zone.crt, "_CRT"); acpi_tz_sanity(sc, &sc->tz_zone.hot, "_HOT"); acpi_tz_sanity(sc, &sc->tz_zone.psv, "_PSV"); for (i = 0; i < TZ_NUMLEVELS; i++) acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx"); return_VALUE (0); }
void AeMiscellaneousTests ( void) { ACPI_HANDLE Handle; ACPI_BUFFER ReturnBuf; char Buffer[32]; ACPI_VENDOR_UUID Uuid = {0, {ACPI_INIT_UUID (0,0,0,0,0,0,0,0,0,0,0)}}; ACPI_STATUS Status; UINT32 LockHandle1; UINT32 LockHandle2; ACPI_STATISTICS Stats; AeHardwareInterfaces (); AeGenericRegisters (); AeSetupConfiguration (Ssdt3Code); AeTestBufferArgument(); AeTestPackageArgument (); Status = AcpiInstallInterface (""); AE_CHECK_STATUS (AcpiInstallInterface, Status, AE_BAD_PARAMETER); Status = AcpiInstallInterface ("TestString"); AE_CHECK_OK (AcpiInstallInterface, Status); Status = AcpiInstallInterface ("TestString"); AE_CHECK_STATUS (AcpiInstallInterface, Status, AE_ALREADY_EXISTS); Status = AcpiRemoveInterface ("Windows 2006"); AE_CHECK_OK (AcpiRemoveInterface, Status); Status = AcpiRemoveInterface ("TestString"); AE_CHECK_OK (AcpiRemoveInterface, Status); Status = AcpiRemoveInterface ("XXXXXX"); AE_CHECK_STATUS (AcpiRemoveInterface, Status, AE_NOT_EXIST); Status = AcpiInstallInterface ("AnotherTestString"); AE_CHECK_OK (AcpiInstallInterface, Status); Status = ExecuteOSI ("Windows 2001", 0xFFFFFFFF); AE_CHECK_OK (ExecuteOSI, Status); Status = ExecuteOSI ("MichiganTerminalSystem", 0); AE_CHECK_OK (ExecuteOSI, Status); ReturnBuf.Length = 32; ReturnBuf.Pointer = Buffer; Status = AcpiGetName (AcpiGbl_RootNode, ACPI_FULL_PATHNAME, &ReturnBuf); AE_CHECK_OK (AcpiGetName, Status); Status = AcpiEnableEvent (ACPI_EVENT_GLOBAL, 0); AE_CHECK_OK (AcpiEnableEvent, Status); /* * GPEs: Handlers, enable/disable, etc. */ Status = AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiRemoveGpeHandler (NULL, 0, AeGpeHandler); AE_CHECK_OK (AcpiRemoveGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiSetGpe (NULL, 0, ACPI_GPE_DISABLE); AE_CHECK_OK (AcpiSetGpe, Status); Status = AcpiSetGpe (NULL, 0, ACPI_GPE_ENABLE); AE_CHECK_OK (AcpiSetGpe, Status); Status = AcpiInstallGpeHandler (NULL, 1, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 1); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiInstallGpeHandler (NULL, 2, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 2); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiInstallGpeHandler (NULL, 3, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 4, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 5, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 0x19, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0x19); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiInstallGpeHandler (NULL, 0x62, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0x62); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiDisableGpe (NULL, 0x62); AE_CHECK_OK (AcpiDisableGpe, Status); AfInstallGpeBlock (); Status = AcpiGetHandle (NULL, "RSRC", &Handle); if (ACPI_SUCCESS (Status)) { ReturnBuf.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiGetVendorResource (Handle, "_CRS", &Uuid, &ReturnBuf); if (ACPI_SUCCESS (Status)) { AcpiOsFree (ReturnBuf.Pointer); } } /* Test global lock */ Status = AcpiAcquireGlobalLock (0xFFFF, &LockHandle1); AE_CHECK_OK (AcpiAcquireGlobalLock, Status); Status = AcpiAcquireGlobalLock (0x5, &LockHandle2); AE_CHECK_OK (AcpiAcquireGlobalLock, Status); Status = AcpiReleaseGlobalLock (LockHandle1); AE_CHECK_OK (AcpiReleaseGlobalLock, Status); Status = AcpiReleaseGlobalLock (LockHandle2); AE_CHECK_OK (AcpiReleaseGlobalLock, Status); /* Get Devices */ Status = AcpiGetDevices (NULL, AeGetDevices, NULL, NULL); AE_CHECK_OK (AcpiGetDevices, Status); Status = AcpiGetStatistics (&Stats); AE_CHECK_OK (AcpiGetStatistics, Status); }
ACPI_TABLE_HEADER * OsGetTable ( char *Signature) { HKEY Handle = NULL; ULONG i; LONG Status; ULONG Type; ULONG NameSize; ULONG DataSize; HKEY SubKey; ACPI_TABLE_HEADER *ReturnTable; /* Get a handle to the table key */ while (1) { ACPI_STRCPY (KeyBuffer, "HARDWARE\\ACPI\\"); ACPI_STRCAT (KeyBuffer, Signature); Status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, 0L, KEY_ALL_ACCESS, &Handle); if (Status != ERROR_SUCCESS) { /* * Somewhere along the way, MS changed the registry entry for * the FADT from * HARDWARE/ACPI/FACP to * HARDWARE/ACPI/FADT. * * This code allows for both. */ if (ACPI_COMPARE_NAME (Signature, "FACP")) { Signature = "FADT"; } else { AcpiOsPrintf ("Could not find %s in registry at %s\n", Signature, KeyBuffer); return (NULL); } } else { break; } } /* Actual data for table is down a couple levels */ for (i = 0; ;) { Status = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer)); i += 1; if (Status == ERROR_NO_MORE_ITEMS) { break; } Status = RegOpenKey (Handle, KeyBuffer, &SubKey); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not open %s entry\n", Signature); return (NULL); } RegCloseKey (Handle); Handle = SubKey; i = 0; } /* Find the (binary) table entry */ for (i = 0; ;) { NameSize = sizeof (KeyBuffer); Status = RegEnumValue (Handle, i, KeyBuffer, &NameSize, NULL, &Type, NULL, 0); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not get %s registry entry\n", Signature); return (NULL); } if (Type == REG_BINARY) { break; } i += 1; } /* Get the size of the table */ Status = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, NULL, &DataSize); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not read the %s table size\n", Signature); return (NULL); } /* Allocate a new buffer for the table */ ReturnTable = AcpiOsAllocate (DataSize); if (!ReturnTable) { goto Cleanup; } /* Get the actual table from the registry */ Status = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, (UCHAR *) ReturnTable, &DataSize); if (Status != ERROR_SUCCESS) { AcpiOsPrintf ("Could not read %s data\n", Signature); AcpiOsFree (ReturnTable); return (NULL); } Cleanup: RegCloseKey (Handle); return (ReturnTable); }
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 acpi_cmbat_get_bst(void *arg) { struct acpi_cmbat_softc *sc; ACPI_STATUS as; ACPI_OBJECT *res; ACPI_HANDLE h; ACPI_BUFFER bst_buffer; device_t dev; ACPI_SERIAL_ASSERT(cmbat); dev = arg; sc = device_get_softc(dev); h = acpi_get_handle(dev); bst_buffer.Pointer = NULL; bst_buffer.Length = ACPI_ALLOCATE_BUFFER; if (!acpi_cmbat_info_expired(&sc->bst_lastupdated)) goto end; as = AcpiEvaluateObject(h, "_BST", NULL, &bst_buffer); if (ACPI_FAILURE(as)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "error fetching current battery status -- %s\n", AcpiFormatException(as)); goto end; } res = (ACPI_OBJECT *)bst_buffer.Pointer; if (!ACPI_PKG_VALID(res, 4)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "battery status corrupted\n"); goto end; } if (acpi_PkgInt32(res, 0, &sc->bst.state) != 0) goto end; if (acpi_PkgInt32(res, 1, &sc->bst.rate) != 0) goto end; if (acpi_PkgInt32(res, 2, &sc->bst.cap) != 0) goto end; if (acpi_PkgInt32(res, 3, &sc->bst.volt) != 0) goto end; acpi_cmbat_info_updated(&sc->bst_lastupdated); /* Clear out undefined/extended bits that might be set by hardware. */ sc->bst.state &= ACPI_BATT_STAT_BST_MASK; if ((sc->bst.state & ACPI_BATT_STAT_INVALID) == ACPI_BATT_STAT_INVALID) ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "battery reports simultaneous charging and discharging\n"); /* XXX If all batteries are critical, perhaps we should suspend. */ if (sc->bst.state & ACPI_BATT_STAT_CRITICAL) { if ((sc->flags & ACPI_BATT_STAT_CRITICAL) == 0) { sc->flags |= ACPI_BATT_STAT_CRITICAL; device_printf(dev, "critically low charge!\n"); } } else sc->flags &= ~ACPI_BATT_STAT_CRITICAL; end: if (bst_buffer.Pointer != NULL) AcpiOsFree(bst_buffer.Pointer); }
ACPI_STATUS AcGetAllTablesFromFile ( char *Filename, UINT8 GetOnlyAmlTables, ACPI_NEW_TABLE_DESC **ReturnListHead) { ACPI_NEW_TABLE_DESC *ListHead = NULL; ACPI_NEW_TABLE_DESC *ListTail = NULL; ACPI_NEW_TABLE_DESC *TableDesc; FILE *File; ACPI_TABLE_HEADER *Table = NULL; UINT32 FileSize; ACPI_STATUS Status = AE_OK; File = fopen (Filename, "rb"); if (!File) { fprintf (stderr, "Could not open input file: %s\n", Filename); if (errno == ENOENT) { return (AE_NOT_EXIST); } return (AE_ERROR); } /* Get the file size */ FileSize = CmGetFileSize (File); if (FileSize == ACPI_UINT32_MAX) { Status = AE_ERROR; goto Exit; } fprintf (stderr, "Input file %s, Length 0x%X (%u) bytes\n", Filename, FileSize, FileSize); /* We must have at least one ACPI table header */ if (FileSize < sizeof (ACPI_TABLE_HEADER)) { Status = AE_BAD_HEADER; goto Exit; } /* Check for an non-binary file */ if (!AcIsFileBinary (File)) { fprintf (stderr, " %s: File does not appear to contain a valid AML table\n", Filename); Status = AE_TYPE; goto Exit; } /* Read all tables within the file */ while (ACPI_SUCCESS (Status)) { /* Get one entire ACPI table */ Status = AcGetOneTableFromFile ( Filename, File, GetOnlyAmlTables, &Table); if (Status == AE_CTRL_TERMINATE) { Status = AE_OK; break; } else if (Status == AE_TYPE) { Status = AE_OK; goto Exit; } else if (ACPI_FAILURE (Status)) { goto Exit; } /* Print table header for iASL/disassembler only */ #ifdef ACPI_ASL_COMPILER AcpiTbPrintTableHeader (0, Table); #endif /* Allocate and link a table descriptor */ TableDesc = AcpiOsAllocate (sizeof (ACPI_NEW_TABLE_DESC)); if (!TableDesc) { AcpiOsFree (Table); Status = AE_NO_MEMORY; goto Exit; } TableDesc->Table = Table; TableDesc->Next = NULL; /* Link at the end of the local table list */ if (!ListHead) { ListHead = TableDesc; ListTail = TableDesc; } else { ListTail->Next = TableDesc; ListTail = TableDesc; } } /* Add the local table list to the end of the global list */ if (*ReturnListHead) { ListTail = *ReturnListHead; while (ListTail->Next) { ListTail = ListTail->Next; } ListTail->Next = ListHead; } else { *ReturnListHead = ListHead; } Exit: fclose(File); return (Status); }
static void acpi_cmbat_get_bif(void *arg) { struct acpi_cmbat_softc *sc; ACPI_STATUS as; ACPI_OBJECT *res; ACPI_HANDLE h; ACPI_BUFFER bif_buffer; device_t dev; ACPI_SERIAL_ASSERT(cmbat); dev = arg; sc = device_get_softc(dev); h = acpi_get_handle(dev); bif_buffer.Pointer = NULL; bif_buffer.Length = ACPI_ALLOCATE_BUFFER; as = AcpiEvaluateObject(h, "_BIF", NULL, &bif_buffer); if (ACPI_FAILURE(as)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "error fetching current battery info -- %s\n", AcpiFormatException(as)); goto end; } res = (ACPI_OBJECT *)bif_buffer.Pointer; if (!ACPI_PKG_VALID(res, 13)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "battery info corrupted\n"); goto end; } if (acpi_PkgInt32(res, 0, &sc->bif.units) != 0) goto end; if (acpi_PkgInt32(res, 1, &sc->bif.dcap) != 0) goto end; if (acpi_PkgInt32(res, 2, &sc->bif.lfcap) != 0) goto end; if (acpi_PkgInt32(res, 3, &sc->bif.btech) != 0) goto end; if (acpi_PkgInt32(res, 4, &sc->bif.dvol) != 0) goto end; if (acpi_PkgInt32(res, 5, &sc->bif.wcap) != 0) goto end; if (acpi_PkgInt32(res, 6, &sc->bif.lcap) != 0) goto end; if (acpi_PkgInt32(res, 7, &sc->bif.gra1) != 0) goto end; if (acpi_PkgInt32(res, 8, &sc->bif.gra2) != 0) goto end; if (acpi_PkgStr(res, 9, sc->bif.model, ACPI_CMBAT_MAXSTRLEN) != 0) goto end; if (acpi_PkgStr(res, 10, sc->bif.serial, ACPI_CMBAT_MAXSTRLEN) != 0) goto end; if (acpi_PkgStr(res, 11, sc->bif.type, ACPI_CMBAT_MAXSTRLEN) != 0) goto end; if (acpi_PkgStr(res, 12, sc->bif.oeminfo, ACPI_CMBAT_MAXSTRLEN) != 0) goto end; end: if (bif_buffer.Pointer != NULL) AcpiOsFree(bif_buffer.Pointer); }
void AbComputeChecksum ( char *FilePath) { UINT32 Actual; ACPI_TABLE_HEADER *Table; UINT8 Checksum; FILE *File; File = fopen (FilePath, "rb"); if (!File) { printf ("Could not open file %s\n", FilePath); return; } Actual = fread (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File); if (Actual < sizeof (ACPI_TABLE_HEADER)) { printf ("File %s does not contain a valid ACPI table header\n", FilePath); goto Exit1; } if (!AbValidateHeader (&Header1)) { goto Exit1; } if (!Gbl_TerseMode) { AbPrintHeaderInfo (&Header1); } /* Allocate a buffer to hold the entire table */ Table = AcpiOsAllocate (Header1.Length); if (!Table) { printf ("Could not allocate buffer for table\n"); goto Exit1; } /* Read the entire table, including header */ fseek (File, 0, SEEK_SET); Actual = fread (Table, 1, Header1.Length, File); if (Actual != Header1.Length) { printf ("Could not read table, length %u\n", Header1.Length); goto Exit2; } /* Compute the checksum for the table */ Table->Checksum = 0; Checksum = (UINT8) (0 - AcpiTbSumTable (Table, Table->Length)); printf ("Computed checksum: 0x%X\n\n", Checksum); if (Header1.Checksum == Checksum) { printf ("Checksum OK in AML file, not updating\n"); goto Exit2; } /* Open the target file for writing, to update checksum */ fclose (File); File = fopen (FilePath, "r+b"); if (!File) { printf ("Could not open file %s for writing\n", FilePath); goto Exit2; } /* Set the checksum, write the new header */ Header1.Checksum = Checksum; Actual = fwrite (&Header1, 1, sizeof (ACPI_TABLE_HEADER), File); if (Actual != sizeof (ACPI_TABLE_HEADER)) { printf ("Could not write updated table header\n"); goto Exit2; } printf ("Wrote new checksum\n"); Exit2: AcpiOsFree (Table); Exit1: if (File) { fclose (File); } return; }
ACPI_STATUS AcpiEvaluateObjectTyped ( ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer, ACPI_OBJECT_TYPE ReturnType) { ACPI_STATUS Status; BOOLEAN FreeBufferOnError = FALSE; ACPI_HANDLE TargetHandle; char *FullPathname; ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); /* Return buffer must be valid */ if (!ReturnBuffer) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) { FreeBufferOnError = TRUE; } /* Get a handle here, in order to build an error message if needed */ TargetHandle = Handle; if (Pathname) { Status = AcpiGetHandle (Handle, Pathname, &TargetHandle); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } FullPathname = AcpiNsGetExternalPathname (TargetHandle); if (!FullPathname) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Evaluate the object */ Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams, ReturnBuffer); if (ACPI_FAILURE (Status)) { goto Exit; } /* Type ANY means "don't care about return value type" */ if (ReturnType == ACPI_TYPE_ANY) { goto Exit; } if (ReturnBuffer->Length == 0) { /* Error because caller specifically asked for a return value */ ACPI_ERROR ((AE_INFO, "%s did not return any object", FullPathname)); Status = AE_NULL_OBJECT; goto Exit; } /* Examine the object type returned from EvaluateObject */ if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) { goto Exit; } /* Return object type does not match requested type */ ACPI_ERROR ((AE_INFO, "Incorrect return type from %s - received [%s], requested [%s]", FullPathname, AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), AcpiUtGetTypeName (ReturnType))); if (FreeBufferOnError) { /* * Free a buffer created via ACPI_ALLOCATE_BUFFER. * Note: We use AcpiOsFree here because AcpiOsAllocate was used * to allocate the buffer. This purposefully bypasses the * (optionally enabled) allocation tracking mechanism since we * only want to track internal allocations. */ AcpiOsFree (ReturnBuffer->Pointer); ReturnBuffer->Pointer = NULL; } ReturnBuffer->Length = 0; Status = AE_TYPE; Exit: ACPI_FREE (FullPathname); return_ACPI_STATUS (Status); }
static ACPI_STATUS ExecuteOSI ( char *OsiString, UINT64 ExpectedResult) { ACPI_STATUS Status; ACPI_OBJECT_LIST ArgList; ACPI_OBJECT Arg[1]; ACPI_BUFFER ReturnValue; ACPI_OBJECT *Obj; /* Setup input argument */ ArgList.Count = 1; ArgList.Pointer = Arg; Arg[0].Type = ACPI_TYPE_STRING; Arg[0].String.Pointer = OsiString; Arg[0].String.Length = strlen (Arg[0].String.Pointer); /* Ask ACPICA to allocate space for the return object */ ReturnValue.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiEvaluateObject (NULL, "\\_OSI", &ArgList, &ReturnValue); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ( "Could not execute _OSI method, %s\n", AcpiFormatException (Status)); return (Status); } Status = AE_ERROR; if (ReturnValue.Length < sizeof (ACPI_OBJECT)) { AcpiOsPrintf ( "Return value from _OSI method too small, %.8X\n", ReturnValue.Length); goto ErrorExit; } Obj = ReturnValue.Pointer; if (Obj->Type != ACPI_TYPE_INTEGER) { AcpiOsPrintf ( "Invalid return type from _OSI method, %.2X\n", Obj->Type); goto ErrorExit; } if (Obj->Integer.Value != ExpectedResult) { AcpiOsPrintf ( "Invalid return value from _OSI, expected %8.8X%8.8X found %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (ExpectedResult), ACPI_FORMAT_UINT64 (Obj->Integer.Value)); goto ErrorExit; } Status = AE_OK; /* Reset the OSI data */ AcpiGbl_OsiData = 0; ErrorExit: /* Free a buffer created via ACPI_ALLOCATE_BUFFER */ AcpiOsFree (ReturnValue.Pointer); return (Status); }
static int acpi_cpu_attach(device_t dev) { ACPI_BUFFER buf; ACPI_OBJECT arg[4], *obj; ACPI_OBJECT_LIST arglist; struct pcpu *pcpu_data; struct acpi_cpu_softc *sc; struct acpi_softc *acpi_sc; ACPI_STATUS status; u_int features; int cpu_id, drv_count, i; driver_t **drivers; uint32_t cap_set[3]; /* UUID needed by _OSC evaluation */ static uint8_t cpu_oscuuid[16] = { 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, 0xBE, 0x47, 0x9E, 0xBD, 0xD8, 0x70, 0x58, 0x71, 0x39, 0x53 }; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->cpu_dev = dev; sc->cpu_handle = acpi_get_handle(dev); cpu_id = acpi_get_magic(dev); cpu_softc[cpu_id] = sc; pcpu_data = pcpu_find(cpu_id); pcpu_data->pc_device = dev; sc->cpu_pcpu = pcpu_data; cpu_smi_cmd = AcpiGbl_FADT.SmiCommand; cpu_cst_cnt = AcpiGbl_FADT.CstControl; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObject(sc->cpu_handle, NULL, NULL, &buf); if (ACPI_FAILURE(status)) { device_printf(dev, "attach failed to get Processor obj - %s\n", AcpiFormatException(status)); return (ENXIO); } obj = (ACPI_OBJECT *)buf.Pointer; sc->cpu_p_blk = obj->Processor.PblkAddress; sc->cpu_p_blk_len = obj->Processor.PblkLength; sc->cpu_acpi_id = obj->Processor.ProcId; AcpiOsFree(obj); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_BLK at %#x/%d\n", device_get_unit(dev), sc->cpu_p_blk, sc->cpu_p_blk_len)); /* * If this is the first cpu we attach, create and initialize the generic * resources that will be used by all acpi cpu devices. */ if (device_get_unit(dev) == 0) { /* Assume we won't be using generic Cx mode by default */ cpu_cx_generic = FALSE; /* Install hw.acpi.cpu sysctl tree */ acpi_sc = acpi_device_get_parent_softc(dev); sysctl_ctx_init(&cpu_sysctl_ctx); cpu_sysctl_tree = SYSCTL_ADD_NODE(&cpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "cpu", CTLFLAG_RD, 0, "node for CPU children"); /* Queue post cpu-probing task handler */ AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_cpu_startup, NULL); } /* * Before calling any CPU methods, collect child driver feature hints * and notify ACPI of them. We support unified SMP power control * so advertise this ourselves. Note this is not the same as independent * SMP control where each CPU can have different settings. */ sc->cpu_features = ACPI_CAP_SMP_SAME | ACPI_CAP_SMP_SAME_C3; if (devclass_get_drivers(acpi_cpu_devclass, &drivers, &drv_count) == 0) { for (i = 0; i < drv_count; i++) { if (ACPI_GET_FEATURES(drivers[i], &features) == 0) sc->cpu_features |= features; } free(drivers, M_TEMP); } /* * CPU capabilities are specified as a buffer of 32-bit integers: * revision, count, and one or more capabilities. The revision of * "1" is not specified anywhere but seems to match Linux. */ if (sc->cpu_features) { arglist.Pointer = arg; arglist.Count = 1; arg[0].Type = ACPI_TYPE_BUFFER; arg[0].Buffer.Length = sizeof(cap_set); arg[0].Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 1; /* revision */ cap_set[1] = 1; /* number of capabilities integers */ cap_set[2] = sc->cpu_features; AcpiEvaluateObject(sc->cpu_handle, "_PDC", &arglist, NULL); /* * On some systems we need to evaluate _OSC so that the ASL * loads the _PSS and/or _PDC methods at runtime. * * TODO: evaluate failure of _OSC. */ arglist.Pointer = arg; arglist.Count = 4; arg[0].Type = ACPI_TYPE_BUFFER; arg[0].Buffer.Length = sizeof(cpu_oscuuid); arg[0].Buffer.Pointer = cpu_oscuuid; /* UUID */ arg[1].Type = ACPI_TYPE_INTEGER; arg[1].Integer.Value = 1; /* revision */ arg[2].Type = ACPI_TYPE_INTEGER; arg[2].Integer.Value = 1; /* count */ arg[3].Type = ACPI_TYPE_BUFFER; arg[3].Buffer.Length = sizeof(cap_set); /* Capabilities buffer */ arg[3].Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 0; AcpiEvaluateObject(sc->cpu_handle, "_OSC", &arglist, NULL); } /* Probe for Cx state support. */ acpi_cpu_cx_probe(sc); /* Finally, call identify and probe/attach for child devices. */ bus_generic_probe(dev); bus_generic_attach(dev); return (0); }
ACPI_STATUS AcpiEvaluateObjectTyped ( ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer, ACPI_OBJECT_TYPE ReturnType) { ACPI_STATUS Status; BOOLEAN FreeBufferOnError = FALSE; ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); /* Return buffer must be valid */ if (!ReturnBuffer) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) { FreeBufferOnError = TRUE; } /* Evaluate the object */ Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Type ANY means "don't care" */ if (ReturnType == ACPI_TYPE_ANY) { return_ACPI_STATUS (AE_OK); } if (ReturnBuffer->Length == 0) { /* Error because caller specifically asked for a return value */ ACPI_ERROR ((AE_INFO, "No return value")); return_ACPI_STATUS (AE_NULL_OBJECT); } /* Examine the object type returned from EvaluateObject */ if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) { return_ACPI_STATUS (AE_OK); } /* Return object type does not match requested type */ ACPI_ERROR ((AE_INFO, "Incorrect return type [%s] requested [%s]", AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), AcpiUtGetTypeName (ReturnType))); if (FreeBufferOnError) { /* * Free a buffer created via ACPI_ALLOCATE_BUFFER. * Note: We use AcpiOsFree here because AcpiOsAllocate was used * to allocate the buffer. This purposefully bypasses the * (optionally enabled) allocation tracking mechanism since we * only want to track internal allocations. */ AcpiOsFree (ReturnBuffer->Pointer); ReturnBuffer->Pointer = NULL; } ReturnBuffer->Length = 0; return_ACPI_STATUS (AE_TYPE); }
/* * Parse a _CST package and set up its Cx states. Since the _CST object * can change dynamically, our notify handler may call this function * to clean up and probe the new _CST package. */ static int acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) { struct acpi_cx *cx_ptr; ACPI_STATUS status; ACPI_BUFFER buf; ACPI_OBJECT *top; ACPI_OBJECT *pkg; uint32_t count; int i; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObject(sc->cpu_handle, "_CST", NULL, &buf); if (ACPI_FAILURE(status)) return (ENXIO); /* _CST is a package with a count and at least one Cx package. */ top = (ACPI_OBJECT *)buf.Pointer; if (!ACPI_PKG_VALID(top, 2) || acpi_PkgInt32(top, 0, &count) != 0) { device_printf(sc->cpu_dev, "invalid _CST package\n"); AcpiOsFree(buf.Pointer); return (ENXIO); } if (count != top->Package.Count - 1) { device_printf(sc->cpu_dev, "invalid _CST state count (%d != %d)\n", count, top->Package.Count - 1); count = top->Package.Count - 1; } if (count > MAX_CX_STATES) { device_printf(sc->cpu_dev, "_CST has too many states (%d)\n", count); count = MAX_CX_STATES; } /* Set up all valid states. */ sc->cpu_cx_count = 0; cx_ptr = sc->cpu_cx_states; for (i = 0; i < count; i++) { pkg = &top->Package.Elements[i + 1]; if (!ACPI_PKG_VALID(pkg, 4) || acpi_PkgInt32(pkg, 1, &cx_ptr->type) != 0 || acpi_PkgInt32(pkg, 2, &cx_ptr->trans_lat) != 0 || acpi_PkgInt32(pkg, 3, &cx_ptr->power) != 0) { device_printf(sc->cpu_dev, "skipping invalid Cx state package\n"); continue; } /* Validate the state to see if we should use it. */ switch (cx_ptr->type) { case ACPI_STATE_C1: sc->cpu_non_c3 = i; cx_ptr++; sc->cpu_cx_count++; continue; case ACPI_STATE_C2: if (cx_ptr->trans_lat > 100) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: C2[%d] not available.\n", device_get_unit(sc->cpu_dev), i)); continue; } sc->cpu_non_c3 = i; break; case ACPI_STATE_C3: default: if (cx_ptr->trans_lat > 1000 || (cpu_quirks & CPU_QUIRK_NO_C3) != 0) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: C3[%d] not available.\n", device_get_unit(sc->cpu_dev), i)); continue; } break; } #ifdef notyet /* Free up any previous register. */ if (cx_ptr->p_lvlx != NULL) { bus_release_resource(sc->cpu_dev, 0, 0, cx_ptr->p_lvlx); cx_ptr->p_lvlx = NULL; } #endif /* Allocate the control register for C2 or C3. */ acpi_PkgGas(sc->cpu_dev, pkg, 0, &cx_ptr->res_type, &sc->cpu_rid, &cx_ptr->p_lvlx, RF_SHAREABLE); if (cx_ptr->p_lvlx) { sc->cpu_rid++; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: Got C%d - %d latency\n", device_get_unit(sc->cpu_dev), cx_ptr->type, cx_ptr->trans_lat)); cx_ptr++; sc->cpu_cx_count++; } } AcpiOsFree(buf.Pointer); return (0); }
static int acpi_cpu_attach(device_t dev) { ACPI_BUFFER buf; ACPI_OBJECT arg, *obj; ACPI_OBJECT_LIST arglist; struct pcpu *pcpu_data; struct acpi_cpu_softc *sc; struct acpi_softc *acpi_sc; ACPI_STATUS status; u_int features; int cpu_id, drv_count, i; driver_t **drivers; uint32_t cap_set[3]; /* UUID needed by _OSC evaluation */ static uint8_t cpu_oscuuid[16] = { 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, 0xBE, 0x47, 0x9E, 0xBD, 0xD8, 0x70, 0x58, 0x71, 0x39, 0x53 }; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->cpu_dev = dev; sc->cpu_handle = acpi_get_handle(dev); cpu_id = (int)(intptr_t)acpi_get_private(dev); cpu_softc[cpu_id] = sc; pcpu_data = pcpu_find(cpu_id); pcpu_data->pc_device = dev; sc->cpu_pcpu = pcpu_data; cpu_smi_cmd = AcpiGbl_FADT.SmiCommand; cpu_cst_cnt = AcpiGbl_FADT.CstControl; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObject(sc->cpu_handle, NULL, NULL, &buf); if (ACPI_FAILURE(status)) { device_printf(dev, "attach failed to get Processor obj - %s\n", AcpiFormatException(status)); return (ENXIO); } obj = (ACPI_OBJECT *)buf.Pointer; sc->cpu_p_blk = obj->Processor.PblkAddress; sc->cpu_p_blk_len = obj->Processor.PblkLength; sc->cpu_acpi_id = obj->Processor.ProcId; AcpiOsFree(obj); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_BLK at %#x/%d\n", device_get_unit(dev), sc->cpu_p_blk, sc->cpu_p_blk_len)); /* * If this is the first cpu we attach, create and initialize the generic * resources that will be used by all acpi cpu devices. */ if (device_get_unit(dev) == 0) { /* Assume we won't be using generic Cx mode by default */ cpu_cx_generic = FALSE; /* Install hw.acpi.cpu sysctl tree */ acpi_sc = acpi_device_get_parent_softc(dev); sysctl_ctx_init(&cpu_sysctl_ctx); cpu_sysctl_tree = SYSCTL_ADD_NODE(&cpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "cpu", CTLFLAG_RD, 0, "node for CPU children"); } /* * Before calling any CPU methods, collect child driver feature hints * and notify ACPI of them. We support unified SMP power control * so advertise this ourselves. Note this is not the same as independent * SMP control where each CPU can have different settings. */ sc->cpu_features = ACPI_CAP_SMP_SAME | ACPI_CAP_SMP_SAME_C3 | ACPI_CAP_C1_IO_HALT; #if defined(__i386__) || defined(__amd64__) /* * Ask for MWAIT modes if not disabled and interrupts work * reasonable with MWAIT. */ if (!acpi_disabled("mwait") && cpu_mwait_usable()) sc->cpu_features |= ACPI_CAP_SMP_C1_NATIVE | ACPI_CAP_SMP_C3_NATIVE; #endif if (devclass_get_drivers(acpi_cpu_devclass, &drivers, &drv_count) == 0) { for (i = 0; i < drv_count; i++) { if (ACPI_GET_FEATURES(drivers[i], &features) == 0) sc->cpu_features |= features; } free(drivers, M_TEMP); } /* * CPU capabilities are specified in * Intel Processor Vendor-Specific ACPI Interface Specification. */ if (sc->cpu_features) { cap_set[1] = sc->cpu_features; status = acpi_EvaluateOSC(sc->cpu_handle, cpu_oscuuid, 1, 2, cap_set, cap_set, false); if (ACPI_SUCCESS(status)) { if (cap_set[0] != 0) device_printf(dev, "_OSC returned status %#x\n", cap_set[0]); } else { arglist.Pointer = &arg; arglist.Count = 1; arg.Type = ACPI_TYPE_BUFFER; arg.Buffer.Length = sizeof(cap_set); arg.Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 1; /* revision */ cap_set[1] = 1; /* number of capabilities integers */ cap_set[2] = sc->cpu_features; AcpiEvaluateObject(sc->cpu_handle, "_PDC", &arglist, NULL); } } /* Probe for Cx state support. */ acpi_cpu_cx_probe(sc); return (0); }
static ACPI_STATUS acpi_pci_link_route_irqs(device_t dev) { struct acpi_pci_link_softc *sc; ACPI_RESOURCE *resource, *end; ACPI_BUFFER srsbuf; ACPI_STATUS status; struct link *link; int i; ACPI_SERIAL_ASSERT(pci_link); sc = device_get_softc(dev); if (sc->pl_crs_bad) status = acpi_pci_link_srs_from_links(sc, &srsbuf); else status = acpi_pci_link_srs_from_crs(sc, &srsbuf); /* Write out new resources via _SRS. */ status = AcpiSetCurrentResources(acpi_get_handle(dev), &srsbuf); if (ACPI_FAILURE(status)) { device_printf(dev, "Unable to route IRQs: %s\n", AcpiFormatException(status)); AcpiOsFree(srsbuf.Pointer); return (status); } /* * Perform acpi_config_intr() on each IRQ resource if it was just * routed for the first time. */ link = sc->pl_links; i = 0; resource = (ACPI_RESOURCE *)srsbuf.Pointer; end = (ACPI_RESOURCE *)((char *)srsbuf.Pointer + srsbuf.Length); for (;;) { if (resource->Type == ACPI_RESOURCE_TYPE_END_TAG) break; switch (resource->Type) { case ACPI_RESOURCE_TYPE_IRQ: case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: MPASS(i < sc->pl_num_links); /* * Only configure the interrupt and update the * weights if this link has a valid IRQ and was * previously unrouted. */ if (!link->l_routed && PCI_INTERRUPT_VALID(link->l_irq)) { link->l_routed = TRUE; acpi_config_intr(dev, resource); pci_link_interrupt_weights[link->l_irq] += link->l_references; } link++; i++; break; } resource = ACPI_NEXT_RESOURCE(resource); if (resource >= end) break; } AcpiOsFree(srsbuf.Pointer); return (AE_OK); }
void AcpiDbCreateExecutionThreads ( char *NumThreadsArg, char *NumLoopsArg, char *MethodNameArg) { ACPI_STATUS Status; UINT32 NumThreads; UINT32 NumLoops; UINT32 i; UINT32 Size; ACPI_MUTEX MainThreadGate; ACPI_MUTEX ThreadCompleteGate; ACPI_MUTEX InfoGate; /* Get the arguments */ NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0); NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0); if (!NumThreads || !NumLoops) { AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n", NumThreads, NumLoops); return; } /* * Create the semaphore for synchronization of * the created threads with the main thread. */ Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", AcpiFormatException (Status)); return; } /* * Create the semaphore for synchronization * between the created threads. */ Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", AcpiFormatException (Status)); (void) AcpiOsDeleteSemaphore (MainThreadGate); return; } Status = AcpiOsCreateSemaphore (1, 1, &InfoGate); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n", AcpiFormatException (Status)); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (MainThreadGate); return; } ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); /* Array to store IDs of threads */ AcpiGbl_DbMethodInfo.NumThreads = NumThreads; Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads; AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size); if (AcpiGbl_DbMethodInfo.Threads == NULL) { AcpiOsPrintf ("No memory for thread IDs array\n"); (void) AcpiOsDeleteSemaphore (MainThreadGate); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (InfoGate); return; } ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); /* Setup the context to be passed to each thread */ AcpiGbl_DbMethodInfo.Name = MethodNameArg; AcpiGbl_DbMethodInfo.Flags = 0; AcpiGbl_DbMethodInfo.NumLoops = NumLoops; AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; AcpiGbl_DbMethodInfo.InfoGate = InfoGate; /* Init arguments to be passed to method */ AcpiGbl_DbMethodInfo.InitArgs = 1; AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[3] = NULL; AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes; AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER; AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER; AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER; AcpiDbUint32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { goto CleanupAndExit; } /* Get the NS node, determines existence also */ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname, &AcpiGbl_DbMethodInfo.Method); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("%s Could not get handle for %s\n", AcpiFormatException (Status), AcpiGbl_DbMethodInfo.Pathname); goto CleanupAndExit; } /* Create the threads */ AcpiOsPrintf ("Creating %X threads to execute %X times each\n", NumThreads, NumLoops); for (i = 0; i < (NumThreads); i++) { Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread, &AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { break; } } /* Wait for all threads to complete */ (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); CleanupAndExit: /* Cleanup and exit */ (void) AcpiOsDeleteSemaphore (MainThreadGate); (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); (void) AcpiOsDeleteSemaphore (InfoGate); AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); AcpiGbl_DbMethodInfo.Threads = NULL; }
ACPI_STATUS AcpiEvaluateObjectTyped ( ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer, ACPI_OBJECT_TYPE ReturnType) { ACPI_STATUS Status; BOOLEAN MustFree = FALSE; ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); /* Return buffer must be valid */ if (!ReturnBuffer) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) { MustFree = TRUE; } /* Evaluate the object */ Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Type ANY means "don't care" */ if (ReturnType == ACPI_TYPE_ANY) { return_ACPI_STATUS (AE_OK); } if (ReturnBuffer->Length == 0) { /* Error because caller specifically asked for a return value */ ACPI_ERROR ((AE_INFO, "No return value")); return_ACPI_STATUS (AE_NULL_OBJECT); } /* Examine the object type returned from EvaluateObject */ if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) { return_ACPI_STATUS (AE_OK); } /* Return object type does not match requested type */ ACPI_ERROR ((AE_INFO, "Incorrect return type [%s] requested [%s]", AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), AcpiUtGetTypeName (ReturnType))); if (MustFree) { /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ AcpiOsFree (ReturnBuffer->Pointer); ReturnBuffer->Pointer = NULL; } ReturnBuffer->Length = 0; return_ACPI_STATUS (AE_TYPE); }