2
0

hmp-cmds-target.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * Miscellaneous target-dependent HMP commands
  3. *
  4. * Copyright (c) 2003-2004 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "disas/disas.h"
  26. #include "exec/address-spaces.h"
  27. #include "exec/memory.h"
  28. #include "monitor/hmp-target.h"
  29. #include "monitor/monitor-internal.h"
  30. #include "qapi/error.h"
  31. #include "qobject/qdict.h"
  32. #include "system/hw_accel.h"
  33. /* Set the current CPU defined by the user. Callers must hold BQL. */
  34. int monitor_set_cpu(Monitor *mon, int cpu_index)
  35. {
  36. CPUState *cpu;
  37. cpu = qemu_get_cpu(cpu_index);
  38. if (cpu == NULL) {
  39. return -1;
  40. }
  41. g_free(mon->mon_cpu_path);
  42. mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
  43. return 0;
  44. }
  45. /* Callers must hold BQL. */
  46. static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
  47. {
  48. CPUState *cpu = NULL;
  49. if (mon->mon_cpu_path) {
  50. cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path,
  51. TYPE_CPU, NULL);
  52. if (!cpu) {
  53. g_free(mon->mon_cpu_path);
  54. mon->mon_cpu_path = NULL;
  55. }
  56. }
  57. if (!mon->mon_cpu_path) {
  58. if (!first_cpu) {
  59. return NULL;
  60. }
  61. monitor_set_cpu(mon, first_cpu->cpu_index);
  62. cpu = first_cpu;
  63. }
  64. assert(cpu != NULL);
  65. if (synchronize) {
  66. cpu_synchronize_state(cpu);
  67. }
  68. return cpu;
  69. }
  70. CPUState *mon_get_cpu(Monitor *mon)
  71. {
  72. return mon_get_cpu_sync(mon, true);
  73. }
  74. CPUArchState *mon_get_cpu_env(Monitor *mon)
  75. {
  76. CPUState *cs = mon_get_cpu(mon);
  77. return cs ? cpu_env(cs) : NULL;
  78. }
  79. int monitor_get_cpu_index(Monitor *mon)
  80. {
  81. CPUState *cs = mon_get_cpu_sync(mon, false);
  82. return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
  83. }
  84. void hmp_info_registers(Monitor *mon, const QDict *qdict)
  85. {
  86. bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
  87. int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
  88. CPUState *cs;
  89. if (all_cpus) {
  90. CPU_FOREACH(cs) {
  91. monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
  92. cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
  93. }
  94. } else {
  95. cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);
  96. if (!cs) {
  97. if (vcpu >= 0) {
  98. monitor_printf(mon, "CPU#%d not available\n", vcpu);
  99. } else {
  100. monitor_printf(mon, "No CPU available\n");
  101. }
  102. return;
  103. }
  104. monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
  105. cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
  106. }
  107. }
  108. static void memory_dump(Monitor *mon, int count, int format, int wsize,
  109. hwaddr addr, int is_physical)
  110. {
  111. int l, line_size, i, max_digits, len;
  112. uint8_t buf[16];
  113. uint64_t v;
  114. CPUState *cs = mon_get_cpu(mon);
  115. if (!cs && (format == 'i' || !is_physical)) {
  116. monitor_printf(mon, "Can not dump without CPU\n");
  117. return;
  118. }
  119. if (format == 'i') {
  120. monitor_disas(mon, cs, addr, count, is_physical);
  121. return;
  122. }
  123. len = wsize * count;
  124. if (wsize == 1) {
  125. line_size = 8;
  126. } else {
  127. line_size = 16;
  128. }
  129. max_digits = 0;
  130. switch(format) {
  131. case 'o':
  132. max_digits = DIV_ROUND_UP(wsize * 8, 3);
  133. break;
  134. default:
  135. case 'x':
  136. max_digits = (wsize * 8) / 4;
  137. break;
  138. case 'u':
  139. case 'd':
  140. max_digits = DIV_ROUND_UP(wsize * 8 * 10, 33);
  141. break;
  142. case 'c':
  143. wsize = 1;
  144. break;
  145. }
  146. while (len > 0) {
  147. if (is_physical) {
  148. monitor_printf(mon, HWADDR_FMT_plx ":", addr);
  149. } else {
  150. monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
  151. }
  152. l = len;
  153. if (l > line_size)
  154. l = line_size;
  155. if (is_physical) {
  156. AddressSpace *as = cs ? cs->as : &address_space_memory;
  157. MemTxResult r = address_space_read(as, addr,
  158. MEMTXATTRS_UNSPECIFIED, buf, l);
  159. if (r != MEMTX_OK) {
  160. monitor_printf(mon, " Cannot access memory\n");
  161. break;
  162. }
  163. } else {
  164. if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) {
  165. monitor_printf(mon, " Cannot access memory\n");
  166. break;
  167. }
  168. }
  169. i = 0;
  170. while (i < l) {
  171. switch(wsize) {
  172. default:
  173. case 1:
  174. v = ldub_p(buf + i);
  175. break;
  176. case 2:
  177. v = lduw_p(buf + i);
  178. break;
  179. case 4:
  180. v = (uint32_t)ldl_p(buf + i);
  181. break;
  182. case 8:
  183. v = ldq_p(buf + i);
  184. break;
  185. }
  186. monitor_printf(mon, " ");
  187. switch(format) {
  188. case 'o':
  189. monitor_printf(mon, "%#*" PRIo64, max_digits, v);
  190. break;
  191. case 'x':
  192. monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
  193. break;
  194. case 'u':
  195. monitor_printf(mon, "%*" PRIu64, max_digits, v);
  196. break;
  197. case 'd':
  198. monitor_printf(mon, "%*" PRId64, max_digits, v);
  199. break;
  200. case 'c':
  201. monitor_printc(mon, v);
  202. break;
  203. }
  204. i += wsize;
  205. }
  206. monitor_printf(mon, "\n");
  207. addr += l;
  208. len -= l;
  209. }
  210. }
  211. void hmp_memory_dump(Monitor *mon, const QDict *qdict)
  212. {
  213. int count = qdict_get_int(qdict, "count");
  214. int format = qdict_get_int(qdict, "format");
  215. int size = qdict_get_int(qdict, "size");
  216. target_long addr = qdict_get_int(qdict, "addr");
  217. memory_dump(mon, count, format, size, addr, 0);
  218. }
  219. void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
  220. {
  221. int count = qdict_get_int(qdict, "count");
  222. int format = qdict_get_int(qdict, "format");
  223. int size = qdict_get_int(qdict, "size");
  224. hwaddr addr = qdict_get_int(qdict, "addr");
  225. memory_dump(mon, count, format, size, addr, 1);
  226. }
  227. void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
  228. {
  229. Int128 gpa_region_size;
  230. MemoryRegionSection mrs = memory_region_find(get_system_memory(),
  231. addr, size);
  232. if (!mrs.mr) {
  233. error_setg(errp, "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
  234. return NULL;
  235. }
  236. if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
  237. error_setg(errp, "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr);
  238. memory_region_unref(mrs.mr);
  239. return NULL;
  240. }
  241. gpa_region_size = int128_make64(size);
  242. if (int128_lt(mrs.size, gpa_region_size)) {
  243. error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
  244. " exceeded.", addr);
  245. memory_region_unref(mrs.mr);
  246. return NULL;
  247. }
  248. *p_mr = mrs.mr;
  249. return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
  250. }
  251. void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
  252. {
  253. hwaddr addr = qdict_get_int(qdict, "addr");
  254. Error *local_err = NULL;
  255. MemoryRegion *mr = NULL;
  256. void *ptr;
  257. ptr = gpa2hva(&mr, addr, 1, &local_err);
  258. if (local_err) {
  259. error_report_err(local_err);
  260. return;
  261. }
  262. monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx
  263. " (%s) is %p\n",
  264. addr, mr->name, ptr);
  265. memory_region_unref(mr);
  266. }
  267. void hmp_gva2gpa(Monitor *mon, const QDict *qdict)
  268. {
  269. target_ulong addr = qdict_get_int(qdict, "addr");
  270. CPUState *cs = mon_get_cpu(mon);
  271. hwaddr gpa;
  272. if (!cs) {
  273. monitor_printf(mon, "No cpu\n");
  274. return;
  275. }
  276. gpa = cpu_get_phys_page_debug(cs, addr & TARGET_PAGE_MASK);
  277. if (gpa == -1) {
  278. monitor_printf(mon, "Unmapped\n");
  279. } else {
  280. monitor_printf(mon, "gpa: %#" HWADDR_PRIx "\n",
  281. gpa + (addr & ~TARGET_PAGE_MASK));
  282. }
  283. }
  284. #ifdef CONFIG_LINUX
  285. static uint64_t vtop(void *ptr, Error **errp)
  286. {
  287. uint64_t pinfo;
  288. uint64_t ret = -1;
  289. uintptr_t addr = (uintptr_t) ptr;
  290. uintptr_t pagesize = qemu_real_host_page_size();
  291. off_t offset = addr / pagesize * sizeof(pinfo);
  292. int fd;
  293. fd = open("/proc/self/pagemap", O_RDONLY);
  294. if (fd == -1) {
  295. error_setg_errno(errp, errno, "Cannot open /proc/self/pagemap");
  296. return -1;
  297. }
  298. /* Force copy-on-write if necessary. */
  299. qatomic_add((uint8_t *)ptr, 0);
  300. if (pread(fd, &pinfo, sizeof(pinfo), offset) != sizeof(pinfo)) {
  301. error_setg_errno(errp, errno, "Cannot read pagemap");
  302. goto out;
  303. }
  304. if ((pinfo & (1ull << 63)) == 0) {
  305. error_setg(errp, "Page not present");
  306. goto out;
  307. }
  308. ret = ((pinfo & 0x007fffffffffffffull) * pagesize) | (addr & (pagesize - 1));
  309. out:
  310. close(fd);
  311. return ret;
  312. }
  313. void hmp_gpa2hpa(Monitor *mon, const QDict *qdict)
  314. {
  315. hwaddr addr = qdict_get_int(qdict, "addr");
  316. Error *local_err = NULL;
  317. MemoryRegion *mr = NULL;
  318. void *ptr;
  319. uint64_t physaddr;
  320. ptr = gpa2hva(&mr, addr, 1, &local_err);
  321. if (local_err) {
  322. error_report_err(local_err);
  323. return;
  324. }
  325. physaddr = vtop(ptr, &local_err);
  326. if (local_err) {
  327. error_report_err(local_err);
  328. } else {
  329. monitor_printf(mon, "Host physical address for 0x%" HWADDR_PRIx
  330. " (%s) is 0x%" PRIx64 "\n",
  331. addr, mr->name, (uint64_t) physaddr);
  332. }
  333. memory_region_unref(mr);
  334. }
  335. #endif