- O2, enums, and switch statements work in romcc
- Support for compiling romcc on non x86 platforms - new romc options -msse and -mmmx for specifying extra registers to use - Bug fixes to device the device disable/enable framework and an amd8111 implementation - Move the link specification to the chip specification instead of the path - Allow specifying devices with internal bridges. - Initial via epia support - Opteron errata fixes git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1200 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
@ -4,15 +4,67 @@
|
||||
#include <cpu/p6/msr.h>
|
||||
#include <cpu/k8/mtrr.h>
|
||||
#include <device/device.h>
|
||||
#include "../../northbridge/amd/amdk8/cpu_rev.c"
|
||||
#include <device/chip.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
#define MCI_STATUS 0x401
|
||||
|
||||
static inline void disable_cache(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
/* Disable cache */
|
||||
/* Write back the cache and flush TLB */
|
||||
asm volatile (
|
||||
"movl %%cr0, %0\n\t"
|
||||
"orl $0x40000000, %0\n\t"
|
||||
"wbinvd\n\t"
|
||||
"movl %0, %%cr0\n\t"
|
||||
"wbinvd\n\t"
|
||||
:"=r" (tmp)
|
||||
::"memory");
|
||||
}
|
||||
|
||||
static inline void enable_cache(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
// turn cache back on.
|
||||
asm volatile (
|
||||
"movl %%cr0, %0\n\t"
|
||||
"andl $0x9fffffff, %0\n\t"
|
||||
"movl %0, %%cr0\n\t"
|
||||
:"=r" (tmp)
|
||||
::"memory");
|
||||
}
|
||||
|
||||
static inline msr_t rdmsr_amd(unsigned index)
|
||||
{
|
||||
msr_t result;
|
||||
__asm__ __volatile__ (
|
||||
"rdmsr"
|
||||
: "=a" (result.lo), "=d" (result.hi)
|
||||
: "c" (index), "D" (0x9c5a203a)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void wrmsr_amd(unsigned index, msr_t msr)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"wrmsr"
|
||||
: /* No outputs */
|
||||
: "c" (index), "a" (msr.lo), "d" (msr.hi), "D" (0x9c5a203a)
|
||||
);
|
||||
}
|
||||
|
||||
void k8_cpufixup(struct mem_range *mem)
|
||||
{
|
||||
unsigned long mmio_basek, tomk;
|
||||
unsigned long i;
|
||||
msr_t msr;
|
||||
|
||||
disable_cache();
|
||||
|
||||
/* Except for the PCI MMIO hold just before 4GB there are no
|
||||
* significant holes in the address space, so just account
|
||||
* for those two and move on.
|
||||
@ -32,28 +84,15 @@ void k8_cpufixup(struct mem_range *mem)
|
||||
mmio_basek = tomk;
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* Report the amount of memory. */
|
||||
print_debug("cpufixup RAM: 0x");
|
||||
print_debug_hex32(tomk);
|
||||
print_debug(" KB\r\n");
|
||||
#endif
|
||||
|
||||
/* Now set top of memory */
|
||||
msr.lo = (tomk & 0x003fffff) << 10;
|
||||
msr.hi = (tomk & 0xffc00000) >> 22;
|
||||
wrmsr(TOP_MEM2, msr);
|
||||
|
||||
/* Leave a 64M hole between TOP_MEM and TOP_MEM2
|
||||
* so I can see my rom chip and other I/O devices.
|
||||
*/
|
||||
if (tomk >= 0x003f0000) {
|
||||
tomk = 0x3f0000;
|
||||
} // tom_k = 0x3c0000;
|
||||
msr.lo = (tomk & 0x003fffff) << 10;
|
||||
msr.hi = (tomk & 0xffc00000) >> 22;
|
||||
wrmsr(TOP_MEM, msr);
|
||||
/* Setup TOP_MEM */
|
||||
msr.hi = mmio_basek >> 22;
|
||||
msr.lo = mmio_basek << 10;
|
||||
wrmsr(TOP_MEM, msr);
|
||||
|
||||
/* Setup TOP_MEM2 */
|
||||
msr.hi = tomk >> 22;
|
||||
msr.lo = tomk << 10;
|
||||
wrmsr(TOP_MEM2, msr);
|
||||
|
||||
/* zero the IORR's before we enable to prevent
|
||||
* undefined side effects.
|
||||
@ -66,6 +105,64 @@ void k8_cpufixup(struct mem_range *mem)
|
||||
msr = rdmsr(SYSCFG_MSR);
|
||||
msr.lo |= SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_TOM2En;
|
||||
wrmsr(SYSCFG_MSR, msr);
|
||||
|
||||
/* zero the machine check error status registers */
|
||||
msr.lo = 0;
|
||||
msr.hi = 0;
|
||||
for(i=0; i<5; i++) {
|
||||
wrmsr(MCI_STATUS + (i*4),msr);
|
||||
}
|
||||
|
||||
if (is_cpu_pre_c0()) {
|
||||
/* Erratum 63... */
|
||||
msr = rdmsr(HWCR_MSR);
|
||||
msr.lo |= (1 << 6);
|
||||
wrmsr(HWCR_MSR, msr);
|
||||
/* Erratum 69... */
|
||||
#if 1
|
||||
msr = rdmsr_amd(BU_CFG_MSR);
|
||||
msr.hi |= (1 << (45 - 32));
|
||||
wrmsr_amd(BU_CFG_MSR, msr);
|
||||
#endif
|
||||
/* Erratum 81... */
|
||||
#if 1
|
||||
msr = rdmsr_amd(DC_CFG_MSR);
|
||||
msr.lo |= (1 << 10);
|
||||
wrmsr_amd(DC_CFG_MSR, msr);
|
||||
#endif
|
||||
|
||||
}
|
||||
/* Erratum 89 ... */
|
||||
msr = rdmsr(NB_CFG_MSR);
|
||||
msr.lo |= 1 << 3;
|
||||
|
||||
if (!is_cpu_pre_c0()) {
|
||||
/* Erratum 86 Disable data masking on C0 and
|
||||
* later processor revs.
|
||||
* FIXME this is only needed if ECC is enabled.
|
||||
*/
|
||||
msr.hi |= 1 << (36 - 32);
|
||||
}
|
||||
wrmsr(NB_CFG_MSR, msr);
|
||||
#if 1 /* The following erratum fixes reset the cpu ???? */
|
||||
|
||||
/* Erratum 97 ... */
|
||||
if (!is_cpu_pre_c0()) {
|
||||
msr = rdmsr_amd(DC_CFG_MSR);
|
||||
msr.lo |= 1 << 3;
|
||||
wrmsr_amd(DC_CFG_MSR, msr);
|
||||
}
|
||||
|
||||
/* Erratum 94 ... */
|
||||
msr = rdmsr_amd(IC_CFG_MSR);
|
||||
msr.lo |= 1 << 11;
|
||||
wrmsr_amd(IC_CFG_MSR, msr);
|
||||
|
||||
#endif
|
||||
|
||||
/* Erratum 91 prefetch miss is handled in the kernel */
|
||||
|
||||
enable_cache();
|
||||
}
|
||||
|
||||
static
|
||||
@ -87,10 +184,6 @@ void k8_enable(struct chip *chip, enum chip_pass pass)
|
||||
}
|
||||
|
||||
struct chip_control cpu_k8_control = {
|
||||
enable: k8_enable,
|
||||
name: "AMD K8"
|
||||
.enable = k8_enable,
|
||||
.name = "AMD K8",
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
|
||||
base.lo = basek << 10;
|
||||
|
||||
if (sizek < 4*1024*1024) {
|
||||
mask.hi = 0x0F;
|
||||
mask.hi = 0x0FF;
|
||||
mask.lo = ~((sizek << 10) -1);
|
||||
}
|
||||
else {
|
||||
|
Reference in New Issue
Block a user