Support for Intel Core Duo and Core 2 Duo (tm) CPUs.

Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3702 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Stefan Reinauer
2008-10-29 04:48:44 +00:00
committed by Stefan Reinauer
parent debb11fc1f
commit 00a889c8aa
17 changed files with 1323 additions and 5 deletions

View File

@@ -0,0 +1,13 @@
uses HAVE_MOVNTI
default HAVE_MOVNTI=1
dir /cpu/x86/tsc
dir /cpu/x86/mtrr
dir /cpu/x86/fpu
dir /cpu/x86/mmx
dir /cpu/x86/sse
dir /cpu/x86/lapic
dir /cpu/x86/cache
dir /cpu/intel/microcode
dir /cpu/intel/hyperthreading
driver model_6fx_init.o

View File

@@ -0,0 +1,159 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
* Copyright (C) 2007-2008 coresystems GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define CACHE_AS_RAM_SIZE DCACHE_RAM_SIZE
#define CACHE_AS_RAM_BASE DCACHE_RAM_BASE
#define post_code(x) intel_chip_post_macro(x)
#include <cpu/x86/mtrr.h>
#include <cpu/amd/mtrr.h>
/* Save the BIST result */
movl %eax, %ebp
cache_as_ram:
#if USE_FALLBACK_IMAGE == 1
post_code(0x20)
/* Send INIT IPI to all excluding ourself */
movl $0x000C4500, %eax
movl $0xFEE00300, %esi
movl %eax, (%esi)
/* Disable prefetchers */
movl $0x01a0, %eax
rdmsr
orl $((1 << 9) | (1 << 19)), %eax
orl $((1 << 5) | (1 << 7)), %edx
wrmsr
/* Zero out all Fixed Range and Variable Range MTRRs */
movl $mtrr_table, %esi
movl $( (mtrr_table_end - mtrr_table) / 2), %edi
xorl %eax, %eax
xorl %edx, %edx
clear_mtrrs:
movw (%esi), %bx
movzx %bx, %ecx
wrmsr
add $2, %esi
dec %edi
jnz clear_mtrrs
/* Configure the default memory type to uncacheable */
movl $MTRRdefType_MSR, %ecx
rdmsr
andl $(~0x00000cff), %eax
wrmsr
/* Set cache as ram base address */
movl $(MTRRphysBase_MSR(0)), %ecx
movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
xorl %edx, %edx
wrmsr
/* Set cache as ram mask */
movl $(MTRRphysMask_MSR(0)), %ecx
movl $(~((CACHE_AS_RAM_SIZE-1)) | (1 << 11)), %eax
movl $0x0000000f, %edx
wrmsr
/* Enable MTRR */
movl $MTRRdefType_MSR, %ecx
rdmsr
orl $(1 << 11), %eax
wrmsr
/* Enable L2 Cache */
movl $0x11e, %ecx
rdmsr
orl $(1 << 8), %eax
wrmsr
/* CR0.CD = 0, CR0.NW = 0 */
movl %cr0, %eax
andl $( ~( (1 << 30) | (1 << 29) ) ), %eax
invd
movl %eax, %cr0
/* Clear the cache memory reagion */
movl $CACHE_AS_RAM_BASE, %esi
movl %esi, %edi
movl $(CACHE_AS_RAM_SIZE / 4), %ecx
//movl $0x23322332, %eax
xorl %eax, %eax
rep stosl
#endif
/* Enable Cache As RAM mode by disabling cache */
movl %cr0, %eax
orl $(1 << 30), %eax
movl %eax, %cr0
#if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE)
/* Enable cache for our code in Flash because we do XIP here */
movl $MTRRphysBase_MSR(1), %ecx
xorl %edx, %edx
movl $(XIP_ROM_BASE | MTRR_TYPE_WRBACK), %eax
wrmsr
movl $MTRRphysMask_MSR(1), %ecx
movl $0x0000000f, %edx
movl $(~(XIP_ROM_SIZE - 1) | 0x800), %eax
wrmsr
#endif /* XIP_ROM_SIZE && XIP_ROM_BASE */
/* enable cache */
movl %cr0, %eax
andl $( ~( (1 << 30) | (1 << 29) ) ), %eax
movl %eax, %cr0
/* Set up stack pointer */
movl $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4), %eax
movl %eax, %esp
/* Restore the BIST result */
movl %ebp, %eax
movl %esp, %ebp
pushl %eax
post_code(0x23)
call stage1_main
post_code(0x2f)
error:
hlt
jmp error
mtrr_table:
/* Fixed MTRRs */
.word 0x250, 0x258, 0x259
.word 0x268, 0x269, 0x26A
.word 0x26B, 0x26C, 0x26D
.word 0x26E, 0x26F
/* Variable MTRRs */
.word 0x200, 0x201, 0x202, 0x203
.word 0x204, 0x205, 0x206, 0x207
.word 0x208, 0x209, 0x20A, 0x20B
.word 0x20C, 0x20D, 0x20E, 0x20F
mtrr_table_end:

View File

@@ -0,0 +1,111 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 coresystems GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "cpu/x86/car/copy_and_run.c"
void real_main(unsigned long bist);
void stage1_main(unsigned long bist)
{
unsigned int cpu_reset = 0;
#if USE_FALLBACK_IMAGE == 1
/* Is this a deliberate reset by the bios */
if (bios_reset_detected() && last_boot_normal()) {
goto normal_image;
} else {
/* This is the primary cpu how should I boot? */
check_cmos_failed();
if (do_normal_boot()) {
goto normal_image;
}
else {
goto fallback_image;
}
}
normal_image:
__asm__ volatile ("jmp __normal_image"
: /* outputs */
: "a" (bist) /* inputs */
);
fallback_image:
#endif
real_main(bist);
/* No servicable parts below this line .. */
{
/* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
unsigned v_esp;
__asm__ volatile (
"movl %%esp, %0\n\t"
: "=a" (v_esp)
);
printk_spew("v_esp=%08x\r\n", v_esp);
}
cpu_reset_x:
printk_spew("cpu_reset = %08x\r\n",cpu_reset);
if(cpu_reset == 0) {
print_spew("Clearing initial memory region: ");
}
print_spew("No cache as ram now - ");
/* store cpu_reset to ebx */
__asm__ volatile (
"movl %0, %%ebx\n\t"
::"a" (cpu_reset)
);
if(cpu_reset==0) {
#define CLEAR_FIRST_1M_RAM 1
#include "cache_as_ram_post.c"
} else {
#undef CLEAR_FIRST_1M_RAM
#include "cache_as_ram_post.c"
}
__asm__ volatile (
/* set new esp */ /* before _RAMBASE */
"subl %0, %%ebp\n\t"
"subl %0, %%esp\n\t"
::"a"( (DCACHE_RAM_BASE + DCACHE_RAM_SIZE)- _RAMBASE )
);
{
unsigned new_cpu_reset;
/* get back cpu_reset from ebx */
__asm__ volatile (
"movl %%ebx, %0\n\t"
:"=a" (new_cpu_reset)
);
/* Copy and execute coreboot_ram */
copy_and_run(new_cpu_reset);
/* We will not return */
}
print_debug("sorry. parachute did not open.\r\n");
}

View File

@@ -0,0 +1,132 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2008 coresystems GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
__asm__ volatile (
"movb $0x30, %al\noutb %al, $0x80\n"
/* Disable Cache */
"movl %cr0, %eax\n"
"orl $(1 << 30), %eax\n"
"movl %eax, %cr0\n"
"movb $0x31, %al\noutb %al, $0x80\n"
/* Disable MTRR */
"movl $MTRRdefType_MSR, %ecx\n"
"rdmsr\n"
"andl $(~(1 << 11)), %eax\n"
"wrmsr\n"
"movb $0x32, %al\noutb %al, $0x80\n"
"invd\n"
#if 0
"xorl %eax, %eax\n"
"xorl %edx, %edx\n"
"movl $MTRRphysBase_MSR(0), %ecx\n"
"wrmsr\n"
"movl $MTRRphysMask_MSR(0), %ecx\n"
"wrmsr\n"
"movl $MTRRphysBase_MSR(1), %ecx\n"
"wrmsr\n"
"movl $MTRRphysMask_MSR(1), %ecx\n"
"wrmsr\n"
#endif
"movb $0x33, %al\noutb %al, $0x80\n"
#ifdef CLEAR_FIRST_1M_RAM
"movb $0x34, %al\noutb %al, $0x80\n"
/* Enable Write Combining and Speculative Reads for the first 1MB */
"movl $MTRRphysBase_MSR(0), %ecx\n"
"movl $(0x00000000 | MTRR_TYPE_WRCOMB), %eax\n"
"xorl %edx, %edx\n"
"wrmsr\n"
"movl $MTRRphysMask_MSR(0), %ecx\n"
"movl $(~(1024*1024 -1) | (1 << 11)), %eax\n"
"movl $0x0000000f, %edx\n" // 36bit address space
"wrmsr\n"
"movb $0x35, %al\noutb %al, $0x80\n"
#endif
/* Enable Cache */
"movl %cr0, %eax\n"
"andl $~( (1 << 30) | (1 << 29) ), %eax\n"
"movl %eax, %cr0\n"
"movb $0x36, %al\noutb %al, $0x80\n"
#ifdef CLEAR_FIRST_1M_RAM
/* Clear first 1MB of RAM */
"movl $0x00000000, %edi\n"
"cld\n"
"xorl %eax, %eax\n"
"movl $((1024*1024) / 4), %ecx\n"
"rep stosl\n"
"movb $0x37, %al\noutb %al, $0x80\n"
#endif
/* Disable Cache */
"movl %cr0, %eax\n"
"orl $(1 << 30), %eax\n"
"movl %eax, %cr0\n"
"movb $0x38, %al\noutb %al, $0x80\n"
/* Enable Write Back and Speculative Reads for the first 1MB */
"movl $MTRRphysBase_MSR(0), %ecx\n"
"movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax\n"
"xorl %edx, %edx\n"
"wrmsr\n"
"movl $MTRRphysMask_MSR(0), %ecx\n"
"movl $(~(1024*1024 -1) | (1 << 11)), %eax\n"
"movl $0x0000000f, %edx // 36bit address space\n"
"wrmsr\n"
"movb $0x39, %al\noutb %al, $0x80\n"
/* And Enable Cache again after setting MTRRs */
"movl %cr0, %eax\n"
"andl $~( (1 << 30) | (1 << 29) ), %eax\n"
"movl %eax, %cr0\n"
"movb $0x3a, %al\noutb %al, $0x80\n"
/* Enable MTRR */
"movl $MTRRdefType_MSR, %ecx\n"
"rdmsr\n"
"orl $(1 << 11), %eax\n"
"wrmsr\n"
"movb $0x3b, %al\noutb %al, $0x80\n"
/* Enable prefetchers */
"movl $0x01a0, %eax\n"
"rdmsr\n"
"andl $~((1 << 9) | (1 << 19)), %eax\n"
"andl $~((1 << 5) | (1 << 7)), %edx\n"
"wrmsr\n"
/* Invalidate the cache again */
"invd\n"
"movb $0x3c, %al\noutb %al, $0x80\n"
);

View File

@@ -0,0 +1,94 @@
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <string.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/hyperthreading.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/mtrr.h>
static const uint32_t microcode_updates[] = {
// #include "microcode_m206e839.h"
/* Dummy terminator */
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
};
static inline void strcpy(char *dst, char *src)
{
while (*src) *dst++ = *src++;
}
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_6ex_init(device_t cpu)
{
char processor_name[49];
/* Turn on caching if we haven't already */
x86_enable_cache();
/* Update the microcode */
intel_update_microcode(microcode_updates);
/* Print processor name */
fill_processor_name(processor_name);
printk_info("CPU: %s.\n", processor_name);
/* Setup MTRRs */
x86_setup_mtrrs(36);
x86_mtrr_check();
/* Enable the local cpu apics */
setup_lapic();
/* Start up my cpu siblings */
intel_sibling_init(cpu);
}
static struct device_operations cpu_dev_ops = {
.init = model_6ex_init,
};
static struct cpu_device_id cpu_table[] = {
{ X86_VENDOR_INTEL, 0x06f0 }, /* Intel Core 2 Solo/Core Duo */
{ X86_VENDOR_INTEL, 0x06f6 }, /* Intel Core 2 Solo/Core Duo */
{ 0, 0 },
};
static const struct cpu_driver driver __cpu_driver = {
.ops = &cpu_dev_ops,
.id_table = cpu_table,
};