static ACPI_STATUS
AeInstallPciHandler (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_STATUS             Status;


    /* Install memory and I/O handlers for the PCI device */

    Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
        AeRegionHandler, AeRegionInit, &AeMyContext);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status,
            "Could not install an OpRegion handler for PCI device (%p)",
            ObjHandle));
    }

    Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY,
        AeRegionHandler, AeRegionInit, &AeMyContext);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status,
            "Could not install an OpRegion handler for PCI device (%p)",
            ObjHandle));
    }

    return (AE_CTRL_TERMINATE);
}
Esempio n. 2
0
static ACPI_STATUS
InstallHandlers (void)
{
    ACPI_STATUS             Status;


    /* Install global notify handler */

    Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT,
        ACPI_SYSTEM_NOTIFY, NotifyHandler, NULL);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status, "While installing Notify handler"));
        return (Status);
    }

    Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
        ACPI_ADR_SPACE_SYSTEM_MEMORY, RegionHandler, RegionInit, NULL);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status, "While installing an OpRegion handler"));
        return (Status);
    }

    return (AE_OK);
}
Esempio n. 3
0
/*
 * Install acpica-provided (default) address-space handlers
 * that may be needed before AcpiEnableSubsystem() runs.
 * See the comment in AcpiInstallAddressSpaceHandler().
 * Default handlers for remaining address spaces are
 * installed later, in AcpiEnableSubsystem.
 */
static int
acpica_install_handlers()
{
	ACPI_STATUS	rv = AE_OK;
	ACPI_STATUS	res;

	/*
	 * Install ACPI CA default handlers
	 */
	if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
	    ACPI_ADR_SPACE_SYSTEM_MEMORY,
	    ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK &&
	    res != AE_SAME_HANDLER) {
		cmn_err(CE_WARN, "!acpica: no default handler for"
		    " system memory");
		rv = AE_ERROR;
	}

	if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
	    ACPI_ADR_SPACE_SYSTEM_IO,
	    ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK &&
	    res != AE_SAME_HANDLER) {
		cmn_err(CE_WARN, "!acpica: no default handler for"
		    " system I/O");
		rv = AE_ERROR;
	}

	if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
	    ACPI_ADR_SPACE_PCI_CONFIG,
	    ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK &&
	    res != AE_SAME_HANDLER) {
		cmn_err(CE_WARN, "!acpica: no default handler for"
		    " PCI Config");
		rv = AE_ERROR;
	}

	if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
	    ACPI_ADR_SPACE_DATA_TABLE,
	    ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK &&
	    res != AE_SAME_HANDLER) {
		cmn_err(CE_WARN, "!acpica: no default handler for"
		    " Data Table");
		rv = AE_ERROR;
	}

	return (rv);
}
ACPI_STATUS
AeInstallLateHandlers (
    void)
{
    ACPI_STATUS             Status;
    UINT32                  i;


#if (!ACPI_REDUCED_HARDWARE)
    if (!AcpiGbl_ReducedHardware)
    {
        /* Install a user SCI handler */

        Status = AeInstallSciHandler ();
        AE_CHECK_OK (AeInstallSciHandler, Status);

        /* Install some fixed event handlers */

        Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
        AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);

        Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
        AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
    }
