历史上的今天
返回首页

历史上的今天

今天是:2025年06月04日(星期三)

正在发生

2018年06月04日 | S3C2440之MMU驱动代码模板(RealView MDK)

2018-06-04 来源:eefocus

好记心不如烂笔头,为方便以后查看代码及代码重复利用,这里贴出自己写的S3C2440 MMU代码库。使用友善MINI2440开发板,开发环境为RealView MDK 4.22。

该源码结构简单明了,原始工程下载地址:点击打开链接


Register 0, ID code register:


  1. unsigned int MMU_ReadID(void)  

  2. {  

  3.     unsigned int id;  

  4.     __asm("mrc p15, 0, id, c0, c0, 0");  

  5.     return id;  

  6. }  


Register 0, cache type register:



  1. unsigned int MMU_ReadCacheType(void)  

  2. {  

  3.     unsigned int type;  

  4.     __asm("mrc p15, 0, type, c0, c0, 1");  

  5.     return type;  

  6. }  


Register 1, control register:



  1. void MMU_EnterFastBusMode(void)  

  2. {  

  3.     unsigned int r0;  

  4.     __asm{  

  5.         mrc p15, 0, r0, c1, c0, 0  

  6.         bic r0, r0, #(3<<30)  

  7.         mcr p15, 0, r0, c1, c0, 0  

  8.     }  

  9. }  

  10.   

  11. void MMU_EnterSyncMode(void)  

  12. {  

  13.     unsigned int r0;  

  14.     __asm{  

  15.         mrc p15, 0, r0, c1, c0, 0  

  16.         bic r0, r0, #(1<<31)  

  17.         orr r0, r0, #(1<<30)  

  18.         mcr p15, 0, r0, c1, c0, 0  

  19.     }  

  20. }  

  21.   

  22. void MMU_EnterAsyncMode(void)  

  23. {  

  24.     unsigned int r0;  

  25.     __asm{  

  26.         mrc p15, 0, r0, c1, c0, 0  

  27.         orr r0, r0, #(11<<30)  

  28.         mcr p15, 0, r0, c1, c0, 0  

  29.     }  

  30. }  

  31.   

  32.   

  33. void MMU_EnableICache(void)  

  34. {  

  35.     unsigned int r0;  

  36.     __asm{  

  37.         mrc p15, 0, r0, c1, c0, 0  

  38.         orr r0, r0, #(1<<12)  

  39.         mcr p15, 0, r0, c1, c0, 0  

  40.     }  

  41. }  

  42.   

  43.   

  44. void MMU_DisableICache(void)  

  45. {  

  46.     unsigned int r0;  

  47.     __asm{  

  48.         mrc p15, 0, r0, c1, c0, 0  

  49.         bic r0, r0, #(1<<12)  

  50.         mcr p15, 0, r0, c1, c0, 0  

  51.     }  

  52. }  

  53.   

  54.   

  55. void MMU_EnableDCache(void)  

  56. {  

  57.     unsigned int r0;  

  58.     __asm{  

  59.         mrc p15, 0, r0, c1, c0, 0  

  60.         orr r0, r0, #(1<<2)  

  61.         mcr p15, 0, r0, c1, c0, 0  

  62.     }  

  63. }  

  64.   

  65.   

  66. void MMU_DisableDCache(void)  

  67. {  

  68.     unsigned int r0;  

  69.     __asm{  

  70.         mrc p15, 0, r0, c1, c0, 0  

  71.         bic r0, r0, #(1<<2)  

  72.         mcr p15, 0, r0, c1, c0, 0  

  73.     }  

  74. }  

  75.   

  76. void MMU_EnableAlignFault(void)  

  77. {  

  78.     unsigned int r0;  

  79.     __asm{  

  80.         mrc p15, 0, r0, c1, c0, 0  

  81.         orr r0, r0, #(1<<1)  

  82.         mcr p15, 0, r0, c1, c0, 0  

  83.     }  

  84. }  

  85.   

  86.   

  87. void MMU_DisableAlignFault(void)  

  88. {  

  89.     unsigned int r0;  

  90.     __asm{  

  91.         mrc p15, 0, r0, c1, c0, 0  

  92.         bic r0, r0, #(1<<1)  

  93.         mcr p15, 0, r0, c1, c0, 0  

  94.     }  

  95. }  

  96.   

  97. void MMU_Enable(void)  

  98. {  

  99.     unsigned int r0;  

  100.     __asm{  

  101.         mrc p15, 0, r0, c1, c0, 0  

  102.         orr r0, r0, #1  

  103.         mcr p15, 0, r0, c1, c0, 0  

  104.     }  

  105. }  

  106.   

  107.   

  108. void MMU_Disable(void)  

  109. {  

  110.     unsigned int r0;  

  111.     __asm{  

  112.         mrc p15, 0, r0, c1, c0, 0  

  113.         bic r0, r0, #1  

  114.         mcr p15, 0, r0, c1, c0, 0  

  115.     }  

  116. }  


