/* * 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 checks if the microcode in the processor has recent enough microcode loaded. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include struct cpu_micro { char cpu[16]; int version; }; static GList *cpus; static void find_add_cpu(struct cpu_micro *cpu) { GList *iter; int found = 0; iter = cpus; while (iter) { struct cpu_micro *c; c = iter->data; if (strcmp(c->cpu, cpu->cpu)==0) { found = 1; if (c->version != cpu->version) { char line[4096]; sprintf(line, "Cpu %s has outdated microcode (version %x while version %x is available)", cpu->cpu, c->version, cpu->version); report_result("microcode", FAIL, line, NULL, NULL); } } iter = g_list_next(iter); } if (!found) cpus = g_list_append(cpus, cpu); } static void gather_info(void) { DIR *dir; struct dirent *entry; char path[4096]; dir = opendir("/sys/devices/system/cpu"); if (!dir) return; do { entry = readdir(dir); if (entry && strlen(entry->d_name)>3 && strstr(entry->d_name,"cpu") && !strstr(entry->d_name,"idle")) { char buf[1024]; struct cpu_micro *cpu; FILE *file; sprintf(path, "/sys/devices/system/cpu/%s/microcode/version", entry->d_name); file = fopen(path, "r"); if (!file) { report_result("microcode", INFO, "Kernel does not export microcode version", path, NULL); return; } buf[0]=0; buf[1023]=0; fgets(buf, 1023, file); cpu = malloc(sizeof(struct cpu_micro)); assert(cpu!=NULL); memset(cpu, 0, sizeof(struct cpu_micro)); strcpy(cpu->cpu, entry->d_name); cpu->version = strtoul(buf, NULL, 16); find_add_cpu(cpu); } } while (entry); closedir(dir); } int main(int argc, char **argv) { start_test("microcode", "Processor microcode update", "This test verifies if the firmware has put a recent version of the microcode into " "the processor at boot time. Recent microcode is important to have all the required " "features and errata updates for the processor."); system("/sbin/modprobe microcode &> /dev/null"); gather_info(); /* now run the microcode update */ system("/sbin/microcode_ctl -u &> /dev/null"); /* and check for lacking updates */ gather_info(); finish_test("microcode"); return EXIT_SUCCESS; }