Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 53892
b: refs/heads/master
c: de938c5
h: refs/heads/master
v: v3
  • Loading branch information
Bernhard Kaindl authored and Andi Kleen committed May 2, 2007
1 parent 826ee57 commit 4f4af79
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3ebad5905609476a4ff1151a66b21d9794009961
refs/heads/master: de938c51d5fec4ae03af64b06beb15d4423ec611
85 changes: 60 additions & 25 deletions trunk/arch/i386/kernel/cpu/mtrr/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ struct mtrr_state {
mtrr_type def_type;
};

struct fixed_range_block {
int base_msr; /* start address of an MTRR block */
int ranges; /* number of MTRRs in this block */
};

static struct fixed_range_block fixed_range_blocks[] = {
{ MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
{ MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
{ MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
{}
};

static unsigned long smp_changes_mask;
static struct mtrr_state mtrr_state = {};

Expand Down Expand Up @@ -152,6 +164,44 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
smp_processor_id(), msr, a, b);
}

/**
* Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs
* see AMD publication no. 24593, chapter 3.2.1 for more information
*/
static inline void k8_enable_fixed_iorrs(void)
{
unsigned lo, hi;

rdmsr(MSR_K8_SYSCFG, lo, hi);
mtrr_wrmsr(MSR_K8_SYSCFG, lo
| K8_MTRRFIXRANGE_DRAM_ENABLE
| K8_MTRRFIXRANGE_DRAM_MODIFY, hi);
}

/**
* Checks and updates an fixed-range MTRR if it differs from the value it
* should have. If K8 extenstions are wanted, update the K8 SYSCFG MSR also.
* see AMD publication no. 24593, chapter 7.8.1, page 233 for more information
* \param msr MSR address of the MTTR which should be checked and updated
* \param changed pointer which indicates whether the MTRR needed to be changed
* \param msrwords pointer to the MSR values which the MSR should have
*/
static void set_fixed_range(int msr, int * changed, unsigned int * msrwords)
{
unsigned lo, hi;

rdmsr(msr, lo, hi);

if (lo != msrwords[0] || hi != msrwords[1]) {
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
boot_cpu_data.x86 == 15 &&
((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK))
k8_enable_fixed_iorrs();
mtrr_wrmsr(msr, msrwords[0], msrwords[1]);
*changed = TRUE;
}
}

int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg)
/* [SUMMARY] Get a free MTRR.
<base> The starting (base) address of the region.
Expand Down Expand Up @@ -201,36 +251,21 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
*type = base_lo & 0xff;
}

/**
* Checks and updates the fixed-range MTRRs if they differ from the saved set
* \param frs pointer to fixed-range MTRR values, saved by get_fixed_ranges()
*/
static int set_fixed_ranges(mtrr_type * frs)
{
unsigned int *p = (unsigned int *) frs;
unsigned long long *saved = (unsigned long long *) frs;
int changed = FALSE;
int i;
unsigned int lo, hi;
int block=-1, range;

rdmsr(MTRRfix64K_00000_MSR, lo, hi);
if (p[0] != lo || p[1] != hi) {
mtrr_wrmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
changed = TRUE;
}

for (i = 0; i < 2; i++) {
rdmsr(MTRRfix16K_80000_MSR + i, lo, hi);
if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
mtrr_wrmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2],
p[3 + i * 2]);
changed = TRUE;
}
}
while (fixed_range_blocks[++block].ranges)
for (range=0; range < fixed_range_blocks[block].ranges; range++)
set_fixed_range(fixed_range_blocks[block].base_msr + range,
&changed, (unsigned int *) saved++);

for (i = 0; i < 8; i++) {
rdmsr(MTRRfix4K_C0000_MSR + i, lo, hi);
if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
mtrr_wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2],
p[7 + i * 2]);
changed = TRUE;
}
}
return changed;
}

Expand Down
5 changes: 5 additions & 0 deletions trunk/include/asm-i386/msr-index.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@
#define MSR_K7_CLK_CTL 0xc001001b
#define MSR_K8_TOP_MEM2 0xc001001d
#define MSR_K8_SYSCFG 0xc0010010

#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */
#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */
#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */

#define MSR_K7_HWCR 0xc0010015
#define MSR_K8_HWCR 0xc0010015
#define MSR_K7_FID_VID_CTL 0xc0010041
Expand Down

0 comments on commit 4f4af79

Please sign in to comment.