精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>嵌入式开发>>TRANSLATE: AMD K6 WriteBack Optimizations

主题:TRANSLATE: AMD K6 WriteBack Optimizations
发信人: 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");
}

[关闭][返回]