VirtualBox

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

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

InnoTek -> innotek: all the headers and comments.

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