xref: /openbmc/qemu/target/i386/monitor.c (revision b4b9a0e3)
1 /*
2  * QEMU monitor
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 
25 #include "qemu/osdep.h"
26 #include "cpu.h"
27 #include "monitor/monitor.h"
28 #include "monitor/hmp-target.h"
29 #include "monitor/hmp.h"
30 #include "qapi/qmp/qdict.h"
31 #include "qapi/qmp/qerror.h"
32 #include "sysemu/kvm.h"
33 #include "qapi/error.h"
34 #include "qapi/qapi-commands-misc-target.h"
35 #include "qapi/qapi-commands-misc.h"
36 #include "hw/i386/pc.h"
37 
38 /* Perform linear address sign extension */
39 static hwaddr addr_canonical(CPUArchState *env, hwaddr addr)
40 {
41 #ifdef TARGET_X86_64
42     if (env->cr[4] & CR4_LA57_MASK) {
43         if (addr & (1ULL << 56)) {
44             addr |= (hwaddr)-(1LL << 57);
45         }
46     } else {
47         if (addr & (1ULL << 47)) {
48             addr |= (hwaddr)-(1LL << 48);
49         }
50     }
51 #endif
52     return addr;
53 }
54 
55 static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
56                       hwaddr pte, hwaddr mask)
57 {
58     addr = addr_canonical(env, addr);
59 
60     monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx
61                    " %c%c%c%c%c%c%c%c%c\n",
62                    addr,
63                    pte & mask,
64                    pte & PG_NX_MASK ? 'X' : '-',
65                    pte & PG_GLOBAL_MASK ? 'G' : '-',
66                    pte & PG_PSE_MASK ? 'P' : '-',
67                    pte & PG_DIRTY_MASK ? 'D' : '-',
68                    pte & PG_ACCESSED_MASK ? 'A' : '-',
69                    pte & PG_PCD_MASK ? 'C' : '-',
70                    pte & PG_PWT_MASK ? 'T' : '-',
71                    pte & PG_USER_MASK ? 'U' : '-',
72                    pte & PG_RW_MASK ? 'W' : '-');
73 }
74 
75 static void tlb_info_32(Monitor *mon, CPUArchState *env)
76 {
77     unsigned int l1, l2;
78     uint32_t pgd, pde, pte;
79 
80     pgd = env->cr[3] & ~0xfff;
81     for(l1 = 0; l1 < 1024; l1++) {
82         cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
83         pde = le32_to_cpu(pde);
84         if (pde & PG_PRESENT_MASK) {
85             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
86                 /* 4M pages */
87                 print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1));
88             } else {
89                 for(l2 = 0; l2 < 1024; l2++) {
90                     cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
91                     pte = le32_to_cpu(pte);
92                     if (pte & PG_PRESENT_MASK) {
93                         print_pte(mon, env, (l1 << 22) + (l2 << 12),
94                                   pte & ~PG_PSE_MASK,
95                                   ~0xfff);
96                     }
97                 }
98             }
99         }
100     }
101 }
102 
103 static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
104 {
105     unsigned int l1, l2, l3;
106     uint64_t pdpe, pde, pte;
107     uint64_t pdp_addr, pd_addr, pt_addr;
108 
109     pdp_addr = env->cr[3] & ~0x1f;
110     for (l1 = 0; l1 < 4; l1++) {
111         cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
112         pdpe = le64_to_cpu(pdpe);
113         if (pdpe & PG_PRESENT_MASK) {
114             pd_addr = pdpe & 0x3fffffffff000ULL;
115             for (l2 = 0; l2 < 512; l2++) {
116                 cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
117                 pde = le64_to_cpu(pde);
118                 if (pde & PG_PRESENT_MASK) {
119                     if (pde & PG_PSE_MASK) {
120                         /* 2M pages with PAE, CR4.PSE is ignored */
121                         print_pte(mon, env, (l1 << 30) + (l2 << 21), pde,
122                                   ~((hwaddr)(1 << 20) - 1));
123                     } else {
124                         pt_addr = pde & 0x3fffffffff000ULL;
125                         for (l3 = 0; l3 < 512; l3++) {
126                             cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
127                             pte = le64_to_cpu(pte);
128                             if (pte & PG_PRESENT_MASK) {
129                                 print_pte(mon, env, (l1 << 30) + (l2 << 21)
130                                           + (l3 << 12),
131                                           pte & ~PG_PSE_MASK,
132                                           ~(hwaddr)0xfff);
133                             }
134                         }
135                     }
136                 }
137             }
138         }
139     }
140 }
141 
142 #ifdef TARGET_X86_64
143 static void tlb_info_la48(Monitor *mon, CPUArchState *env,
144         uint64_t l0, uint64_t pml4_addr)
145 {
146     uint64_t l1, l2, l3, l4;
147     uint64_t pml4e, pdpe, pde, pte;
148     uint64_t pdp_addr, pd_addr, pt_addr;
149 
150     for (l1 = 0; l1 < 512; l1++) {
151         cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
152         pml4e = le64_to_cpu(pml4e);
153         if (!(pml4e & PG_PRESENT_MASK)) {
154             continue;
155         }
156 
157         pdp_addr = pml4e & 0x3fffffffff000ULL;
158         for (l2 = 0; l2 < 512; l2++) {
159             cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
160             pdpe = le64_to_cpu(pdpe);
161             if (!(pdpe & PG_PRESENT_MASK)) {
162                 continue;
163             }
164 
165             if (pdpe & PG_PSE_MASK) {
166                 /* 1G pages, CR4.PSE is ignored */
167                 print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30),
168                         pdpe, 0x3ffffc0000000ULL);
169                 continue;
170             }
171 
172             pd_addr = pdpe & 0x3fffffffff000ULL;
173             for (l3 = 0; l3 < 512; l3++) {
174                 cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
175                 pde = le64_to_cpu(pde);
176                 if (!(pde & PG_PRESENT_MASK)) {
177                     continue;
178                 }
179 
180                 if (pde & PG_PSE_MASK) {
181                     /* 2M pages, CR4.PSE is ignored */
182                     print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30) +
183                             (l3 << 21), pde, 0x3ffffffe00000ULL);
184                     continue;
185                 }
186 
187                 pt_addr = pde & 0x3fffffffff000ULL;
188                 for (l4 = 0; l4 < 512; l4++) {
189                     cpu_physical_memory_read(pt_addr
190                             + l4 * 8,
191                             &pte, 8);
192                     pte = le64_to_cpu(pte);
193                     if (pte & PG_PRESENT_MASK) {
194                         print_pte(mon, env, (l0 << 48) + (l1 << 39) +
195                                 (l2 << 30) + (l3 << 21) + (l4 << 12),
196                                 pte & ~PG_PSE_MASK, 0x3fffffffff000ULL);
197                     }
198                 }
199             }
200         }
201     }
202 }
203 
204 static void tlb_info_la57(Monitor *mon, CPUArchState *env)
205 {
206     uint64_t l0;
207     uint64_t pml5e;
208     uint64_t pml5_addr;
209 
210     pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
211     for (l0 = 0; l0 < 512; l0++) {
212         cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
213         pml5e = le64_to_cpu(pml5e);
214         if (pml5e & PG_PRESENT_MASK) {
215             tlb_info_la48(mon, env, l0, pml5e & 0x3fffffffff000ULL);
216         }
217     }
218 }
219 #endif /* TARGET_X86_64 */
220 
221 void hmp_info_tlb(Monitor *mon, const QDict *qdict)
222 {
223     CPUArchState *env;
224 
225     env = mon_get_cpu_env(mon);
226     if (!env) {
227         monitor_printf(mon, "No CPU available\n");
228         return;
229     }
230 
231     if (!(env->cr[0] & CR0_PG_MASK)) {
232         monitor_printf(mon, "PG disabled\n");
233         return;
234     }
235     if (env->cr[4] & CR4_PAE_MASK) {
236 #ifdef TARGET_X86_64
237         if (env->hflags & HF_LMA_MASK) {
238             if (env->cr[4] & CR4_LA57_MASK) {
239                 tlb_info_la57(mon, env);
240             } else {
241                 tlb_info_la48(mon, env, 0, env->cr[3] & 0x3fffffffff000ULL);
242             }
243         } else
244 #endif
245         {
246             tlb_info_pae32(mon, env);
247         }
248     } else {
249         tlb_info_32(mon, env);
250     }
251 }
252 
253 static void mem_print(Monitor *mon, CPUArchState *env,
254                       hwaddr *pstart, int *plast_prot,
255                       hwaddr end, int prot)
256 {
257     int prot1;
258     prot1 = *plast_prot;
259     if (prot != prot1) {
260         if (*pstart != -1) {
261             monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " "
262                            TARGET_FMT_plx " %c%c%c\n",
263                            addr_canonical(env, *pstart),
264                            addr_canonical(env, end),
265                            addr_canonical(env, end - *pstart),
266                            prot1 & PG_USER_MASK ? 'u' : '-',
267                            'r',
268                            prot1 & PG_RW_MASK ? 'w' : '-');
269         }
270         if (prot != 0)
271             *pstart = end;
272         else
273             *pstart = -1;
274         *plast_prot = prot;
275     }
276 }
277 
278 static void mem_info_32(Monitor *mon, CPUArchState *env)
279 {
280     unsigned int l1, l2;
281     int prot, last_prot;
282     uint32_t pgd, pde, pte;
283     hwaddr start, end;
284 
285     pgd = env->cr[3] & ~0xfff;
286     last_prot = 0;
287     start = -1;
288     for(l1 = 0; l1 < 1024; l1++) {
289         cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
290         pde = le32_to_cpu(pde);
291         end = l1 << 22;
292         if (pde & PG_PRESENT_MASK) {
293             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
294                 prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
295                 mem_print(mon, env, &start, &last_prot, end, prot);
296             } else {
297                 for(l2 = 0; l2 < 1024; l2++) {
298                     cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
299                     pte = le32_to_cpu(pte);
300                     end = (l1 << 22) + (l2 << 12);
301                     if (pte & PG_PRESENT_MASK) {
302                         prot = pte & pde &
303                             (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
304                     } else {
305                         prot = 0;
306                     }
307                     mem_print(mon, env, &start, &last_prot, end, prot);
308                 }
309             }
310         } else {
311             prot = 0;
312             mem_print(mon, env, &start, &last_prot, end, prot);
313         }
314     }
315     /* Flush last range */
316     mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
317 }
318 
319 static void mem_info_pae32(Monitor *mon, CPUArchState *env)
320 {
321     unsigned int l1, l2, l3;
322     int prot, last_prot;
323     uint64_t pdpe, pde, pte;
324     uint64_t pdp_addr, pd_addr, pt_addr;
325     hwaddr start, end;
326 
327     pdp_addr = env->cr[3] & ~0x1f;
328     last_prot = 0;
329     start = -1;
330     for (l1 = 0; l1 < 4; l1++) {
331         cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
332         pdpe = le64_to_cpu(pdpe);
333         end = l1 << 30;
334         if (pdpe & PG_PRESENT_MASK) {
335             pd_addr = pdpe & 0x3fffffffff000ULL;
336             for (l2 = 0; l2 < 512; l2++) {
337                 cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
338                 pde = le64_to_cpu(pde);
339                 end = (l1 << 30) + (l2 << 21);
340                 if (pde & PG_PRESENT_MASK) {
341                     if (pde & PG_PSE_MASK) {
342                         prot = pde & (PG_USER_MASK | PG_RW_MASK |
343                                       PG_PRESENT_MASK);
344                         mem_print(mon, env, &start, &last_prot, end, prot);
345                     } else {
346                         pt_addr = pde & 0x3fffffffff000ULL;
347                         for (l3 = 0; l3 < 512; l3++) {
348                             cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
349                             pte = le64_to_cpu(pte);
350                             end = (l1 << 30) + (l2 << 21) + (l3 << 12);
351                             if (pte & PG_PRESENT_MASK) {
352                                 prot = pte & pde & (PG_USER_MASK | PG_RW_MASK |
353                                                     PG_PRESENT_MASK);
354                             } else {
355                                 prot = 0;
356                             }
357                             mem_print(mon, env, &start, &last_prot, end, prot);
358                         }
359                     }
360                 } else {
361                     prot = 0;
362                     mem_print(mon, env, &start, &last_prot, end, prot);
363                 }
364             }
365         } else {
366             prot = 0;
367             mem_print(mon, env, &start, &last_prot, end, prot);
368         }
369     }
370     /* Flush last range */
371     mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
372 }
373 
374 
375 #ifdef TARGET_X86_64
376 static void mem_info_la48(Monitor *mon, CPUArchState *env)
377 {
378     int prot, last_prot;
379     uint64_t l1, l2, l3, l4;
380     uint64_t pml4e, pdpe, pde, pte;
381     uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
382 
383     pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
384     last_prot = 0;
385     start = -1;
386     for (l1 = 0; l1 < 512; l1++) {
387         cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
388         pml4e = le64_to_cpu(pml4e);
389         end = l1 << 39;
390         if (pml4e & PG_PRESENT_MASK) {
391             pdp_addr = pml4e & 0x3fffffffff000ULL;
392             for (l2 = 0; l2 < 512; l2++) {
393                 cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
394                 pdpe = le64_to_cpu(pdpe);
395                 end = (l1 << 39) + (l2 << 30);
396                 if (pdpe & PG_PRESENT_MASK) {
397                     if (pdpe & PG_PSE_MASK) {
398                         prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
399                                        PG_PRESENT_MASK);
400                         prot &= pml4e;
401                         mem_print(mon, env, &start, &last_prot, end, prot);
402                     } else {
403                         pd_addr = pdpe & 0x3fffffffff000ULL;
404                         for (l3 = 0; l3 < 512; l3++) {
405                             cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
406                             pde = le64_to_cpu(pde);
407                             end = (l1 << 39) + (l2 << 30) + (l3 << 21);
408                             if (pde & PG_PRESENT_MASK) {
409                                 if (pde & PG_PSE_MASK) {
410                                     prot = pde & (PG_USER_MASK | PG_RW_MASK |
411                                                   PG_PRESENT_MASK);
412                                     prot &= pml4e & pdpe;
413                                     mem_print(mon, env, &start,
414                                               &last_prot, end, prot);
415                                 } else {
416                                     pt_addr = pde & 0x3fffffffff000ULL;
417                                     for (l4 = 0; l4 < 512; l4++) {
418                                         cpu_physical_memory_read(pt_addr
419                                                                  + l4 * 8,
420                                                                  &pte, 8);
421                                         pte = le64_to_cpu(pte);
422                                         end = (l1 << 39) + (l2 << 30) +
423                                             (l3 << 21) + (l4 << 12);
424                                         if (pte & PG_PRESENT_MASK) {
425                                             prot = pte & (PG_USER_MASK | PG_RW_MASK |
426                                                           PG_PRESENT_MASK);
427                                             prot &= pml4e & pdpe & pde;
428                                         } else {
429                                             prot = 0;
430                                         }
431                                         mem_print(mon, env, &start,
432                                                   &last_prot, end, prot);
433                                     }
434                                 }
435                             } else {
436                                 prot = 0;
437                                 mem_print(mon, env, &start,
438                                           &last_prot, end, prot);
439                             }
440                         }
441                     }
442                 } else {
443                     prot = 0;
444                     mem_print(mon, env, &start, &last_prot, end, prot);
445                 }
446             }
447         } else {
448             prot = 0;
449             mem_print(mon, env, &start, &last_prot, end, prot);
450         }
451     }
452     /* Flush last range */
453     mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 48, 0);
454 }
455 
456 static void mem_info_la57(Monitor *mon, CPUArchState *env)
457 {
458     int prot, last_prot;
459     uint64_t l0, l1, l2, l3, l4;
460     uint64_t pml5e, pml4e, pdpe, pde, pte;
461     uint64_t pml5_addr, pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
462 
463     pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
464     last_prot = 0;
465     start = -1;
466     for (l0 = 0; l0 < 512; l0++) {
467         cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
468         pml5e = le64_to_cpu(pml5e);
469         end = l0 << 48;
470         if (!(pml5e & PG_PRESENT_MASK)) {
471             prot = 0;
472             mem_print(mon, env, &start, &last_prot, end, prot);
473             continue;
474         }
475 
476         pml4_addr = pml5e & 0x3fffffffff000ULL;
477         for (l1 = 0; l1 < 512; l1++) {
478             cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
479             pml4e = le64_to_cpu(pml4e);
480             end = (l0 << 48) + (l1 << 39);
481             if (!(pml4e & PG_PRESENT_MASK)) {
482                 prot = 0;
483                 mem_print(mon, env, &start, &last_prot, end, prot);
484                 continue;
485             }
486 
487             pdp_addr = pml4e & 0x3fffffffff000ULL;
488             for (l2 = 0; l2 < 512; l2++) {
489                 cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
490                 pdpe = le64_to_cpu(pdpe);
491                 end = (l0 << 48) + (l1 << 39) + (l2 << 30);
492                 if (pdpe & PG_PRESENT_MASK) {
493                     prot = 0;
494                     mem_print(mon, env, &start, &last_prot, end, prot);
495                     continue;
496                 }
497 
498                 if (pdpe & PG_PSE_MASK) {
499                     prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
500                             PG_PRESENT_MASK);
501                     prot &= pml5e & pml4e;
502                     mem_print(mon, env, &start, &last_prot, end, prot);
503                     continue;
504                 }
505 
506                 pd_addr = pdpe & 0x3fffffffff000ULL;
507                 for (l3 = 0; l3 < 512; l3++) {
508                     cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
509                     pde = le64_to_cpu(pde);
510                     end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
511                     if (pde & PG_PRESENT_MASK) {
512                         prot = 0;
513                         mem_print(mon, env, &start, &last_prot, end, prot);
514                         continue;
515                     }
516 
517                     if (pde & PG_PSE_MASK) {
518                         prot = pde & (PG_USER_MASK | PG_RW_MASK |
519                                 PG_PRESENT_MASK);
520                         prot &= pml5e & pml4e & pdpe;
521                         mem_print(mon, env, &start, &last_prot, end, prot);
522                         continue;
523                     }
524 
525                     pt_addr = pde & 0x3fffffffff000ULL;
526                     for (l4 = 0; l4 < 512; l4++) {
527                         cpu_physical_memory_read(pt_addr + l4 * 8, &pte, 8);
528                         pte = le64_to_cpu(pte);
529                         end = (l0 << 48) + (l1 << 39) + (l2 << 30) +
530                             (l3 << 21) + (l4 << 12);
531                         if (pte & PG_PRESENT_MASK) {
532                             prot = pte & (PG_USER_MASK | PG_RW_MASK |
533                                     PG_PRESENT_MASK);
534                             prot &= pml5e & pml4e & pdpe & pde;
535                         } else {
536                             prot = 0;
537                         }
538                         mem_print(mon, env, &start, &last_prot, end, prot);
539                     }
540                 }
541             }
542         }
543     }
544     /* Flush last range */
545     mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 57, 0);
546 }
547 #endif /* TARGET_X86_64 */
548 
549 void hmp_info_mem(Monitor *mon, const QDict *qdict)
550 {
551     CPUArchState *env;
552 
553     env = mon_get_cpu_env(mon);
554     if (!env) {
555         monitor_printf(mon, "No CPU available\n");
556         return;
557     }
558 
559     if (!(env->cr[0] & CR0_PG_MASK)) {
560         monitor_printf(mon, "PG disabled\n");
561         return;
562     }
563     if (env->cr[4] & CR4_PAE_MASK) {
564 #ifdef TARGET_X86_64
565         if (env->hflags & HF_LMA_MASK) {
566             if (env->cr[4] & CR4_LA57_MASK) {
567                 mem_info_la57(mon, env);
568             } else {
569                 mem_info_la48(mon, env);
570             }
571         } else
572 #endif
573         {
574             mem_info_pae32(mon, env);
575         }
576     } else {
577         mem_info_32(mon, env);
578     }
579 }
580 
581 void hmp_mce(Monitor *mon, const QDict *qdict)
582 {
583     X86CPU *cpu;
584     CPUState *cs;
585     int cpu_index = qdict_get_int(qdict, "cpu_index");
586     int bank = qdict_get_int(qdict, "bank");
587     uint64_t status = qdict_get_int(qdict, "status");
588     uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
589     uint64_t addr = qdict_get_int(qdict, "addr");
590     uint64_t misc = qdict_get_int(qdict, "misc");
591     int flags = MCE_INJECT_UNCOND_AO;
592 
593     if (qdict_get_try_bool(qdict, "broadcast", false)) {
594         flags |= MCE_INJECT_BROADCAST;
595     }
596     cs = qemu_get_cpu(cpu_index);
597     if (cs != NULL) {
598         cpu = X86_CPU(cs);
599         cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
600                            flags);
601     }
602 }
603 
604 static target_long monitor_get_pc(Monitor *mon, const struct MonitorDef *md,
605                                   int val)
606 {
607     CPUArchState *env = mon_get_cpu_env(mon);
608     return env->eip + env->segs[R_CS].base;
609 }
610 
611 const MonitorDef monitor_defs[] = {
612 #define SEG(name, seg) \
613     { name, offsetof(CPUX86State, segs[seg].selector), NULL, MD_I32 },\
614     { name ".base", offsetof(CPUX86State, segs[seg].base) },\
615     { name ".limit", offsetof(CPUX86State, segs[seg].limit), NULL, MD_I32 },
616 
617     { "eax", offsetof(CPUX86State, regs[0]) },
618     { "ecx", offsetof(CPUX86State, regs[1]) },
619     { "edx", offsetof(CPUX86State, regs[2]) },
620     { "ebx", offsetof(CPUX86State, regs[3]) },
621     { "esp|sp", offsetof(CPUX86State, regs[4]) },
622     { "ebp|fp", offsetof(CPUX86State, regs[5]) },
623     { "esi", offsetof(CPUX86State, regs[6]) },
624     { "edi", offsetof(CPUX86State, regs[7]) },
625 #ifdef TARGET_X86_64
626     { "r8", offsetof(CPUX86State, regs[8]) },
627     { "r9", offsetof(CPUX86State, regs[9]) },
628     { "r10", offsetof(CPUX86State, regs[10]) },
629     { "r11", offsetof(CPUX86State, regs[11]) },
630     { "r12", offsetof(CPUX86State, regs[12]) },
631     { "r13", offsetof(CPUX86State, regs[13]) },
632     { "r14", offsetof(CPUX86State, regs[14]) },
633     { "r15", offsetof(CPUX86State, regs[15]) },
634 #endif
635     { "eflags", offsetof(CPUX86State, eflags) },
636     { "eip", offsetof(CPUX86State, eip) },
637     SEG("cs", R_CS)
638     SEG("ds", R_DS)
639     SEG("es", R_ES)
640     SEG("ss", R_SS)
641     SEG("fs", R_FS)
642     SEG("gs", R_GS)
643     { "pc", 0, monitor_get_pc, },
644     { NULL },
645 };
646 
647 const MonitorDef *target_monitor_defs(void)
648 {
649     return monitor_defs;
650 }
651 
652 void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
653 {
654     CPUState *cs;
655 
656     if (qdict_haskey(qdict, "apic-id")) {
657         int id = qdict_get_try_int(qdict, "apic-id", 0);
658         cs = cpu_by_arch_id(id);
659     } else {
660         cs = mon_get_cpu(mon);
661     }
662 
663 
664     if (!cs) {
665         monitor_printf(mon, "No CPU available\n");
666         return;
667     }
668     x86_cpu_dump_local_apic_state(cs, CPU_DUMP_FPU);
669 }
670 
671 void hmp_info_io_apic(Monitor *mon, const QDict *qdict)
672 {
673     monitor_printf(mon, "This command is obsolete and will be "
674                    "removed soon. Please use 'info pic' instead.\n");
675 }
676