- remove deprecated directories

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1658 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Eric Biederman 2004-10-14 19:39:27 +00:00
parent fcd5ace00b
commit b84166e8e5
31 changed files with 0 additions and 2420 deletions

View File

@ -1,4 +0,0 @@
/* Carefully print the failure if the built in self test did not pass */
testl %eax, %eax
jnz bist32_fail

View File

@ -1,44 +0,0 @@
jmp bist32_fail_0
bist32_fail:
movl %eax, %ebp
#if 1
#define SIO_BASE 0x2e
#define SIO_INDEX SIO_BASE
#define SIO_DATA SIO_BASE+1
#define SIO_WRITE_CONFIG(value, reg) \
movb reg, %al ; \
outb %al, $(SIO_INDEX) ; \
movb value, %al ; \
outb %al, $(SIO_DATA)
#define SIO_READ_CONFIG(reg) \
movb reg, %al ; \
outb %al, $(SIO_INDEX) ; \
inb $(SIO_DATA), %al
#define SIO_SET_LOGICAL_DEVICE(device) \
SIO_WRITE_CONFIG(device, $0x07)
/* Enable serial 1 */
SIO_SET_LOGICAL_DEVICE($3)
SIO_WRITE_CONFIG($1, $0x30)
SIO_WRITE_CONFIG($0x3, $0x60)
SIO_WRITE_CONFIG($0xf8, $0x61)
#endif
CALLSP(serial_init)
CONSOLE_DEBUG_TX_STRING($str_bist_failed)
CONSOLE_DEBUG_TX_HEX32(%ebp)
CONSOLE_DEBUG_TX_STRING($str_bist_newline)
jmp .Lhlt
bist32_fail_0:
.section ".rom.data"
str_bist_failed: .string "BIST failed: "
str_bist_newline: .string "\r\n"
.previous

View File

@ -1,117 +0,0 @@
/*
This software and ancillary information (herein called SOFTWARE )
called LinuxBIOS is made available under the terms described
here. The SOFTWARE has been approved for release with associated
LA-CC Number 00-34 . Unless otherwise indicated, this SOFTWARE has
been authored by an employee or employees of the University of
California, operator of the Los Alamos National Laboratory under
Contract No. W-7405-ENG-36 with the U.S. Department of Energy. The
U.S. Government has rights to use, reproduce, and distribute this
SOFTWARE. The public may copy, distribute, prepare derivative works
and publicly display this SOFTWARE without charge, provided that this
Notice and any statement of authorship are reproduced on all copies.
Neither the Government nor the University makes any warranty, express
or implied, or assumes any liability or responsibility for the use of
this SOFTWARE. If SOFTWARE is modified to produce derivative works,
such modified SOFTWARE should be clearly marked, so as not to confuse
it with the version available from LANL.
*/
/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
* rminnich@lanl.gov
*/
/** Start code to put an i386 or later processor into 32-bit
* protected mode.
*/
/* .section ".rom.text" */
#include <arch/rom_segs.h>
.code16
.globl _start
.type _start, @function
_start:
cli
/* Save the BIST result */
movl %eax, %ebp
/* thanks to kmliu@sis.tw.com for this TBL fix ... */
/**/
/* IMMEDIATELY invalidate the translation lookaside buffer before executing*/
/* any further code. Even though paging is disabled we could still get*/
/*false address translations due to the TLB if we didn't invalidate it.*/
/**/
xorl %eax, %eax
movl %eax, %cr3 /* Invalidate TLB*/
/* invalidate the cache */
invd
/* Note: gas handles memory addresses in 16 bit code very poorly.
* In particular it doesn't appear to have a directive allowing you
* associate a section or even an absolute offset with a segment register.
*
* This means that anything except cs:ip relative offsets are
* a real pain in 16 bit mode. And explains why it is almost
* imposible to get gas to do lgdt correctly.
*
* One way to work around this is to have the linker do the
* math instead of the assembler. This solves the very
* pratical problem of being able to write code that can
* be relocated.
*
* An lgdt call before we have memory enabled cannot be
* position independent, as we cannot execute a call
* instruction to get our current instruction pointer.
* So while this code is relocateable it isn't arbitrarily
* relocatable.
*
* The criteria for relocation have been relaxed to their
* utmost, so that we can use the same code for both
* our initial entry point and startup of the second cpu.
* The code assumes when executing at _start that:
* (((cs & 0xfff) == 0) and (ip == _start & 0xffff))
* or
* ((cs == anything) and (ip == 0)).
*
* The restrictions in reset16.inc mean that _start initially
* must be loaded at or above 0xffff0000 or below 0x100000.
*
* The linker scripts computs gdtptr16_offset by simply returning
* the low 16 bits. This means that the intial segment used
* when start is called must be 64K aligned. This should not
* restrict the address as the ip address can be anything.
*/
movw %cs, %ax
shlw $4, %ax
movw $gdtptr16_offset, %bx
subw %ax, %bx
data32 lgdt %cs:(%bx)
movl %cr0, %eax
andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
orl $0x60000001, %eax /* CD, NW, PE = 1 */
movl %eax, %cr0
/* Restore BIST to %eax */
movl %ebp, %eax
/* Now that we are in protected mode jump to a 32 bit code segment. */
data32 ljmp $ROM_CODE_SEG, $__protected_start
/** The gdt has a 4 Gb code segment at 0x10, and a 4 GB data segment
* at 0x18; these are Linux-compatible.
*/
.align 4
.globl gdtptr16
gdtptr16:
.word gdt_end - gdt -1 /* compute the table limit */
.long gdt /* we know the offset */
.globl _estart
_estart:
.code32

View File

@ -1,2 +0,0 @@
gdtptr16_offset = gdtptr16 & 0xffff;
_start_offset = _start & 0xffff;

View File

@ -1,61 +0,0 @@
/* For starting linuxBIOS in protected mode */
#include <arch/rom_segs.h>
/* .section ".rom.text" */
.code32
.align 4
.globl gdtptr
gdt:
gdtptr:
.word gdt_end - gdt -1 /* compute the table limit */
.long gdt /* we know the offset */
.word 0
/* flat code segment */
.word 0xffff, 0x0000
.byte 0x00, 0x9b, 0xcf, 0x00
/* flat data segment */
.word 0xffff, 0x0000
.byte 0x00, 0x93, 0xcf, 0x00
gdt_end:
/*
* When we come here we are in protected mode. We expand
* the stack and copies the data segment from ROM to the
* memory.
*
* After that, we call the chipset bootstrap routine that
* does what is left of the chipset initialization.
*
* NOTE aligned to 4 so that we are sure that the prefetch
* cache will be reloaded.
*/
.align 4
.globl protected_start
protected_start:
lgdt %cs:gdtptr
ljmp $ROM_CODE_SEG, $__protected_start
__protected_start:
/* Save the BIST value */
movl %eax, %ebp
intel_chip_post_macro(0x10) /* post 10 */
movw $ROM_DATA_SEG, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw %ax, %fs
movw %ax, %gs
/* Restore the BIST value to %eax */
movl %ebp, %eax

View File

@ -1,14 +0,0 @@
/*
_cache_ram_seg_base = DEFINED(CACHE_RAM_BASE)? CACHE_RAM_BASE - _rodata : 0;
_cache_ram_seg_base_low = (_cache_ram_seg_base) & 0xffff;
_cache_ram_seg_base_middle = (_cache_ram_seg_base >> 16) & 0xff;
_cache_ram_seg_base_high = (_cache_ram_seg_base >> 24) & 0xff;
_rom_code_seg_base = _ltext - _text;
_rom_code_seg_base_low = (_rom_code_seg_base) & 0xffff;
_rom_code_seg_base_middle = (_rom_code_seg_base >> 16) & 0xff;
_rom_code_seg_base_high = (_rom_code_seg_base >> 24) & 0xff;
*/

View File

@ -1,21 +0,0 @@
.section ".reset"
.code16
.globl reset_vector
reset_vector:
#if _ROMBASE >= 0xffff0000
/* jmp _start */
.byte 0xe9
.int _start - ( . + 2 )
/* Note: The above jump is hand coded to work around bugs in binutils.
* 5 byte are used for a 3 byte instruction. This works because x86
* is little endian and allows us to use supported 32bit relocations
* instead of the weird 16 bit relocations that binutils does not
* handle consistenly between versions because they are used so rarely.
*/
#else
# error _ROMBASE is an unsupported value
#endif
. = 0x8;
.code32
jmp protected_start
.previous

View File

@ -1,14 +0,0 @@
/*
* _ROMTOP : The top of the rom used where we
* need to put the reset vector.
*/
SECTIONS {
_ROMTOP = (_ROMBASE >= 0xffff0000)? 0xfffffff0 : 0xffff0;
. = _ROMTOP;
.reset . : {
*(.reset)
. = 15 ;
BYTE(0x00);
}
}

View File

@ -1,10 +0,0 @@
.section ".reset"
.code16
.globl reset_vector
reset_vector:
. = 0x8;
.code32
jmp protected_start
.previous

View File

@ -1,14 +0,0 @@
/*
* _ROMTOP : The top of the rom used where we
* need to put the reset vector.
*/
SECTIONS {
_ROMTOP = _ROMBASE + ROM_IMAGE_SIZE - 0x10;
. = _ROMTOP;
.reset (.): {
*(.reset)
. = 15 ;
BYTE(0x00);
}
}

View File