#endif /* !ACPI_REDUCED_HARDWARE */

    AeMyContext.Connection = NULL;
    AeMyContext.AccessLength = 0xA5;

    /*
     * We will install a handler for each EC device, directly under the EC
     * device definition. This is unlike the other handlers which we install
     * at the root node. Also install memory and I/O handlers at any PCI
     * devices.
     */
    AeInstallDeviceHandlers ();

    /*
     * Install handlers for some of the "device driver" address spaces
     * such as SMBus, etc.
     */
    for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
    {
        /* Install handler at the root object */

        Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
                    SpaceIdList[i], AeRegionHandler,
                    AeRegionInit, &AeMyContext);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "Could not install an OpRegion handler for %s space(%u)",
                AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
            return (Status);
        }
    }

    return (AE_OK);
}
Esempio n. 5
0
status_t
install_address_space_handler(acpi_handle handle, uint32 spaceId,
                              acpi_adr_space_handler handler, acpi_adr_space_setup setup,	void *data)
{
    return AcpiInstallAddressSpaceHandler(handle, spaceId,
                                          (ACPI_ADR_SPACE_HANDLER)handler, (ACPI_ADR_SPACE_SETUP)setup, data)
           == AE_OK ? B_OK : B_ERROR;
}
Esempio n. 6
0
static void
smbus_acpi_install_address_space_handler(struct smbus_acpi_softc *sc)
{
	ACPI_HANDLE handle;
	ACPI_STATUS s;

	handle = acpi_get_handle(sc->parent);
	sc->space_handler_data.dev = sc->parent;
	s = AcpiInstallAddressSpaceHandler(handle, ACPI_ADR_SPACE_GSBUS,
	    &smbus_acpi_space_handler, NULL, &sc->space_handler_data);
	if (ACPI_FAILURE(s)) {
		device_printf(sc->dev,
		    "Failed to install GSBUS Address Space Handler in ACPI\n");
	}
}
static ACPI_STATUS
AeInstallEcHandler (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_STATUS             Status;


    /* Install the handler for this EC device */

    Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC,
        AeRegionHandler, AeRegionInit, &AeMyContext);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status,
            "Could not install an OpRegion handler for EC device (%p)",
            ObjHandle));
    }

    return (Status);
}
Esempio n. 8
0
static int
acpi_ec_attach(device_t dev)
{
    struct acpi_ec_softc	*sc;
    struct acpi_ec_params	*params;
    ACPI_STATUS			Status;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    /* Fetch/initialize softc (assumes softc is pre-zeroed). */
    sc = device_get_softc(dev);
    params = acpi_get_private(dev);
    sc->ec_dev = dev;
    sc->ec_handle = acpi_get_handle(dev);
    ACPI_SERIAL_INIT(ec);

    /* Retrieve previously probed values via device ivars. */
    sc->ec_glk = params->glk;
    sc->ec_gpebit = params->gpe_bit;
    sc->ec_gpehandle = params->gpe_handle;
    sc->ec_uid = params->uid;
    sc->ec_suspending = FALSE;
    acpi_set_private(dev, NULL);
    kfree(params, M_TEMP);

    /* Attach bus resources for data and command/status ports. */
    sc->ec_data_rid = 0;
    sc->ec_data_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT,
			&sc->ec_data_rid, RF_ACTIVE);
    if (sc->ec_data_res == NULL) {
	device_printf(dev, "can't allocate data port\n");
	goto error;
    }
    sc->ec_data_tag = rman_get_bustag(sc->ec_data_res);
    sc->ec_data_handle = rman_get_bushandle(sc->ec_data_res);

    sc->ec_csr_rid = 1;
    sc->ec_csr_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT,
			&sc->ec_csr_rid, RF_ACTIVE);
    if (sc->ec_csr_res == NULL) {
	device_printf(dev, "can't allocate command/status port\n");
	goto error;
    }
    sc->ec_csr_tag = rman_get_bustag(sc->ec_csr_res);
    sc->ec_csr_handle = rman_get_bushandle(sc->ec_csr_res);

    /*
     * Install a handler for this EC's GPE bit.  We want edge-triggered
     * behavior.
     */
    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching GPE handler\n"));
    Status = AcpiInstallGpeHandler(sc->ec_gpehandle, sc->ec_gpebit,
		ACPI_GPE_EDGE_TRIGGERED, &EcGpeHandler, sc);
    if (ACPI_FAILURE(Status)) {
	device_printf(dev, "can't install GPE handler for %s - %s\n",
		      acpi_name(sc->ec_handle), AcpiFormatException(Status));
	goto error;
    }

    /*
     * Install address space handler
     */
    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching address space handler\n"));
    Status = AcpiInstallAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC,
		&EcSpaceHandler, &EcSpaceSetup, sc);
    if (ACPI_FAILURE(Status)) {
	device_printf(dev, "can't install address space handler for %s - %s\n",
		      acpi_name(sc->ec_handle), AcpiFormatException(Status));
	goto error;
    }

    /* Enable runtime GPEs for the handler */
    Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit);
    if (ACPI_FAILURE(Status)) {
	device_printf(dev, "AcpiEnableGpe failed: %s\n",
		      AcpiFormatException(Status));
	goto error;
    }

    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "acpi_ec_attach complete\n"));
    return (0);

