/*
* p6uc - Update Intel Microcode on P6 processors.
*
* Copyright (C) 2000, Tigran Aivazian (GPL v2, as usual)
*
* Reference: Section 8.10 of Volume III,
* Intel Pentium III Manual, Order Number 243192.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <asm/mtrr.h>
struct mtrr_p6update ioc;
void * ucode;
static char * myname;
static void die(const char * fmt, ...);
int main(int argc, char *argv[])
{
int fd;
struct stat st;
myname = argv[0];
if (argc != 2) {
fprintf(stderr, "usage: %s [mcode_file]\n", argv[0]);
exit(1);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1)
die("open(%s)", argv[1]);
if (fstat(fd, &st) == -1)
die("fstat(fd=%d)", fd);
if (st.st_size == 0 || (st.st_size % sizeof(struct p6ucode) != 0)) {
fprintf(stderr, "%s: corrupted microcode in '%s' or 'struct p6ucode' "
"in <asm/mtrr.h> needs updating\n", argv[0], argv[1]);
exit(1);
}
ucode = malloc(st.st_size);
if (!ucode)
die("Can't malloc(%ld) to hold microcode\n", st.st_size);
if (read(fd, ucode, st.st_size) != st.st_size)
die("read(fd, ucode, %ld)", st.st_size);
if (close(fd) == -1)
die("close(fd=%d)", fd);
fd = open("/proc/mtrr", O_RDONLY);
if (fd == -1)
die("open(/proc/mtrr)");
ioc.num = st.st_size/sizeof(struct p6ucode);
ioc.uaddr = ucode;
if (ioctl(fd, MTRRIOC_P6UPDATE, &ioc) == -1)
die("ioctl(MTRRIOC_P6UPDATE, num=%d)", ioc.num);
if (close(fd) == -1)
die("close(fd=%d)", fd);
return 0;
}
static void die(const char * fmt, ...)
{
va_list args;
static char buf[4096];
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
fprintf(stderr, "%s: %s, errno=%d (%s)\n",
myname, buf, errno, strerror(errno));
exit(1);
}