AMD K6 WriteBack Optimisations |
This source code uses GCC inline assembler (AT&T syntax).
I wrote and tested this on my own K6 (k6-200) and it works ok, but I was unable to find anyone with a K6-2 (CXT core) or K6-3 since there is two different methods for enabling writeback mode. It _should_ work fine on k6-2 CXT and K6-3 processors. With some tweaking, can be put into anyone's OS. You call AMD_K6_writeback with the CPUID results family, model and stepping, only when you are sure you have an AMD cpu. void AMD_K6_writeback(int family, int model, int stepping) { /* mem_end == top of memory in bytes */ int mem=(mem_end>>20)/4; /* turn into 4mb aligned pages */ int c; union REGS regs; if(family==5) { c=model; /* model 8 stepping 0-7 use old style, 8-F use new style */ if(model==8) { if(stepping<8) c=7; else c=9; } switch(c) { /* old style write back */ case 6: case 7: AMD_K6_read_msr(0xC0000082, ®s); if(((regs.x.eax>>1)&0x7F)==0) kprintf("AMD K6 : WriteBack currently disabled\n"); else kprintf("AMD K6 : WriteBack currently enabled (%luMB)\n", ((regs.x.eax>>1)&0x7F)*4); kprintf("AMD K6 : Enabling WriteBack to %luMB\n", mem*4); AMD_K6_write_msr(0xC0000082, ((mem<<1)&0x7F), 0, ®s); break; /* new style write back */ case 9: AMD_K6_read_msr(0xC0000082, ®s); if(((regs.x.eax>>22)&0x3FF)==0) kprintf("AMD K6 : WriteBack Disabled\n"); else kprintf("AMD K6 : WriteBack Enabled (%luMB)\n", ((regs.x.eax>>22)&0x3FF)*4); kprintf("AMD K6 : Enabled WriteBack (%luMB)\n", mem*4); AMD_K6_write_msr(0xC0000082, ((mem<<22)&0x3FF), 0, ®s); break; default: /* dont set it on Unknowns + k5's */ break; } } } void AMD_K6_write_msr(ULONG msr, ULONG v1, ULONG v2, union REGS *regs) { asm __volatile__ ( "pushfl\n" "cli\n" "wbinvd\n" "wrmsr\n" "popfl\n" : "=a" (regs->x.eax), "=b" (regs->x.ebx), "=c" (regs->x.ecx), "=d" (regs->x.edx) : "a" (v1), "d" (v2), "c" (msr) : "eax", "ecx", "edx", "ebx", "memory"); } void AMD_K6_read_msr(ULONG msr, union REGS *regs) { asm __volatile__ ( "pushfl\n" "cli\n" "wbinvd\n" "xorl %%eax, %%eax\n" "xorl %%edx, %%edx\n" "rdmsr\n" "popfl\n" : "=a" (regs->x.eax), "=b" (regs->x.ebx), "=c" (regs->x.ecx), "=d" (regs->x.edx) : "c" (msr) : "eax", "ecx", "edx", "ebx", "memory"); } |