Register 2, translation table base (TTB) register:


  1. void MMU_SetTTB(void)  

  2. {  

  3.     unsigned int r0 = (unsigned int)TTB;  

  4.     __asm("mcr p15, 0, r0, c2, c0, 0");  

  5. }  


Register 3, domain access control register:


  1. void MMU_SetDomain(unsigned int domain)  

  2. {  

  3.     __asm("mcr p15, 0, domain, c3, c0, 0");  

  4. }  


Register 7, cache operations register:


  1. void MMU_InvalidICacheDCache(void)  

  2. {  

  3.     unsigned int r0 = 0;  

  4.       

  5.     __asm("mcr p15, 0, r0, c7, c7, 0");  

  6. }  

  7.   

  8. void MMU_InvalidICache(void)  

  9. {  

  10.     unsigned int r0 = 0;  

  11.       

  12.     __asm("mcr p15, 0, r0, c7, c5, 0");  

  13. }  

  14.   

  15. void MMU_InvalidICacheSingleEntry(unsigned int MVA)  

  16. {  

  17.     __asm("mcr p15, 0, MVA, c7, c5, 1");  

  18. }  

  19.   

  20. void MMU_PrefechICacheLine(unsigned int MVA)  

  21. {  

  22.     __asm("mcr p15, 0, MVA, c7, c13, 1");  

  23. }  

  24.   

  25. void MMU_InvalidDCache(void)  

  26. {  

  27.     unsigned int r0 = 0;  

  28.       

  29.     __asm("mcr p15, 0, r0, c7, c6, 0");  

  30. }  

  31.   

  32. void MMU_InvalidDCacheSingleEntry(unsigned int MVA)  

  33. {  

  34.     __asm("mcr p15, 0, MVA, c7, c6, 1");  

  35. }  

  36.   

  37. void MMU_CleanDCacheSingleEntry(unsigned int MVA)  

  38. {  

  39.     __asm("mcr p15, 0, MVA, c7, c10, 1");  

  40. }  

  41.   

  42. void MMU_CleanInvalidDCacheEntry(unsigned int MVA)  

  43. {  

  44.     __asm("mcr p15, 0, MVA, c7, c14, 1");  

  45. }  

  46.   

  47. void MMU_CleanDCacheSingleEntry2(unsigned int index)  

  48. {  

  49.     __asm("mcr p15, 0, index, c7, c10, 2");  

  50. }  

  51.   

  52. void MMU_CleanInvalidDCacheEntry2(unsigned int index)  

  53. {  

  54.     __asm("mcr p15, 0, index, c7, c14, 2");  

  55. }  

  56.   

  57. void MMU_DrainWriteBuffer(void)  

  58. {  

  59.     unsigned int r0 = 0;  

  60.       

  61.     __asm("mcr p15, 0, r0, c7, c10, 4");  

  62. }  

  63.   

  64. void MMU_WaitForInterrupt(void)  

  65. {  

  66.     unsigned int r0 = 0;  

  67.       

  68.     __asm("mcr p15, 0, r0, c7, c0, 4");  

  69. }  



