vivi中基于NOR FLASH的相关代码

来源:互联网 发布:吉利知豆d1 编辑:程序博客网 时间:2024/05/29 16:42

void mem_map_nor(void)
{
    copy_vivi_to_ram();
    mem_mapping_linear();
    nor_flash_mapping();
    nor_flash_remapping();
}

 

 

static void copy_vivi_to_ram(void)
{
    putstr_hex("Evacuating 1MB of Flash to DRAM at 0x", VIVI_RAM_BASE);
    memcpy((void *)VIVI_RAM_BASE, (void *)VIVI_ROM_BASE, VIVI_RAM_SIZE);
}
由于NORFLASH的也是可以通过地址线立即寻址的,所以读操作可以通过MEMCPY直接实现,比NAND要简单。

 

mem_mapping_linear(void)

static inline void mem_mapping_linear(void)
{
    unsigned long pageoffset, sectionNumber;

    putstr_hex("MMU table base address = 0x", (unsigned long)mmu_tlb_base);
    /* 4G 康开阑 1:1肺 概俏. not cacacheable, not bufferable */
    for (sectionNumber = 0; sectionNumber < 4096; sectionNumber++) {
        pageoffset = (sectionNumber << 20);
        *(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC;
    }

    /* make dram cacheable */
    for (pageoffset = DRAM_BASE; pageoffset < (DRAM_BASE+DRAM_SIZE); pageoffset += SZ_1M) {
        //DPRINTK(3, "Make DRAM section cacheable: 0x%08lx/n", pageoffset);
        *(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC | MMU_CACHEABLE;
    }
}

 

函数的第一部分(for 1):可以看到是从TLB的偏址0开始直到最后共4K个索引,因为每个索引对应1M的空间(sectionNumber << 20),所以它是针对整个4G范围设置映射关系的。

函数的第二部分(for 2): 可以看到它是从对应DRAM的偏址开始到DRAM结束的索引,因此它针对的是DRAM空间的映射。

 

 

nor_flash_mapping();
将FLASH_BASE(0x0)和FLASH_UNCACHED_BASE(0x10000000) 都映射到FLASH_BASE,大小为FLASH_SIZE
这就是我们可以通过基于FLASH_UNCACHED_BASE的地址来访问到nor flash的原因(linux内核下是通过ioremap来实现的),但是看代码的时候发现这个函数有明显的BUG,网上查了下,果然也有人遇到了这个问题:

static inline void nor_flash_mapping(void)    //by yhn, has bug.
{
    unsigned long offset, cached_addr, uncached_addr;

    cached_addr = FLASH_BASE;                               //------------------------------bug
    uncached_addr = FLASH_UNCACHED_BASE;       //------------------------------bug

    for (offset = 0; offset < FLASH_SIZE; offset += MMU_SECTION_SIZE) {
        cached_addr += offset;
        uncached_addr += offset;
        *(mmu_tlb_base + (cached_addr >> 20)) = /
                (cached_addr | MMU_SECDESC | MMU_CACHEABLE);
        *(mmu_tlb_base + (uncached_addr >> 20)) = /
                (cached_addr | MMU_SECDESC);
    }
}

 

nor_flash_remapping(void)

因为已经将VIVI搬移到了SDRAM中,所以vivi在FLASH中的地址也映射到相应的RAM中,可以使得VIVI的读写在RAM中进行。

static inline void nor_flash_remapping(void)
{
    putstr_hex("Map flash virtual section to DRAM at 0x", VIVI_RAM_BASE);
    *(mmu_tlb_base + (VIVI_ROM_BASE >> 20)) = /
                (VIVI_RAM_BASE | MMU_SECDESC | MMU_CACHEABLE);

 

  按照从上往下的步骤实现这4个函数,后一步在前一步的基础上进行修改。完成映射操作。

原创粉丝点击