tlb.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright 2008 Freescale Semiconductor, Inc.
  3. *
  4. * (C) Copyright 2000
  5. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. */
  25. #include <common.h>
  26. #include <asm/processor.h>
  27. #include <asm/mmu.h>
  28. void set_tlb(u8 tlb, u32 epn, u64 rpn,
  29. u8 perms, u8 wimge,
  30. u8 ts, u8 esel, u8 tsize, u8 iprot)
  31. {
  32. u32 _mas0, _mas1, _mas2, _mas3, _mas7;
  33. _mas0 = FSL_BOOKE_MAS0(tlb, esel, 0);
  34. _mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize);
  35. _mas2 = FSL_BOOKE_MAS2(epn, wimge);
  36. _mas3 = FSL_BOOKE_MAS3(rpn, 0, perms);
  37. _mas7 = rpn >> 32;
  38. mtspr(MAS0, _mas0);
  39. mtspr(MAS1, _mas1);
  40. mtspr(MAS2, _mas2);
  41. mtspr(MAS3, _mas3);
  42. #ifdef CONFIG_ENABLE_36BIT_PHYS
  43. mtspr(MAS7, _mas7);
  44. #endif
  45. asm volatile("isync;msync;tlbwe;isync");
  46. }
  47. void disable_tlb(u8 esel)
  48. {
  49. u32 _mas0, _mas1, _mas2, _mas3, _mas7;
  50. _mas0 = FSL_BOOKE_MAS0(1, esel, 0);
  51. _mas1 = 0;
  52. _mas2 = 0;
  53. _mas3 = 0;
  54. _mas7 = 0;
  55. mtspr(MAS0, _mas0);
  56. mtspr(MAS1, _mas1);
  57. mtspr(MAS2, _mas2);
  58. mtspr(MAS3, _mas3);
  59. #ifdef CONFIG_ENABLE_36BIT_PHYS
  60. mtspr(MAS7, _mas7);
  61. #endif
  62. asm volatile("isync;msync;tlbwe;isync");
  63. }
  64. void invalidate_tlb(u8 tlb)
  65. {
  66. if (tlb == 0)
  67. mtspr(MMUCSR0, 0x4);
  68. if (tlb == 1)
  69. mtspr(MMUCSR0, 0x2);
  70. }
  71. void init_tlbs(void)
  72. {
  73. int i;
  74. for (i = 0; i < num_tlb_entries; i++) {
  75. set_tlb(tlb_table[i].tlb, tlb_table[i].epn, tlb_table[i].rpn,
  76. tlb_table[i].perms, tlb_table[i].wimge,
  77. tlb_table[i].ts, tlb_table[i].esel, tlb_table[i].tsize,
  78. tlb_table[i].iprot);
  79. }
  80. return ;
  81. }
  82. unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg)
  83. {
  84. unsigned int tlb_size;
  85. unsigned int ram_tlb_index;
  86. unsigned int ram_tlb_address;
  87. /*
  88. * Determine size of each TLB1 entry.
  89. */
  90. switch (memsize_in_meg) {
  91. case 16:
  92. case 32:
  93. tlb_size = BOOKE_PAGESZ_16M;
  94. break;
  95. case 64:
  96. case 128:
  97. tlb_size = BOOKE_PAGESZ_64M;
  98. break;
  99. case 256:
  100. case 512:
  101. tlb_size = BOOKE_PAGESZ_256M;
  102. break;
  103. case 1024:
  104. case 2048:
  105. if (PVR_VER(get_pvr()) > PVR_VER(PVR_85xx))
  106. tlb_size = BOOKE_PAGESZ_1G;
  107. else
  108. tlb_size = BOOKE_PAGESZ_256M;
  109. break;
  110. default:
  111. puts("DDR: only 16M, 32M, 64M, 128M, 256M, 512M, 1G"
  112. " and 2G are supported.\n");
  113. /*
  114. * The memory was not able to be mapped.
  115. * Default to a small size.
  116. */
  117. tlb_size = BOOKE_PAGESZ_64M;
  118. memsize_in_meg = 64;
  119. break;
  120. }
  121. /*
  122. * Configure DDR TLB1 entries.
  123. * Starting at TLB1 8, use no more than 8 TLB1 entries.
  124. */
  125. ram_tlb_index = 8;
  126. ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE;
  127. while (ram_tlb_address < (memsize_in_meg * 1024 * 1024)
  128. && ram_tlb_index < 16) {
  129. set_tlb(1, ram_tlb_address, ram_tlb_address,
  130. MAS3_SX|MAS3_SW|MAS3_SR, 0,
  131. 0, ram_tlb_index, tlb_size, 1);
  132. ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2));
  133. ram_tlb_index++;
  134. }
  135. /*
  136. * Confirm that the requested amount of memory was mapped.
  137. */
  138. return memsize_in_meg;
  139. }