mmu.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*****************************************************************
  2. * mmu.c
  3. * by Zhiyi Huang, [email protected]
  4. * University of Otago
  5. *
  6. ********************************************************************/
  7. #include "types.h"
  8. #include "defs.h"
  9. #include "memlayout.h"
  10. #include "mmu.h"
  11. void mmuinit0(void)
  12. {
  13. pde_t *l1;
  14. pte_t *l2;
  15. uint pa, va, *p;
  16. // diable mmu
  17. // use inline assembly here as there is a limit on
  18. // branch distance after mmu is disabled
  19. asm volatile("mrc p15, 0, r1, c1, c0, 0\n\t"
  20. "bic r1,r1,#0x00000004\n\t"
  21. "bic r1,r1,#0x00001000\n\t"
  22. "bic r1,r1,#0x00000800\n\t"
  23. "bic r1,r1,#0x00000001\n\t"
  24. "mcr p15, 0, r1, c1, c0, 0\n\t"
  25. "mov r0, #0\n\t"
  26. "mcr p15, 0, r0, c7, c7, 0\n\t"
  27. "mcr p15, 0, r0, c8, c7, 0\n\t"
  28. ::: "r0", "r1", "cc", "memory");
  29. for(p=(uint *)0x2000; p<(uint *)0x8000; p++) *p = 0;
  30. l1 = (pde_t *) K_PDX_BASE;
  31. l2 = (pte_t *) K_PTX_BASE;
  32. // map all of ram at KERNBASE
  33. va = KERNBASE;
  34. for(pa = PA_START; pa < PA_START+RAMSIZE; pa += MBYTE){
  35. l1[PDX(va)] = pa|DOMAIN0|PDX_AP(K_RW)|SECTION|CACHED|BUFFERED;
  36. va += MBYTE;
  37. }
  38. // identity map first MB of ram so mmu can be enabled
  39. l1[PDX(PA_START)] = PA_START|DOMAIN0|PDX_AP(K_RW)|SECTION|CACHED|BUFFERED;
  40. // map IO region
  41. va = DEVSPACE;
  42. for(pa = PHYSIO; pa < PHYSIO+IOSIZE; pa += MBYTE){
  43. l1[PDX(va)] = pa|DOMAIN0|PDX_AP(K_RW)|SECTION;
  44. va += MBYTE;
  45. }
  46. // map GPU memory
  47. va = GPUMEMBASE;
  48. for(pa = GPUMEMBASE; pa < (uint)GPUMEMBASE+(uint)GPUMEMSIZE; pa += MBYTE){
  49. l1[PDX(va)] = pa|DOMAIN0|PDX_AP(K_RW)|SECTION;
  50. va += MBYTE;
  51. }
  52. // double map exception vectors at top of virtual memory
  53. va = HVECTORS;
  54. l1[PDX(va)] = (uint)l2|DOMAIN0|COARSE;
  55. l2[PTX(va)] = PA_START|PTX_AP(K_RW)|SMALL;
  56. asm volatile("mov r1, #1\n\t"
  57. "mcr p15, 0, r1, c3, c0\n\t"
  58. "mov r1, #0x4000\n\t"
  59. "mcr p15, 0, r1, c2, c0\n\t"
  60. "mrc p15, 0, r0, c1, c0, 0\n\t"
  61. "mov r1, #0x00002000\n\t"
  62. "orr r1, #0x00000004\n\t"
  63. "orr r1, #0x00001000\n\t"
  64. "orr r1, #0x00000001\n\t"
  65. "orr r0, r1\n\t"
  66. "mcr p15, 0, r0, c1, c0, 0\n\t"
  67. "mov r1, #1\n\t"
  68. "mcr p15, 0, r1, c15, c12, 0\n\t"
  69. ::: "r0", "r1", "cc", "memory");
  70. }
  71. void
  72. mmuinit1(void)
  73. {
  74. pde_t *l1;
  75. uint va1, va2;
  76. l1 = (pde_t*)(K_PDX_BASE);
  77. // undo identity map of first MB of ram
  78. l1[PDX(PA_START)] = 0;
  79. // drain write buffer; writeback data cache range [va, va+n]
  80. va1 = (uint)&l1[PDX(PA_START)];
  81. va2 = va1 + sizeof(pde_t);
  82. va1 = va1 & ~((uint)CACHELINESIZE-1);
  83. va2 = va2 & ~((uint)CACHELINESIZE-1);
  84. flush_dcache(va1, va2);
  85. // invalidate TLB; DSB barrier used
  86. flush_tlb();
  87. }