armmmu_translate.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "KEHeader.h"
  5. extern uint64_t get_mpt(void);
  6. extern uint64_t kedump_mem_read(uint64_t data, unsigned long sz, void *buf);
  7. #if 0
  8. extern int sLOG(char *fmt, ...);
  9. #define LOG(fmt, ...) \
  10. do { \
  11. sLOG(fmt, ##__VA_ARGS__); \
  12. printf(fmt, ##__VA_ARGS__); \
  13. } while(0)
  14. #else
  15. #define LOG(fmt, ...)
  16. #endif
  17. static int read_mem(uint64_t paddr, void *buf, unsigned long size)
  18. {
  19. uint64_t ret = 0;
  20. ret = kedump_mem_read(paddr, size, buf);
  21. return (ret == size) ? 0 : -1;
  22. }
  23. #define PAGE_SIZE 4096
  24. #define PNUM_64 (PAGE_SIZE / sizeof(uint64_t))
  25. static uint64_t lxpage[PNUM_64];
  26. static uint64_t mmutable_64_translate_l3(uint64_t vptr,
  27. uint64_t ptable)
  28. {
  29. int ret = 0;
  30. uint64_t pa;
  31. unsigned int lxidx = (vptr >> 12) & 0x1ff;
  32. if (lxidx >= PNUM_64) {
  33. LOG("address:0x%llx index:%d overflow error\n", vptr, lxidx);
  34. return 0;
  35. }
  36. memset(lxpage, 0, PAGE_SIZE);
  37. ret = read_mem(ptable, lxpage, PAGE_SIZE);
  38. if (ret == 0) {
  39. LOG("(%d)ent value:0x%llx\n", lxidx, lxpage[lxidx]);
  40. } else {
  41. return 0;
  42. }
  43. switch(lxpage[lxidx] & 3) {
  44. case 3:
  45. pa = (lxpage[lxidx] & 0x0000fffffffff000)
  46. + (vptr & 0xfff);
  47. break;
  48. default:
  49. LOG("invalid (%d)ent value:0x%llx\n", lxidx,
  50. lxpage[lxidx]);
  51. pa = 0;
  52. }
  53. return pa;
  54. }
  55. static uint64_t mmutable_64_translate_l2(uint64_t vptr,
  56. uint64_t ptable)
  57. {
  58. int ret = 0;
  59. uint64_t pa;
  60. uint64_t next_table_address;
  61. unsigned int lxidx = (vptr >> 21) & 0x1ff;
  62. if (lxidx >= PNUM_64) {
  63. LOG("address:0x%llx index:%d overflow error\n", vptr, lxidx);
  64. return 0;
  65. }
  66. memset(lxpage, 0, PAGE_SIZE);
  67. ret = read_mem(ptable, lxpage, PAGE_SIZE);
  68. if (ret == 0) {
  69. LOG("(%d)ent value:0x%llx\n", lxidx, lxpage[lxidx]);
  70. } else {
  71. return 0;
  72. }
  73. switch(lxpage[lxidx] & 3) {
  74. case 1:
  75. pa = (lxpage[lxidx] & 0x0000ffffffe00000)
  76. + (vptr & 0x1fffff);
  77. break;
  78. case 3:
  79. next_table_address = lxpage[lxidx]
  80. & 0x0000fffffffff000;
  81. pa = mmutable_64_translate_l3(vptr,
  82. next_table_address);
  83. break;
  84. default:
  85. LOG("invalid (%d)ent value:0x%llx\n", lxidx,
  86. lxpage[lxidx]);
  87. pa = 0;
  88. }
  89. return pa;
  90. }
  91. static uint64_t mmutable_64_translate_l1(uint64_t vptr,
  92. uint64_t ptable)
  93. {
  94. int ret = 0;
  95. uint64_t pa;
  96. uint64_t next_table_address;
  97. unsigned int lxidx = (vptr >> 30) & 0x1ff;
  98. if (lxidx >= PNUM_64) {
  99. LOG("address:0x%llx index:%d overflow error\n", vptr, lxidx);
  100. return 0;
  101. }
  102. memset(lxpage, 0, PAGE_SIZE);
  103. ret = read_mem(ptable, lxpage, PAGE_SIZE);
  104. if (ret == 0) {
  105. LOG("(%d)ent value:0x%llx\n", lxidx, lxpage[lxidx]);
  106. } else {
  107. return 0;
  108. }
  109. switch(lxpage[lxidx] & 3) {
  110. case 1:
  111. pa = (lxpage[lxidx] & 0x0000ffffc0000000)
  112. + (vptr & 0x3fffffff);
  113. break;
  114. case 3:
  115. next_table_address = lxpage[lxidx]
  116. & 0x0000fffffffff000;
  117. pa = mmutable_64_translate_l2(vptr,
  118. next_table_address);
  119. break;
  120. default:
  121. LOG("invalid (%d)ent value:0x%llx\n", lxidx,
  122. lxpage[lxidx]);
  123. pa = 0;
  124. }
  125. return pa;
  126. }
  127. uint64_t v2p_64(uint64_t vptr)
  128. {
  129. uint64_t mpt = get_mpt();
  130. /* LOG("mater_page_table:0x%llx, vptr:0x%llx\n", mpt, vptr); */
  131. if ((vptr & 0x8000000000000000) != 0) {
  132. return mmutable_64_translate_l1(vptr, mpt);
  133. } else {
  134. LOG("illegal address:0x%llx\n", vptr);
  135. }
  136. return 0;
  137. }