Register 8, TLB operations register:


  1. void MMU_InvalidAllTLB(void)  

  2. {  

  3.     unsigned int r0 = 0;  

  4.       

  5.     __asm("mcr p15, 0, r0, c8, c7, 0");  

  6. }  

  7.   

  8. void MMU_InvalidITLB(void)  

  9. {  

  10.     unsigned int r0 = 0;  

  11.       

  12.     __asm("mcr p15, 0, r0, c8, c5, 0");  

  13. }  

  14.   

  15. void MMU_InvalidITLBSingleEntry(unsigned int MVA)  

  16. {  

  17.     __asm("mcr p15, 0, MVA, c8, c5, 1");  

  18. }  

  19.   

  20. void MMU_InvalidDTLB(void)  

  21. {  

  22.     unsigned int r0 = 0;  

  23.       

  24.     __asm("mcr p15, 0, r0, c8, c6, 0");  

  25. }  

  26.   

  27. void MMU_InvalidDTLBSingleEntry(unsigned int MVA)  

  28. {  

  29.     __asm("mcr p15, 0, MVA, c8, c6, 1");  

  30. }  


Register 9, cache lockdown register:


  1. unsigned int MMU_ReadDCacheLockdownBase(void)  

  2. {  

  3.     unsigned int r0;  

  4.       

  5.     __asm("mrc p15, 0, r0, c9, c0, 0");  

  6.     r0 >>= 26;  

  7.       

  8.     return r0;  

  9. }  

  10.   

  11. void MMU_WriteDCacheLockdownBase(unsigned int index)  

  12. {  

  13.     index <<= 26;  

  14.     __asm("mcr p15, 0, index, c9, c0, 0");  

  15. }  

  16.   

  17.   

  18. unsigned int MMU_ReadICacheLockdownBase(void)  

  19. {  

  20.     unsigned int r0;  

  21.       

  22.     __asm("mrc p15, 0, r0, c9, c0, 1");  

  23.     r0 >>= 26;  

  24.       

  25.     return r0;  

  26. }  

  27.   

  28. void MMU_WriteICacheLockdownBase(unsigned int index)  

  29. {  

  30.     index <<= 26;  

  31.     __asm("mcr p15, 0, index, c9, c0, 1");  

  32. }  


Register 13, FCSE PID register:


  1. unsigned int MMU_ReadPID(void)  

  2. {  

  3.     unsigned int pid;  

  4.       

  5.     __asm("mrc p15, 0, pid, c13, c0, 0");  

  6.       

  7.     return (pid >> 25);  

  8. }  

  9.   

  10. void MMU_WritePID(unsigned int pid)  

  11. {  

  12.     pid <<= 25;  

  13.     __asm("mcr p15, 0, pid, c13, c0, 0");  

  14. }  


设置Memory Translation Table:


  1. void MMU_SetMTT(unsigned int vStart, unsigned int vEnd, unsigned int pStart, unsigned int attr)  

  2. {  

  3.     unsigned int vaddr, paddr;  

  4.       

  5.     vaddr = vStart;  

  6.     paddr = pStart;  

  7.     while(vaddr != (vEnd + 1))  

  8.     {  

  9.         TTB[vaddr >> 20] = (paddr & 0xFFF00000) | attr;  

  10.         vaddr += 0x100000;  

  11.         paddr += 0x100000;  

  12.     }  

  13. }  


