现在的位置: 首页 > 综合 > 正文

uclinux-2008r1(bf561)内核的icache支持(3):__fill_code_cplbtab

2013年09月05日 ⁄ 综合 ⁄ 共 3304字 ⁄ 字号 评论关闭
 

  
这个函数的实现为:
/* helper function */
static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
{
     if (cplb_data[i].psize) {
         fill_cplbtab(t,
                   cplb_data[i].start,
                   cplb_data[i].end,
                   cplb_data[i].psize,
                   cplb_data[i].i_conf);
     #if defined(CONFIG_BFIN_ICACHE)
         if (ANOMALY_05000263 && i == SDRAM_KERN) {
              fill_cplbtab(t,
                       cplb_data[i].start,
                       cplb_data[i].end,
                       SIZE_4M,
                       cplb_data[i].i_conf);
         } else
#endif
} else {
              fill_cplbtab(t,
                       cplb_data[i].start,
                       a_start,
                       SIZE_1M,
                       cplb_data[i].i_conf);
              fill_cplbtab(t,
                       a_start,
                       a_end,
                       SIZE_4M,
                       cplb_data[i].i_conf);
              fill_cplbtab(t, a_end,
                       cplb_data[i].end,
                       SIZE_1M,
                       cplb_data[i].i_conf);
         }
}
static unsigned short __init
fill_cplbtab(struct cplb_tab *table,
          unsigned long start, unsigned long end,
          unsigned long block_size, unsigned long cplb_data)
{
     int i;
 
     switch (block_size) {
     case SIZE_4M:
         i = 3;
         break;
     case SIZE_1M:
         i = 2;
         break;
     case SIZE_4K:
         i = 1;
         break;
     case SIZE_1K:
     default:
         i = 0;
         break;
     }
 
     cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
 
     while ((start < end) && (table->pos < table->size)) {
 
         table->tab[table->pos++] = start;
 
         if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
              table->tab[table->pos++] =
                  cplb_data | CPLB_LOCK | CPLB_DIRTY;
         else
              table->tab[table->pos++] = cplb_data;
 
         start += block_size;
     }
     return 0;
}
1             L1 I-Memory
     {
         .start = L1_CODE_START,
         .end = L1_CODE_START + L1_CODE_LENGTH,
         .psize = SIZE_4M,
         .attr = INITIAL_T | SWITCH_T | I_CPLB,
         .i_conf = L1_IMEMORY,
         .d_conf = 0,
         .valid = 1,
         .name = "L1 I-Memory",
     },
这个块传递进来时,它将直接调用
         fill_cplbtab(t,
                   cplb_data[i].start,
                   cplb_data[i].end,
                   cplb_data[i].psize,
                   cplb_data[i].i_conf);
从fill_cplbtab这个函数可以看出此时ICPLB_ADDR的值将为L1_CODE_START,也就是0xffa0 0000,而ICPLB_DATA的值将为0x0003 0007,这个值的意义是:
16位和17位的值为11,即页面大小为4M。
第0位,也即CPLB_VALID,为1,表示Valid CPLB Entry。
第1位,也即CPLB_LOCK,为1,表示CPLB Entry Should not be replaced。
第2位,也即CPLB_USER_RD,为1,表示User mode read access permitted。
2             Kernel Memory
     {
         .start = 0,
         .end = 0, /* dynamic */
         .psize = 0,
         .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
         .i_conf = SDRAM_IGENERIC,
         .d_conf = SDRAM_DGENERIC,
         .valid = 1,
         .name = "Kernel Memory",
     },
这个块传进来的时候,它将调用
              fill_cplbtab(t,
                       cplb_data[i].start,
                       cplb_data[i].end,
                       SIZE_4M,
                       cplb_data[i].i_conf);
此时将生成15个SDRAM的块,每个都是4M,且从0开始递增。此时它们的CPLB_DATA值将为0x0003 1205,这个值的意义是:
16位和17位的值为11,即页面大小为4M。
第0位,也即CPLB_VALID,为1,表示Valid CPLB Entry。
第1位,也即CPLB_LOCK,为0,表示CPLB Entry can be replaced。
第2位,也即CPLB_USER_RD,为1,表示User mode read access permitted。
第9位,也即CPLB_MEM_LEV,为1,表示Determins Line Buffer, Low Priority。
第12位,也即CPLB_L1_CHBL,为1,表示Cacherable in l1。

抱歉!评论已关闭.