S3C44B0x 开cache后造成不一致问题的解决办法

来源:互联网 发布:中国数据新闻大赛 编辑:程序博客网 时间:2024/05/16 12:10

关于s3c44b0的cpu内部8Kcache SRAM的初始化问题。主要是因为cpu_init()调用了icache_enable()函数,而该函数又调用了s3c44b0_flush_cache()而引发的问题

 s3c44b0_flush_cache()函数就这么几行,代码如下:

static void s3c44b0_flush_cache(void)
{
 volatile int i;
 /* flush cycle */
 for(i=0x10002000;i<0x10004800;i+=16)
 {
  *((int *)i)=0x0;
 }
}

 首先莫名的是:计数用的变量i要用volatile来修饰!也许这就是arm或说是嵌入式或说是基于硬件的C程序与基于PC的C程序不同之处吧。加volatile是为了防止编译器把i给合谐掉,然后就是赋值句*((int *)i)=0x0:这个对写过或是看过arm程序的都知道吧,不解释。

 关键在于for(i=0x10002000;i<0x10004800;i+=16)参看s3c44b0手册,cache set0:3地址是0x1000000~0x10002000;cache tag0:3+LRU地址是0x10002000~0x10004800。刚开始以为刷新cache是要向cache set0:3写0,而其实应该向且cache tag0:3+LRU空间写入0来刷新cache。有点意思的是:cache tag和LRU RAM写入的地址。(参看s3c44b0手册关于cache tag部分)由于cache tag和LRU RAM是16字节读写的,故i的增加应该是以16为单位的。

 接下来是设置非缓冲区范围。

NCACHBE0 = 0xC0000000;
NCACHBE1 = 0x00000000;

 完全依据程序员个人主观,呵呵  当然是要好的想法:比如不应该把IO地址放入缓冲区,而应该把它放入非缓冲区;不应该不把SDRAM放入非缓冲区,而应该放入缓冲区。所以,这里把除SDRAM地址外的所有映射地址做为非缓冲区。然后依据地址设置NCACHBE0和NCACHBE1。NCACHBE0在在这里是有用的,高地址为0x0c000000,低地址为0x00000000;而 NCACHBE1可以理解为不用它,所以起始和终止地址都设为0

 在设置完之后就只要开启cpu cache功能就可以。

reg = SYSCFG;
reg |= 0x00000006; /* 8kB */
SYSCFG = reg;

 当然,坚持一惯的风格,操作SYSCFG寄存器方式为:读---操作---回写。这里把8K内部RAM全作为cache

    除了s3c44b0_flush_cache()外,其他都很简单,呵呵 不是吗

原创粉丝点击