VirtualBox

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

Last change on this file since 4071 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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