@ -1,5 +0,0 @@
uses k7
uses CPU_FIXUP
default k7=1
dir /cpu/p6
#object cpufixup.o

View File

@ -1,12 +0,0 @@
# How does the config tool pick the correct
# cpufixup.c to generate cpufixup.o ?
uses k8
uses CPU_FIXUP
default k8=1
dir /cpu/k7
config chip.h
if CPU_FIXUP
object cpufixup.o
object apic_timer.o
end

View File

@ -1,26 +0,0 @@
#include <stdint.h>
#include <delay.h>
#include <cpu/p6/msr.h>
#include <cpu/p6/apic.h>
void init_timer(void)
{
/* Set the apic timer to no interrupts and periodic mode */
apic_write(APIC_LVTT, (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0));
/* Set the divider to 1, no divider */
apic_write(APIC_TDCR, APIC_TDR_DIV_1);
/* Set the initial counter to 0xffffffff */
apic_write(APIC_TMICT, 0xffffffff);
}
void udelay(unsigned usecs)
{
uint32_t start, value, ticks;
/* Calculate the number of ticks to run, our FSB runs a 200Mhz */
ticks = usecs * 200;
start = apic_read(APIC_TMCCT);
do {
value = apic_read(APIC_TMCCT);
} while((start - value) < ticks);
}

View File

@ -1,10 +0,0 @@
extern struct chip_control cpu_k8_control;
struct ht_link {
struct chip *chip;
unsigned int ht_width, ht_speed;
};
struct cpu_k8_config {
struct ht_link ldt0, ldt1, ldt2;
};

View File

@ -1,475 +0,0 @@
/* Needed so the AMD K8 runs correctly. */
#include <console/console.h>
#include <mem.h>
#include <cpu/p6/msr.h>
#include <cpu/k8/mtrr.h>
#include <device/device.h>
#include <device/chip.h>
#include <device/device.h>
#include <device/pci.h>
#include <smp/start_stop.h>
#include <string.h>
#include <cpu/p6/msr.h>
#include <cpu/p6/pgtbl.h>
#include <pc80/mc146818rtc.h>
#include <arch/smp/lapic.h>
#include "../../northbridge/amd/amdk8/amdk8.h"
#include "../../northbridge/amd/amdk8/cpu_rev.c"
#include "chip.h"
#define MCI_STATUS 0x401
static inline void disable_cache(void)
{
unsigned int tmp;
/* Disable cache */
/* Write back the cache */
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)
);
}
#define MTRR_COUNT 8
#define ZERO_CHUNK_KB 0x800UL /* 2M */
#define TOLM_KB 0x400000UL
struct mtrr {
msr_t base;
msr_t mask;
};
struct mtrr_state {
struct mtrr mtrrs[MTRR_COUNT];
msr_t top_mem, top_mem2;
msr_t def_type;
};
static void save_mtrr_state(struct mtrr_state *state)
{
int i;
for(i = 0; i < MTRR_COUNT; i++) {
state->mtrrs[i].base = rdmsr(MTRRphysBase_MSR(i));
state->mtrrs[i].mask = rdmsr(MTRRphysMask_MSR(i));
}
state->top_mem = rdmsr(TOP_MEM);
state->top_mem2 = rdmsr(TOP_MEM2);
state->def_type = rdmsr(MTRRdefType_MSR);
}
static void restore_mtrr_state(struct mtrr_state *state)
{
int i;
disable_cache();
for(i = 0; i < MTRR_COUNT; i++) {
wrmsr(MTRRphysBase_MSR(i), state->mtrrs[i].base);
wrmsr(MTRRphysMask_MSR(i), state->mtrrs[i].mask);
}
wrmsr(TOP_MEM, state->top_mem);
wrmsr(TOP_MEM2, state->top_mem2);
wrmsr(MTRRdefType_MSR, state->def_type);
enable_cache();
}
#if 0
static void print_mtrr_state(struct mtrr_state *state)
{
int i;
for(i = 0; i < MTRR_COUNT; i++) {
printk_debug("var mtrr %d: %08x%08x mask: %08x%08x\n",
i,
state->mtrrs[i].base.hi, state->mtrrs[i].base.lo,
state->mtrrs[i].mask.hi, state->mtrrs[i].mask.lo);
}
printk_debug("top_mem: %08x%08x\n",
state->top_mem.hi, state->top_mem.lo);
printk_debug("top_mem2: %08x%08x\n",
state->top_mem2.hi, state->top_mem2.lo);
printk_debug("def_type: %08x%08x\n",
state->def_type.hi, state->def_type.lo);
}
#endif
static void set_init_ecc_mtrrs(void)
{
msr_t msr;
int i;
disable_cache();
/* First clear all of the msrs to be safe */
for (i = 0; i < MTRR_COUNT; i++) {
msr_t zero;
zero.lo = zero.hi = 0;
wrmsr(MTRRphysBase_MSR(i), zero);
wrmsr(MTRRphysMask_MSR(i), zero);
}
/* Write back cache the first 1MB */
msr.hi = 0x00000000;
msr.lo = 0x00000000 | MTRR_TYPE_WRBACK;
wrmsr(MTRRphysBase_MSR(0), msr);
msr.hi = 0x000000ff;
msr.lo = ~((CONFIG_LB_MEM_TOPK << 10) - 1) | 0x800;
wrmsr(MTRRphysMask_MSR(0), msr);
/* Set the default type to write combining */
msr.hi = 0x00000000;
msr.lo = 0xc00 | MTRR_TYPE_WRCOMB;
wrmsr(MTRRdefType_MSR, msr);
/* Set TOP_MEM to 4G */
msr.hi = 0x00000001;
msr.lo = 0x00000000;
wrmsr(TOP_MEM, msr);
enable_cache();
}
static void init_ecc_memory(void)
{
unsigned long startk, begink, endk;
unsigned long basek;
struct mtrr_state mtrr_state;
device_t f1_dev, f2_dev, f3_dev;
int cpu_index, cpu_id, node_id;
int enable_scrubbing;
uint32_t dcl;
cpu_id = this_processors_id();
cpu_index = processor_index(cpu_id);
/* For now there is a 1-1 mapping between node_id and cpu_id */
node_id = cpu_id;
f1_dev = dev_find_slot(0, PCI_DEVFN(0x18 + node_id, 1));
if (!f1_dev) {
die("Cannot find cpu function 1\n");
}
f2_dev = dev_find_slot(0, PCI_DEVFN(0x18 + node_id, 2));
if (!f2_dev) {
die("Cannot find cpu function 2\n");
}
f3_dev = dev_find_slot(0, PCI_DEVFN(0x18 + node_id, 3));
if (!f3_dev) {
die("Cannot find cpu function 3\n");
}
/* See if we scrubbing should be enabled */
enable_scrubbing = 1;
get_option(&enable_scrubbing, "hw_scrubber");
/* Enable cache scrubbing at the lowest possible rate */
if (enable_scrubbing) {
pci_write_config32(f3_dev, SCRUB_CONTROL,
(SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_NONE << 0));
} else {
pci_write_config32(f3_dev, SCRUB_CONTROL,
(SCRUB_NONE << 16) | (SCRUB_NONE << 8) | (SCRUB_NONE << 0));
printk_debug("Scrubbing Disabled\n");
}
/* If ecc support is not enabled don't touch memory */
dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
if (!(dcl & DCL_DimmEccEn)) {
return;
}
startk = (pci_read_config32(f1_dev, 0x40 + (node_id*8)) & 0xffff0000) >> 2;
endk = ((pci_read_config32(f1_dev, 0x44 + (node_id*8)) & 0xffff0000) >> 2) + 0x4000;
/* Don't start too early */
begink = startk;
if (begink < CONFIG_LB_MEM_TOPK) {
begink = CONFIG_LB_MEM_TOPK;
}
printk_debug("Clearing memory %uK - %uK: ", startk, endk);
/* Save the normal state */
save_mtrr_state(&mtrr_state);
/* Switch to the init ecc state */
set_init_ecc_mtrrs();
disable_lapic();
/* Walk through 2M chunks and zero them */
for(basek = begink; basek < endk; basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) {
unsigned long limitk;
unsigned long size;
void *addr;
/* Report every 64M */
if ((basek % (64*1024)) == 0) {
/* Restore the normal state */
map_2M_page(cpu_index, 0);
restore_mtrr_state(&mtrr_state);
enable_lapic();
/* Print a status message */
printk_debug("%c", (basek >= TOLM_KB)?'+':'-');
/* Return to the initialization state */
set_init_ecc_mtrrs();
disable_lapic();
}
limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1);
if (limitk > endk) {
limitk = endk;
}
size = (limitk - basek) << 10;
addr = map_2M_page(cpu_index, basek >> 11);
addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
if (addr == MAPPING_ERROR) {
continue;
}
/* clear memory 2M (limitk - basek) */
__asm__ volatile(
"1: \n\t"
"movl %0, (%1)\n\t"
"addl $4,%1\n\t"
"subl $4,%2\n\t"
"jnz 1b\n\t"
:
: "a" (0), "D" (addr), "c" (size)
);
}
/* Restore the normal state */
map_2M_page(cpu_index, 0);
restore_mtrr_state(&mtrr_state);
enable_lapic();
/* Set the scrub base address registers */
pci_write_config32(f3_dev, SCRUB_ADDR_LOW, startk << 10);
pci_write_config32(f3_dev, SCRUB_ADDR_HIGH, startk >> 22);
/* Enable the scrubber? */
if (enable_scrubbing) {
/* Enable scrubbing at the lowest possible rate */
pci_write_config32(f3_dev, SCRUB_CONTROL,
(SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_84ms << 0));
}
printk_debug(" done\n");
}
static void k8_errata(void)
{
msr_t msr;
if (is_cpu_pre_c0()) {
/* Erratum 63... */
msr = rdmsr(HWCR_MSR);
msr.lo |= (1 << 6);
wrmsr(HWCR_MSR, msr);
/* Erratum 69... */
msr = rdmsr_amd(BU_CFG_MSR);
msr.hi |= (1 << (45 - 32));
wrmsr_amd(BU_CFG_MSR, msr);
/* Erratum 81... */
msr = rdmsr_amd(DC_CFG_MSR);
msr.lo |= (1 << 10);
wrmsr_amd(DC_CFG_MSR, msr);
}
/* I can't touch this msr on early buggy cpus */
if (!is_cpu_pre_b3()) {
/* 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);
}
/* 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);
/* Erratum 91 prefetch miss is handled in the kernel */
}
static void setup_toms(struct mem_range *mem)
{
unsigned long i;
msr_t msr;
unsigned long mmio_basek, tomk;
printk_spew("%s\n", __FUNCTION__);
/* 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.
*/
mmio_basek = tomk = 0;
for(i = 0; mem[i].sizek; i++) {
unsigned long topk;
topk = mem[i].basek + mem[i].sizek;
if (tomk < topk) {
tomk = topk;
}
if ((topk < 4*1024*1024) && (mmio_basek < topk)) {
mmio_basek = topk;
}
}
if (mmio_basek > tomk) {
mmio_basek = tomk;
}
/* Round mmio_basek down to the nearst size that will fit in TOP_MEM */
mmio_basek = mmio_basek & ~TOP_MEM_MASK_KB;
/* Round tomk up to the next greater size that will fit in TOP_MEM */
tomk = (tomk + TOP_MEM_MASK_KB) & ~TOP_MEM_MASK_KB;
/* 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);
}
static void setup_iorrs(void)
{
unsigned long i;
msr_t msr;
device_t f3_dev;
uint32_t base, size;
/* zero the IORR's before we enable to prevent
* undefined side effects. */
msr.lo = msr.hi = 0;
for (i = IORR_FIRST; i <= IORR_LAST; i++) {
wrmsr(i, msr);
}
/* enable IORR1 for AGP Aperture */
f3_dev = dev_find_slot(0, PCI_DEVFN(0x18, 3));
if (!f3_dev) {
die("Cannot find cpu function 3\n");
}
size = (pci_read_config32(f3_dev, 0x90) & 0x0E) >> 1;
size = (32*1024*1024) << size;
base = pci_read_config32(f3_dev, 0x94) << 25;
printk_debug("%s: setting IORR1 for AGP aperture base 0x%x, size 0x%x\n",
__FUNCTION__, base, size);
msr.lo = base;
msr.hi = 0xff;
wrmsr(IORR1_BASE, msr);
msr.lo = ~(size - 1);
msr.hi = 0xff;
wrmsr(IORR1_MASK, msr);
}
void k8_cpufixup(struct mem_range *mem)
{
unsigned long i;
msr_t msr;
disable_cache();
setup_toms(mem);
setup_iorrs();
/* Enable TOMs and IORRs */
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);
}
k8_errata();
enable_cache();
/* Is this a bad location? In particular can another node prefecth
* data from this node before we have initialized it?
*/
init_ecc_memory();
}
static
void k8_enable(struct chip *chip, enum chip_pass pass)
{
struct cpu_k8_config *conf = (struct cpu_k8_config *)chip->chip_info;
switch (pass) {
case CONF_PASS_PRE_CONSOLE:
break;
case CONF_PASS_PRE_PCI:
init_timer();
break;
default:
/* nothing yet */
break;
}
}
struct chip_control cpu_k8_control = {
.enable = k8_enable,
.name = "AMD K8 CPU",
};

