Commit 89b831ef authored by Jacob Shin's avatar Jacob Shin Committed by Linus Torvalds
Browse files

[PATCH] x86_64: Support for AMD specific MCE Threshold.



MC4_MISC - DRAM Errors Threshold Register realized under AMD K8 Rev F.
This register is used to count correctable and uncorrectable ECC errors that occur during DRAM read operations.
The user may interface through sysfs files in order to change the threshold configuration.

bank%d/error_count - reads current error count, write to clear.
bank%d/interrupt_enable - set/clear interrupt enable.
bank%d/threshold_limit - read/write the threshold limit.

APIC vector 0xF9 in hw_irq.h.
5 software defined bank ids in mce.h.
new apic.c function to setup threshold apic lvt.
defaults to interrupt off, count enabled, and threshold limit max.
sysfs interface created on /sys/devices/system/threshold.

AK: added some ifdefs to make it compile on UP

Signed-off-by: default avatarJacob Shin <jacob.shin@amd.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 979edfad
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -374,6 +374,14 @@ config X86_MCE_INTEL
	   Additional support for intel specific MCE features such as
	   the thermal monitor.

config X86_MCE_AMD
	bool "AMD MCE features"
	depends on X86_MCE && X86_LOCAL_APIC
	default y
	help
	   Additional support for AMD specific MCE features such as
	   the DRAM Error Threshold.

config PHYSICAL_START
	hex "Physical address where the kernel is loaded" if EMBEDDED
	default "0x100000"
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \

obj-$(CONFIG_X86_MCE)         += mce.o
obj-$(CONFIG_X86_MCE_INTEL)	+= mce_intel.o
obj-$(CONFIG_X86_MCE_AMD)	+= mce_amd.o
obj-$(CONFIG_MTRR)		+= ../../i386/kernel/cpu/mtrr/
obj-$(CONFIG_ACPI)		+= acpi/
obj-$(CONFIG_X86_MSR)		+= msr.o
+10 −0
Original line number Diff line number Diff line
@@ -833,6 +833,16 @@ int setup_profiling_timer(unsigned int multiplier)
	return 0;
}

#ifdef CONFIG_X86_MCE_AMD
void setup_threshold_lvt(unsigned long lvt_off)
{
	unsigned int v = 0;
	unsigned long reg = (lvt_off << 4) + 0x500;
	v |= THRESHOLD_APIC_VECTOR;
	apic_write(reg, v);
}
#endif /* CONFIG_X86_MCE_AMD */

#undef APIC_DIVISOR

/*
+3 −0
Original line number Diff line number Diff line
@@ -612,6 +612,9 @@ retint_kernel:
ENTRY(thermal_interrupt)
	apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt

ENTRY(threshold_interrupt)
	apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt

#ifdef CONFIG_SMP	
ENTRY(reschedule_interrupt)
	apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
+2 −0
Original line number Diff line number Diff line
@@ -492,6 +492,7 @@ void invalidate_interrupt5(void);
void invalidate_interrupt6(void);
void invalidate_interrupt7(void);
void thermal_interrupt(void);
void threshold_interrupt(void);
void i8254_timer_resume(void);

static void setup_timer_hardware(void)
@@ -580,6 +581,7 @@ void __init init_IRQ(void)
	set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
#endif	
	set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
	set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);

#ifdef CONFIG_X86_LOCAL_APIC
	/* self generated IPI for local APIC timer */
Loading