summaryrefslogtreecommitdiff
path: root/src/cpu/k8/cpufixup.c
blob: 8e7ad95d5d679d944055a97bd816d54a55249c31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* Needed so the AMD K8 runs correctly.  */
#include <console/console.h>
#include <mem.h>
#include <cpu/p6/msr.h>

#define TOP_MEM    0xc001001A
#define TOP_MEM2   0xc001001D
#define IORR_FIRST 0xC0010016
#define IORR_LAST  0xC0010019
#define SYSCFG     0xC0010010

#define MTRRVARDRAMEN (1 << 20)

void k8_cpufixup(struct mem_range *mem)
{
	msr_t msr;
	unsigned long i;
	unsigned long ram_megabytes;

	/* For now no Athlon board has significant holes in it's
	 * address space so just find the last memory region
	 * and compute the end of memory from that.
	 */
	for(i = 0; mem[i].sizek; i++)
		;
	if (i == 0) 
		return;
	ram_megabytes = (mem[i-1].basek + mem[i-1].sizek) *1024;
		

#warning "FIXME handle > 4GB of ram"
	// 8 MB alignment please
	ram_megabytes += 0x7fffff;
	ram_megabytes &= (~0x7fffff);

	// set top_mem registers to ram size
	printk_spew("Setting top_mem to 0x%x\n", ram_megabytes);
	msr = rdmsr(TOP_MEM);
	printk_spew("TOPMEM was 0x%02x:0x%02x\n", msr.hi, msr.lo);
	msr.hi = 0;
	msr.lo = ram_megabytes;
	wrmsr(TOP_MEM, msr);

	// I am setting this even though I won't enable it
	wrmsr(TOP_MEM2, msr);

	/* 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);

	msr = rdmsr(SYSCFG);
	printk_spew("SYSCFG was 0x%x:0x%x\n", msr.hi, msr.lo);
	msr.lo |= MTRRVARDRAMEN;
	wrmsr(SYSCFG, msr);
	msr = rdmsr(SYSCFG);
	printk_spew("SYSCFG IS NOW 0x%x:0x%x\n", msr.hi, msr.lo);
}