View File

@ -1,27 +0,0 @@
/* Clear out an mmx state */
emms
/*
* Put the processor back into a reset state
* with respect to the xmm registers.
*/
pxor %xmm0, %xmm0
pxor %xmm1, %xmm1
pxor %xmm2, %xmm2
pxor %xmm3, %xmm3
pxor %xmm4, %xmm4
pxor %xmm5, %xmm5
pxor %xmm6, %xmm6
pxor %xmm7, %xmm7
/* Disable floating point emulation */
movl %cr0, %eax
andl $~(1<<2), %eax
movl %eax, %cr0
/* Disable sse instructions */
movl %cr4, %eax
andl $~(3<<9), %eax
movl %eax, %cr4

View File

@ -1,98 +0,0 @@
#include <cpu/k8/mtrr.h>
/* the fixed and variable MTTRs are power-up with random values,
* clear them to MTRR_TYPE_UNCACHEABLE for safty.
*/
static void early_mtrr_init(void)
{
static const unsigned long mtrr_msrs[] = {
/* fixed mtrr */
0x250, 0x258, 0x259,
0x268, 0x269, 0x26A
0x26B, 0x26C, 0x26D
0x26E, 0x26F,
/* var mtrr */
0x200, 0x201, 0x202, 0x203,
0x204, 0x205, 0x206, 0x207,
0x208, 0x209, 0x20A, 0x20B,
0x20C, 0x20D, 0x20E, 0x20F,
/* var iorr msr */
0xC0010016, 0xC0010017, 0xC0010018, 0xC0010019,
/* mem top */
0xC001001A, 0xC001001D,
/* NULL end of table */
0
};
msr_t msr;
const unsigned long *msr_addr;
/* Enable the access to AMD RdDram and WrDram extension bits */
msr = rdmsr(SYSCFG_MSR);
msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
wrmsr(SYSCFG_MSR, msr);
/* Inialize all of the relevant msrs to 0 */
msr.lo = 0;
msr.hi = 0;
for (msr_addr = mtrr_msrs; *msr_addr; msr_addr++) {
wrmsr(*msr_addr, msr);
}
/* Disable the access to AMD RdDram and WrDram extension bits */
msr = rdmsr(SYSCFG_MSR);
msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
wrmsr(SYSCFG_MSR, msr);
/* Enable memory access for 0 - 1MB using top_mem */
msr.hi = 0;
msr.lo = ((CONFIG_LB_MEM_TOPK << 10) + TOP_MEM_MASK) & ~TOP_MEM_MASK;
wrmsr(TOP_MEM, msr);
/* Enable caching for 0 - 1MB using variable mtrr */
msr = rdmsr(0x200);
msr.hi &= 0xfffffff0;
msr.hi |= 0x00000000;
msr.lo &= 0x00000f00;
msr.lo |= 0x00000000 | MTRR_TYPE_WRBACK;
wrmsr(0x200, msr);
msr = rdmsr(0x201);
msr.hi &= 0xfffffff0;
msr.hi |= 0x0000000f;
msr.lo &= 0x000007ff;
msr.lo |= (~((CONFIG_LB_MEM_TOPK << 10) - 1)) | 0x800;
wrmsr(0x201, msr);
#if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE)
/* enable write through caching so we can do execute in place
* on the flash rom.
*/
msr.hi = 0x00000000;
msr.lo = XIP_ROM_BASE | MTRR_TYPE_WRTHROUGH;
wrmsr(0x202, msr);
#error "FIXME verify the type of MTRR I have setup"
msr.hi = 0x0000000f;
msr.lo = ~(XIP_ROM_SIZE - 1) | 0x800;
wrmsr(0x203, msr);
#endif
/* Set the default memory type and enable fixed and variable MTRRs
*/
/* Enable Variable MTRRs */
msr.hi = 0x00000000;
msr.lo = 0x00000800;
wrmsr(MTRRdefType_MSR, msr);
/* Enale the MTRRs in SYSCFG */
msr = rdmsr(SYSCFG_MSR);
msr.lo |= SYSCFG_MSR_MtrrVarDramEn;
wrmsr(SYSCFG_MSR, msr);
/* Enable the cache */
unsigned long cr0;
cr0 = read_cr0();
cr0 &= 0x9fffffff;
write_cr0(cr0);
}

View File