error:
    AcpiRemoveGpeHandler(sc->ec_gpehandle, sc->ec_gpebit, &EcGpeHandler);
    AcpiRemoveAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC,
	EcSpaceHandler);
    if (sc->ec_csr_res)
	bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_csr_rid,
			     sc->ec_csr_res);
    if (sc->ec_data_res)
	bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid,
			     sc->ec_data_res);
    return (ENXIO);
}
Esempio n. 9
0
ACPI_STATUS
AcpiEvPciConfigRegionSetup (
    ACPI_HANDLE             Handle,
    UINT32                  Function,
    void                    *HandlerContext,
    void                    **RegionContext)
{
    ACPI_STATUS             Status = AE_OK;
    UINT64                  PciValue;
    ACPI_PCI_ID             *PciId = *RegionContext;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_NAMESPACE_NODE     *ParentNode;
    ACPI_NAMESPACE_NODE     *PciRootNode;
    ACPI_NAMESPACE_NODE     *PciDeviceNode;
    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;


    ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);


    HandlerObj = RegionObj->Region.Handler;
    if (!HandlerObj)
    {
        /*
         * No installed handler. This shouldn't happen because the dispatch
         * routine checks before we get here, but we check again just in case.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
            "Attempting to init a region %p, with no handler\n", RegionObj));
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    *RegionContext = NULL;
    if (Function == ACPI_REGION_DEACTIVATE)
    {
        if (PciId)
        {
            ACPI_FREE (PciId);
        }
        return_ACPI_STATUS (Status);
    }

    ParentNode = RegionObj->Region.Node->Parent;

    /*
     * Get the _SEG and _BBN values from the device upon which the handler
     * is installed.
     *
     * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
     * This is the device the handler has been registered to handle.
     */

    /*
     * If the AddressSpace.Node is still pointing to the root, we need
     * to scan upward for a PCI Root bridge and re-associate the OpRegion
     * handlers with that device.
     */
    if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
    {
        /* Start search from the parent object */

        PciRootNode = ParentNode;
        while (PciRootNode != AcpiGbl_RootNode)
        {
            /* Get the _HID/_CID in order to detect a RootBridge */

            if (AcpiEvIsPciRootBridge (PciRootNode))
            {
                /* Install a handler for this PCI root bridge */

                Status = AcpiInstallAddressSpaceHandler (
                    (ACPI_HANDLE) PciRootNode,
                    ACPI_ADR_SPACE_PCI_CONFIG,
                    ACPI_DEFAULT_HANDLER, NULL, NULL);
                if (ACPI_FAILURE (Status))
                {
                    if (Status == AE_SAME_HANDLER)
                    {
                        /*
                         * It is OK if the handler is already installed on the
                         * root bridge. Still need to return a context object
                         * for the new PCI_Config operation region, however.
                         */
                        Status = AE_OK;
                    }
                    else
                    {
                        ACPI_EXCEPTION ((AE_INFO, Status,
                            "Could not install PciConfig handler "
                            "for Root Bridge %4.4s",
                            AcpiUtGetNodeName (PciRootNode)));
                    }
                }
                break;
            }

            PciRootNode = PciRootNode->Parent;
        }

        /* PCI root bridge not found, use namespace root node */
    }
    else
    {
        PciRootNode = HandlerObj->AddressSpace.Node;
    }

    /*
     * If this region is now initialized, we are done.
     * (InstallAddressSpaceHandler could have initialized it)
     */
    if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Region is still not initialized. Create a new context */

    PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
    if (!PciId)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * For PCI_Config space access, we need the segment, bus, device and
     * function numbers. Acquire them here.
     *
     * Find the parent device object. (This allows the operation region to be
     * within a subscope under the device, such as a control method.)
     */
    PciDeviceNode = RegionObj->Region.Node;
    while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
    {
        PciDeviceNode = PciDeviceNode->Parent;
    }

    if (!PciDeviceNode)
    {
        ACPI_FREE (PciId);
        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }

    /*
     * Get the PCI device and function numbers from the _ADR object
     * contained in the parent's scope.
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
        PciDeviceNode, &PciValue);

    /*
     * The default is zero, and since the allocation above zeroed the data,
     * just do nothing on failure.
     */
    if (ACPI_SUCCESS (Status))
    {
        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
    }

    /* The PCI segment number comes from the _SEG method */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
        PciRootNode, &PciValue);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Segment = ACPI_LOWORD (PciValue);
    }

    /* The PCI bus number comes from the _BBN method */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
        PciRootNode, &PciValue);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Bus = ACPI_LOWORD (PciValue);
    }

    /* Complete/update the PCI ID for this device */

    Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (PciId);
        return_ACPI_STATUS (Status);
    }

    *RegionContext = PciId;
    return_ACPI_STATUS (AE_OK);
}
Esempio n. 10
0
static status_t
acpi_std_ops(int32 op,...)
{
    switch (op) {
    case B_MODULE_INIT:
    {
        ACPI_OBJECT arg;
        ACPI_OBJECT_LIST parameter;
        void *settings;
        bool acpiDisabled = false;
        AcpiGbl_CopyDsdtLocally = true;

        settings = load_driver_settings("kernel");
        if (settings != NULL) {
            acpiDisabled = !get_driver_boolean_parameter(settings, "acpi",
                           true, true);
            unload_driver_settings(settings);
        }

        if (!acpiDisabled) {
            // check if safemode settings disable ACPI
            settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS);
            if (settings != NULL) {
                acpiDisabled = get_driver_boolean_parameter(settings,
                               B_SAFEMODE_DISABLE_ACPI, false, false);
                unload_driver_settings(settings);
            }
        }

        if (acpiDisabled) {
            ERROR("ACPI disabled\n");
            return ENOSYS;
        }

        if (gDPC->new_dpc_queue(&gDPCHandle, "acpi_task",
                                B_URGENT_DISPLAY_PRIORITY + 1) != B_OK) {
            ERROR("failed to create os execution queue\n");
            return B_ERROR;
        }

#ifdef ACPI_DEBUG_OUTPUT
        AcpiDbgLevel = ACPI_DEBUG_ALL | ACPI_LV_VERBOSE;
        AcpiDbgLayer = ACPI_ALL_COMPONENTS;
#endif

        if (checkAndLogFailure(AcpiInitializeSubsystem(),
                               "AcpiInitializeSubsystem failed"))
            goto err;

        if (checkAndLogFailure(AcpiInitializeTables(NULL, 0, TRUE),
                               "AcpiInitializeTables failed"))
            goto err;

        if (checkAndLogFailure(AcpiLoadTables(),
                               "AcpiLoadTables failed"))
            goto err;

        /* Install the default address space handlers. */
        if (checkAndLogFailure(AcpiInstallAddressSpaceHandler(
                                   ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY,
                                   ACPI_DEFAULT_HANDLER, NULL, NULL),
                               "Could not initialise SystemMemory handler:"))
            goto err;

        if (checkAndLogFailure(AcpiInstallAddressSpaceHandler(
                                   ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_IO,
                                   ACPI_DEFAULT_HANDLER, NULL, NULL),
                               "Could not initialise SystemIO handler:"))
            goto err;

        if (checkAndLogFailure(AcpiInstallAddressSpaceHandler(
                                   ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_PCI_CONFIG,
                                   ACPI_DEFAULT_HANDLER, NULL, NULL),
                               "Could not initialise PciConfig handler:"))
            goto err;

        arg.Integer.Type = ACPI_TYPE_INTEGER;
        arg.Integer.Value = apic_available() ? APIC_MODE : PIC_MODE;

        parameter.Count = 1;
        parameter.Pointer = &arg;

        AcpiEvaluateObject(NULL, "\\_PIC", &parameter, NULL);

        if (checkAndLogFailure(AcpiEnableSubsystem(
                                   ACPI_FULL_INITIALIZATION),
                               "AcpiEnableSubsystem failed"))
            goto err;

        if (checkAndLogFailure(AcpiInitializeObjects(
                                   ACPI_FULL_INITIALIZATION),
                               "AcpiInitializeObjects failed"))
            goto err;

        //TODO: Walk namespace init ALL _PRW's

#ifdef ACPI_DEBUG_OUTPUT
        checkAndLogFailure(
            AcpiInstallGlobalEventHandler(globalGPEHandler, NULL),
            "Failed to install global GPE-handler.");

        checkAndLogFailure(AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
                           ACPI_ALL_NOTIFY, globalNotifyHandler, NULL),
                           "Failed to install global Notify-handler.");
#endif
        checkAndLogFailure(AcpiEnableAllRuntimeGpes(),
                           "Failed to enable all runtime Gpes");

        checkAndLogFailure(AcpiUpdateAllGpes(),
                           "Failed to update all Gpes");

        TRACE("ACPI initialized\n");
        return B_OK;

err:
        return B_ERROR;
    }

    case B_MODULE_UNINIT:
    {
        if (checkAndLogFailure(AcpiTerminate(),
                               "Could not bring system out of ACPI mode. Oh well."));

        gDPC->delete_dpc_queue(gDPCHandle);
        gDPCHandle = NULL;
        break;
    }

    default:
        return B_ERROR;
    }
    return B_OK;
}
ACPI_STATUS
AeInstallHandlers (void)
{
    ACPI_STATUS             Status;
    UINT32                  i;
    ACPI_HANDLE             Handle;


    ACPI_FUNCTION_ENTRY ();


    Status = AcpiInstallTableHandler (AeTableHandler, NULL);
    if (ACPI_FAILURE (Status))
    {
        printf ("Could not install table handler, %s\n",
            AcpiFormatException (Status));
    }

    Status = AcpiInstallExceptionHandler (AeExceptionHandler);
    if (ACPI_FAILURE (Status))
    {
        printf ("Could not install exception handler, %s\n",
            AcpiFormatException (Status));
    }

    /* Install global notify handler */

    Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
                                        AeNotifyHandler, NULL);
    if (ACPI_FAILURE (Status))
    {
        printf ("Could not install a global notify handler, %s\n",
            AcpiFormatException (Status));
    }

    Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
                                        AeDeviceNotifyHandler, NULL);
    if (ACPI_FAILURE (Status))
    {
        printf ("Could not install a global notify handler, %s\n",
            AcpiFormatException (Status));
    }

    Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
    if (ACPI_SUCCESS (Status))
    {
        Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
                                            AeNotifyHandler, NULL);
        if (ACPI_FAILURE (Status))
        {
            printf ("Could not install a notify handler, %s\n",
                AcpiFormatException (Status));
        }

        Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
                                            AeNotifyHandler);
        if (ACPI_FAILURE (Status))
        {
            printf ("Could not remove a notify handler, %s\n",
                AcpiFormatException (Status));
        }

        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
                                            AeNotifyHandler, NULL);
        Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
                                            AeNotifyHandler);
        Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
                                            AeNotifyHandler, NULL);
        if (ACPI_FAILURE (Status))
        {
            printf ("Could not install a notify handler, %s\n",
                AcpiFormatException (Status));
        }

        Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
        Status = AcpiDetachData (Handle, AeAttachedDataHandler);
        Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
    }
    else
    {
        printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
    }

    /* Set a handler for all supported operation regions */

    for (i = 0; i < AEXEC_NUM_REGIONS; i++)
    {
        Status = AcpiRemoveAddressSpaceHandler (AcpiGbl_RootNode,
                        SpaceId[i], AeRegionHandler);

        /* Install handler at the root object.
         * TBD: all default handlers should be installed here!
         */
        Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
                        SpaceId[i], AeRegionHandler, AeRegionInit, NULL);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "Could not install an OpRegion handler for %s space(%u)",
                AcpiUtGetRegionName((UINT8) SpaceId[i]), SpaceId[i]));
            return (Status);
        }
    }

    /*
     * Initialize the global Region Handler space
     * MCW 3/23/00
     */
    AeRegions.NumberOfRegions = 0;
    AeRegions.RegionList = NULL;

    return Status;
}
Esempio n. 12
0
ACPI_STATUS
AcpiEvInitAddressSpaces (
    void)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE ("EvInitAddressSpaces");


    /*
     * All address spaces (PCI Config, EC, SMBus) are scope dependent
     * and registration must occur for a specific device.  In the case
     * system memory and IO address spaces there is currently no device
     * associated with the address space.  For these we use the root.
     * We install the default PCI config space handler at the root so
     * that this space is immediately available even though the we have
     * not enumerated all the PCI Root Buses yet.  This is to conform
     * to the ACPI specification which states that the PCI config
     * space must be always available -- even though we are nowhere
     * near ready to find the PCI root buses at this point.
     *
     * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
     * has already been installed (via AcpiInstallAddressSpaceHandler)
     */

    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode,
                                             ACPI_ADR_SPACE_SYSTEM_MEMORY,
                                             ACPI_DEFAULT_HANDLER, NULL, NULL);
    if ((ACPI_FAILURE (Status)) &&
        (Status != AE_ALREADY_EXISTS))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode,
                                             ACPI_ADR_SPACE_SYSTEM_IO,
                                             ACPI_DEFAULT_HANDLER, NULL, NULL);
    if ((ACPI_FAILURE (Status)) &&
        (Status != AE_ALREADY_EXISTS))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode,
                                             ACPI_ADR_SPACE_PCI_CONFIG,
                                             ACPI_DEFAULT_HANDLER, NULL, NULL);
    if ((ACPI_FAILURE (Status)) &&
        (Status != AE_ALREADY_EXISTS))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode,
                                             ACPI_ADR_SPACE_DATA_TABLE,
                                             ACPI_DEFAULT_HANDLER, NULL, NULL);
    if ((ACPI_FAILURE (Status)) &&
        (Status != AE_ALREADY_EXISTS))
    {
        return_ACPI_STATUS (Status);
    }

    return_ACPI_STATUS (AE_OK);
}
Esempio n. 13
0
static int
acpi_ec_attach(device_t dev)
{
    struct acpi_ec_softc	*sc;
    ACPI_STATUS			Status;
    int errval = 0;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    /*
     * Fetch/initialise softc
     */
    sc = device_get_softc(dev);
    bzero(sc, sizeof(*sc));
    sc->ec_dev = dev;
    sc->ec_handle = acpi_get_handle(dev);

    /* 
     * Attach bus resources
     */
    sc->ec_data_rid = 0;
    if ((sc->ec_data_res = bus_alloc_resource(sc->ec_dev, SYS_RES_IOPORT, &sc->ec_data_rid,
					      0, ~0, 1, RF_ACTIVE)) == NULL) {
	device_printf(dev, "can't allocate data port\n");
	errval = ENXIO;
	goto out;
    }
    sc->ec_data_tag = rman_get_bustag(sc->ec_data_res);
    sc->ec_data_handle = rman_get_bushandle(sc->ec_data_res);

    sc->ec_csr_rid = 1;
    if ((sc->ec_csr_res = bus_alloc_resource(sc->ec_dev, SYS_RES_IOPORT, &sc->ec_csr_rid,
					     0, ~0, 1, RF_ACTIVE)) == NULL) {
	device_printf(dev, "can't allocate command/status port\n");
	errval = ENXIO;
	goto out;
    }
    sc->ec_csr_tag = rman_get_bustag(sc->ec_csr_res);
    sc->ec_csr_handle = rman_get_bushandle(sc->ec_csr_res);

    /*
     * Install GPE handler
     *
     * Evaluate the _GPE method to find the GPE bit used by the EC to signal
     * status (SCI).
     */
    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching GPE\n"));
    if (ACPI_FAILURE(Status = acpi_EvaluateInteger(sc->ec_handle, "_GPE", &sc->ec_gpebit))) {
	device_printf(dev, "can't evaluate _GPE - %s\n", AcpiFormatException(Status));
	errval =ENXIO;
	goto out;
    }

    /*
     * Install a handler for this EC's GPE bit.  Note that EC SCIs are 
     * treated as both edge- and level-triggered interrupts; in other words
     * we clear the status bit immediately after getting an EC-SCI, then
     * again after we're done processing the event.  This guarantees that
     * events we cause while performing a transaction (e.g. IBE/OBF) get 
     * cleared before re-enabling the GPE.
     */
    if (ACPI_FAILURE(Status = AcpiInstallGpeHandler(sc->ec_gpebit,
						    ACPI_EVENT_LEVEL_TRIGGERED |
						    ACPI_EVENT_EDGE_TRIGGERED, 
						    EcGpeHandler, sc))) {
	device_printf(dev, "can't install GPE handler for %s - %s\n",
		      acpi_name(sc->ec_handle), AcpiFormatException(Status));
	errval = ENXIO;
	goto out;
    }

    /* 
     * Install address space handler
     */
    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching address space handler\n"));
    if (ACPI_FAILURE(Status = AcpiInstallAddressSpaceHandler(sc->ec_handle,
							     ACPI_ADR_SPACE_EC,
							     EcSpaceHandler,
							     EcSpaceSetup,
							     sc))) {
	device_printf(dev, "can't install address space handler for %s - %s\n",
		      acpi_name(sc->ec_handle), AcpiFormatException(Status));
	panic("very suck");
	errval = ENXIO;
	goto out;
    }
    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attach complete\n"));
    return_VALUE(0);
 out:
    if(sc->ec_csr_res)
	bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_csr_rid, 
			     sc->ec_csr_res);
    if(sc->ec_data_res)
        bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid,
			     sc->ec_data_res);
    return_VALUE(errval);
}
Esempio n. 14
0
/*
 * acpiec_attach:
 *
 *	Autoconfiguration `attach' routine.
 */