MMU初始化:


  1. void MMU_Init(void)  

  2. {  

  3.     MMU_DisableICache();  

  4.     MMU_DisableDCache();  

  5.       

  6.     MMU_SetTTB();  

  7.     MMU_SetDomain(0xFFFFFFFF);  

  8.     MMU_InvalidAllTLB();  

  9.     MMU_EnableAlignFault();  

  10.       

  11.     MMU_SetMTT(0x00000000, 0x001FFFFF, 0x00000000, RW_CB);  

  12.     MMU_SetMTT(0x30000000, 0x33FFFFFF, 0x30000000, RW_CB);  

  13.     MMU_SetMTT(0x40000000, 0x4FFFFFFF, 0x40000000, RW_NCNB);  

  14.     MMU_SetMTT(0x50000000, 0x5FFFFFFF, 0x50000000, RW_NCNB);  

  15.       

  16.     MMU_EnableICache();  

  17.     MMU_EnableDCache();  

  18.     MMU_Enable();  

  19. }  


在本代码中需要注意的是,如果直接使用S3C2440.s的话,在C代码中调用上述代码会导致Undefine异常。因为进入main()之前,启动代码已经将处理器模式设置为USER模式了,而在USER模式下是无法操作CP15处理器的,所以产生异常。如果要在C中正常调用上述嵌入汇编,则需要将启动代码S3C2440.s中处理器模式设置为USER模式的那段代码注释掉,直接以SVC模式运行,就能正常执行,如下:


  1. ;  Enter Supervisor Mode and set its Stack Pointer  

  2.                 MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit  

  3.                 MOV     SP, R0  

  4.                 SUB     R0, R0, #SVC_Stack_Size  

  5.   

  6. ;  Enter User Mode and set its Stack Pointer  

  7. ;                MSR     CPSR_c, #Mode_USR  

  8. ;                MOV     SP, R0  

  9. ;                SUB     SL, SP, #USR_Stack_Size  

  10.   

  11. ;  Enter User Mode and set its Stack Pointer  

  12. ;                MSR     CPSR_c, #Mode_USR  

  13. ;                IF      :DEF:__MICROLIB  

  14.   

  15. ;                EXPORT __initial_sp  

  16.   

  17. ;                ELSE  

  18.   

  19. ;                MOV     SP, R0  

  20. ;                SUB     SL, SP, #USR_Stack_Size  

  21.   

  22. ;                ENDIF  


或者不修改处理器模式,而直接将以下汇编插入到S3C2440.s中Clock设置代码的后面,一样能运行:


  1. mrc p15, 0, r0, c1, c0, 0   

  2. orr r0, r0, #0xc0000000   

  3. mcr p15, 0, r0, c1, c0, 0   



推荐阅读

史海拾趣

永源微电子(APM)公司的发展小趣事

随着产品线的拓展和技术实力的增强,永源微电子开始积极拓展市场。公司在台湾、深圳、香港、无锡等地设立了研发与销售中心,通过多渠道的市场推广和品牌建设活动,不断提升“APM”品牌的知名度和影响力。同时,永源微电子还积极参加国内外电子行业的展会和交流活动,与业界同行建立了广泛的合作关系,进一步拓展了公司的市场版图。

ETL semiconductor公司的发展小趣事

AMD(Advanced Micro Devices)在半导体行业中的发展经历了一个从追赶到逆袭的过程。在英特尔的强大市场压力下,AMD通过不断创新和技术提升,逐渐在处理器市场上获得了一席之地。尤其是在游戏和高端计算领域,AMD的处理器凭借其出色的性能和性价比赢得了众多消费者的青睐。

Gore公司的发展小趣事
在隔离型中压大容量直流变换器中,可能存在直流偏磁问题,导致变压器磁路饱和、励磁电流增加、局部过热和噪声增大等问题。
HALO Electronics公司的发展小趣事
由于直流侧电压被分成上、下两个部分,如何保持上、下直流侧电压的动态平衡是一个重要问题。中点电位的低频振荡和中点偏移都可能影响输出电压的波形和系统的稳定性。
Delkin Devices公司的发展小趣事

