Subject: K6 MTRR's could be handled better
To: Jason R Thorpe <thorpej@wasabisystems.com>
From: Frederick Bruckman <fredb@immanent.net>
List: tech-kern
Date: 08/26/2002 13:11:46
Hi. Regarding K6 MTRR's, according to AMD:

    Prior to programming write-combining or uncacheable areas of
    memory in the UWCCR, the software must disable the
    processor's cache, then flush the cache. This can be achieved by
    setting the CD bit in CR0 to 1 and executing the WBINVD
    instruction. Following the programming of the UWCCR, the
    processor's cache must be enabled by setting the CD bit in CR0
    to 0.

[AMD_K6 (R) Processor BIOS Design, Pub 21329, Rev. L, December 1999, p27,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21329.pdf]

That isn't exactly what the kernel K6 MTRR code does. Shouldn't it
rather be more like the following?


Index: mtrr_k6.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/mtrr_k6.c,v
retrieving revision 1.2
diff -u -r1.2 mtrr_k6.c
--- mtrr_k6.c	2001/11/15 07:03:30	1.2
+++ mtrr_k6.c	2002/08/19 00:27:34
@@ -102,10 +102,15 @@
 k6_mtrr_reload(void)
 {
 	uint64_t uwccr;
+	uint32_t origcr0, cr0;
 	int i;

 	disable_intr();

+	origcr0 = cr0 = rcr0();
+	cr0 |= CR0_CD;
+	lcr0(cr0);
+
 	wbinvd();

 	for (i = 0, uwccr = 0; i < MTRR_K6_NVAR; i++) {
@@ -115,7 +120,7 @@

 	wrmsr(MSR_K6_UWCCR, uwccr);

-	wbinvd();
+	lcr0(origcr0);

 	enable_intr();
 }


Regards,

Frederick