Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd786dd1 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

x86: move mtrr cpu cap setting early in early_init_xxxx



Krzysztof Helt found MTRR is not detected on k6-2

root cause:
	we moved mtrr_bp_init() early for mtrr trimming,
and in early_detect we only read the CPU capability from cpuid,
so some cpu doesn't have that bit in cpuid.

So we need to add early_init_xxxx to preset those bit before mtrr_bp_init
for those earlier cpus.

this patch is for v2.6.27

Reported-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 12cf105c
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -31,6 +31,11 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
		if (c->x86_power & (1<<8))
		if (c->x86_power & (1<<8))
			set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
			set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
	}
	}

	/*  Set MTRR capability flag if appropriate */
	if (c->x86_model == 13 || c->x86_model == 9 ||
	   (c->x86_model == 8 && c->x86_mask >= 8))
		set_cpu_cap(c, X86_FEATURE_K6_MTRR);
}
}


static void __cpuinit init_amd(struct cpuinfo_x86 *c)
static void __cpuinit init_amd(struct cpuinfo_x86 *c)
@@ -166,10 +171,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
						mbytes);
						mbytes);
				}
				}


				/*  Set MTRR capability flag if appropriate */
				if (c->x86_model == 13 || c->x86_model == 9 ||
				   (c->x86_model == 8 && c->x86_mask >= 8))
					set_cpu_cap(c, X86_FEATURE_K6_MTRR);
				break;
				break;
			}
			}


+11 −0
Original line number Original line Diff line number Diff line
@@ -314,6 +314,16 @@ enum {
		EAMD3D		= 1<<20,
		EAMD3D		= 1<<20,
};
};


static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
{
	switch (c->x86) {
	case 5:
		/* Emulate MTRRs using Centaur's MCR. */
		set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
		break;
	}
}

static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
{
{


@@ -462,6 +472,7 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
	.c_vendor	= "Centaur",
	.c_vendor	= "Centaur",
	.c_ident	= { "CentaurHauls" },
	.c_ident	= { "CentaurHauls" },
	.c_early_init	= early_init_centaur,
	.c_init		= init_centaur,
	.c_init		= init_centaur,
	.c_size_cache	= centaur_size_cache,
	.c_size_cache	= centaur_size_cache,
};
};
+28 −4
Original line number Original line Diff line number Diff line
@@ -15,13 +15,11 @@
/*
/*
 * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
 * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
 */
 */
static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
static void __cpuinit __do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
{
{
	unsigned char ccr2, ccr3;
	unsigned char ccr2, ccr3;
	unsigned long flags;


	/* we test for DEVID by checking whether CCR3 is writable */
	/* we test for DEVID by checking whether CCR3 is writable */
	local_irq_save(flags);
	ccr3 = getCx86(CX86_CCR3);
	ccr3 = getCx86(CX86_CCR3);
	setCx86(CX86_CCR3, ccr3 ^ 0x80);
	setCx86(CX86_CCR3, ccr3 ^ 0x80);
	getCx86(0xc0);   /* dummy to change bus */
	getCx86(0xc0);   /* dummy to change bus */
@@ -44,9 +42,16 @@ static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
		*dir0 = getCx86(CX86_DIR0);
		*dir0 = getCx86(CX86_DIR0);
		*dir1 = getCx86(CX86_DIR1);
		*dir1 = getCx86(CX86_DIR1);
	}
	}
	local_irq_restore(flags);
}
}


static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
{
	unsigned long flags;

	local_irq_save(flags);
	__do_cyrix_devid(dir0, dir1);
	local_irq_restore(flags);
}
/*
/*
 * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
 * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
 * order to identify the Cyrix CPU model after we're out of setup.c
 * order to identify the Cyrix CPU model after we're out of setup.c
@@ -161,6 +166,24 @@ static void __cpuinit geode_configure(void)
	local_irq_restore(flags);
	local_irq_restore(flags);
}
}


static void __cpuinit early_init_cyrix(struct cpuinfo_x86 *c)
{
	unsigned char dir0, dir0_msn, dir1 = 0;

	__do_cyrix_devid(&dir0, &dir1);
	dir0_msn = dir0 >> 4; /* identifies CPU "family"   */

	switch (dir0_msn) {
	case 3: /* 6x86/6x86L */
		/* Emulate MTRRs using Cyrix's ARRs. */
		set_cpu_cap(c, X86_FEATURE_CYRIX_ARR);
		break;
	case 5: /* 6x86MX/M II */
		/* Emulate MTRRs using Cyrix's ARRs. */
		set_cpu_cap(c, X86_FEATURE_CYRIX_ARR);
		break;
	}
}


static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
{
{
@@ -416,6 +439,7 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c)
static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
	.c_vendor	= "Cyrix",
	.c_vendor	= "Cyrix",
	.c_ident	= { "CyrixInstead" },
	.c_ident	= { "CyrixInstead" },
	.c_early_init	= early_init_cyrix,
	.c_init		= init_cyrix,
	.c_init		= init_cyrix,
	.c_identify	= cyrix_identify,
	.c_identify	= cyrix_identify,
};
};