FADT表的parse

在acpi_tb_parse_root_table 函数中会调用 acpi_tb_parse_fadt parse FADT table
当然前提是acpi_gbl_root_table_list 中有fdat table,判断的额方法如下:
        if (ACPI_SUCCESS(status) &&
            ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
                      tables[table_index].signature,
                      ACPI_SIG_FADT)) {
            acpi_gbl_fadt_index = table_index;
            acpi_tb_parse_fadt();

于此同时acpi_gbl_fadt_index 表示fadt在这个acpi_tb_parse_root_table 数组中的index.
可见会比较signature 是否相等来作为是否parse fadt的条件
void acpi_tb_parse_fadt(void)
{
    u32 length;
    struct acpi_table_header *table;

    /*
     * The FADT has multiple versions with different lengths,
     * and it contains pointers to both the DSDT and FACS tables.
     *
     * Get a local copy of the FADT and convert it to a common format
     * Map entire FADT, assumed to be smaller than one page.
     */
    length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;

    table =
        acpi_os_map_memory(acpi_gbl_root_table_list.
                   tables[acpi_gbl_fadt_index].address, length);
    if (!table) {
        return;
    }

    /*
     * Validate the FADT checksum before we copy the table. Ignore
     * checksum error as we want to try to get the DSDT and FACS.
     */
    (void)acpi_tb_verify_checksum(table, length);

    /* Create a local copy of the FADT in common ACPI 2.0+ format */

    acpi_tb_create_local_fadt(table, length);

    /* All done with the real FADT, unmap it */

    acpi_os_unmap_memory(table, length);

    /* Obtain the DSDT and FACS tables via their addresses within the FADT */

    acpi_tb_install_standard_table((acpi_physical_address)acpi_gbl_FADT.
                       Xdsdt,
                       ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
                       FALSE, TRUE, &acpi_gbl_dsdt_index);

    /* If Hardware Reduced flag is set, there is no FACS */

    if (!acpi_gbl_reduced_hardware) {
        if (acpi_gbl_FADT.facs) {
            acpi_tb_install_standard_table((acpi_physical_address)
                               acpi_gbl_FADT.facs,
                               ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
                               FALSE, TRUE,
                               &acpi_gbl_facs_index);
        }
        if (acpi_gbl_FADT.Xfacs) {
            acpi_tb_install_standard_table((acpi_physical_address)
                               acpi_gbl_FADT.Xfacs,
                               ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
                               FALSE, TRUE,
                               &acpi_gbl_xfacs_index);
        }
    }
}
acpi_tb_parse_fadt 中首先的到fadt的长度
    length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;

得到memory
    table =
        acpi_os_map_memory(acpi_gbl_root_table_list.
                   tables[acpi_gbl_fadt_index].address, length);
调用
    (void)acpi_tb_verify_checksum(table, length);
来计算fadt的checksum
acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
{
    u8 checksum;

    /*
     * FACS/S3PT:
     * They are the odd tables, have no standard ACPI header and no checksum
     */

    if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_S3PT) ||
        ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FACS)) {
        return (AE_OK);
    }

    /* Compute the checksum on the table */

    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);

    /* Checksum ok? (should be zero) */

    if (checksum) {
        ACPI_BIOS_WARNING((AE_INFO,
                   "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
                   "should be 0x%2.2X",
                   table->signature, table->checksum,
                   (u8)(table->checksum - checksum)));

#if (ACPI_CHECKSUM_ABORT)
        return (AE_BAD_CHECKSUM);
#endif
    }

    return (AE_OK);
}
acpi_tb_verify_checksum 的就是计算checksum 然后看table->checksum - checksum的结果是否为0
也就是说无论checksum是否ok 都会打印“Incorrect checksum in table”
最后会调用acpi_tb_install_standard_table -> acpi_tb_install_table_with_override
来将fadt table安装到acpi_gbl_root_table_list中
void
acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
                    u8 override, u32 *table_index)
{
    u32 i;
    acpi_status status;

    status = acpi_tb_get_next_table_descriptor(&i, NULL);
    if (ACPI_FAILURE(status)) {
        return;
    }

    /*
     * ACPI Table Override:
     *
     * Before we install the table, let the host OS override it with a new
     * one if desired. Any table within the RSDT/XSDT can be replaced,
     * including the DSDT which is pointed to by the FADT.
     */
    if (override) {
        acpi_tb_override_table(new_table_desc);
    }

    acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i],
                      new_table_desc->address,
                      new_table_desc->flags,
                      new_table_desc->pointer);

    acpi_tb_print_table_header(new_table_desc->address,
                   new_table_desc->pointer);

    /* This synchronizes acpi_gbl_dsdt_index */

    *table_index = i;

    /* Set the global integer width (based upon revision of the DSDT) */

    if (i == acpi_gbl_dsdt_index) {
        acpi_ut_set_integer_width(new_table_desc->pointer->revision);
    }
}
acpi_tb_install_table_with_override 中首先调用acpi_tb_get_next_table_descriptor 获得acpi_gbl_root_table_list 中的位置
最后调用acpi_tb_init_table_descriptor 更新fadt到acpi_gbl_root_table_list
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值