/* * 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 */ /* * This test sanity checks apic irq information * rule of thumb: * interrupts <16 should be EDGE * interrupts >16 should be LEVEL * acpi interrupt should be LEVEL */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include static char *full_apicedge; int main(int argc, char **argv) { FILE *file; start_test("apicedge", "(experimental) APIC Edge/Level check", "This test checks if legacy interrupts are edge and PCI interrupts are level"); full_apicedge = strdup("Interrupt distribution table:\n"); file = fopen("/proc/interrupts", "r"); if (!file) { report_result("apicedge", FAIL, "Could not open file /proc/interrupts", NULL, NULL); finish_test("apicedge"); return EXIT_SUCCESS; } while (!feof(file)) { char line[4096], *c; int edge = -1; int irq = 0; memset(line, 0, 4096); if (fgets(line, 4095, file)==NULL) break; full_apicedge = scatprintf(full_apicedge, "%s", line); if (! (line[0]==' ' || (line[0]>='0' && line[0]<='9')) ) continue; irq = strtoul(line, &c, 10); if (c==line) continue; if (strstr(line, "IO-APIC-edge")) edge = 1; if (strstr(line, "IO-APIC-fasteoi")) edge = 0; if (strstr(line, "PCI-MSI-level")) edge = 0; if (strstr(line, "PCI-MSI-edge")) edge = 1; if (strstr(line, "IO-APIC-level")) edge = 0; if (strstr(line,"acpi")) { if (edge==1) report_result("apicedge", FAIL, "ACPI Interrupt is incorrectly edge triggered", line, "interrupts://"); continue; } if (irq<15) { char buffer[4095]; sprintf(buffer,"Legacy interrupt %i is incorrectly level triggered", irq); if (edge==0) report_result("apicedge", FAIL, buffer, line, "interrupts://"); } if (irq<15) { char buffer[4095]; sprintf(buffer,"Non-Legacy interrupt %i is incorrectly level triggered", irq); if (edge==-1) report_result("apicedge", FAIL, buffer, line, "interrupts://"); } } fclose(file); announce_resource("interrupts://", full_apicedge, NULL); finish_test("apicedge"); return EXIT_SUCCESS; }