Index: src/cpu/intel/model_67x/Makefile.inc
===================================================================
--- src/cpu/intel/model_67x/Makefile.inc	(revision 6247)
+++ src/cpu/intel/model_67x/Makefile.inc	(working copy)
@@ -18,5 +18,6 @@
 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 ##
 
+driver-y += l2_cache.c
 driver-y += model_67x_init.c
-
+obj-y += l2_cache.o
Index: src/cpu/intel/model_67x/model_67x_init.c
===================================================================
--- src/cpu/intel/model_67x/model_67x_init.c	(revision 6247)
+++ src/cpu/intel/model_67x/model_67x_init.c	(working copy)
@@ -24,6 +24,7 @@
 #include <cpu/x86/mtrr.h>
 #include <cpu/x86/lapic.h>
 #include <cpu/intel/microcode.h>
+#include <cpu/intel/l2_cache.h>
 #include <cpu/x86/cache.h>
 #include <cpu/x86/msr.h>
 
@@ -41,14 +42,296 @@
 	0x0, 0x0, 0x0, 0x0,
 };
 
+/*--- Begin L2 init code from coreboot v1 ---
+ * The rest of this code is in l2_cache.c
+ */
+
+
+/* int calculate_l2_latency(void);
+int signal_l2(unsigned int address_high, unsigned int address_low,
+	unsigned int data_high, unsigned int data_low,
+	int way, int command);
+unsigned int read_l2(unsigned int address);
+int write_l2(unsigned int address, int data);
+int write_l2_2(unsigned int address, unsigned int data1, unsigned int data2);
+int test_l2_address_alias(unsigned int address1, unsigned int address2,
+                                unsigned int data_high, unsigned int data_low);
+int set_l2_register4(int l);
+int calculate_l2_cache_size(void);
+int calculate_l2_physical_address_range(void);
+int calculate_l2_ecc(void); */
+
+
+static int p6_configure_l2_cache(void)
+{
+        struct cpuid_result cpuid_res;
+        msr_t msr, bblctl3;
+        unsigned int eax;
+         int signature, tmp;
+        int cache_size;
+        int result;
+
+ printk(BIOS_INFO, "Configuring L2 cache... ");
+
+        cpuid_res = cpuid(0);
+
+        if (cpuid_res.ebx != 0x756e6547 || cpuid_res.edx != 0x49656e69 || cpuid_res.ecx != 0x6c65746e) {
+                printk(BIOS_INFO, "Not 'GenuineIntel' Processor");
+                return 0;
+        }
+
+        /* Mask out the stepping */
+        signature = cpuid_eax(1) & 0xfff0;
+	if (signature & 0x1000) {
+                printk(BIOS_DEBUG,"Overdrive chip no L2 cache configuration\n");
+                return 0;
+        }
+
+        if (signature < 0x630 || signature >= 0x680) {
+                printk(BIOS_DEBUG,"L2 cache on CPUID %x does not require configuration\n", signature);
+                return 0;
+        }
+
+        /* Read BBL_CR_CTL3 */
+        bblctl3 = rdmsr(BBL_CR_CTL3);
+        eax = bblctl3.lo;
+        /* If bit 23 (L2 Hardware disable) is set then done */
+        /* These would be Covington core Celerons with no L2 cache */
+        if (eax & 0x800000) {
+                printk(BIOS_INFO,"L2 Hardware disabled");
+                return 0;
+        }
+
+        int calc_eax;
+        int v;
+
+        /* Read EBL_CR_POWERON */
+        msr = rdmsr(EBL_CR_POWERON);
+        eax = msr.lo;
+        /* Mask out [22-24] Clock frequency ratio */
+        eax &= 0x3c00000;
+        if (eax == 0xc00000 || eax == 0x3000000) {
+                printk(BIOS_ERR, "Incorrect clock frequency ratio %x\n", eax);
+                goto bad;
+        }
+
+        disable_cache();
+
+        /* Mask out from BBL_CR_CTL3:
+         * [0] L2 Configured
+         * [5] ECC Check Enable
+         * [6] Address Parity Check Enable
+         * [7] CRTN Parity Check Enable
+         * [8] L2 Enabled
+         * [12:11] Number of L2 banks
+         * [17:13] Cache size per bank
+         * [18] Cache state error checking enable
+         * [22:20] L2 Physical Address Range Support
+         */
+        bblctl3.lo &= 0xff88061e;
+        bblctl3.lo |= 0x40000;
+
+        /* Set:
+         * [17:13] = 00000 = 128Kbyte Cache size per bank
+         * [18] Cache state error checking enable
+         */
+
+/* Write BBL_CR_CTL3 */
+        wrmsr(BBL_CR_CTL3, bblctl3);
+        eax = bblctl3.lo;
+
+        /* Set the l2 latency in BBL_CR_CTL3 */
+        if (calculate_l2_latency() != 0)
+                goto bad;
+
+        /* Read the new latency values back */
+        bblctl3 = rdmsr(BBL_CR_CTL3);
+        calc_eax = bblctl3.lo;
+
+        /* Write back the original default value */
+        bblctl3.lo = eax;
+        wrmsr(BBL_CR_CTL3, bblctl3);
+
+        /* Mask [27:26] out of BBL_CR_CTL3 - Reserved?? */
+        v = calc_eax & 0xc000000;
+
+        /* Shift to [1:0] */
+        v >>= 26;
+
+        printk(BIOS_DEBUG,"Sending %x to set_l2_register4\n", v);
+        if (set_l2_register4(v) != 0)
+                goto bad;
+
+/* Restore the correct latency value into BBL_CR_CTL3 */
+        bblctl3.lo = calc_eax;
+        wrmsr(BBL_CR_CTL3, bblctl3);
+
+        /* Read L2 register 0 */
+        tmp = read_l2(0);
+        if (tmp < 0) {
+                printk(BIOS_ERR, "Failed to read_l2(0)\n");
+                goto bad;
+        }
+
+        /* test if L2(0) has bit 0x20 set */
+         if ((tmp & 0x20) != 0) {
+                /* Read BBL_CR_CTL3 */
+                 bblctl3 = rdmsr(BBL_CR_CTL3);
+                /* Set bits [6-7] CRTN + Address Parity enable */
+                bblctl3.lo |= 0xc0;
+                /* Write BBL_CR_CTL3 */
+                 wrmsr(BBL_CR_CTL3, bblctl3);
+        }
+
+        if (calculate_l2_ecc() != 0) {
+                printk(BIOS_ERR, "Failed to calculate L2 ECC");
+                goto bad;
+        }
+
+        if (calculate_l2_physical_address_range() != 0) {
+                printk(BIOS_ERR, "Failed to calculate L2 physical address range");
+                goto bad;
+        }
+
+        if (calculate_l2_cache_size() != 0) {
+                printk(BIOS_ERR, "Failed to calculate L2 cache size");
+                goto bad;
+        } 
+
+/* Turn on cache. Only L1 is active at this time. */
+        enable_cache();
+
+        /* Get the calculated cache size from BBL_CR_CTL3 [17:13] */
+        bblctl3 = rdmsr(BBL_CR_CTL3);
+        cache_size = (bblctl3.lo & 0x3e000);
+        if (cache_size == 0)
+                cache_size = 0x1000;
+        cache_size = cache_size << 3;
+
+        /* Cache is 4 way for each address */
+        printk(BIOS_DEBUG, "L2 Cache size is %dK\n", cache_size * 4 / 1024);
+
+        /* Write to all cache lines to initialize */
+        while (cache_size > 0) {
+                int way;
+
+                /* Each Cache line in 32 bytes */
+                cache_size -= 0x20;
+
+                /* Update each way */
+                for (way = 0; way < 4; way++) {
+                        /* Send Tag Write w/Data Write (TWW) to L2 controller 
+                         * MESI = Invalid
+                         */
+                        if (signal_l2(0, cache_size, 0, 0, way, 0x1c) != 0) {
+                                printk(BIOS_ERR,
+                                       "Failed on signal_l2(%x, %x)\n",
+                                       cache_size, way);
+                                goto bad;
+                        }
+                }
+        }
+        printk(BIOS_DEBUG, "L2 Cache lines initialized\n");
+
+/* Disable cache */
+        disable_cache();
+
+        /* Set L2 cache configured in BBL_CR_CTL3 */
+        bblctl3 = rdmsr(BBL_CR_CTL3);
+        bblctl3.lo |= 0x1;
+        wrmsr(BBL_CR_CTL3, bblctl3);
+
+        /* Invalidate cache and discard unsaved writes */
+        asm volatile ("invd");
+
+        /* Write 0 to L2 control register 5 */
+        if (write_l2(5, 0) != 0) {
+                printk(BIOS_ERR,"write_l2(5, 0) failed\n");
+                goto done;
+        }
+
+        bblctl3 = rdmsr(BBL_CR_CTL3);
+        if (signature == 0x650 || signature == 0x670) {
+                /* Change the L2 latency to 0101 then back to 
+                 * original value. I don't know why this is needed - dpd
+                 */
+                int old_eax;
+                old_eax = bblctl3.lo;
+                bblctl3.lo &= 0xffffffe1;
+                bblctl3.lo |= 0x0000000a;
+                wrmsr(BBL_CR_CTL3, bblctl3);
+                bblctl3.lo = old_eax;
+                wrmsr(BBL_CR_CTL3, bblctl3);
+        }
+
+        /* Set L2 enabled in BBL_CR_CTL3 */
+        bblctl3.lo |= 0x00000100;
+        wrmsr(BBL_CR_CTL3, bblctl3);
+
+
+ /* Turn on cache. Both L1 and L2 are now active. Wahoo! */
+done:
+        result = 0;
+ out:
+
+
+        printk(BIOS_INFO, "done.\n");
+        return result;
+bad: 
+        result = -1;
+        goto out;
+}
+
+/*--- End L2 init code from coreboot v1 ---*/
+
+static void fill_processor_name(char *processor_name)
+{
+       struct cpuid_result regs;
+       char temp_processor_name[49];
+       char *processor_name_start;
+       unsigned int *name_as_ints = (unsigned int *)temp_processor_name;
+       int i;
+
+       for (i=0; i<3; i++) {
+               regs = cpuid(0x80000002 + i);
+               name_as_ints[i*4 + 0] = regs.eax;
+               name_as_ints[i*4 + 1] = regs.ebx;
+               name_as_ints[i*4 + 2] = regs.ecx;
+               name_as_ints[i*4 + 3] = regs.edx;
+       }
+
+       temp_processor_name[48] = 0;
+
+       /* Skip leading spaces */
+       processor_name_start = temp_processor_name;
+       while (*processor_name_start == ' ')
+               processor_name_start++;
+
+       memset(processor_name, 0, 49);
+       strcpy(processor_name, processor_name_start);
+}
+
+
 static void model_67x_init(device_t cpu)
 {
+	char processor_name[49];
+        int l2res;
+
+
 	/* Update the microcode */
 	intel_update_microcode(microcode_updates);
 
+	/* Initialize L2 cache */
+	l2res = p6_configure_l2_cache();
+
 	/* Turn on caching if we haven't already */
 	x86_enable_cache();
 
+	/* Print processor name */
+        fill_processor_name(processor_name);
+        printk(BIOS_INFO, "CPU: %s.\n", processor_name);
+
+
 	/* Setup MTRRs */
 	x86_setup_mtrrs(36);
 	x86_mtrr_check();
Index: src/cpu/intel/slot_1/Kconfig
===================================================================
--- src/cpu/intel/slot_1/Kconfig	(revision 6247)
+++ src/cpu/intel/slot_1/Kconfig	(working copy)
@@ -26,3 +26,5 @@
 	default 0x01000
 	depends on CPU_INTEL_SLOT_1
 
+select CPU_INTEL_MODEL_67X
+select MMX

