VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstAnimate.cpp@ 19

Last change on this file since 19 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.1 KB
Line 
1/** @file
2 *
3 * VBox Animation Testcase / Tool.
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include <VBox/vm.h>
27#include <VBox/vmm.h>
28#include <VBox/cpum.h>
29#include <VBox/cfgm.h>
30#include <VBox/pgm.h>
31#include <VBox/rem.h>
32#include <VBox/dbgf.h>
33#include <VBox/err.h>
34#include <VBox/param.h>
35#include <VBox/log.h>
36#include <iprt/assert.h>
37#include <iprt/alloc.h>
38#include <iprt/runtime.h>
39#include <iprt/semaphore.h>
40#include <iprt/string.h>
41#include <iprt/stream.h>
42#include <iprt/file.h>
43#include <iprt/thread.h>
44
45#include <string.h>
46#include <ctype.h>
47#include <signal.h>
48
49/*******************************************************************************
50* Global Variables *
51*******************************************************************************/
52static volatile bool g_fSignaled = false;
53
54
55static void SigInterrupt(int iSignal)
56{
57 signal(SIGINT, SigInterrupt);
58 g_fSignaled = true;
59 RTPrintf("caught SIGINT\n");
60}
61
62typedef DECLCALLBACK(int) FNSETGUESTGPR(PVM, uint32_t);
63typedef FNSETGUESTGPR *PFNSETGUESTGPR;
64static int scriptGPReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
65{
66 uint32_t u32;
67 int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
68 if (VBOX_FAILURE(rc))
69 return rc;
70 return ((PFNSETGUESTGPR)(uintptr_t)pvUser)(pVM, u32);
71}
72
73typedef DECLCALLBACK(int) FNSETGUESTSEL(PVM, uint16_t);
74typedef FNSETGUESTSEL *PFNSETGUESTSEL;
75static int scriptSelReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
76{
77 uint16_t u16;
78 int rc = RTStrToUInt16Ex(pszValue, NULL, 16, &u16);
79 if (VBOX_FAILURE(rc))
80 return rc;
81 return ((PFNSETGUESTSEL)(uintptr_t)pvUser)(pVM, u16);
82}
83
84typedef DECLCALLBACK(int) FNSETGUESTSYS(PVM, uint32_t);
85typedef FNSETGUESTSYS *PFNSETGUESTSYS;
86static int scriptSysReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
87{
88 uint32_t u32;
89 int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
90 if (VBOX_FAILURE(rc))
91 return rc;
92 return ((PFNSETGUESTSYS)(uintptr_t)pvUser)(pVM, u32);
93}
94
95
96typedef DECLCALLBACK(int) FNSETGUESTDTR(PVM, uint32_t, uint16_t);
97typedef FNSETGUESTDTR *PFNSETGUESTDTR;
98static int scriptDtrReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
99{
100 char *pszPart2 = strchr(pszValue, ':');
101 if (!pszPart2)
102 return -1;
103 *pszPart2++ = '\0';
104 pszPart2 = RTStrStripL(pszPart2);
105 pszValue = RTStrStripR(pszValue);
106
107 uint32_t u32;
108 int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
109 if (VBOX_FAILURE(rc))
110 return rc;
111
112 uint16_t u16;
113 rc = RTStrToUInt16Ex(pszPart2, NULL, 16, &u16);
114 if (VBOX_FAILURE(rc))
115 return rc;
116
117 return ((PFNSETGUESTDTR)(uintptr_t)pvUser)(pVM, u32, u16);
118}
119
120
121
122
123
124
125
126static int scriptCommand(PVM pVM, const char *pszIn, size_t cch)
127{
128 int rc = VINF_SUCCESS;
129 char *psz = RTStrDup(pszIn);
130 char *pszEqual = strchr(psz, '=');
131 if (pszEqual)
132 {
133 /*
134 * var = value
135 */
136 *pszEqual = '\0';
137 RTStrStripR(psz);
138 char *pszValue = RTStrStrip(pszEqual + 1);
139
140 /* variables */
141 static struct
142 {
143 const char *pszVar;
144 int (*pfnHandler)(PVM pVM, char *pszVar, char *pszValue, void *pvUser);
145 PFNRT pvUser;
146 } aVars[] =
147 {
148 { "eax", scriptGPReg, (PFNRT)CPUMSetGuestEAX },
149 { "ebx", scriptGPReg, (PFNRT)CPUMSetGuestEBX },
150 { "ecx", scriptGPReg, (PFNRT)CPUMSetGuestECX },
151 { "edx", scriptGPReg, (PFNRT)CPUMSetGuestEDX },
152 { "esp", scriptGPReg, (PFNRT)CPUMSetGuestESP },
153 { "ebp", scriptGPReg, (PFNRT)CPUMSetGuestEBP },
154 { "esi", scriptGPReg, (PFNRT)CPUMSetGuestESI },
155 { "edi", scriptGPReg, (PFNRT)CPUMSetGuestEDI },
156 { "efl", scriptGPReg, (PFNRT)CPUMSetGuestEFlags },
157 { "eip", scriptGPReg, (PFNRT)CPUMSetGuestEIP },
158 { "ss", scriptSelReg, (PFNRT)CPUMSetGuestSS },
159 { "cs", scriptSelReg, (PFNRT)CPUMSetGuestCS },
160 { "ds", scriptSelReg, (PFNRT)CPUMSetGuestDS },
161 { "es", scriptSelReg, (PFNRT)CPUMSetGuestES },
162 { "fs", scriptSelReg, (PFNRT)CPUMSetGuestFS },
163 { "gs", scriptSelReg, (PFNRT)CPUMSetGuestGS },
164 { "cr0", scriptSysReg, (PFNRT)CPUMSetGuestCR0 },
165 { "cr2", scriptSysReg, (PFNRT)CPUMSetGuestCR2 },
166 { "cr3", scriptSysReg, (PFNRT)CPUMSetGuestCR3 },
167 { "cr4", scriptSysReg, (PFNRT)CPUMSetGuestCR4 },
168 { "ldtr",scriptSelReg, (PFNRT)CPUMSetGuestLDTR },
169 { "tr", scriptSelReg, (PFNRT)CPUMSetGuestTR },
170 { "idtr",scriptDtrReg, (PFNRT)CPUMSetGuestIDTR },
171 { "gdtr",scriptDtrReg, (PFNRT)CPUMSetGuestGDTR }
172 };
173
174 rc = -1;
175 for (unsigned i = 0; i < ELEMENTS(aVars); i++)
176 {
177 if (!strcmp(psz, aVars[i].pszVar))
178 {
179 rc = aVars[i].pfnHandler(pVM, psz, pszValue, (void*)(uintptr_t)aVars[i].pvUser);
180 break;
181 }
182 }
183 }
184
185 RTStrFree(psz);
186 return rc;
187}
188
189static DECLCALLBACK(int) scriptRun(PVM pVM, RTFILE File)
190{
191 RTPrintf("info: running script...\n");
192 uint64_t cb;
193 int rc = RTFileGetSize(File, &cb);
194 if (VBOX_SUCCESS(rc))
195 {
196 if (cb == 0)
197 return VINF_SUCCESS;
198 if (cb < _1M)
199 {
200 char *pszBuf = (char *)RTMemAllocZ(cb + 1);
201 if (pszBuf)
202 {
203 rc = RTFileRead(File, pszBuf, cb, NULL);
204 if (VBOX_SUCCESS(rc))
205 {
206 pszBuf[cb] = '\0';
207
208 /*
209 * Now process what's in the buffer.
210 */
211 char *psz = pszBuf;
212 while (psz && *psz)
213 {
214 /* skip blanks. */
215 while (isspace(*psz))
216 psz++;
217 if (!*psz)
218 break;
219
220 /* end of line */
221 char *pszNext;
222 char *pszEnd = strchr(psz, '\n');
223 if (!pszEnd)
224 pszEnd = strchr(psz, '\r');
225 if (!pszEnd)
226 pszNext = pszEnd = strchr(psz, '\0');
227 else
228 pszNext = pszEnd + 1;
229
230 if (*psz != ';' && *psz != '#' && *psz != '/')
231 {
232 /* strip end */
233 *pszEnd = '\0';
234 while (pszEnd > psz && isspace(pszEnd[-1]))
235 *--pszEnd = '\0';
236
237 /* process the line */
238 RTPrintf("debug: executing script line '%s'\n", psz);
239 rc = scriptCommand(pVM, psz, pszEnd - psz);
240 if (VBOX_FAILURE(rc))
241 {
242 RTPrintf("error: '%s' failed: %Vrc\n", psz, rc);
243 break;
244 }
245 }
246 /* else comment line */
247
248 /* next */
249 psz = pszNext;
250 }
251
252 }
253 else
254 RTPrintf("error: failed to read script file: %Vrc\n", rc);
255 RTMemFree(pszBuf);
256 }
257 else
258 {
259 RTPrintf("error: Out of memory. (%d bytes)\n", cb + 1);
260 rc = VERR_NO_MEMORY;
261 }
262 }
263 else
264 RTPrintf("error: script file is too large (0x%llx bytes)\n", cb);
265 }
266 else
267 RTPrintf("error: couldn't get size of script file: %Vrc\n", rc);
268
269 return rc;
270}
271
272
273static DECLCALLBACK(int) loadMem(PVM pVM, RTFILE File, uint64_t *poff)
274{
275 uint64_t off = *poff;
276 RTPrintf("info: loading memory...\n");
277
278 int rc = RTFileSeek(File, off, RTFILE_SEEK_BEGIN, NULL);
279 if (VBOX_SUCCESS(rc))
280 {
281 RTGCPHYS GCPhys = 0;
282 for (;;)
283 {
284 if (!(GCPhys % (PAGE_SIZE * 0x1000)))
285 RTPrintf("info: %VGp...\n", GCPhys);
286
287 /* read a page from the file */
288 unsigned cbRead = 0;
289 uint8_t au8Page[PAGE_SIZE * 16];
290 rc = RTFileRead(File, &au8Page, sizeof(au8Page), &cbRead);
291 if (VBOX_SUCCESS(rc) && !cbRead)
292 rc = RTFileRead(File, &au8Page, sizeof(au8Page), &cbRead);
293 if (VBOX_SUCCESS(rc) && !cbRead)
294 rc = VERR_EOF;
295 if (VBOX_FAILURE(rc) || rc == VINF_EOF)
296 {
297 if (rc == VERR_EOF)
298 rc = VINF_SUCCESS;
299 else
300 RTPrintf("error: Read error %Vrc while reading the raw memory file.\n", rc);
301 break;
302 }
303
304 /* Write that page to the guest - skip known rom areas for now. */
305 if (GCPhys < 0xa0000 || GCPhys >= 0x10000) /* ASSUME size of a8Page is a power of 2. */
306 PGMPhysWrite(pVM, GCPhys, &au8Page, cbRead);
307 GCPhys += cbRead;
308 }
309 }
310 else
311 RTPrintf("error: Failed to seek to 0x%llx in the raw memory file. rc=%Vrc\n", off, rc);
312
313 return rc;
314}
315
316
317/**
318 * Creates the default configuration.
319 * This assumes an empty tree.
320 *
321 * @returns VBox status code.
322 * @param pVM VM handle.
323 */
324static DECLCALLBACK(int) cfgmR3CreateDefault(PVM pVM, void *pvUser)
325{
326 uint64_t cbMem = *(uint64_t *)pvUser;
327 int rc;
328 int rcAll = VINF_SUCCESS;
329#define UPDATERC() do { if (VBOX_FAILURE(rc) && VBOX_SUCCESS(rcAll)) rcAll = rc; } while (0)
330
331 /*
332 * Create VM default values.
333 */
334 PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
335 rc = CFGMR3InsertString(pRoot, "Name", "Default VM");
336 UPDATERC();
337 rc = CFGMR3InsertInteger(pRoot, "RamSize", cbMem);
338 UPDATERC();
339 rc = CFGMR3InsertInteger(pRoot, "TimerMillies", 10);
340 UPDATERC();
341 rc = CFGMR3InsertInteger(pRoot, "RawR3Enabled", 0);
342 UPDATERC();
343 /** @todo CFGM Defaults: RawR0, PATMEnabled and CASMEnabled needs attention later. */
344 rc = CFGMR3InsertInteger(pRoot, "RawR0Enabled", 0);
345 UPDATERC();
346 rc = CFGMR3InsertInteger(pRoot, "PATMEnabled", 0);
347 UPDATERC();
348 rc = CFGMR3InsertInteger(pRoot, "CSAMEnabled", 0);
349 UPDATERC();
350
351 /*
352 * PDM.
353 */
354 PCFGMNODE pPdm;
355 rc = CFGMR3InsertNode(pRoot, "PDM", &pPdm);
356 UPDATERC();
357 PCFGMNODE pDevices = NULL;
358 rc = CFGMR3InsertNode(pPdm, "Devices", &pDevices);
359 UPDATERC();
360 rc = CFGMR3InsertInteger(pDevices, "LoadBuiltin", 1); /* boolean */
361 UPDATERC();
362 PCFGMNODE pDrivers = NULL;
363 rc = CFGMR3InsertNode(pPdm, "Drivers", &pDrivers);
364 UPDATERC();
365 rc = CFGMR3InsertInteger(pDrivers, "LoadBuiltin", 1); /* boolean */
366 UPDATERC();
367
368
369 /*
370 * Devices
371 */
372 pDevices = NULL;
373 rc = CFGMR3InsertNode(pRoot, "Devices", &pDevices);
374 UPDATERC();
375 /* device */
376 PCFGMNODE pDev = NULL;
377 PCFGMNODE pInst = NULL;
378 PCFGMNODE pCfg = NULL;
379#if 0
380 PCFGMNODE pLunL0 = NULL;
381 PCFGMNODE pLunL1 = NULL;
382#endif
383
384 /*
385 * PC Arch.
386 */
387 rc = CFGMR3InsertNode(pDevices, "pcarch", &pDev);
388 UPDATERC();
389 rc = CFGMR3InsertNode(pDev, "0", &pInst);
390 UPDATERC();
391 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
392 UPDATERC();
393 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
394 UPDATERC();
395
396 /*
397 * PC Bios.
398 */
399 rc = CFGMR3InsertNode(pDevices, "pcbios", &pDev);
400 UPDATERC();
401 rc = CFGMR3InsertNode(pDev, "0", &pInst);
402 UPDATERC();
403 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
404 UPDATERC();
405 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
406 UPDATERC();
407 rc = CFGMR3InsertInteger(pCfg, "RamSize", cbMem);
408 UPDATERC();
409 rc = CFGMR3InsertString(pCfg, "BootDevice0", "IDE");
410 UPDATERC();
411 rc = CFGMR3InsertString(pCfg, "BootDevice1", "NONE");
412 UPDATERC();
413 rc = CFGMR3InsertString(pCfg, "BootDevice2", "NONE");
414 UPDATERC();
415 rc = CFGMR3InsertString(pCfg, "BootDevice3", "NONE");
416 UPDATERC();
417 rc = CFGMR3InsertString(pCfg, "HardDiskDevice", "piix3ide");
418 UPDATERC();
419 rc = CFGMR3InsertString(pCfg, "FloppyDevice", "");
420 UPDATERC();
421 /* Bios logo. */
422 rc = CFGMR3InsertInteger(pCfg, "FadeIn", 0);
423 UPDATERC();
424 rc = CFGMR3InsertInteger(pCfg, "FadeOut", 0);
425 UPDATERC();
426 rc = CFGMR3InsertInteger(pCfg, "LogoTime", 0);
427 UPDATERC();
428 rc = CFGMR3InsertString(pCfg, "LogoFile", "");
429 UPDATERC();
430
431 /*
432 * PCI bus.
433 */
434 rc = CFGMR3InsertNode(pDevices, "pci", &pDev); /* piix3 */
435 UPDATERC();
436 rc = CFGMR3InsertNode(pDev, "0", &pInst);
437 UPDATERC();
438 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
439 UPDATERC();
440 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
441 UPDATERC();
442
443 /*
444 * PS/2 keyboard & mouse
445 */
446 rc = CFGMR3InsertNode(pDevices, "pckbd", &pDev);
447 UPDATERC();
448 rc = CFGMR3InsertNode(pDev, "0", &pInst);
449 UPDATERC();
450 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
451 UPDATERC();
452
453 /*
454 * i8254 Programmable Interval Timer And Dummy Speaker
455 */
456 rc = CFGMR3InsertNode(pDevices, "i8254", &pDev);
457 UPDATERC();
458 rc = CFGMR3InsertNode(pDev, "0", &pInst);
459 UPDATERC();
460 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
461 UPDATERC();
462
463 /*
464 * i8259 Programmable Interrupt Controller.
465 */
466 rc = CFGMR3InsertNode(pDevices, "i8259", &pDev);
467 UPDATERC();
468 rc = CFGMR3InsertNode(pDev, "0", &pInst);
469 UPDATERC();
470 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
471 UPDATERC();
472 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
473 UPDATERC();
474
475 /*
476 * RTC MC146818.
477 */
478 rc = CFGMR3InsertNode(pDevices, "mc146818", &pDev);
479 UPDATERC();
480 rc = CFGMR3InsertNode(pDev, "0", &pInst);
481 UPDATERC();
482 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
483 UPDATERC();
484
485 /*
486 * VGA.
487 */
488 rc = CFGMR3InsertNode(pDevices, "vga", &pDev);
489 UPDATERC();
490 rc = CFGMR3InsertNode(pDev, "0", &pInst);
491 UPDATERC();
492 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
493 UPDATERC();
494 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
495 UPDATERC();
496 rc = CFGMR3InsertInteger(pCfg, "VRamSize", 4 * _1M);
497 UPDATERC();
498
499 /*
500 * IDE controller.
501 */
502 rc = CFGMR3InsertNode(pDevices, "piix3ide", &pDev); /* piix3 */
503 UPDATERC();
504 rc = CFGMR3InsertNode(pDev, "0", &pInst);
505 UPDATERC();
506 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
507 UPDATERC();
508 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
509 UPDATERC();
510
511
512
513 /*
514 * ...
515 */
516
517#undef UPDATERC
518 return rcAll;
519}
520
521static void syntax(void)
522{
523 RTPrintf("Syntax: tstAnimate <-r <raw-mem-file>> [-o <rawmem offset>] [-s <script file>] [-m <bytes>]\n"
524 "\n"
525 "The script is on the form:\n"
526 "<reg>=<value>\n");
527}
528
529
530int main(int argc, char **argv)
531{
532 int rcRet = 1;
533 RTR3Init();
534
535 /*
536 * Parse input.
537 */
538 if (argc <= 1)
539 {
540 syntax();
541 return 1;
542 }
543
544 uint64_t cbMem = ~0ULL;
545 const char *pszRawMem = NULL;
546 uint64_t offRawMem = 0;
547 const char *pszScript = NULL;
548 for (int i = 1; i < argc; i++)
549 {
550 if (argv[i][0] == '-')
551 {
552 /* check that it's on short form */
553 if (argv[i][2])
554 {
555 if ( strcmp(argv[i], "--help")
556 && strcmp(argv[i], "-help"))
557 RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]);
558 else
559 syntax();
560 return 1;
561 }
562
563 /* check for 2nd argument */
564 switch (argv[i][1])
565 {
566 case 'r':
567 case 'o':
568 case 'c':
569 case 'm':
570 if (i + 1 < argc)
571 break;
572 RTPrintf("tstAnimate: Syntax error: '%s' takes a 2nd argument.\n", argv[i]);
573 return 1;
574 }
575
576 /* process argument */
577 switch (argv[i][1])
578 {
579 case 'r':
580 pszRawMem = argv[++i];
581 break;
582
583 case 'o':
584 {
585 int rc = RTStrToUInt64Ex(argv[++i], NULL, 0, &offRawMem);
586 if (VBOX_FAILURE(rc))
587 {
588 RTPrintf("tstAnimate: Syntax error: Invalid offset given to -o.\n");
589 return 1;
590 }
591 break;
592 }
593
594 case 'm':
595 {
596 int rc = RTStrToUInt64Ex(argv[++i], NULL, 0, &cbMem);
597 if (VBOX_FAILURE(rc))
598 {
599 RTPrintf("tstAnimate: Syntax error: Invalid offset given to -m.\n");
600 return 1;
601 }
602 break;
603 }
604
605 case 's':
606 pszScript = argv[++i];
607 break;
608
609 case 'h':
610 case 'H':
611 case '?':
612 syntax();
613 return 1;
614
615 default:
616 RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]);
617 return 1;
618 }
619 }
620 else
621 {
622 RTPrintf("tstAnimate: Syntax error at arg no. %d '%s'.\n", i, argv[i]);
623 syntax();
624 return 1;
625 }
626 }
627
628 /*
629 * Check that the basic requirements are met.
630 */
631 if (!pszRawMem)
632 {
633 RTPrintf("tstAnimate: Syntax error: The -r argument is compulsory.\n");
634 return 1;
635 }
636
637 /*
638 * Open the files.
639 */
640 RTFILE FileRawMem;
641 int rc = RTFileOpen(&FileRawMem, pszRawMem, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
642 if (VBOX_FAILURE(rc))
643 {
644 RTPrintf("tstAnimate: error: Failed to open '%s': %Vrc\n", pszRawMem, rc);
645 return 1;
646 }
647 RTFILE FileScript = NIL_RTFILE;
648 if (pszScript)
649 {
650 rc = RTFileOpen(&FileScript, pszScript, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
651 if (VBOX_FAILURE(rc))
652 {
653 RTPrintf("tstAnimate: error: Failed to open '%s': %Vrc\n", pszScript, rc);
654 return 1;
655 }
656 }
657
658 /*
659 * Figure the memsize if not specified.
660 */
661 if (cbMem == ~0ULL)
662 {
663 rc = RTFileGetSize(FileRawMem, &cbMem);
664 AssertReleaseRC(rc);
665 cbMem -= offRawMem;
666 cbMem &= ~(PAGE_SIZE - 1);
667 }
668 RTPrintf("tstAnimate: info: cbMem=0x%llx bytes\n", cbMem);
669
670 /*
671 * Create empty VM.
672 */
673 PVM pVM;
674 rc = VMR3Create(NULL, NULL, cfgmR3CreateDefault, &cbMem, &pVM);
675 if (VBOX_SUCCESS(rc))
676 {
677 /*
678 * Load memory.
679 */
680 PVMREQ pReq1 = NULL;
681 rc = VMR3ReqCall(pVM, &pReq1, RT_INDEFINITE_WAIT, (PFNRT)loadMem, 3, pVM, FileRawMem, &offRawMem);
682 AssertReleaseRC(rc);
683 rc = pReq1->iStatus;
684 VMR3ReqFree(pReq1);
685 if (VBOX_SUCCESS(rc))
686 {
687 /*
688 * Load register script.
689 */
690 if (FileScript != NIL_RTFILE)
691 {
692 rc = VMR3ReqCall(pVM, &pReq1, RT_INDEFINITE_WAIT, (PFNRT)scriptRun, 2, pVM, FileScript);
693 AssertReleaseRC(rc);
694 rc = pReq1->iStatus;
695 VMR3ReqFree(pReq1);
696 }
697 if (VBOX_SUCCESS(rc))
698 {
699 /*
700 * Start the thing.
701 */
702 RTPrintf("info: powering on the VM...\n");
703 RTLogGroupSettings(NULL, "+REM_DISAS.e.l.f");
704 rc = REMR3DisasEnableStepping(pVM, true);
705 if (VBOX_SUCCESS(rc))
706 {
707 DBGFR3InfoLog(pVM, "cpumguest", "verbose");
708 rc = VMR3PowerOn(pVM);
709 if (VBOX_SUCCESS(rc))
710 {
711 RTPrintf("info: VM is running\n");
712 signal(SIGINT, SigInterrupt);
713 while (!g_fSignaled)
714 RTThreadSleep(1000);
715 }
716 else
717 RTPrintf("error: Failed to power on the VM: %Vrc\n", rc);
718 }
719 else
720 RTPrintf("error: Failed to enabled singlestepping: %Vrc\n", rc);
721 RTPrintf("info: shutting down the VM...\n");
722 }
723 /* execScript complains */
724 }
725 /* loadMem complains */
726 rcRet = VBOX_SUCCESS(rc) ? 0 : 1;
727
728 /*
729 * Cleanup.
730 */
731 rc = VMR3Destroy(pVM);
732 if (!VBOX_SUCCESS(rc))
733 {
734 RTPrintf("tstAnimate: error: failed to destroy vm! rc=%d\n", rc);
735 rcRet++;
736 }
737 }
738 else
739 {
740 RTPrintf("tstAnimate: fatal error: failed to create vm! rc=%d\n", rc);
741 rcRet++;
742 }
743
744 return rcRet;
745}
746
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette