WeHack BBS
最近可能要看看Linux内核的ACPI实现 - 可打印的版本

+- WeHack BBS (https://bbs.wehack.space)
+-- 版块: 计算机技术 (https://bbs.wehack.space/forum-5.html)
+--- 版块: 固件技术讨论区 (https://bbs.wehack.space/forum-8.html)
+--- 主题: 最近可能要看看Linux内核的ACPI实现 (/thread-37.html)



最近可能要看看Linux内核的ACPI实现 - vimacs - 03-27-2018

要禁用ACPI,在内核命令行加上acpi=off就行了,这个参数是在源码arch/x86/kernel/acpi/boot.c的最后一行early_param("acpi", parse_acpi)定义的,在parse_acpi()中,使用disable_acpi()禁用ACPI,其定义如下:

引用:static inline void disable_acpi(void)
{
    acpi_disabled = 1;
    acpi_pci_disabled = 1;
    acpi_noirq = 1;
}

接下来要看看,在不禁用ACPI的时候到底做了什么操作,似乎内核并不只是执行了DSDT,SSDT的代码。


RE: 最近可能要看看Linux内核的ACPI实现 - vimacs - 03-30-2018

现在找到了Linux内核让硬件启用/禁用ACPI模式的方式,在drivers/acpi/acpica/hwacpi.c的acpi_hw_set_mode函数中:

引用:/******************************************************************************
 *
 * FUNCTION:    acpi_hw_set_mode
 *
 * PARAMETERS:  mode            - SYS_MODE_ACPI or SYS_MODE_LEGACY
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Transitions the system into the requested mode.
 *
 ******************************************************************************/
acpi_status acpi_hw_set_mode(u32 mode)
{

    acpi_status status;

    ACPI_FUNCTION_TRACE(hw_set_mode);

    /* If the Hardware Reduced flag is set, machine is always in acpi mode */

    if (acpi_gbl_reduced_hardware) {
        return_ACPI_STATUS(AE_OK);
    }

    /*
     * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
     * system does not support mode transition.
     */
    if (!acpi_gbl_FADT.smi_command) {
        ACPI_ERROR((AE_INFO,
                "No SMI_CMD in FADT, mode transition failed"));
        return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
    }

    /*
     * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
     * in FADT: If it is zero, enabling or disabling is not supported.
     * As old systems may have used zero for mode transition,
     * we make sure both the numbers are zero to determine these
     * transitions are not supported.
     */
    if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
        ACPI_ERROR((AE_INFO,
                "No ACPI mode transition supported in this system "
                "(enable/disable both zero)"));
        return_ACPI_STATUS(AE_OK);
    }

    switch (mode) {
    case ACPI_SYS_MODE_ACPI:

        /* BIOS should have disabled ALL fixed and GP events */

        status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
                        (u32) acpi_gbl_FADT.acpi_enable, 8);
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                  "Attempting to enable ACPI mode\n"));
        break;

    case ACPI_SYS_MODE_LEGACY:
        /*
         * BIOS should clear all fixed status bits and restore fixed event
         * enable bits to default
         */
        status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
                        (u32)acpi_gbl_FADT.acpi_disable, 8);
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                  "Attempting to enable Legacy (non-ACPI) mode\n"));
        break;

    default:

        return_ACPI_STATUS(AE_BAD_PARAMETER);
    }

    if (ACPI_FAILURE(status)) {
        ACPI_EXCEPTION((AE_INFO, status,
                "Could not write ACPI mode change"));
        return_ACPI_STATUS(status);
    }

    return_ACPI_STATUS(AE_OK);
}

其中涉及到ACPI的FADT表,里面有3个参数FADT.smi_command,FADT.acpi_enable和FADT.acpi_disable,它们分别是触发SMI的端口和启用/禁用ACPI的命令,要启用/禁用ACPI,就将相应的命令写入端口,触发SMI,CPU进入SMM后固件执行相应的代码。