s3c44b0内部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()外,其他都很简单.