|
[Original]
[Print]
[Top]
|
我想通过如下的操作进行cache invalidate操作。但是我感觉下面的代码好像没如我的期望那样运行
li t4, K1BASE|0x7FFFFC
li t5, K1BASE|0xFFFFFC
.set push
.set mips32
cache 9, 0(t4) # invalidate data cache line
cache 9, 0(t5)
.set pop
我用 cache 0,0(t4) 和 cache 0,0(t5) 也没达到效果。
请高手指点下该如何操作。
|
|
|
----
一切有为法,如梦幻泡影。
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
Please pay attention to MIPS 4K cache arch. The L1 and L2 are not inclusive cache. In other words, you have to EXPLICITELY handle both L1 and L2 cache.
Meantime, please read/google some articles about what the Inclusive/Exclusive Cache stands for, so as to better understand what I am suggesting above.
Wish helpful,
|
|
|
----
天若有情天亦老,人间正道是沧桑。
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
多谢。 其实我想做的事情是在板子上电的时候在bootloader自动检测sdram大小。
对于成条的内存条来说可以通过读取SPD得到。 但是我们用的是内存颗粒,也就是没有SPD的。 我们的硬件有2个版本,一个版本是8M sdram,一个版本是16M sdram.
我的想法是通过向偏移为 0x7FFFFC和0xFFFFFC地址写入不同的值。因为这两个地址正好是8M和16M的最后个字。对于8M的sdram, 因为地址折回,这两个地址实际上指向了同一个地方。所以,如果读会的值不一样,说明是16M,否则应该是8M。 程序写好后对16M的sdram,测试通过没问题。但是对于8M的sdram,测试照样过了,本来认为应该是相同的值,结果取出的并不相同。所以我郁闷了,开始怀疑是cache在作怪。但是后来做了Invalidate之后还是这样。 搞不明白了。不知道你们有没有什么好的点子。
LEAF(romSizeMemory)
li a2, K1BASE | RST_MEMCTL
lw t0, 0(a2)
and t0, ~RST_MEMCTL_EXT_FB
or t0, RST_MEMCTL_EXT_FB
sw t0, 0(a2)
sync
/*
** Setup Memory for 2-2-2 configuration
*/
li a2, K1BASE | MEM_STMG0R
li t0, 0x2265655
sw t0, 0(a2)
sync
/* Setup Memory Refresh value */
li a2, K1BASE | MEM_REF
li t0, SDRAM_MEMORY_REFRESH_VALUE
sw t0, 0(a2) # MEM_REF
sync
li a2, K1BASE | MEM_STMG0R
lw t0, 0(a2) # MEM_TIMING
and t0, ~0x3
ori t0, 0x1
sw t0, 0(a2) # MEM_TIMING
sync
li a2, K1BASE | MEM_CFG
lw t0, 0(a2) # MEM_CFG
and t0, ~(SDRAM_DATA_WIDTH_M | SDRAM_COL_WIDTH_M |
SDRAM_ROW_WIDTH_M|SDRAM_BANKADDR_BITS_M)
or t0, (((SDRAM_DATA_WIDTH / 8) - 2) << SDRAM_DATA_WIDTH_S)
/* Bank Address Bits are 2 */
or t0, (1 << SDRAM_BANKADDR_BITS_S)
/*
* SDRAM size auto detect.8M and 16M SDRAM supported. Supportting for
* any other size can be append easily.
*/
sdram_16m_test:
/* Column Width & Row Width*/
or t0, ((SDRAM_16M_COL_WIDTH-1) << SDRAM_COL_WIDTH_S)
or t0, ((SDRAM_16M_ROW_WIDTH-1) << SDRAM_ROW_WIDTH_S)
sw t0, 0(a2) # MEM_CFG
sync
/* Place SDRAM into Auto Initialize state */
li a2, K1BASE | MEM_CTRL
li t0, 0x3089
sw t0, 0(a2) # MEM_CTRL
sync
1:
lw t0, 0(a2) # MEM_CTRL
andi t1,t0,0x1
bnez t1, 1b
/*SDRAM size detect*/
li t2, 0x55AA55AA
li t3, 0xAA55AA55
li t4, K1BASE|0x7FFFFC
/*write 0x55AA55AA to 0x7FFFFC(last word of 8M SDRAM)*/
li t5, K1BASE|0xFFFFFC
/*write 0xAA55AA55 to 0xFFFFFC(last word of 16M SDRAM)*/
sw t2, 0x0(t4)
sync
sw t3, 0x0(t5)
sync
.set push
.set mips32
cache Hit_Invalidate_D, 0(t4)
cache Hit_Invalidate_D, 0(t5)
.set pop
lw t6, 0x0(t4)
sync
lw t7, 0x0(t5)
sync
bne t6, t2, sdram_8m_test
/*The values read back from 0xFFFFFC isn't equal with 0x55AA55AA:8M posible.*/
bne t7, t3, sdram_8m_test
/*The values read back from 0x7FFFFC isn't equal with 0xAA55AA55:8M posible.*/
/*
* I don't know why it can reach here for 8M sdram.
* I check the registers' values,and found value in t6 is 0x55AA55AA,
* and in t7 is 0xAA55AA55.I thought it should be a same value 0xAA55AA55
* because the address is fold back.
*/
b sdram_config_ok
sdram_8m_test:
/*t0 hold the value of MEM_CFG*/
li a2, K1BASE | MEM_CFG
and t0, ~(SDRAM_COL_WIDTH_M | SDRAM_ROW_WIDTH_M)
/* Column Width & Row Width*/
or t0, ((SDRAM_8M_COL_WIDTH-1) << SDRAM_COL_WIDTH_S)
or t0, ((SDRAM_8M_ROW_WIDTH-1) << SDRAM_ROW_WIDTH_S)
sw t0, 0(a2) # MEM_CFG
sync
/* Place SDRAM into Auto Initialize state */
li a2, K1BASE | MEM_CTRL
li t0, 0x3089
sw t0, 0(a2) # MEM_CTRL
sync
1:
lw t0, 0(a2) # MEM_CTRL
andi t1,t0,0x1
bnez t1, 1b
/*SDRAM size detect*/
li t2, 0xAA55AA55
li t3, K1BASE|SDRAM0|0x7FFFFC
sw t2, 0x0(t3)
sync
lw a0, 0x0(t3)
beq a0, t2, sdram_config_ok
sdram_config_fail:
/*mem detect error, do cold reset*/
ROM_PUTS("ram config failed")
li a0, K1BASE|COLD_RESET
li t0, RESET_SYSTEM
sw t0, 0(a0)
sdram_config_ok:
j ra
END(romSizeMemory)
|
|
|
----
一切有为法,如梦幻泡影。
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
I did it!. I found my problem. The difference for 8M and 16M sdram is the column numbers of them are different. The addresss I had ever chosen had the same column address bud different row address,, so They would never conflicted. We must choose the adress that have the same row address and conflicting column address.
|
|
|
----
编程之道犹如庄周梦蝶
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
代码片段,在RMI XLR上验证OK:
#define STR(x) #x
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
#define Index_Store_Tag_I 0x08
#define Index_Store_Tag_D 0x09
#define Hit_Invalidate_I 0x10
#define Hit_Invalidate_D 0x11
#define Fetch_I 0x14
#define Hit_Writeback_Inv_D 0x15
#define Fetch_Lock_D 0x1D
#define Fetch_Lock_I 0x1C
#define cache_op(address,op)
({
__asm__ __volatile__(
"cache "STR(op)", 0(%0)
"
: :"r"(address));
})
/*
* Hit and invalidate, it will not write back cache to memory! Only invilidate!!!
*/
__inline__ void _cacheHitInvalidate(enum caches ca, uint32_t memAddr, int cacheLineCnt)
{
uint32_t cacheLineSz;
int i;
cacheLineSz = xlr_caches[ca].line_size; /* XLR cache line size 32 bytes */
if(I_CACHE == ca){
for(i = 0; i < cacheLineCnt; i++, memAddr += cacheLineSz){
cache_op(memAddr, Hit_Invalidate_I);
}
}
else if(D_CACHE == ca){
for(i = 0; i < cacheLineCnt; i++, memAddr += cacheLineSz){
cache_op(memAddr, Hit_Invalidate_D);
}
}
printk("[%d way(s) Done!]
", i);
return;
133 }
|
|
|
----
路漫漫兮修远兮,吾将上下而求索!
|
|
[Original]
[Print]
[Top]
|
|