Delkin Devices公司成立于1986年,总部设在美国加利福尼亚州的圣迭戈市。公司由一群富有远见和创造力的工程师和企业家创立,他们看到了未来数据存储技术的巨大潜力。在创立初期,Delkin Devices专注于研发和生产高质量的闪存存储设备,以满足当时市场对数据存储不断增长的需求。通过不断的技术创新和优质的客户服务,Delkin Devices逐渐在电子行业中崭露头角。

Blue Giga公司的发展小趣事

随着技术的不断进步,Blue Giga在无线网络连接领域取得了重要突破。其研发的超低功耗Bluetooth Smart和Bluetooth Classic模块,以及Wi-Fi模块,受到了市场的广泛欢迎。同时,公司还推出了配套的软件栈、开发工具和SDK,进一步丰富了产品线,满足了不同领域的需求。

问答坊 | AI 解惑

電解電容爆裂!

請教各位 電解電容爆裂,除了受高壓導致,還有其他什麽因素會導致? 另外電解電容得頂部有“人”或”+“的凹槽樣,是有什麽作用的? 謝謝…

查看全部问答>

WIFE不能记住登录过的网络和密码

我现在的WIFE登录后,重新开机发现不能记住上次我成功登录的网络,密码也不会记,用户使用起来很麻烦。 我也看到别人的机器上能够保存,我找了一下,好象是在PUBLIC下面的NETUI里面实现的,不知道哪位仁兄做过,赐教一下 或是微软有更新过这里, ...…

查看全部问答>

[在线讨论]wince下能否支持JavaScript?

如题,var myTextField=document.getElementById(\"myText\"); 这个没法实现。要是能实现该如何做? 看了yudong54的回帖(http://topic.eeworld.net/u/20091116/14/1b2cc357-3aea-4329-b527-ab7828142f8f.html?26416)说要打08年的补丁和09年一月 ...…

查看全部问答>

移植人脸识别程序到ARM处理器

本人有人脸识别的源代码,需要移植到ARM处理器,希望能够找到人脸识别方面的朋友共同讨论切磋技术问题。…

查看全部问答>

VxWorks下的打印机并口问题

大家好. 我碰到了一个vxworks中打印机方面的问题.我的目标机是pc486, TornadoV2.02, 24针老式打印机EPSON LQ-1600K,用telnet 进行连接调试.BUILD中包含了并口组件.现在我想要让打印机打出一些测试文字,然后我写了一小段代码 ******************** ...…

查看全部问答>

承接电子设计(单片机)项目

承接电子设计(单片机)项目 (一)、PCB LAYOUT(2层 or 4层) 老牛承接专业抄板、画板,质优价廉,可每天查看画板进度,有问题及时沟通。 可加我QQ看画过的样板,因为老牛是个人接活,所以价钱肯定比抄板公司低,希望各位同行有活之余多多照顾。 ...…

查看全部问答>

飞思卡尔底盘与安全微控制器

ftf上一个突出的主题就是汽车电子,而汽车安全自然是一个重要的问题,飞思卡尔提供了完整的解决方案…

查看全部问答>

学习心得:PWM模块的学习和使用

最近在使用TI的stellaris的芯片,项目主要用来做系统的控制模块,M3的外设基本都用到了,后面一点点总结各个模块简单的用法,并附上之前搜集和学习的资料,方便大家学习特别适合新手的入门学习,共同进步吧,感觉自己也还属于菜鸟级的呢,同时也感 ...…

查看全部问答>

STM32接光纤模块构建以太网,官方参考电路板的PHY片子DP83848CVV可以接光纤模块吗?

我用的方案是STM32F107+DP83848CVV+OCM2521,DP83848是官方的电路图使用的PHY,但是官方的电路图接的是RJ45电口,我想用DP83848CVV接光纤模块,光纤模块用的是OCM2521多模光纤,但是现在一直无法连通,光纤链路的灯都不亮。 我阅读了DP83848CVV的 ...…

查看全部问答>