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 "monitor/hmp-target.h"
  28. #include "monitor/monitor-internal.h"
  29. #include "qapi/error.h"
  30. #include "qapi/qmp/qdict.h"
  31. #include "sysemu/hw_accel.h"
  32. /* Set the current CPU defined by the user. Callers must hold BQL. */
  33. int monitor_set_cpu(Monitor *mon, int cpu_index)
  34. {
  35. CPUState *cpu;
  36. cpu = qemu_get_cpu(cpu_index);
  37. if (cpu == NULL) {
  38. return -1;
  39. }
  40. g_free(mon->mon_cpu_path);
  41. mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
  42. return 0;
  43. }
  44. /* Callers must hold BQL. */
  45. static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
  46. {
  47. CPUState *cpu = NULL;
  48. if (mon->mon_cpu_path) {
  49. cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path,
  50. TYPE_CPU, NULL);
  51. if (!cpu) {
  52. g_free(mon->mon_cpu_path);
  53. mon->mon_cpu_path = NULL;
  54. }
  55. }
  56. if (!mon->mon_cpu_path) {
  57. if (!first_cpu) {
  58. return NULL;
  59. }
  60. monitor_set_cpu(mon, first_cpu->cpu_index);
  61. cpu = first_cpu;
  62. }
  63. assert(cpu != NULL);
  64. if (synchronize) {
  65. cpu_synchronize_state(cpu);
  66. }
  67. return cpu;
  68. }
  69. CPUState *mon_get_cpu(Monitor *mon)
  70. {
  71. return mon_get_cpu_sync(mon, true);
  72. }
  73. CPUArchState *mon_get_cpu_env(Monitor *mon)
  74. {
  75. CPUState *cs = mon_get_cpu(mon);
  76. return cs ? cs->env_ptr : NULL;
  77. }
  78. int monitor_get_cpu_index(Monitor *mon)
  79. {
  80. CPUState *cs = mon_get_cpu_sync(mon, false);
  81. return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
  82. }
  83. void hmp_info_registers(Monitor *mon, const QDict *qdict)
  84. {
  85. bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
  86. int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
  87. CPUState *cs;
  88. if (all_cpus) {
  89. CPU_FOREACH(cs) {
  90. monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
  91. cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
  92. }
  93. } else {
  94. cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);
  95. if (!cs) {
  96. if (vcpu >= 0) {
  97. monitor_printf(mon, "CPU#%d not available\n", vcpu);
  98. } else {
  99. monitor_printf(mon, "No CPU available\n");
  100. }
  101. return;
  102. }
  103. monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
  104. cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
  105. }
  106. }
  107. static void memory_dump(Monitor *mon, int count, int format, int wsize,
  108. hwaddr addr, int is_physical)
  109. {
  110. int l, line_size, i, max_digits, len;
  111. uint8_t buf[16];
  112. uint64_t v;
  113. CPUState *cs = mon_get_cpu(mon);
  114. if (!cs && (format == 'i' || !is_physical)) {
  115. monitor_printf(mon, "Can not dump without CPU\n");
  116. return;
  117. }
  118. if (format == 'i') {
  119. monitor_disas(mon, cs, addr, count, is_physical);
  120. return;
  121. }
  122. len = wsize * count;
  123. if (wsize == 1) {
  124. line_size = 8;
  125. } else {
  126. line_size = 16;
  127. }
  128. max_digits = 0;
  129. switch(format) {
  130. case 'o':
  131. max_digits = DIV_ROUND_UP(wsize * 8, 3);
  132. break;
  133. default:
  134. case 'x':
  135. max_digits = (wsize * 8) / 4;
  136. break;
  137. case 'u':
  138. case 'd':
  139. max_digits = DIV_ROUND_UP(wsize * 8 * 10, 33);
  140. break;
  141. case 'c':
  142. wsize = 1;
  143. break;
  144. }
  145. while (len > 0) {
  146. if (is_physical) {
  147. monitor_printf(mon, HWADDR_FMT_plx ":", addr);
  148. } else {
  149. monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
  150. }
  151. l = len;
  152. if (l > line_size)
  153. l = line_size;
  154. if (is_physical) {
  155. AddressSpace *as = cs ? cs->as : &address_space_memory;
  156. MemTxResult r = address_space_read(as, addr,
  157. MEMTXATTRS_UNSPECIFIED, buf, l);
  158. if (r != MEMTX_OK) {
  159. monitor_printf(mon, " Cannot access memory\n");
  160. break;
  161. }
  162. } else {
  163. if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) {
  164. monitor_printf(mon, " Cannot access memory\n");
  165. break;
  166. }
  167. }
  168. i = 0;
  169. while (i < l) {
  170. switch(wsize) {
  171. default:
  172. case 1:
  173. v = ldub_p(buf + i);
  174. break;
  175. case 2:
  176. v = lduw_p(buf + i);
  177. break;
  178. case 4:
  179. v = (uint32_t)ldl_p(buf + i);
  180. break;
  181. case 8:
  182. v = ldq_p(buf + i);
  183. break;
  184. }
  185. monitor_printf(mon, " ");
  186. switch(format) {
  187. case 'o':
  188. monitor_printf(mon, "%#*" PRIo64, max_digits, v);
  189. break;
  190. case 'x':
  191. monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
  192. break;
  193. case 'u':
  194. monitor_printf(mon, "%*" PRIu64, max_digits, v);
  195. break;
  196. case 'd':
  197. monitor_printf(mon, "%*" PRId64, max_digits, v);
  198. break;
  199. case 'c':
  200. monitor_printc(mon, v);
  201. break;
  202. }
  203. i += wsize;
  204. }
  205. monitor_printf(mon, "\n");
  206. addr += l;
  207. len -= l;
  208. }
  209. }
  210. void hmp_memory_dump(Monitor *mon, const QDict *qdict)
  211. {
  212. int count = qdict_get_int(qdict, "count");
  213. int format = qdict_get_int(qdict, "format");
  214. int size = qdict_get_int(qdict, "size");
  215. target_long addr = qdict_get_int(qdict, "addr");
  216. memory_dump(mon, count, format, size, addr, 0);
  217. }
  218. void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
  219. {
  220. int count = qdict_get_int(qdict, "count");
  221. int format = qdict_get_int(qdict, "format");
  222. int size = qdict_get_int(qdict, "size");
  223. hwaddr addr = qdict_get_int(qdict, "addr");
  224. memory_dump(mon, count, format, size, addr, 1);
  225. }
  226. void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
  227. {
  228. Int128 gpa_region_size;
  229. MemoryRegionSection mrs = memory_region_find(get_system_memory(),
  230. addr, size);
  231. if (!mrs.mr) {
  232. error_setg(errp, "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
  233. return NULL;
  234. }
  235. if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
  236. error_setg(errp, "Memory at address 0x%" HWADDR_PRIx "is not RAM", addr);
  237. memory_region_unref(mrs.mr);
  238. return NULL;
  239. }
  240. gpa_region_size = int128_make64(size);
  241. if (int128_lt(mrs.size, gpa_region_size)) {
  242. error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
  243. " exceeded.", addr);
  244. memory_region_unref(mrs.mr);
  245. return NULL;
  246. }
  247. *p_mr = mrs.mr;
  248. return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
  249. }
  250. void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
  251. {
  252. hwaddr addr = qdict_get_int(qdict, "addr");
  253. Error *local_err = NULL;
  254. MemoryRegion *mr = NULL;
  255. void *ptr;
  256. ptr = gpa2hva(&mr, addr, 1, &local_err);
  257. if (local_err) {
  258. error_report_err(local_err);
  259. return;
  260. }
  261. monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx
  262. " (%s) is %p\n",
  263. addr, mr->name, ptr);
  264. memory_region_unref(mr);
  265. }
  266. void hmp_gva2gpa(Monitor *mon, const QDict *qdict)
  267. {
  268. target_ulong addr = qdict_get_int(qdict, "addr");
  269. MemTxAttrs attrs;
  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_attrs_debug(cs, addr & TARGET_PAGE_MASK, &attrs);
  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