/* * Copyright (C) 2006, Intel Corporation * * This file is part of the Linux-ready Firmware Developer Kit * * This program file is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation;version 2.1 of the License. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in a file named COPYING; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../biostest.h" #include "acpitable.h" #include #include #include #include #include #if 0 #define CHECK_FIELD(field) \ if (table32->field != table64->field) { \ sprintf(line, "FADT field " #field " has value %x in the 32 bit table and value %x in the 64 bit table.", table32->field, table64->field); \ report_result("FADT", WARN, "FADT field " #field " has different 32/64 bit values", line, NULL); \ } void compare_32_and_64_fadt(void) { struct fadt_descriptor *table32, *table64; unsigned long address; unsigned long size; char *table_ptr; char line[4096]; if (locate_acpi_table32("FACP", &address, &size)) return; if (address == 0 || address == -1) return; table_ptr = copy_acpi_table(address, "FACP"); table32 = (struct fadt_descriptor *) table_ptr; if (locate_acpi_table64("FACP", &address, &size)) return; if (address == 0 || address == -1) return; table_ptr = copy_acpi_table(address, "FACP"); table64 = (struct fadt_descriptor *) table_ptr; CHECK_FIELD(V1_firmware_ctrl); CHECK_FIELD(V1_dsdt); CHECK_FIELD(prefer_PM_profile); CHECK_FIELD(sci_int); CHECK_FIELD(smi_cmd); CHECK_FIELD(acpi_enable); CHECK_FIELD(acpi_disable); CHECK_FIELD(S4bios_req); CHECK_FIELD(pstate_cnt); CHECK_FIELD(V1_pm1a_evt_blk); CHECK_FIELD(V1_pm1b_evt_blk); CHECK_FIELD(V1_pm1a_cnt_blk); CHECK_FIELD(V1_pm1b_cnt_blk); CHECK_FIELD(V1_pm2_cnt_blk); CHECK_FIELD(V1_pm_tmr_blk); CHECK_FIELD(V1_gpe0_blk); CHECK_FIELD(V1_gpe1_blk); CHECK_FIELD(pm1_evt_len); CHECK_FIELD(pm1_cnt_len); CHECK_FIELD(pm2_cnt_len); CHECK_FIELD(pm_tm_len); CHECK_FIELD(gpe0_blk_len); CHECK_FIELD(gpe1_blk_len); CHECK_FIELD(gpe1_base); CHECK_FIELD(cst_cnt); CHECK_FIELD(plvl2_lat); CHECK_FIELD(plvl3_lat); CHECK_FIELD(flush_size); CHECK_FIELD(flush_stride); CHECK_FIELD(duty_offset); CHECK_FIELD(duty_width); CHECK_FIELD(day_alrm); CHECK_FIELD(mon_alrm); CHECK_FIELD(century); CHECK_FIELD(iapc_boot_arch); } #endif void do_manual_fadt_test(void) { unsigned long address; unsigned long size; char *table_ptr, *table_page; struct fadt_descriptor_rev2 *table; start_test("FADT", "FADT test", "verify FADT SCI_EN bit enabled or NOT."); if (locate_acpi_table("FACP", &address, &size)) { report_result("FADT", WARN, "No FADT ACPI table found.", NULL, NULL); goto out; } if (address == 0) { report_result("FADT", WARN, "No FADT ACPI table found.", NULL, NULL); goto out; } table_page = table_ptr = address; table = (struct fadt_descriptor_rev2 *) table_ptr; { unsigned int value,port,width; char line[4096]; int version1=1; if (table->length >= ( (unsigned char*)&(table->xpm1a_cnt_blk.address) - (unsigned char*)&(table->signature))) version1 = 0; value=0; port = table->V1_pm1a_cnt_blk; width = table->pm1_cnt_len*8; if (!version1) { if (width != table->xpm1a_cnt_blk.register_bit_width) report_result("FADT", WARN, "64 bit and 32 bit versions of pm1_cnt size don't match", NULL, NULL); if (port != table->xpm1a_cnt_blk.address) report_result("FADT", WARN, "64 bit and 32 bit versions of pm1_cnt address don't match", NULL, NULL); port = table->xpm1a_cnt_blk.address; width = table->xpm1a_cnt_blk.register_bit_width; } ioperm(port,width/8,TRUE); switch(width){ case 8: value = inb(port); break; case 16: value = inw(port); break; case 32: value = inl(port); break; default: sprintf(line, "PM1a register is at port address %i and is %i bits wide", port, width); report_result("FADT", FAIL, "Invalid register bit width", line, NULL); } if (value & 0x1) /*SCI_EN bit*/ report_result("FADT", PASS, "ACPI mode, SCI_EN bit in PM1a_Control register is correctly enabled",NULL,NULL); else report_result("FADT", FAIL, "Legacy mode, SCI_EN bit in PM1a_Control register is incorrectly Disabled",NULL,NULL); } #if 0 compare_32_and_64_fadt(); #endif out: finish_test("FADT"); } void run_test(void) { register_interactive_test("FADT test", do_manual_fadt_test); }