S3C2440 MMU driver code template (RealView MDK)

Publisher:ZhenxiangLatest update time:2018-06-04 Source: eefocusKeywords:S3C2440  MMU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

A good memory is not as good as a bad pen. In order to facilitate the code review and code reuse in the future, here is the S3C2440 MMU code library I wrote. I used the friendly MINI2440 development board and the development environment was RealView MDK 4.22.

The source code structure is simple and clear. The original project download address: click to open the link


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. }  


Setting up the 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 initialization:


  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. }  


It should be noted that if S3C2440.s is used directly, calling the above code in C code will cause an Undefine exception. This is because before entering main(), the startup code has set the processor mode to USER mode, and the CP15 processor cannot be operated in USER mode, so an exception occurs. If you want to call the above embedded assembly normally in C, you need to comment out the code in the startup code S3C2440.s that sets the processor mode to USER mode, and run it directly in SVC mode, and it will execute normally, as follows:


  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  


Or you can insert the following assembly directly after the Clock setting code in S3C2440.s without changing the processor mode, and it will work just the same:


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

  2. orr r0, r0, #0xc0000000   

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



Keywords:S3C2440  MMU Reference address:S3C2440 MMU driver code template (RealView MDK)

Previous article:S3C2440 UART driver code template (RealView MDK)
Next article:S3C2440 LCD driver code template (RealView MDK)

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号