vivi中mmu.c文件解读

本文介绍 ARM920T 处理器 MMU 的初始化过程,包括缓存清理、TLB 无效化、MMU 控制寄存器配置及内存映射等关键步骤,特别关注了段页表项的设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在ARM系统中,MMU通过页式虚拟存储管理,将虚拟空间和物理空间分别分成一个个固定大小的页,并建立两者之间的映射关系,从而实现虚拟地址到物理地址的转换。MMU还可完成存储器访问权限的控制和虚拟存储器空间缓冲特性的设置。

  1. * 2002-07-15: Janghoon Lyu <NANDY@MIZI.COM> 
  2.  *  
  3.  */  
  4.   
  5. #include "config.h"   
  6. #include "machine.h"   
  7. #include "mmu.h"   
  8. #include "vivi_string.h"   
  9.   
  10. static unsigned long *mmu_tlb_base = (unsigned long *) MMU_TABLE_BASE;  
  11.   
  12. /* 
  13.  * cpu_arm920_cache_clean_invalidate_all() 
  14.  * 
  15.  * clean and invalidate all cache lines 
  16.  * 
  17.  */  
  18. static inline void cpu_arm920_cache_clean_invalidate_all(void)  
  19. {  
  20. __asm__(   
  21.     "   mov r1, #0/n"  
  22.     "   mov r1, #7 << 5/n"          /* 8 segments */  
  23.     "1: orr r3, r1, #63 << 26/n"    /* 64 entries */  
  24.     "2: mcr p15, 0, r3, c7, c14, 2/n"   /* clean & invalidate D index *//*"c7,c14,2"清空并使无效数据cache中某块*/  
  25.                             /*Clean and Invalidate DCache entry (using index), s3c2410 user manual P551*/     
  26.                         /*Corperate Register 7 Index Format(arm r3):  
  27.                           [31:26]=Index,  [25:8, 4:0]=SBZ(should be zero),[7;5]=Segment 
  28.                           16k data cache = 8 segment, 1 segment = 64 lines, 1 line = 8 words*/  
  29.     "   subs    r3, r3, #1 << 26/n"  
  30.     "   bcs 2b/n"             /* entries 64 to 0 */  
  31.     "   subs    r1, r1, #1 << 5/n"  
  32.     "   bcs 1b/n"             /* segments 7 to 0 */  
  33.     "   mcr p15, 0, r1, c7, c5, 0/n"  /* invalidate I cache *//*s3c210 data sheet P551*/  
  34.     "   mcr p15, 0, r1, c7, c10, 4/n" /* drain WB(清空写缓冲区) *//*Will stop execution until the write buffer has drained.*/  
  35.     );  
  36. }  
  37.   
  38. void cache_clean_invalidate(void)  
  39. {  
  40.     cpu_arm920_cache_clean_invalidate_all();  
  41. }  
  42.   
  43. /* 
  44.  * cpu_arm920_tlb_invalidate_all() 
  45.  * 
  46.  * Invalidate all TLB entries 
  47.  */  
  48. static inline void cpu_arm920_tlb_invalidate_all(void)  
  49. {  
  50.     __asm__(  
  51.         "mov    r0, #0/n"  
  52.         "mcr    p15, 0, r0, c7, c10, 4/n"   /* drain WB */  
  53.         "mcr    p15, 0, r0, c8, c7, 0/n"    /* invalidate I & D TLBs *//*s3c2410 data sheet P546*/  
  54.         );  
  55. }  
  56.   
  57. void tlb_invalidate(void)  
  58. {  
  59.     cpu_arm920_tlb_invalidate_all();  
  60. }  
  61.   
  62. static inline void arm920_setup(void)  
  63. {  
  64.     unsigned long ttb = MMU_TABLE_BASE;  
  65.   
  66. __asm__(  
  67.     /* Invalidate caches */  
  68.     "mov    r0, #0/n"  
  69.     "mcr    p15, 0, r0, c7, c7, 0/n"    /* invalidate I,D caches on v4 */  
  70.     "mcr    p15, 0, r0, c7, c10, 4/n"   /* drain write buffer on v4 */  
  71.     "mcr    p15, 0, r0, c8, c7, 0/n"    /* invalidate I,D TLBs on v4 */  
  72.     /* Load page table pointer */  
  73.     "mov    r4, %0/n"  
  74.     "mcr    p15, 0, r4, c2, c0, 0/n"    /* load page table pointer */  
  75.     /* Write domain id (cp15_r3) */  
  76.     "mvn    r0, #0/n"           /* Domains 0, 1 = client *//*11=Manager*/  
  77.     "mcr    p15, 0, r0, c3, c0, 0/n"    /* load domain access register *//*write domain 15:0 access permissions P548*/  
  78.     /* Set control register v4 */  
  79.     "mrc    p15, 0, r0, c1, c0, 0/n"    /* get control register v4 *//*read control register P545*/  
  80.     /* Clear out 'unwanted' bits (then put them in if we need them) */  
  81.                         /* ..VI ..RS B... .CAM */ /*these bits's meanning are at data sheet P546*/  
  82.     "bic    r0, r0, #0x3000/n"      /* ..11 .... .... .... *//*I(bit[12])=0 = Instruction cache disabled*/  
  83.                     /*V[bit[13]](Base location of exception registers)=0 = Low addresses = 0x0000 0000*/  
  84.     "bic    r0, r0, #0x0300/n"      /* .... ..11 .... .... */  
  85.                     /*R(ROM protection bit[9])=0*/  
  86.                     /*S(System protection bit[8])=0*/  
  87.                     /*由于TTB中AP=0b11(line141),所以RS位不使用(P579)*/  
  88.     "bic    r0, r0, #0x0087/n"      /* .... .... 1... .111 */  
  89.                     /*M(bit[0])=0 = MMU disabled*/  
  90.                     /*A(bit[1])=0 =Data address alignment fault checking disable*/  
  91.                     /*C(bit[2])=0 = Data cache disabled*/  
  92.                     /*B(bit[7])=0 = Little-endian operation*/  
  93.     /* Turn on what we want */  
  94.     /* Fault checking enabled */  
  95.     "orr    r0, r0, #0x0002/n"      /* .... .... .... ..1. *//*A(bit[1])=1 = Data address alignment fault checking enable*/  
  96. #ifdef CONFIG_CPU_D_CACHE_ON        /*is not set*/   
  97.     "orr    r0, r0, #0x0004/n"      /* .... .... .... .1.. *//*C(bit[2])=1 = Data cache enabled*/  
  98. #endif     
  99. #ifdef CONFIG_CPU_I_CACHE_ON        /*is not set*/    
  100.     "orr    r0, r0, #0x1000/n"      /* ...1 .... .... .... *//*I(bit[12])=1 = Instruction cache enabled*/  
  101. #endif     
  102.     /* MMU enabled */  
  103.     "orr    r0, r0, #0x0001/n"      /* .... .... .... ...1 *//*M(bit[0])=1 = MMU enabled*/  
  104.     "mcr    p15, 0, r0, c1, c0, 0/n"    /* write control register *//*write control register P545*/  
  105.     : /* no outputs */  
  106.     : "r" (ttb) );  
  107. }  
  108.   
  109. void mmu_init(void)  
  110. {  
  111.     arm920_setup();  
  112. }  
  113.   
  114. #ifndef CONFIG_S3C2410_NAND_BOOT   
  115. static void copy_vivi_to_ram(void)  
  116. {  
  117.     putstr_hex("Evacuating 1MB of Flash to DRAM at 0x", VIVI_RAM_BASE);  
  118.     memcpy((void *)VIVI_RAM_BASE, (void *)VIVI_ROM_BASE, VIVI_RAM_SIZE);  
  119. }  
  120. #endif   
  121.   
  122.   
  123. /********************************************************************* 
  124. * 段页表项entry:[31:20]段基址,[11:10]为AP(控制访问权限),[8:5]域, 
  125. *   [3:2]=CP(decide cached&buffered),[1:0]=0b10-->页表为段 
  126. * MMU_SECDESC: 
  127. *   AP=0b11 
  128. *   DOMAIN=0 
  129. *   [1:0]=0b10--->页表为段 
  130. * MMU_CACHEABLE: 
  131. *   C=1(bit[3]) 
  132. * 
  133. * 本函数先将4G虚拟空间万全映射到相同的物理地址上:Section,not cacacheable, not bufferable 
  134. * 再修改虚拟地址0x30000000到0x33f00000,映射到SDRAM的64M物理地址:Section, cacacheable, not bufferable(即write-through mode,写通) 
  135. **********************************************************************/  
  136. static inline void mem_mapping_linear(void)  
  137. {  
  138.     unsigned long pageoffset, sectionNumber;  
  139.   
  140.     putstr_hex("MMU table base address = 0x", (unsigned long)mmu_tlb_base);  
  141.     /* 4G 虚拟地址映射到相同的物理地址. not cacacheable, not bufferable */  
  142.     for (sectionNumber = 0; sectionNumber < 4096; sectionNumber++) {  
  143.         pageoffset = (sectionNumber << 20);  
  144.         *(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC;  
  145.     }  
  146.   
  147.     /* make dram cacheable */  
  148.     /* SDRAM物理地址0x3000000-0x33ffffff,DRAM_BASE=0x30000000,DRAM_SIZE=64M*/  
  149.     for (pageoffset = DRAM_BASE; pageoffset < (DRAM_BASE+DRAM_SIZE); pageoffset += SZ_1M) {  
  150.         //DPRINTK(3, "Make DRAM section cacheable: 0x%08lx/n", pageoffset);   
  151.         *(mmu_tlb_base + (pageoffset >> 20)) = pageoffset | MMU_SECDESC | MMU_CACHEABLE;   
  152.     }  
  153. }  
  154.   
  155. static inline void nor_flash_mapping(void)  
  156. {  
  157.     unsigned long offset, cached_addr, uncached_addr;  
  158.   
  159.     cached_addr = FLASH_BASE;  
  160.     uncached_addr = FLASH_UNCACHED_BASE;  
  161.   
  162.     for (offset = 0; offset < FLASH_SIZE; offset += MMU_SECTION_SIZE) {   
  163.         cached_addr += offset;  
  164.         uncached_addr += offset;  
  165.         *(mmu_tlb_base + (cached_addr >> 20)) = /  
  166.                 (cached_addr | MMU_SECDESC | MMU_CACHEABLE);   
  167.         *(mmu_tlb_base + (uncached_addr >> 20)) = /  
  168.                 (cached_addr | MMU_SECDESC);  
  169.     }  
  170. }  
  171.   
  172. /* 
  173.  * PC蔼狼 疙矫利牢 函拳 绝捞 何飘肺歹啊 伐俊辑 角青登档废 
  174.  * Flash狼 何飘肺歹 康开阑 RAM狼 何飘肺歹 康开栏肺 概俏矫诺聪促. 
  175.  */  
  176. static inline void nor_flash_remapping(void)  
  177. {  
  178.     putstr_hex("Map flash virtual section to DRAM at 0x", VIVI_RAM_BASE);  
  179.     *(mmu_tlb_base + (VIVI_ROM_BASE >> 20)) = /  
  180.                 (VIVI_RAM_BASE | MMU_SECDESC | MMU_CACHEABLE);  
  181. }  
  182.   
  183. void mem_map_nand_boot(void)  
  184. {  
  185.     mem_mapping_linear();  
  186. }  
  187.   
  188. #ifndef CONFIG_S3C2410_NAND_BOOT   
  189. void mem_map_nor(void)  
  190. {  
  191.     copy_vivi_to_ram();  
  192.     mem_mapping_linear();  
  193.     nor_flash_mapping();  
  194.     nor_flash_remapping();  
  195. }  
  196. #endif   
  197.   
  198. void mem_map_init(void)  
  199. {  
  200. #ifdef CONFIG_S3C2410_NAND_BOOT /* CONFIG_S3C2410_NAND_BOOT=y */   
  201.     mem_map_nand_boot();    /* 最终调用mem_mepping_linear, 建立页表 */  
  202. #else   
  203.     mem_map_nor();  
  204. #endif   
  205.     cache_clean_invalidate();/* 清空cache,使无效cache */    
  206.     tlb_invalidate();   /* 使无效快表TLB */  
  207. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值