Second attempt -- the first one got lost due to some local mail client
problems...

---------- Forwarded message ----------
Date: Fri, 1 Dec 2000 11:43:10 +0000 (GMT)
From: Tigran Aivazian <[EMAIL PROTECTED]>
To: Linus Torvalds <[EMAIL PROTECTED]>
Cc: [EMAIL PROTECTED]
Subject: [patch-2.4.0-test12-pre3] microcode update for P4

Hi Linus,

Here is the patch to microcode update driver to support the new P4
CPU.

Regards,
Tigran

diff -urN -X dontdiff linux/arch/i386/kernel/microcode.c 
ucode/arch/i386/kernel/microcode.c
--- linux/arch/i386/kernel/microcode.c  Mon Oct 30 22:44:29 2000
+++ ucode/arch/i386/kernel/microcode.c  Fri Dec  1 09:45:47 2000
@@ -4,13 +4,13 @@
  *     Copyright (C) 2000 Tigran Aivazian
  *
  *     This driver allows to upgrade microcode on Intel processors
- *     belonging to P6 family - PentiumPro, Pentium II, 
- *     Pentium III, Xeon etc.
+ *     belonging to IA-32 family - PentiumPro, Pentium II, 
+ *     Pentium III, Xeon, Pentium 4, etc.
  *
- *     Reference: Section 8.10 of Volume III, Intel Pentium III Manual, 
- *     Order Number 243192 or free download from:
+ *     Reference: Section 8.10 of Volume III, Intel Pentium 4 Manual, 
+ *     Order Number 245472 or free download from:
  *             
- *     http://developer.intel.com/design/pentiumii/manuals/243192.htm
+ *     http://developer.intel.com/design/pentium4/manuals/245472.htm
  *
  *     For more information, go to http://www.urbanmyth.org/microcode
  *
@@ -44,6 +44,9 @@
  *             to be 0 on my machine which is why it worked even when I
  *             disabled update by the BIOS)
  *             Thanks to Eric W. Biederman <[EMAIL PROTECTED]> for the fix.
+ *     1.08    01 Dec 2000, Richard Schaal <[EMAIL PROTECTED]> and
+ *                          Tigran Aivazian <[EMAIL PROTECTED]>
+ *             Intel P4 processor support.
  */
 
 #include <linux/init.h>
@@ -58,12 +61,20 @@
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 
-#define MICROCODE_VERSION      "1.07"
+#define MICROCODE_VERSION      "1.08"
 
-MODULE_DESCRIPTION("Intel CPU (P6) microcode update driver");
+MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <[EMAIL PROTECTED]>");
 EXPORT_NO_SYMBOLS;
 
+#define MICRO_DEBUG 0
+
+#if MICRO_DEBUG
+#define Dprintk(x...) printk(##x)
+#else
+#define Dprintk(x...)
+#endif
+
 /* VFS interface */
 static int microcode_open(struct inode *, struct file *);
 static ssize_t microcode_read(struct file *, char *, size_t, loff_t *);
@@ -114,7 +125,10 @@
                printk(KERN_ERR "microcode: failed to devfs_register()\n");
                return -EINVAL;
        }
-       printk(KERN_INFO "P6 Microcode Update Driver v%s\n", MICROCODE_VERSION);
+       printk(KERN_INFO 
+               "IA-32 Microcode Update Driver: v%s <[EMAIL PROTECTED]>\n", 
+               MICROCODE_VERSION);
+
        return 0;
 }
 
@@ -124,12 +138,12 @@
        devfs_unregister(devfs_handle);
        if (mc_applied)
                kfree(mc_applied);
-       printk(KERN_INFO "P6 Microcode Update Driver v%s unregistered\n", 
+       printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n", 
                        MICROCODE_VERSION);
 }
 
-module_init(microcode_init);
-module_exit(microcode_exit);
+module_init(microcode_init)
+module_exit(microcode_exit)
 
 static int microcode_open(struct inode *unused1, struct file *unused2)
 {
@@ -177,16 +191,18 @@
 
        req->err = 1; /* assume the worst */
 
-       if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 != 6){
-               printk(KERN_ERR "microcode: CPU%d not an Intel P6\n", cpu_num);
+       if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
+               test_bit(X86_FEATURE_IA64, &c->x86_capability)){
+               printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", 
+cpu_num);
                return;
        }
 
        sig = c->x86_mask + (c->x86_model<<4) + (c->x86<<8);
 