@ -1,121 +0,0 @@
#include <cpu/k8/mtrr.h>
/* Save off the BIST value */
movl %eax, %ebp
/* The fixed and variable MTRRs are powered-up with random values, clear them to
* MTRR_TYPE_UNCACHEABLE for safty reason
*/
earlymtrr_start:
xorl %eax, %eax # clear %eax and %edx
xorl %edx, %edx #
movl $fixed_mtrr_msr, %esi
enable_fixed_mtrr_dram_modify:
/* Enable the access to AMD RdDram and WrDram extension bits */
movl $SYSCFG_MSR, %ecx
rdmsr
orl $SYSCFG_MSR_MtrrFixDramModEn, %eax
wrmsr
clear_fixed_var_mtrr:
lodsl (%esi), %eax
testl %eax, %eax
jz clear_fixed_var_mtrr_out
movl %eax, %ecx
xorl %eax, %eax
wrmsr
jmp clear_fixed_var_mtrr
clear_fixed_var_mtrr_out:
disable_fixed_mtrr_dram_modify:
/* Disable the access to AMD RdDram and WrDram extension bits */
movl $SYSCFG_MSR, %ecx
rdmsr
andl $(~SYSCFG_MSR_MtrrFixDramModEn), %eax
wrmsr
/* enable memory access for 0 - 1MB using top_mem */
movl $TOP_MEM, %ecx
xorl %edx, %edx
movl $(((CONFIG_LB_MEM_TOPK << 10) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
wrmsr
set_var_mtrr:
/* enable caching for 0 - 1MB using variable mtrr */
movl $0x200, %ecx
rdmsr
andl $0xfffffff0, %edx
orl $0x00000000, %edx
andl $0x00000f00, %eax
orl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
wrmsr
movl $0x201, %ecx
rdmsr
andl $0xfffffff0, %edx
orl $0x0000000f, %edx
andl $0x000007ff, %eax
orl $((~((CONFIG_LB_MEM_TOPK << 10) - 1)) | 0x800), %eax
wrmsr
#if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE)
/* enable write base caching so we can do execute in place
* on the flash rom.
*/
movl $0x202, %ecx
xorl %edx, %edx
movl $(XIP_ROM_BASE | MTRR_TYPE_WRBACK), %eax
wrmsr
movl $0x203, %ecx
movl $0x0000000f, %edx
movl $(~(XIP_ROM_SIZE - 1) | 0x800), %eax
wrmsr
#endif /* XIP_ROM_SIZE && XIP_ROM_BASE */
enable_mtrr:
/* Set the default memory type and enable fixed and variable MTRRs */
movl $MTRRdefType_MSR, %ecx
xorl %edx, %edx
/* Enable Variable MTRRs */
movl $0x00000800, %eax
wrmsr
/* Enable the MTRRs and IORRs in SYSCFG */
movl $SYSCFG_MSR, %ecx
rdmsr
/* Don't enable SYSCFG_MSR_MtrrFixDramEn untill we have done with VGA BIOS */
orl $(SYSCFG_MSR_MtrrVarDramEn), %eax
wrmsr
/* enable cache */
movl %cr0, %eax
andl $0x9fffffff,%eax
movl %eax, %cr0
jmp earlymtrr_end
fixed_mtrr_msr:
.long 0x250, 0x258, 0x259
.long 0x268, 0x269, 0x26A
.long 0x26B, 0x26C, 0x26D
.long 0x26E, 0x26F
var_mtrr_msr:
.long 0x200, 0x201, 0x202, 0x203
.long 0x204, 0x205, 0x206, 0x207
.long 0x208, 0x209, 0x20A, 0x20B
.long 0x20C, 0x20D, 0x20E, 0x20F
var_iorr_msr:
.long 0xC0010016, 0xC0010017, 0xC0010018, 0xC0010019
mem_top:
.long 0xC001001A, 0xC001001D
.long 0x000 /* NULL, end of table */
earlymtrr_end:
/* Restore the BIST value */
movl %ebp, %eax

View File

@ -1,20 +0,0 @@
/* Save the BIST result */
movl %eax, %ebp
/*
* Enabling mmx registers is a noop
* Enable the use of the xmm registers
*/
/* Disable floating point emulation */
movl %cr0, %eax
andl $~(1<<2), %eax
movl %eax, %cr0
/* Enable sse instructions */
movl %cr4, %eax
orl $(1<<9), %eax
movl %eax, %cr4
/* Restore the BIST result */
movl %ebp, %eax

View File

@ -1,5 +0,0 @@
uses CONFIG_UDELAY_TSC
object cpuid.o
if CONFIG_UDELAY_TSC object delay_tsc.o end

View File

@ -1,217 +0,0 @@
#include <console/console.h>
#include <cpu/p5/cpuid.h>
#if i586==1
#include <cpu/p6/msr.h>
#endif
int mtrr_check(void)
{
#if i686==1
/* Only Pentium Pro and later have MTRR */
msr_t msr;
printk_debug("\nMTRR check\n");
msr = rdmsr(0x2ff);
msr.lo >>= 10;
printk_debug("Fixed MTRRs : ");
if (msr.lo & 0x01)
printk_debug("Enabled\n");
else
printk_debug("Disabled\n");
printk_debug("Variable MTRRs: ");
if (msr.lo & 0x02)
printk_debug("Enabled\n");
else
printk_debug("Disabled\n");
printk_debug("\n");
post_code(0x93);
return ((int) msr.lo);
#else /* !i686 */
return 0;
#endif /* i686 */
}
void display_cpuid(void)
{
int op, eax, ebx, ecx, edx;
int max_op;
max_op = 0;
printk_debug("\n");
for (op = 0; op <= max_op; op++) {
cpuid(op, &eax, &ebx, &ecx, &edx);
if (0 == op) {
max_op = eax;
printk_debug("Max cpuid index : %d\n", eax);
printk_debug("Vendor ID : "
"%c%c%c%c%c%c%c%c%c%c%c%c\n",
ebx, ebx >> 8, ebx >> 16, ebx >> 24, edx,
edx >> 8, edx >> 16, edx >> 24, ecx, ecx >> 8,
ecx >> 16, ecx >> 24);
} else if (1 == op) {
printk_debug("Processor Type : 0x%02x\n",
(eax >> 12) & 0x03);
printk_debug("Processor Family : 0x%02x\n",
(eax >> 8) & 0x0f);
printk_debug("Processor Model : 0x%02x\n",
(eax >> 4) & 0x0f);
printk_debug("Processor Mask : 0x%02x\n",
(ecx >> 0) & 0x0f);
printk_debug("Processor Stepping : 0x%02x\n",
(eax >> 0) & 0x0f);
printk_debug("Feature flags : 0x%08x\n", edx);
} else if (2 == op) {
int desc[4];
int ii;
int _desc;
printk_debug("\n");
printk_debug("Cache/TLB descriptor values: %d "
"reads required\n", eax & 0xff);
desc[0] = eax;
desc[1] = ebx;
desc[2] = ecx;
desc[3] = edx;
for (ii = 1; ii < 16; ii++) {
if (desc[ii >> 2] & 0x80000000) {
printk_debug("reserved descriptor\n");
continue;
}
_desc =
((desc[ii >> 2]) >> ((ii & 0x3) << 3))
& 0xff;
printk_debug("Desc 0x%02x : ", _desc);
switch (_desc) {
case 0x00:
printk_debug("null\n");
break;
case 0x01:
printk_debug("Instr TLB: "
"4KB pages, "
"4-way set assoc, "
"32 entries\n");
break;
case 0x02:
printk_debug("Instr TLB: "
"4MB pages, "
"fully assoc, " "2 entries\n");
break;
case 0x03:
printk_debug("Data TLB: "
"4KB pages, "
"4-way set assoc, "
"64 entries\n");
break;
case 0x04:
printk_debug("Data TLB: "
"4MB pages, "
"4-way set assoc, "
"8 entries\n");
break;
case 0x06:
printk_debug("Inst cache: "
"8K bytes, "
"4-way set assoc, "
"32 byte line size\n");
break;
case 0x08:
printk_debug("Inst cache: "
"16K bytes, "
"4-way set assoc, "
"32 byte line size\n");
break;
case 0x0a:
printk_debug("Data cache: "
"8K bytes, "
"2-way set assoc, "
"32 byte line size\n");
break;
case 0x0c:
printk_debug("Data cache: "
"16K bytes, "
"2-way or 4-way set assoc, "
"32 byte line size\n");
break;
case 0x40:
printk_debug("No L2 cache\n");
break;
case 0x41:
printk_debug("L2 Unified cache: "
"128K bytes, "
"4-way set assoc, "
"32 byte line size\n");
break;
case 0x42:
printk_debug("L2 Unified cache: "
"256K bytes, "
"4-way set assoc, "
"32 byte line size\n");
break;
case 0x43:
printk_debug("L2 Unified cache: "
"512K bytes, "
"4-way set assoc, "
"32 byte line size\n");
break;
case 0x44:
printk_debug("L2 Unified cache: "
"1M byte, "
"4-way set assoc, "
"32 byte line size\n");
break;
case 0x45:
printk_debug("L2 Unified cache: "
"2M byte, "
"4-way set assoc, "
"32 byte line size\n");
break;
case 0x82:
printk_debug("L2 Unified cache: "
"256K bytes, "
"8-way set assoc, "
"32 byte line size\n");
break;
default:
printk_debug("UNKNOWN\n");
}
}
printk_debug("\n");
} else {
printk_debug("op: 0x%02x eax:0x%08x "
"ebx:0x%08x ecx:0x%08x edx:0x%08x\n",
op, eax, ebx, ecx, edx);
}
}
printk_debug("\n");
post_code(0x92);
}

View File

@ -1,10 +0,0 @@
uses INTEL_PPRO_MTRR
uses CPU_FIXUP
dir /cpu/p5
config chip.h
if CPU_FIXUP
object cpufixup.o
object apic_timer.o
end
object mtrr.o
object pgtbl.o

View File

@ -1,26 +0,0 @@
#include <stdint.h>
#include <delay.h>
#include <cpu/p6/msr.h>
#include <cpu/p6/apic.h>
void init_timer(void)
{
/* Set the apic timer to no interrupts and periodic mode */
apic_write(APIC_LVTT, (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0));
/* Set the divider to 1, no divider */
apic_write(APIC_TDCR, APIC_TDR_DIV_1);
/* Set the initial counter to 0xffffffff */
apic_write(APIC_TMICT, 0xffffffff);
}
void udelay(unsigned usecs)
{
uint32_t start, value, ticks;
/* Calculate the number of ticks to run, our FSB runs a 200Mhz */
ticks = usecs * 200;
start = apic_read(APIC_TMCCT);
do {
value = apic_read(APIC_TMCCT);
} while((start - value) < ticks);
}

View File

@ -1,10 +0,0 @@
#include <cpu/p6/msr.h>
int boot_cpu(void)
{
int bsp;
msr_t msr;
msr = rdmsr(0x1b);
bsp = !!(msr.lo & (1 << 8));
return bsp;
}

View File

@ -1,5 +0,0 @@
extern struct chip_control cpu_p6_control;
struct cpu_p6_config {
int nothing;
};

View File

@ -1,377 +0,0 @@
/* microcode.c: Microcode update for PIII and later CPUS
*
*/
#include <console/console.h>
#include <mem.h>
#include <cpu/p6/msr.h>
#include <cpu/p5/cpuid.h>
#include <cpu/k8/mtrr.h>
#include <device/device.h>
#include <device/chip.h>
struct microcode {
unsigned int hdrver;
unsigned int rev;
unsigned int date;
unsigned int sig;
unsigned int cksum;
unsigned int ldrver;
unsigned int pf;
unsigned int reserved[5];
unsigned int bits[500];
};
unsigned int microcode_updates [] = {
/*
Copyright Intel Corporation, 1995, 96, 97, 98, 99, 2000.
These microcode updates are distributed for the sole purpose of
installation in the BIOS or Operating System of computer systems
which include an Intel P6 family microprocessor sold or distributed
to or by you. You are authorized to copy and install this material
on such systems. You are not authorized to use this material for
any other purpose.
*/
/* MU16830c.inc */
0x00000001, 0x0000000c, 0x01102000, 0x00000683,
0xb1605bca, 0x00000001, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x7d021266, 0xd3890df1, 0x08a3a61b, 0x3c9bd396,
0x516b77d0, 0xf119ce39, 0xd63a44b0, 0x523efada,
0x1a0c3ed7, 0x04711f21, 0x515f945e, 0xbb5f13ba,
0x254eabfc, 0x5bd1e959, 0x67373898, 0x61605a8f,
0x6ea7c5a9, 0x5e64a058, 0xc0a019ee, 0x56af4cfe,
0x1acd6406, 0x4e7eb040, 0xf2ebd7ef, 0xc659db4f,
0xfe77108b, 0xfdceb47b, 0xf0757eb8, 0xb1622949,
0xdceb744b, 0x19e2ad26, 0xe9c745ab, 0xb385f196,
0x9ecc3483, 0x0a126045, 0x5320d6be, 0x8557a583,
0x7faf0073, 0x5ab281b4, 0x34dbbac6, 0x8a0bc7cd,
0x52584248, 0x3c3ef309, 0x41403737, 0x8200991d,
0x7e0dfb86, 0xea1e3a8f, 0x5b87ca8a, 0x004be481,
0x74e9fd6f, 0x80d518d6, 0xf10672c8, 0x2b8936b5,
0xd7092242, 0xbaa950a4, 0xaa6a2305, 0xeccbb48b,
0x43f6b561, 0x8607570a, 0x6143ba7b, 0x4c534447,
0x45d97f76, 0x0ccf7b83, 0xd89482bd, 0x32c46a60,
0x6db7b842, 0x0f7ad008, 0x4ce4968c, 0x2af52761,
0x26a2a653, 0x5806f996, 0xfe844901, 0x6164e754,
0xaf9287ab, 0x1f495a8d, 0x6cd70b5e, 0x681df673,
0xc94dc88f, 0x4b9650f8, 0xdfc826d9, 0xb5710e59,
0x80ed0f08, 0x615ce9c2, 0x0864130d, 0xc604520e,
0x9be149db, 0xeefb463f, 0x15b7e000, 0xc3bf13ab,
0x29d75556, 0x99420678, 0x505b5858, 0x6dadaeae,
0xf87f8f56, 0xe9be5867, 0xd772475a, 0x0a4642c0,
0xc59b2b86, 0x9e0f0a7f, 0x4c54834f, 0xb39f1d7c,
0xd52dac56, 0x1fdde74b, 0x60fddc1c, 0x367321f1,
0x98a7c9bd, 0x9a7896d2, 0x8d1f200b, 0x7975e907,
0x0e7d4411, 0x1671c027, 0x438550a2, 0x385dfc21,
0xb26c638d, 0x9b43b0d2, 0x03a0512d, 0x6b195c14,
0x9db53322, 0x78512b73, 0x86714a5b, 0x9b900bb3,
0xdbd702f9, 0xcdb985cb, 0x1033fd1e, 0xc75ed099,
0x8a8c99fc, 0x12c5b949, 0x913249a0, 0xbd40f4b1,
0x87406189, 0x977927e0, 0x76915a37, 0x79ffa5f2,
0x5e1812b8, 0x8e7eb819, 0x6bfc46a5, 0x8d80c798,
0x56d5a7ec, 0x5904350a, 0x82a1b59a, 0x27c64a52,
0x4effaac0, 0x8e1519ec, 0x29ffed29, 0x3eaccc55,
0x823e79c1, 0xdb5f2295, 0xb6ab9c23, 0xb301f2c5,
0xe17f14f3, 0xf4e8892a, 0x107c9db8, 0x6a8a8ff4,
0xaf9df422, 0xb14bd8f4, 0x00fa2a4c, 0x15324701,
0x95e86a3b, 0xf74566e1, 0x386a788f, 0x9333e875,
0xdea61190, 0x307a5338, 0xd9cec152, 0xe77165da,
0x54187a14, 0x9a7d99bf, 0x4b31e986, 0x7d7ed557,
0x626bb548, 0x434c4a78, 0x562b1588, 0xe0d15f63,
0x524473f7, 0x484459e1, 0xbe617125, 0xb96f7eb8,
0xb86620f7, 0xcc1e09b1, 0x7ad3b154, 0xae1f697e,
0x11d0bfb1, 0xb1218568, 0x83a44b34, 0xeecec8bc,
0xa06b01d8, 0xccadf143, 0xe1f9702c, 0x1e7c3d0d,
0xd907d836, 0x780b3a02, 0x9a5e81fa, 0x0015cf61,
0xbd148c0c, 0x84a65389, 0x99e77502, 0x0d630a94,
0xd7f97779, 0x75567907, 0xa859be05, 0x8baab7b7,
0x4f1a8101, 0x9992f951, 0xdd918c8a, 0x12b3ca17,
0x117358b4, 0xf27a4783, 0xe3363be6, 0x3847f05d,
0xb642595a, 0x4fbb98ae, 0xd6259c55, 0x3c72ff94,
0xa9c3e102, 0x256e26c1, 0x2faf190b, 0xaaa1d198,
0x8e25fc06, 0x8aa6fc5d, 0x9b994d46, 0x15045f23,
0x23813558, 0x0173ef1b, 0xe4198a76, 0x36aa0de4,
0x341d7595, 0xe186740f, 0xec371375, 0x1a4cabbe,
0x6241897f, 0x388bd888, 0x2542e1f7, 0x61620df5,
0x209f9d94, 0xca90f89b, 0x286a3e92, 0xea1cc30f,
0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631,
0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a,
0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f,
0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038,
0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c,
0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea,
0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7,
0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed,
0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce,
0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1,
0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643,
0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2,
0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95,
0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708,
0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550,
0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e,
0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300,
0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06,
0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226,
0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff,
0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f,
0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa,
0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900,
0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282,
0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5,
0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21,
0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f,
0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b,
0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a,
0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb,
0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1,
0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8,
0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18,
0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d,
0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429,
0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b,
0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879,
0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950,
0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95,
0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61,
0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff,
0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9,
0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44,
0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d,
0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8,
0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5,
0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276,
0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d,
0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777,
0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758,
0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f,
0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60,
0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb,
0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef,
0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d,
0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89,
0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81,
0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8,
0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0,
0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007,
0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c,
0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6,
0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75,
0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116,
0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e,
0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec,
/* MU16810d.inc */
0x00000001, 0x0000000d, 0x09211999, 0x00000681,
0x31708166, 0x00000001, 0x00000001, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x710e5240, 0xab8bc2df, 0x6e652d5a, 0xcc16718b,
0xaa5c7d1a, 0x43ac1ba0, 0xbdf8684e, 0x82565fa7,
0x1d108edc, 0x96d2d5a2, 0x85f783a0, 0x16e4cba1,
0xbc311213, 0xc36c45a2, 0x443b8d2b, 0xfdc5e9ce,
0xbb6f8637, 0x47011b8b, 0xf3898e4a, 0xb3e90f68,
0x60af6e3a, 0xff9d3de4, 0x9fb2333c, 0x5a1a39ce,
0xffd75d72, 0xa60cc2c0, 0x5729267c, 0xfc6d2da7,
0x8a2c8ae7, 0x71aba5ba, 0xb639ff31, 0x8d1642b8,
0x3aa67efc, 0x9f786473, 0xaedec560, 0x1acb694f,
0x97582a6f, 0x8dc17ea5, 0x19636cfe, 0xb5032243,
0xc46f764f, 0x3a5d3833, 0xf3d1a2b9, 0xc22e59be,
0x15e0b2f3, 0xe58eff24, 0xc679600d, 0x21a3a845,
0xc11cc921, 0xed2f5061, 0x2d4db0d1, 0xcc0cc78f,
0x80197c08, 0x20739d8a, 0xc92ec866, 0xacef343b,
0x47c0913a, 0xee8a69e4, 0xa7b0157e, 0x4c3607a9,
0xcc7ff7ea, 0xb0a36667, 0x41d1bcf0, 0xf54c42d2,
0x946c590e, 0x6da18fe9, 0xf20df0e6, 0x984a2160,
0x479becd3, 0xfb11dd36, 0xbb816653, 0x60c605c2,
0xf52efe8b, 0x90a9f863, 0x69654bfa, 0xf0f03f7c,
0xbf0498d5, 0x68708d82, 0xdab94924, 0x92371217,
0x603feed7, 0xf0ff8329, 0x9c8769df, 0x6d40ab73,
0xd8fd132a, 0x9335543f, 0x40fd3abb, 0xf25665a0,
0x93fe56a6, 0x682a3b24, 0xf3a0f14a, 0x97e92084,
0x4e8736a3, 0xf322db48, 0xb65de2ad, 0x6af68474,
0xfd6dae0d, 0x953afb0e, 0x6ef22a82, 0xfa7a3d7b,
0xb5fe683f, 0x647579c3, 0xd184e7db, 0x99ec7c97,
0x66486a26, 0xf08c8290, 0x94eb3fce, 0x6305e16e,
0xd61dd210, 0x9b8bdbba, 0x41a4b4f5, 0xfca38a75,
0x9c55c7a4, 0x6a4b1f02, 0xf277077a, 0x900e3d03,
0x4f173146, 0xf6fbf7c8, 0xb2636cb2, 0x6329a9d7,
0xf2697eb4, 0x90f80f6f, 0x65de6167, 0xfc6cd065,
0xb4326188, 0x67507c3a, 0xdf3179ff, 0x91207c0b,
0x6408ad58, 0xf7e7d2fe, 0x999af7c0, 0x6a994828,
0xdaecedf4, 0x93cba457, 0x4d924b31, 0xf12b5ae1,
0x9563d541, 0x65bd28f8, 0xfa87a363, 0x983adc3d,
0x45c4f64d, 0xfae3e1ef, 0xb2eb287f, 0x6050f699,
0xfb28cfb6, 0x999b1d45, 0x65027980, 0xf4e507d0,
0xbbd059b7, 0x64cb2688, 0xd29dff15, 0x90927c2c,
0x6d52471a, 0xf64fc745, 0x9e4050ff, 0x68b66e3f,
0xd0a1dd96, 0x9fe8a5a3, 0x454c936b, 0xf926115d,
0x9bfb60ff, 0x604049aa, 0xf3509e5c, 0x9d6cf26f,
0x4d777c5a, 0xfd7cd5ff, 0xb15d4f35, 0x6b1aa6e3,
0xfa279f20, 0x94916fae, 0x9b04dbcc, 0x600defd9,
0xf2977cd8, 0x65fa64be, 0x968feaee, 0xc11681af,
0x66568af6, 0xa539a4ee, 0xcfed5cb1, 0x108445de,
0xa603dfdd, 0xbf5ada02, 0x14b868c5, 0xb2d3b8d2,
0xbabf3637, 0x0c25bfbc, 0xb7a4c247, 0xf2837e05,
0x062ce963, 0xfcb65c46, 0xc6d190e7, 0x4dfce123,
0xcb0bf4c7, 0x8bff9d9d, 0x6794e002, 0x2879661e,
0xa5e93199, 0x77be4be8, 0x22fe3324, 0xb943e4ef,
0x73463d52, 0x31471050, 0xb68fd63f, 0x84cad24f,
0x343d922b, 0x42b9ab31, 0x88ee1549, 0xe913e2ab,
0x4a127048, 0x5057f79f, 0x636eb512, 0x42e02f9c,
0xd3a8b863, 0x9bc40609, 0x4a18edb5, 0x86a4bdaa,
0x91819a4b, 0x12a11e17, 0x8a6d7f21, 0xf42998d9,
0x132b6bbd, 0xe3239feb, 0xf52519d7, 0xada08128,
0xe6febacf, 0x44e15a80, 0xa977610a, 0xf56a8665,
0x4693b6f0, 0xb8386320, 0xfcf7d071, 0xb8a1128d,
0xb2a45d18, 0x075a2095, 0x98ebde53, 0xe8762eaf,
0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631,
0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a,
0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f,
0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038,
0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c,
0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea,
0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7,
0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed,
0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce,
0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1,
0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643,
0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2,
0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95,
0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708,
0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550,
0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e,
0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300,
0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06,
0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226,
0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff,
0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f,
0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa,
0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900,
0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282,
0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5,
0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21,
0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f,
0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b,
0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a,
0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb,
0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1,
0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8,
0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18,
0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d,
0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429,
0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b,
0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879,
0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950,
0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95,
0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61,
0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff,
0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9,
0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44,
0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d,
0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8,
0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5,
0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276,
0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d,
0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777,
0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758,
0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f,
0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60,
0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb,
0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef,
0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d,
0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89,
0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81,
0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8,
0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0,
0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007,
0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c,
0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6,
0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75,
0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116,
0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e,
0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec,
};
static void display_cpuid_update_microcode(void)
{
unsigned int eax, ebx, ecx, edx;
unsigned int pf, rev, sig, val[2];
unsigned int x86_model, x86_family, i;
struct microcode *m;
msr_t msr;
/* cpuid sets msr 0x8B iff a microcode update has been loaded. */
//wrmsr(0x8B, 0, 0);
msr.lo = msr.hi = 0;
wrmsr(0x8b, msr);
cpuid(1, &eax, &ebx, &ecx, &edx);
//rdmsr(0x8B, val[0], rev);
msr = rdmsr(0x8b);
val[0] = msr.lo;
rev = msr.hi;
x86_model = (eax >>4) & 0x0f;
x86_family = (eax >>8) & 0x0f;
sig = eax;
pf = 0;
if ((x86_model >= 5)||(x86_family>6)) {
//rdmsr(0x17, val[0], val[1]);
msr = rdmsr(0x17);
val[0] = msr.lo;
val[1] = msr.hi;
pf = 1 << ((val[1] >> 18) & 7);
}
printk_debug("microcode_info: sig = 0x%08x pf=0x%08x rev = 0x%08x\n",
sig, pf, rev);
m = (void *)&microcode_updates;
for(i = 0; i < sizeof(microcode_updates)/sizeof(struct microcode); i++) {
if ((m[i].sig == sig) && (m[i].pf == pf)) {
//wrmsr(0x79, (unsigned int)&m[i].bits, 0);
msr.lo = (unsigned int)&m[i].bits;
msr.hi = 0;
wrmsr(0x79, msr);
__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
//rdmsr(0x8B, val[0], val[1]);
msr = rdmsr(0x8b);
val[0] = msr.lo;
val[1] = msr.hi;
printk_info("microcode updated from revision %d to %d\n",
rev, val[1]);
}
}
}
void p6_cpufixup(struct mem_range *mem)
{
printk_debug("Updating microcode\n");
display_cpuid_update_microcode();
}
static
void p6_enable(struct chip *chip, enum chip_pass pass)
{
struct cpu_p6_config *conf = (struct cpu_p6_config *)chip->chip_info;
switch (pass) {
case CONF_PASS_PRE_CONSOLE:
break;
case CONF_PASS_PRE_PCI:
init_timer();
break;
default:
/* nothing yet */
break;
}
}
struct chip_control cpu_p6_control = {
.enable = p6_enable,
.name = "Intel P6 CPU",
};

View File

@ -1,27 +0,0 @@
/* Clear out an mmx state */
emms
/*
* Put the processor back into a reset state
* with respect to the xmm registers.
*/
pxor %xmm0, %xmm0
pxor %xmm1, %xmm1
pxor %xmm2, %xmm2
pxor %xmm3, %xmm3
pxor %xmm4, %xmm4
pxor %xmm5, %xmm5
pxor %xmm6, %xmm6
pxor %xmm7, %xmm7
/* Disable floating point emulation */
movl %cr0, %eax
andl $~(1<<2), %eax
movl %eax, %cr0
/* Disable sse instructions */
movl %cr4, %eax
andl $~(3<<9), %eax
movl %eax, %cr4

View File

@ -1,108 +0,0 @@
#include <cpu/p6/mtrr.h>
#include <cpu/p6/msr.h>
static inline unsigned long read_cr0(void)
{
unsigned long cr0;
asm volatile ("movl %%cr0, %0" : "=r" (cr0));
return cr0;
}
static inline void write_cr0(unsigned long cr0)
{
asm volatile ("movl %0, %%cr0" : : "r" (cr0));
}
/* the fixed and variable MTTRs are power-up with random values,
* clear them to MTRR_TYPE_UNCACHEABLE for safty.
*/
static void early_mtrr_init(void)
{
static const unsigned long mtrr_msrs[] = {
/* fixed mtrr */
0x250, 0x258, 0x259,
0x268, 0x269, 0x26A,
0x26B, 0x26C, 0x26D,
0x26E, 0x26F,
/* var mtrr */
0x200, 0x201, 0x202, 0x203,
0x204, 0x205, 0x206, 0x207,
0x208, 0x209, 0x20A, 0x20B,
0x20C, 0x20D, 0x20E, 0x20F,
/* NULL end of table */
0
};
msr_t msr;
const unsigned long *msr_addr;
unsigned long cr0;
print_debug("Disabling cache\r\n");
/* Just to be sure, take all the steps to disable the cache.
* This may not be needed, but C3's may...
* Invalidate the cache */
asm volatile ("invd");
/* Disable the cache */
cr0 = read_cr0();
cr0 |= 0x40000000;
write_cr0(cr0);
/* Disable Variable MTRRs */
msr.hi = 0x00000000;
msr.lo = 0x00000000;
wrmsr(MTRRdefType_MSR, msr);
/* Invalidate the cache again */
asm volatile ("invd");
print_debug("Clearing mtrr\r\n");
/* Inialize all of the relevant msrs to 0 */
msr.lo = 0;
msr.hi = 0;
for(msr_addr = mtrr_msrs; *msr_addr; msr_addr++) {
wrmsr(*msr_addr, msr);
}
/* Enable caching for 0 - 1MB using variable mtrr */
msr = rdmsr(0x200);
msr.hi &= 0xfffffff0;
msr.hi |= 0x00000000;
msr.lo &= 0x00000f00;
msr.lo |= 0x00000000 | MTRR_TYPE_WRBACK;
wrmsr(0x200, msr);
msr = rdmsr(0x201);
msr.hi &= 0xfffffff0;
msr.hi |= 0x0000000f;
msr.lo &= 0x000007ff;
msr.lo |= (~((CONFIG_LB_MEM_TOPK << 10) - 1)) | 0x800;
wrmsr(0x201, msr);
#if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE)
print_debug("Setting XIP\r\n");
/* enable write through caching so we can do execute in place
* on the flash rom.
*/
msr.hi = 0x00000000;
msr.lo = XIP_ROM_BASE | MTRR_TYPE_WRTHROUGH;
wrmsr(0x202, msr);
msr.hi = 0x0000000f;
msr.lo = ~(XIP_ROM_SIZE - 1) | 0x800;
wrmsr(0x203, msr);
#endif
/* Set the default memory type and enable fixed and variable MTRRs
*/
/* Enable Variable MTRRs */
msr.hi = 0x00000000;
msr.lo = 0x00000800;
wrmsr(MTRRdefType_MSR, msr);
/* Enable the cache */
cr0 = read_cr0();
cr0 &= 0x9fffffff;
write_cr0(cr0);
print_debug("Enabled the cache\r\n");
}

View File

@ -1,25 +0,0 @@
/* Save the BIST result */
movl %eax, %ebp
/*
* Enabling mmx registers is a noop
* Enable the use of the xmm registers
*/
/* Enable sse instructions */
movl %cr4, %eax
orl $(1<<9), %eax
movl %eax, %cr4
/* Disable floating point emulation */
movl %cr0, %eax
andl $~(1<<2), %eax
movl %eax, %cr0
/* enable sse extension */
movl %cr0, %eax
andl $~(1<<1), %eax
movl %eax, %cr0
/* Restore the BIST result */
movl %ebp, %eax

View File

@ -1,424 +0,0 @@
/*
* intel_mtrr.c: setting MTRR to decent values for cache initialization on P6
*
* Derived from intel_set_mtrr in intel_subr.c and mtrr.c in linux kernel
*
* Copyright 2000 Silicon Integrated System Corporation
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* Reference: Intel Architecture Software Developer's Manual, Volume 3: System Programming
*/
#include <console/console.h>
#include <mem.h>
#include <cpu/p6/msr.h>
#include <cpu/p6/mtrr.h>
#include <cpu/k7/mtrr.h>
#define arraysize(x) (sizeof(x)/sizeof((x)[0]))
#ifdef k8
# define ADDRESS_BITS 40
#else
# define ADDRESS_BITS 36
#endif
#define ADDRESS_BITS_HIGH (ADDRESS_BITS - 32)
#define ADDRESS_MASK_HIGH ((1u << ADDRESS_BITS_HIGH) - 1)
static unsigned int mtrr_msr[] = {
MTRRfix64K_00000_MSR, MTRRfix16K_80000_MSR, MTRRfix16K_A0000_MSR,
MTRRfix4K_C0000_MSR, MTRRfix4K_C8000_MSR, MTRRfix4K_D0000_MSR, MTRRfix4K_D8000_MSR,
MTRRfix4K_E0000_MSR, MTRRfix4K_E8000_MSR, MTRRfix4K_F0000_MSR, MTRRfix4K_F8000_MSR,
};
static int mtrr_count = 0;
static void intel_enable_fixed_mtrr(void)
{
msr_t msr;
msr = rdmsr(MTRRdefType_MSR);
msr.lo |= 0xc00;
wrmsr(MTRRdefType_MSR, msr);
}
static void intel_enable_var_mtrr(void)
{
msr_t msr;
msr = rdmsr(MTRRdefType_MSR);
msr.lo |= 0x800;
wrmsr(MTRRdefType_MSR, msr);
}
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 wbinvd(void)
{
asm volatile (
"wbinvd\n\t");
}
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");
}
/* setting variable mtrr, comes from linux kernel source */
/* funtion nows saves and restores state of deftype regs so that extra mtrr's can be set-up
* after the initial main memory mtrr's
*/
static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
{
msr_t base, mask, def,defsave;
base.hi = basek >> 22;
base.lo = basek << 10;
//printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH);
printk_debug("Adding mtrr #%d at %08x size %x\n",reg,base.lo,sizek<<10);
if (sizek < 4*1024*1024) {
mask.hi = ADDRESS_MASK_HIGH;
mask.lo = ~((sizek << 10) -1);
}
else {
mask.hi = ADDRESS_MASK_HIGH & (~((sizek >> 22) -1));
mask.lo = 0;
}
if (reg >= 8)
return;
// it is recommended that we disable and enable cache when we
// do this.
disable_cache();
def = defsave = rdmsr(MTRRdefType_MSR);
def.lo &= 0xf300;
wrmsr(MTRRdefType_MSR,def);
if (sizek == 0) {
msr_t zero;
zero.lo = zero.hi = 0;
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
wrmsr (MTRRphysMask_MSR(reg), zero);
} else {
/* Bit 32-35 of MTRRphysMask should be set to 1 */
base.lo |= type;
mask.lo |= 0x800;
wrmsr (MTRRphysBase_MSR(reg), base);
wrmsr (MTRRphysMask_MSR(reg), mask);
}
wbinvd();
wrmsr(MTRRdefType_MSR,defsave);
enable_cache();
}
/* setting variable mtrr, comes from linux kernel source */
void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type)
{
if (reg >= 8)
return;
// it is recommended that we disable and enable cache when we
// do this.
disable_cache();
if (size == 0) {
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
msr_t zero;
zero.lo = zero.hi = 0;
wrmsr (MTRRphysMask_MSR(reg), zero);
} else {
/* Bit 32-35 of MTRRphysMask should be set to 1 */
msr_t basem, maskm;
basem.lo = base | type;
basem.hi = 0;
maskm.lo = ~(size - 1) | 0x800;
maskm.hi = 0x0F;
wrmsr (MTRRphysBase_MSR(reg), basem);
wrmsr (MTRRphysMask_MSR(reg), maskm);
}
// turn cache back on.
enable_cache();
}
/* fms: find most sigificant bit set, stolen from Linux Kernel Source. */
static inline unsigned int fms(unsigned int x)
{
int r;
__asm__("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $0,%0\n"
"1:" : "=r" (r) : "g" (x));
return r;
}
/* fms: find least sigificant bit set */
static inline unsigned int fls(unsigned int x)
{
int r;
__asm__("bsfl %1,%0\n\t"
"jnz 1f\n\t"
"movl $32,%0\n"
"1:" : "=r" (r) : "g" (x));
return r;
}
/* setting up variable and fixed mtrr
*
* From Intel Vol. III Section 9.12.4, the Range Size and Base Alignment has some kind of requirement:
* 1. The range size must be 2^N byte for N >= 12 (i.e 4KB minimum).
* 2. The base address must be 2^N aligned, where the N here is equal to the N in previous
* requirement. So a 8K range must be 8K aligned not 4K aligned.
*
* These requirement is meet by "decompositing" the ramsize into Sum(Cn * 2^n, n = [0..N], Cn = [0, 1]).
* For Cm = 1, there is a WB range of 2^m size at base address Sum(Cm * 2^m, m = [N..n]).
* A 124MB (128MB - 4MB SMA) example:
* ramsize = 124MB == 64MB (at 0MB) + 32MB (at 64MB) + 16MB (at 96MB ) + 8MB (at 112MB) + 4MB (120MB).
* But this wastes a lot of MTRR registers so we use another more "aggresive" way with Uncacheable Regions.
*
* In the Uncacheable Region scheme, we try to cover the whole ramsize by one WB region as possible,
* If (an only if) this can not be done we will try to decomposite the ramesize, the mathematical formula
* whould be ramsize = Sum(Cn * 2^n, n = [0..N], Cn = [-1, 0, 1]). For Cn = -1, a Uncachable Region is used.
* The same 124MB example:
* ramsize = 124MB == 128MB WB (at 0MB) + 4MB UC (at 124MB)
* or a 156MB (128MB + 32MB - 4MB SMA) example:
* ramsize = 156MB == 128MB WB (at 0MB) + 32MB WB (at 128MB) + 4MB UC (at 156MB)
*/
/* 2 MTRRS are reserved for the operating system */
#define BIOS_MTRRS 6
#define OS_MTRRS 2
#define MTRRS (BIOS_MTRRS + OS_MTRRS)
static void set_fixed_mtrrs(unsigned int first, unsigned int last, unsigned char type)
{
unsigned int i;
unsigned int fixed_msr = NUM_FIXED_RANGES >> 3;
msr_t msr;
msr.lo = msr.hi = 0; /* Shut up gcc */
for (i = first; i < last; i++) {
/* When I switch to a new msr read it in */
if (fixed_msr != i >> 3) {
/* But first write out the old msr */
if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
disable_cache();
wrmsr(mtrr_msr[fixed_msr], msr);
enable_cache();
}
fixed_msr = i>>3;
msr = rdmsr(mtrr_msr[fixed_msr]);
}
if ((i & 7) < 4) {
msr.lo &= ~(0xff << ((i&3)*8));
msr.lo |= type << ((i&3)*8);
} else {
msr.hi &= ~(0xff << ((i&3)*8));
msr.hi |= type << ((i&3)*8);
}
}
/* Write out the final msr */
if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
disable_cache();
wrmsr(mtrr_msr[fixed_msr], msr);
enable_cache();
}
}
static unsigned fixed_mtrr_index(unsigned long addrk)
{
unsigned index;
index = (addrk - 0) >> 6;
if (index >= 8) {
index = ((addrk - 8*64) >> 4) + 8;
}
if (index >= 24) {
index = ((addrk - (8*64 + 16*16)) >> 2) + 24;
}
if (index > NUM_FIXED_RANGES) {
index = NUM_FIXED_RANGES;
}
return index;
}
// Externally visible function to add extra non system memory based mtrr's such
// as AGP mtrr's - needs to be called after setup_mtrrs
void add_var_mtrr(unsigned long range_startk, unsigned long range_sizek,
unsigned char type)
{
intel_set_var_mtrr(mtrr_count++,range_startk,range_sizek,type);
}
static unsigned int range_to_mtrr(unsigned int reg,
unsigned long range_startk, unsigned long range_sizek,
unsigned long next_range_startk)
{
if (!range_sizek || (reg >= BIOS_MTRRS)) {
return reg;
}
while(range_sizek) {
unsigned long max_align, align;
unsigned long sizek;
/* Compute the maximum size I can make a range */
max_align = fls(range_startk);
align = fms(range_sizek);
if (align > max_align) {
align = max_align;
}
sizek = 1 << align;
printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type WB\n",
reg, range_startk >>10, sizek >> 10);
intel_set_var_mtrr(reg++, range_startk, sizek, MTRR_TYPE_WRBACK);
range_startk += sizek;
range_sizek -= sizek;
if (reg >= BIOS_MTRRS)
break;
}
return reg;
}
void setup_mtrrs(struct mem_range *mem)
{
/* Try this the simple way of incrementally adding together
* mtrrs. If this doesn't work out we can get smart again
* and clear out the mtrrs.
*/
struct mem_range *memp;
unsigned long range_startk, range_sizek;
unsigned int reg;
msr_t msr;
#if defined(k7) || defined(k8)
/* Enable the access to AMD RdDram and WrDram extension bits */
msr = rdmsr(SYSCFG_MSR);
msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
wrmsr(SYSCFG_MSR, msr);
#endif
printk_debug("\n");
/* Initialized the fixed_mtrrs to uncached */
printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n",
0, NUM_FIXED_RANGES);
set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE);
/* Now see which of the fixed mtrrs cover ram.
*/
for (memp = mem; memp->sizek; memp++) {
unsigned int start_mtrr;
unsigned int last_mtrr;
start_mtrr = fixed_mtrr_index(memp->basek);
last_mtrr = fixed_mtrr_index(memp->basek + memp->sizek);
if (start_mtrr >= NUM_FIXED_RANGES) {
break;
}
printk_debug("Setting fixed MTRRs(%d-%d) type: WB\n",
start_mtrr, last_mtrr);
#if defined(k7) || defined(k8)
set_fixed_mtrrs(start_mtrr, last_mtrr,
MTRR_TYPE_WRBACK | MTRR_READ_MEM| MTRR_WRITE_MEM);
#else
set_fixed_mtrrs(start_mtrr, last_mtrr,
MTRR_TYPE_WRBACK);
#endif
}
printk_debug("DONE fixed MTRRs\n");
#if defined(k7) || defined(k8)
/* Disable the access to AMD RdDram and WrDram extension bits */
msr = rdmsr(SYSCFG_MSR);
msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
wrmsr(SYSCFG_MSR, msr);
/* Enale the RdMEM and WrMEM bits in SYSCFG */
msr = rdmsr(SYSCFG_MSR);
msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
wrmsr(SYSCFG_MSR, msr);
#endif
/* Cache as many memory areas as possible */
/* FIXME is there an algorithm for computing the optimal set of mtrrs?
* In some cases it is definitely possible to do better.
*/
range_startk = 0;
range_sizek = 0;
reg = 0;
for (memp = mem; memp->sizek; memp++) {
/* See if I can merge with the last range
* Either I am below 1M and the fixed mtrrs handle it, or
* the ranges touch.
*/
if ((memp->basek <= 1024) || (range_startk + range_sizek == memp->basek)) {
unsigned long endk = memp->basek + memp->sizek;
range_sizek = endk - range_startk;
continue;
}
/* Write the range mtrrs */
if (range_sizek != 0) {
reg = range_to_mtrr(reg, range_startk, range_sizek, memp->basek);
range_startk = 0;
range_sizek = 0;
if (reg >= BIOS_MTRRS)
break;
}
/* Allocate an msr */
range_startk = memp->basek;
range_sizek = memp->sizek;
}
/* Write the last range */
reg = range_to_mtrr(reg, range_startk, range_sizek, 0);
mtrr_count = reg;
printk_debug("DONE variable MTRRs\n");
printk_debug("Clear out the extra MTRR's\n");
/* Clear out the extra MTRR's */
while(reg < MTRRS) {
intel_set_var_mtrr(reg++, 0, 0, 0);
}
/* enable fixed MTRR */
printk_debug("call intel_enable_fixed_mtrr()\n");
intel_enable_fixed_mtrr();
printk_debug("call intel_enable_var_mtrr()\n");
intel_enable_var_mtrr();
printk_debug("Leave %s\n", __FUNCTION__);
}

