发信人: wucheng_ai(子程)
整理人: wenbobo(2003-01-09 23:23:13), 站内信件
|
AMD K6 WriteBack Optimizations
AMD K6 反写(技术)最佳化
This source code uses GCC inline assembler (AT&T syntax).
该源程序需用内嵌AT&T语法汇编器的GCC来编译.
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.
这是我写的代码,并且在我自己的K6(K6-200)上运行良好。但是自启用两种不同反写方法后,我就不能正常运行于K6-2(CXT内核)或K6-3了.它跑在K6-2 CXT和K6-3处理器上是最佳的。
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.
你可以用AMD-K6反写技术获得CPU系列的识别符,型号和级别,最关键是你必须确定你有一个AMD处理器.
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");
}
|
|