-       if (c->x86_model >= 5) {
-               /* get processor flags from BBL_CR_OVRD MSR (0x17) */
-               rdmsr(0x17, val[0], val[1]);
+       if ((c->x86_model >= 5) || (c->x86 > 6))
+               {
+               /* get processor flags from MSR 0x17 */
+               rdmsr(IA32_PLATFORM_ID, val[0], val[1]);
                pf = 1 << ((val[1] >> 18) & 7);
        }
 
@@ -195,13 +211,32 @@
                    microcode[i].ldrver == 1 && microcode[i].hdrver == 1) {
 
                        found=1;
-                       wrmsr(0x8B, 0, 0);
+
+                       Dprintk("Microcode\n");
+                       Dprintk("   Header Revision %d\n",microcode[i].hdrver);
+                       Dprintk("   Date %x/%x/%x\n",
+                               ((microcode[i].date >> 24 ) & 0xff),
+                               ((microcode[i].date >> 16 ) & 0xff),
+                               (microcode[i].date & 0xFFFF));
+                       Dprintk("   Type %x Family %x Model %x Stepping %x\n",
+                               ((microcode[i].sig >> 12) & 0x3),
+                               ((microcode[i].sig >> 8) & 0xf),
+                               ((microcode[i].sig >> 4) & 0xf),
+                               ((microcode[i].sig & 0xf)));
+                       Dprintk("   Checksum %x\n",microcode[i].cksum);
+                       Dprintk("   Loader Revision %x\n",microcode[i].ldrver);
+                       Dprintk("   Processor Flags %x\n\n",microcode[i].pf);
+
+                       /* trick, to work even if there was no prior update by the 
+BIOS */
+                       wrmsr(IA32_UCODE_REV, 0, 0);
                        __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
-                       rdmsr(0x8B, val[0], rev);
+
+                       /* get current (on-cpu) revision into rev (ignore val[0]) */
+                       rdmsr(IA32_UCODE_REV, val[0], rev);
                        if (microcode[i].rev < rev) {
                                printk(KERN_ERR 
                                        "microcode: CPU%d not 'upgrading' to earlier 
revision"
-                                       " %d (current=%d)\n", cpu_num, 
microcode[i].rev, rev);
+                                       " %x (current=%x)\n", cpu_num, 
+microcode[i].rev, rev);
                        } else if (microcode[i].rev == rev) {
                                printk(KERN_ERR
                                        "microcode: CPU%d already up-to-date (revision 
%d)\n",
@@ -219,9 +254,14 @@
                                        break;
                                }
 
-                               wrmsr(0x79, (unsigned int)(m->bits), 0);
+                               /* write microcode via MSR 0x79 */
+                               wrmsr(IA32_UCODE_WRITE, (unsigned int)(m->bits), 0);
+
+                               /* serialize */
                                __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", 
"dx");
-                               rdmsr(0x8B, val[0], val[1]);
+
+                               /* get the current revision from MSR 0x8B */
+                               rdmsr(IA32_UCODE_REV, val[0], val[1]);
 
                                req->err = 0;
                                req->slot = i;
@@ -267,8 +307,8 @@
                mc_applied = kmalloc(smp_num_cpus*sizeof(struct microcode),
                                GFP_KERNEL);
                if (!mc_applied) {
-                       printk(KERN_ERR "microcode: out of memory for saved 
microcode\n");
                        up_write(&microcode_rwsem);
+                       printk(KERN_ERR "microcode: out of memory for saved 
+microcode\n");
                        return -ENOMEM;
                }
        }
diff -urN -X dontdiff linux/include/asm-i386/msr.h ucode/include/asm-i386/msr.h
--- linux/include/asm-i386/msr.h        Thu Oct  7 18:17:09 1999
+++ ucode/include/asm-i386/msr.h        Fri Dec  1 09:38:59 2000
@@ -30,3 +30,7 @@
                          : "=a" (low), "=d" (high) \
                          : "c" (counter))
 
+/* symbolic names for some interesting MSRs */
+#define IA32_PLATFORM_ID       0x17
+#define IA32_UCODE_WRITE       0x79
+#define IA32_UCODE_REV         0x8B


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to