Chinaunix首页 | 论坛 | 博客
  • 博客访问: 850315
  • 博文数量: 190
  • 博客积分: 7021
  • 博客等级: 少将
  • 技术积分: 1752
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-17 19:26
文章分类

全部博文(190)

文章存档

2014年(9)

2011年(32)

2010年(149)

我的朋友

分类: LINUX

2010-06-07 15:06:09

stage2的第三步为建立内存映射表等一系列于内存相关的工作

/*
 * Step 3
 * 4G linear mapping, flash mapping
 * MMU on
 */

//mem_map_init()

//mmu_init()

//putstr("Succeed memory mapping.\r\n")

void mem_map_init(void)
{
#ifdef CONFIG_S3C2440_NAND_BOOT
    mem_map_nand_boot();
#else
    mem_map_nor();
#endif
    cache_clean_invalidate();
    tlb_invalidate();
}

可以看出,当从nand或者是nor启动是调用的是不同的内存映射函数

vivi中使用的是段式页表,只需要一级页表
step3-->mem_map_init()-->mem_map_nand_boot()-->mem_maping_linear()

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

    putstr_hex("MMU table base address = 0x",(unsigned long)mmu_tlb_base);
    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_IM)
    {
        *(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC \
                                               |MMU_CACHEABLE;
    }
}

从0x33dfc000开始的16k建立页表
一共有4096个页表,每个页表4个字节==>16k,每个页表项对应1M的空间,一共4G,此函数的目的就是将4G虚拟地址映射到相同的物理地址上,且不使用cache及writebuffer,完成上面的步骤之后,再将SDRAM对应的空间页表项改为cacheable

void putstr_hex(const char *str, unsigned long value)
{
    char buf[9];
    binarytohex(buf, value, 4);
    putstr(str);
    putstr(buf);
    putstr("\r\n");
}

void binarytohex(char *buf, long x, int nbytes)
{
    int i;
    int s = 4 * (2 * nbytes - 1);
    if (hex_to_ascii_table[0] != '0')
        putstr("hex_to_ascii_table corrupted\r\n");
    for (i = 0; i < 2 * nbytes; i++)
    {
        buf[i] = hex_to_ascii_table[(x >> s) & 0x0f];
        s -= 4;
    }
    buf[2 * nbytes] = 0;
}

static char hex_to_ascii_table[16] = "0123456789abcdef";


下面的是清除cache的函数,涉及到一个内嵌汇编的知识和协处理器的知识
step3-->mem_map_init()-->cache_clean_invalidate();


void cache_clean_invalidate(void)
{
   cpu_arm920_cache_clean_invalidata_all();
}

static inline void cpu_arm920_cache_clean_invalidate_all(void)
{
__asm__(
        "mov r1, #0\n"
        "mov r1, #7 << 5\n" /* 8 segments */
        "1: orr r3, r1, #63 << 26\n" /* 64 entries */
        "2: mcr p15, 0, r3, c7, c14, 2\n" /* clean & invalidate D index*/
        "subs r3, r3, #1 << 26\n"
        "bcs 2b\n"
        "subs r1, r1, #1 << 5\n"
        "bcs 1b\n"
        "mcr p15, 0, r1, c7, c5, 0\n" /* invalidate I cache */
        "mcr p15, 0, r1, c7, c10, 4\n" /* drain WB */
        );
}


step3-->mem_map_init()-->tlb_invalidate();

void tlb_invalidate(void)
{
    cpu_arm920_tlb_invalidate_all();
}

static inline void cpu_arm920_tlb_invalidate_all(void)
{
__asm__(
    "mov r0, #0\n"
    "mcr p15, 0, r0, c7, c10, 4\n" //draim WB

    "mcr p15, 0, r0, c8, c7, 0\n" //invalidate I & D TLBs

        );
}


step3-->mmu_init()

static inline void arm920_setup(void)
{
    unsigned long ttb = MMU_TABLE_BASE;

__asm__(
    /* Invalidate caches */
    "mov r0, #0\n"
    "mcr p15, 0, r0, c7, c7, 0\n" /* invalidate I,D caches on v4 */
    "mcr p15, 0, r0, c7, c10, 4\n" /* drain write buffer on v4 */
    "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate I,D TLBs on v4 */
    /* Load page table pointer */
    "mov r4, %0\n"
    "mcr p15, 0, r4, c2, c0, 0\n" /* load page table pointer */
    /* Write domain id (cp15_r3) */
    "mvn r0, #0\n" /* Domains 0, 1 = client */
    "mcr p15, 0, r0, c3, c0, 0\n" /* load domain access register */
    /* Set control register v4 */
    "mrc p15, 0, r0, c1, c0, 0\n" /* get control register v4 */
    /* Clear out 'unwanted' bits (then put them in if we need them) */
                        /* .RVI ..RS B... .CAM */
    "bic r0, r0, #0x3000\n" /* ..11 .... .... .... */
    "bic r0, r0, #0x0300\n" /* .... ..11 .... .... */
    "bic r0, r0, #0x0087\n" /* .... .... 1... .111 */
    /* Turn on what we want */
    /* Fault checking enabled */
    "orr r0, r0, #0x0002\n" /* .... .... .... ..1. */
#ifdef CONFIG_CPU_D_CACHE_ON
    "orr r0, r0, #0x0004\n" /* .... .... .... .1.. */
#endif
#ifdef CONFIG_CPU_I_CACHE_ON
    "orr r0, r0, #0x1000\n" /* ...1 .... .... .... */
#endif
    /* MMU enabled */
    "orr r0, r0, #0x0001\n" /* .... .... .... ...1 */
    "mcr p15, 0, r0, c1, c0, 0\n" /* write control register */
    : /* no outputs */
    : "r" (ttb) );
}

void mmu_init(void)
{
    arm920_setup();
}

   以上的函数在vivi文件的mmu.h文件中。对于920T系列的arm处理器可以通用。
阅读(1649) | 评论(0) | 转发(0) |
0

上一篇:vivi-stage2-step2

下一篇:Gcc嵌入式汇编

给主人留下些什么吧!~~