View File

@ -1,91 +0,0 @@
#include <console/console.h>
#include <smp/start_stop.h>
#include <cpu/p6/pgtbl.h>
static void paging_off(void)
{
__asm__ __volatile__ (
/* Disable paging */
"movl %%cr0, %%eax\n\t"
"andl $0x7FFFFFFF, %%eax\n\t"
"movl %%eax, %%cr0\n\t"
/* Disable pae */
"movl %%cr4, %%eax\n\t"
"andl $0xFFFFFFDF, %%eax\n\t"
:
:
: "eax"
);
}
static void paging_on(void *pdp)
{
__asm__ __volatile__(
/* Load the page table address */
"movl %0, %%cr3\n\t"
/* Enable pae */
"movl %%cr4, %%eax\n\t"
"orl $0x00000020, %%eax\n\t"
"movl %%eax, %%cr4\n\t"
/* Enable paging */
"movl %%cr0, %%eax\n\t"
"orl $0x80000000, %%eax\n\t"
"movl %%eax, %%cr0\n\t"
:
: "r" (pdp)
: "eax"
);
}
void *map_2M_page(int cpu_index, unsigned long page)
{
struct pde {
uint32_t addr_lo;
uint32_t addr_hi;
} __attribute__ ((packed));
struct pg_table {
struct pde pd[2048];
struct pde pdp[512];
} __attribute__ ((packed));
static struct pg_table pgtbl[CONFIG_MAX_CPUS] __attribute__ ((aligned(4096)));
static unsigned long mapped_window[CONFIG_MAX_CPUS];
unsigned long window;
void *result;
int i;
if ((cpu_index < 0) || (cpu_index >= CONFIG_MAX_CPUS)) {
return MAPPING_ERROR;
}
window = page >> 10;
if (window != mapped_window[cpu_index]) {
paging_off();
if (window > 1) {
struct pde *pd, *pdp;
/* Point the page directory pointers at the page directories */
memset(&pgtbl[cpu_index].pdp, 0, sizeof(pgtbl[cpu_index].pdp));
pd = pgtbl[cpu_index].pd;
pdp = pgtbl[cpu_index].pdp;
pdp[0].addr_lo = ((uint32_t)&pd[512*0])|1;
pdp[1].addr_lo = ((uint32_t)&pd[512*1])|1;
pdp[2].addr_lo = ((uint32_t)&pd[512*2])|1;
pdp[3].addr_lo = ((uint32_t)&pd[512*3])|1;
/* The first half of the page table is identity mapped */
for(i = 0; i < 1024; i++) {
pd[i].addr_lo = ((i & 0x3ff) << 21)| 0xE3;
pd[i].addr_hi = 0;
}
/* The second half of the page table holds the mapped page */
for(i = 1024; i < 2048; i++) {
pd[i].addr_lo = ((window & 1) << 31) | ((i & 0x3ff) << 21) | 0xE3;
pd[i].addr_hi = (window >> 1);
}
paging_on(pdp);
}
mapped_window[cpu_index] = window;
}
if (window == 0) {
result = (void *)(page << 21);
} else {
result = (void *)(0x80000000 | ((page & 0x3ff) << 21));
}
return result;
}