void
acpiec_attach(struct device *parent, struct device *self, void *aux)
{
	struct acpi_ec_softc *sc = (void *) self;
	struct acpi_attach_args *aa = aux;
	struct acpi_io *io0, *io1;
	ACPI_STATUS rv;

	FUNCTION_TRACE(__FUNCTION__);

	printf(": ACPI Embedded Controller\n");

	sc->sc_node = aa->aa_node;

	/* Parse our resources. */
	ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "parsing EC resources\n"));
	rv = acpi_resource_parse(&sc->sc_dev, sc->sc_node, &sc->sc_res,
	    &acpi_resource_parse_ops_default);
	if (rv != AE_OK) {
		printf("%s: unable to parse resources: %d\n",
		    sc->sc_dev.dv_xname, rv);
		return;
	}

	sc->sc_data_st = aa->aa_iot;
	io0 = acpi_res_io(&sc->sc_res, 0);
	if (io0 == NULL) {
		printf("%s: unable to find data register resource\n",
		    sc->sc_dev.dv_xname);
		return;
	}
	if (bus_space_map(sc->sc_data_st, io0->ar_base, io0->ar_length,
	    0, &sc->sc_data_sh) != 0) {
		printf("%s: unable to map data register\n",
		    sc->sc_dev.dv_xname);
		return;
	}

	sc->sc_csr_st = aa->aa_iot;
	io1 = acpi_res_io(&sc->sc_res, 1);
	if (io1 == NULL) {
		printf("%s: unable to find csr register resource\n",
		    sc->sc_dev.dv_xname);
		return;
	}
	if (bus_space_map(sc->sc_csr_st, io1->ar_base, io1->ar_length,
	    0, &sc->sc_csr_sh) != 0) {
		printf("%s: unable to map csr register\n",
		    sc->sc_dev.dv_xname);
		return;
	}

	/*
	 * Install GPE handler.
	 *
	 * We evaluate the _GPE method to find the GPE bit used by the
	 * Embedded Controller to signal status (SCI).
	 */
	if ((rv = acpi_eval_integer(sc->sc_node->ad_handle, "_GPE",
	     &sc->sc_gpebit)) != AE_OK) {
		printf("%s: unable to evaluate _GPE: %d\n",
		    sc->sc_dev.dv_xname, rv);
		return;
	}

	/*
	 * Install a handler for this EC's GPE bit.  Note that EC SCIs are 
	 * treated as both edge- and level-triggered interrupts; in other words
	 * we clear the status bit immediately after getting an EC-SCI, then
	 * again after we're done processing the event.  This guarantees that
	 * events we cause while performing a transaction (e.g. IBE/OBF) get 
	 * cleared before re-enabling the GPE.
	 */
	if ((rv = AcpiInstallGpeHandler(sc->sc_gpebit,
	     ACPI_EVENT_LEVEL_TRIGGERED | ACPI_EVENT_EDGE_TRIGGERED,
	     EcGpeHandler, sc)) != AE_OK) {
		printf("%s: unable to install GPE handler: %d\n",
		    sc->sc_dev.dv_xname, rv);
		return;
	}

	/* Install address space handler. */
	if ((rv = AcpiInstallAddressSpaceHandler(sc->sc_node->ad_handle,
	     ACPI_ADR_SPACE_EC, EcSpaceHandler, EcSpaceSetup, sc)) != AE_OK) {
		printf("%s: unable to install address space handler: %d\n",
		    sc->sc_dev.dv_xname, rv);
		return;
	}

	return_VOID;
}
Esempio n. 15
0
ACPI_STATUS
AcpiEvPciConfigRegionSetup (
    ACPI_HANDLE             Handle,
    UINT32                  Function,
    void                    *HandlerContext,
    void                    **RegionContext)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_INTEGER            Temp;
    ACPI_PCI_ID             *PciId = *RegionContext;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
    ACPI_DEVICE_ID          ObjectHID;


    ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup");


    HandlerObj = RegionObj->Region.AddrHandler;
    if (!HandlerObj)
    {
        /*
         * No installed handler. This shouldn't happen because the dispatch
         * routine checks before we get here, but we check again just in case.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
            "Attempting to init a region %p, with no handler\n", RegionObj));
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    if (Function == ACPI_REGION_DEACTIVATE)
    {
        if (PciId)
        {
            ACPI_MEM_FREE (PciId);
            *RegionContext = NULL;
        }

        return_ACPI_STATUS (Status);
    }

    /* Create a new context */

    PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
    if (!PciId)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * For PCI Config space access, we have to pass the segment, bus,
     * device and function numbers.  This routine must acquire those.
     */

    /*
     * First get device and function numbers from the _ADR object
     * in the parent's scope.
     */
    Node = AcpiNsGetParentNode (RegionObj->Region.Node);

    /* Evaluate the _ADR object */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Temp);

    /*
     * The default is zero, and since the allocation above zeroed
     * the data, just do nothing on failure.
     */
    if (ACPI_SUCCESS (Status))
    {
        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (Temp));
        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (Temp));
    }

    /*
     * Get the _SEG and _BBN values from the device upon which the handler
     * is installed.
     *
     * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
     * This is the device the handler has been registered to handle.
     */

    /*
     * If the AddrHandler.Node is still pointing to the root, we need
     * to scan upward for a PCI Root bridge and re-associate the OpRegion
     * handlers with that device.
     */
    if (HandlerObj->AddrHandler.Node == AcpiGbl_RootNode)
    {
        /*
         * Node is currently the parent object
         */
        while (Node != AcpiGbl_RootNode)
        {
            Status = AcpiUtExecute_HID (Node, &ObjectHID);
            if (ACPI_SUCCESS (Status))
            {
                /* Got a valid _HID, check if this is a PCI root */

                if (!(ACPI_STRNCMP (ObjectHID.Buffer, PCI_ROOT_HID_STRING,
                                    sizeof (PCI_ROOT_HID_STRING))))
                {
                    /* Install a handler for this PCI root bridge */

                    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) Node,
                                        ACPI_ADR_SPACE_PCI_CONFIG,
                                        ACPI_DEFAULT_HANDLER, NULL, NULL);
                    if (ACPI_FAILURE (Status))
                    {
                        ACPI_REPORT_ERROR (("Could not install PciConfig handler for %4.4s, %s\n",
                            Node->Name.Ascii, AcpiFormatException (Status)));
                    }
                    break;
                }
            }

            Node = AcpiNsGetParentNode (Node);
        }
    }
    else
    {
        Node = HandlerObj->AddrHandler.Node;
    }

    /*
     * The PCI segment number comes from the _SEG method
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Segment = ACPI_LOWORD (Temp);
    }

    /*
     * The PCI bus number comes from the _BBN method
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Bus = ACPI_LOWORD (Temp);
    }

    /*
     * Complete this device's PciId
     */
    AcpiOsDerivePciId (Node, RegionObj->Region.Node, &PciId);

    *RegionContext = PciId;
    return_ACPI_STATUS (AE_OK);
}