VirtualBox

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

Last change on this file since 56985 was 56287, checked in by vboxsync, 9 years ago

VMM: Updated (C) year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 32.3 KB
Line 
1/* $Id: tstAnimate.cpp 56287 2015-06-09 11:15:22Z vboxsync $ */
2/** @file
3 * VBox Animation Testcase / Tool.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <VBox/vmm/vm.h>
23#include <VBox/vmm/vmm.h>
24#include <VBox/vmm/cpum.h>
25#include <VBox/vmm/cfgm.h>
26#include <VBox/vmm/em.h>
27#include <VBox/vmm/pgm.h>
28#ifdef VBOX_WITH_REM
29# include <VBox/vmm/rem.h>
30#endif
31#include <VBox/vmm/ssm.h>
32#include <VBox/vmm/dbgf.h>
33#include <VBox/err.h>
34#include <VBox/vmm/pdmifs.h>
35#include <VBox/param.h>
36#include <VBox/log.h>
37#include <iprt/assert.h>
38#include <iprt/alloc.h>
39#include <iprt/initterm.h>
40#include <iprt/semaphore.h>
41#include <iprt/string.h>
42#include <iprt/stream.h>
43#include <iprt/file.h>
44#include <iprt/thread.h>
45#include <iprt/ctype.h>
46#include <iprt/uuid.h>
47
48#include <signal.h>
49
50/*******************************************************************************
51* Global Variables *
52*******************************************************************************/
53static volatile bool g_fSignaled = false;
54
55
56static void SigInterrupt(int iSignal)
57{
58 NOREF(iSignal);
59 signal(SIGINT, SigInterrupt);
60 g_fSignaled = true;
61 RTPrintf("caught SIGINT\n");
62}
63
64typedef DECLCALLBACK(int) FNSETGUESTGPR(PVM, uint32_t);
65typedef FNSETGUESTGPR *PFNSETGUESTGPR;
66static int scriptGPReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
67{
68 NOREF(pszVar);
69 uint32_t u32;
70 int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
71 if (RT_FAILURE(rc))
72 return rc;
73 return ((PFNSETGUESTGPR)(uintptr_t)pvUser)(pVM, u32);
74}
75
76typedef DECLCALLBACK(int) FNSETGUESTSEL(PVM, uint16_t);
77typedef FNSETGUESTSEL *PFNSETGUESTSEL;
78static int scriptSelReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
79{
80 NOREF(pszVar);
81 uint16_t u16;
82 int rc = RTStrToUInt16Ex(pszValue, NULL, 16, &u16);
83 if (RT_FAILURE(rc))
84 return rc;
85 return ((PFNSETGUESTSEL)(uintptr_t)pvUser)(pVM, u16);
86}
87
88typedef DECLCALLBACK(int) FNSETGUESTSYS(PVM, uint32_t);
89typedef FNSETGUESTSYS *PFNSETGUESTSYS;
90static int scriptSysReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
91{
92 NOREF(pszVar);
93 uint32_t u32;
94 int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
95 if (RT_FAILURE(rc))
96 return rc;
97 return ((PFNSETGUESTSYS)(uintptr_t)pvUser)(pVM, u32);
98}
99
100
101typedef DECLCALLBACK(int) FNSETGUESTDTR(PVM, uint32_t, uint16_t);
102typedef FNSETGUESTDTR *PFNSETGUESTDTR;
103static int scriptDtrReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
104{
105 NOREF(pszVar);
106 char *pszPart2 = strchr(pszValue, ':');
107 if (!pszPart2)
108 return -1;
109 *pszPart2++ = '\0';
110 pszPart2 = RTStrStripL(pszPart2);
111 pszValue = RTStrStripR(pszValue);
112
113 uint32_t u32;
114 int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
115 if (RT_FAILURE(rc))
116 return rc;
117
118 uint16_t u16;
119 rc = RTStrToUInt16Ex(pszPart2, NULL, 16, &u16);
120 if (RT_FAILURE(rc))
121 return rc;
122
123 return ((PFNSETGUESTDTR)(uintptr_t)pvUser)(pVM, u32, u16);
124}
125
126
127
128
129
130
131
132static int scriptCommand(PVM pVM, const char *pszIn, size_t cch)
133{
134 NOREF(cch);
135 int rc = VINF_SUCCESS;
136 char *psz = RTStrDup(pszIn);
137 char *pszEqual = strchr(psz, '=');
138 if (pszEqual)
139 {
140 /*
141 * var = value
142 */
143 *pszEqual = '\0';
144 RTStrStripR(psz);
145 char *pszValue = RTStrStrip(pszEqual + 1);
146
147 /* variables */
148 static struct
149 {
150 const char *pszVar;
151 int (*pfnHandler)(PVM pVM, char *pszVar, char *pszValue, void *pvUser);
152 PFNRT pvUser;
153 } aVars[] =
154 {
155 { "eax", scriptGPReg, (PFNRT)CPUMSetGuestEAX },
156 { "ebx", scriptGPReg, (PFNRT)CPUMSetGuestEBX },
157 { "ecx", scriptGPReg, (PFNRT)CPUMSetGuestECX },
158 { "edx", scriptGPReg, (PFNRT)CPUMSetGuestEDX },
159 { "esp", scriptGPReg, (PFNRT)CPUMSetGuestESP },
160 { "ebp", scriptGPReg, (PFNRT)CPUMSetGuestEBP },
161 { "esi", scriptGPReg, (PFNRT)CPUMSetGuestESI },
162 { "edi", scriptGPReg, (PFNRT)CPUMSetGuestEDI },
163 { "efl", scriptGPReg, (PFNRT)CPUMSetGuestEFlags },
164 { "eip", scriptGPReg, (PFNRT)CPUMSetGuestEIP },
165 { "ss", scriptSelReg, (PFNRT)CPUMSetGuestSS },
166 { "cs", scriptSelReg, (PFNRT)CPUMSetGuestCS },
167 { "ds", scriptSelReg, (PFNRT)CPUMSetGuestDS },
168 { "es", scriptSelReg, (PFNRT)CPUMSetGuestES },
169 { "fs", scriptSelReg, (PFNRT)CPUMSetGuestFS },
170 { "gs", scriptSelReg, (PFNRT)CPUMSetGuestGS },
171 { "cr0", scriptSysReg, (PFNRT)CPUMSetGuestCR0 },
172 { "cr2", scriptSysReg, (PFNRT)CPUMSetGuestCR2 },
173 { "cr3", scriptSysReg, (PFNRT)CPUMSetGuestCR3 },
174 { "cr4", scriptSysReg, (PFNRT)CPUMSetGuestCR4 },
175 { "ldtr",scriptSelReg, (PFNRT)CPUMSetGuestLDTR },
176 { "tr", scriptSelReg, (PFNRT)CPUMSetGuestTR },
177 { "idtr",scriptDtrReg, (PFNRT)CPUMSetGuestIDTR },
178 { "gdtr",scriptDtrReg, (PFNRT)CPUMSetGuestGDTR }
179 };
180
181 rc = -1;
182 for (unsigned i = 0; i < RT_ELEMENTS(aVars); i++)
183 {
184 if (!strcmp(psz, aVars[i].pszVar))
185 {
186 rc = aVars[i].pfnHandler(pVM, psz, pszValue, (void*)(uintptr_t)aVars[i].pvUser);
187 break;
188 }
189 }
190 }
191
192 RTStrFree(psz);
193 return rc;
194}
195
196static DECLCALLBACK(int) scriptRun(PVM pVM, RTFILE File)
197{
198 RTPrintf("info: running script...\n");
199 uint64_t cb;
200 int rc = RTFileGetSize(File, &cb);
201 if (RT_SUCCESS(rc))
202 {
203 if (cb == 0)
204 return VINF_SUCCESS;
205 if (cb < _1M)
206 {
207 char *pszBuf = (char *)RTMemAllocZ(cb + 1);
208 if (pszBuf)
209 {
210 rc = RTFileRead(File, pszBuf, cb, NULL);
211 if (RT_SUCCESS(rc))
212 {
213 pszBuf[cb] = '\0';
214
215 /*
216 * Now process what's in the buffer.
217 */
218 char *psz = pszBuf;
219 while (psz && *psz)
220 {
221 /* skip blanks. */
222 while (RT_C_IS_SPACE(*psz))
223 psz++;
224 if (!*psz)
225 break;
226
227 /* end of line */
228 char *pszNext;
229 char *pszEnd = strchr(psz, '\n');
230 if (!pszEnd)
231 pszEnd = strchr(psz, '\r');
232 if (!pszEnd)
233 pszNext = pszEnd = strchr(psz, '\0');
234 else
235 pszNext = pszEnd + 1;
236
237 if (*psz != ';' && *psz != '#' && *psz != '/')
238 {
239 /* strip end */
240 *pszEnd = '\0';
241 while (pszEnd > psz && RT_C_IS_SPACE(pszEnd[-1]))
242 *--pszEnd = '\0';
243
244 /* process the line */
245 RTPrintf("debug: executing script line '%s'\n", psz);
246 rc = scriptCommand(pVM, psz, pszEnd - psz);
247 if (RT_FAILURE(rc))
248 {
249 RTPrintf("error: '%s' failed: %Rrc\n", psz, rc);
250 break;
251 }
252 }
253 /* else comment line */
254
255 /* next */
256 psz = pszNext;
257 }
258
259 }
260 else
261 RTPrintf("error: failed to read script file: %Rrc\n", rc);
262 RTMemFree(pszBuf);
263 }
264 else
265 {
266 RTPrintf("error: Out of memory. (%d bytes)\n", cb + 1);
267 rc = VERR_NO_MEMORY;
268 }
269 }
270 else
271 RTPrintf("error: script file is too large (0x%llx bytes)\n", cb);
272 }
273 else
274 RTPrintf("error: couldn't get size of script file: %Rrc\n", rc);
275
276 return rc;
277}
278
279
280static DECLCALLBACK(int) loadMem(PVM pVM, RTFILE File, uint64_t *poff)
281{
282 uint64_t off = *poff;
283 RTPrintf("info: loading memory...\n");
284
285 int rc = RTFileSeek(File, off, RTFILE_SEEK_BEGIN, NULL);
286 if (RT_SUCCESS(rc))
287 {
288 RTGCPHYS GCPhys = 0;
289 for (;;)
290 {
291 if (!(GCPhys % (PAGE_SIZE * 0x1000)))
292 RTPrintf("info: %RGp...\n", GCPhys);
293
294 /* read a page from the file */
295 size_t cbRead = 0;
296 uint8_t au8Page[PAGE_SIZE * 16];
297 rc = RTFileRead(File, &au8Page, sizeof(au8Page), &cbRead);
298 if (RT_SUCCESS(rc) && !cbRead)
299 rc = RTFileRead(File, &au8Page, sizeof(au8Page), &cbRead);
300 if (RT_SUCCESS(rc) && !cbRead)
301 rc = VERR_EOF;
302 if (RT_FAILURE(rc) || rc == VINF_EOF)
303 {
304 if (rc == VERR_EOF)
305 rc = VINF_SUCCESS;
306 else
307 RTPrintf("error: Read error %Rrc while reading the raw memory file.\n", rc);
308 break;
309 }
310
311 /* Write that page to the guest - skip known rom areas for now. */
312 if (GCPhys < 0xa0000 || GCPhys >= 0x100000) /* ASSUME size of a8Page is a power of 2. */
313 PGMPhysWrite(pVM, GCPhys, &au8Page, cbRead, PGMACCESSORIGIN_DEBUGGER);
314 GCPhys += cbRead;
315 }
316 }
317 else
318 RTPrintf("error: Failed to seek to 0x%llx in the raw memory file. rc=%Rrc\n", off, rc);
319
320 return rc;
321}
322
323
324/**
325 * Creates the default configuration.
326 * This assumes an empty tree.
327 *
328 * @returns VBox status code.
329 * @param pVM Pointer to the VM.
330 */
331static DECLCALLBACK(int) cfgmR3CreateDefault(PUVM pUVM, PVM pVM, void *pvUser)
332{
333 uint64_t cbMem = *(uint64_t *)pvUser;
334 int rc;
335 int rcAll = VINF_SUCCESS;
336 bool fIOAPIC = false;
337#define UPDATERC() do { if (RT_FAILURE(rc) && RT_SUCCESS(rcAll)) rcAll = rc; } while (0)
338
339 /*
340 * Create VM default values.
341 */
342 PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
343 rc = CFGMR3InsertString(pRoot, "Name", "Default VM");
344 UPDATERC();
345 rc = CFGMR3InsertInteger(pRoot, "RamSize", cbMem);
346 UPDATERC();
347 rc = CFGMR3InsertInteger(pRoot, "TimerMillies", 10);
348 UPDATERC();
349 rc = CFGMR3InsertInteger(pRoot, "RawR3Enabled", 0);
350 UPDATERC();
351 /** @todo CFGM Defaults: RawR0, PATMEnabled and CASMEnabled needs attention later. */
352 rc = CFGMR3InsertInteger(pRoot, "RawR0Enabled", 0);
353 UPDATERC();
354 rc = CFGMR3InsertInteger(pRoot, "PATMEnabled", 0);
355 UPDATERC();
356 rc = CFGMR3InsertInteger(pRoot, "CSAMEnabled", 0);
357 UPDATERC();
358
359 /*
360 * PDM.
361 */
362 PCFGMNODE pPdm;
363 rc = CFGMR3InsertNode(pRoot, "PDM", &pPdm);
364 UPDATERC();
365 PCFGMNODE pDevices = NULL;
366 rc = CFGMR3InsertNode(pPdm, "Devices", &pDevices);
367 UPDATERC();
368 rc = CFGMR3InsertInteger(pDevices, "LoadBuiltin", 1); /* boolean */
369 UPDATERC();
370 PCFGMNODE pDrivers = NULL;
371 rc = CFGMR3InsertNode(pPdm, "Drivers", &pDrivers);
372 UPDATERC();
373 rc = CFGMR3InsertInteger(pDrivers, "LoadBuiltin", 1); /* boolean */
374 UPDATERC();
375
376
377 /*
378 * Devices
379 */
380 pDevices = NULL;
381 rc = CFGMR3InsertNode(pRoot, "Devices", &pDevices);
382 UPDATERC();
383 /* device */
384 PCFGMNODE pDev = NULL;
385 PCFGMNODE pInst = NULL;
386 PCFGMNODE pCfg = NULL;
387#if 0
388 PCFGMNODE pLunL0 = NULL;
389 PCFGMNODE pLunL1 = NULL;
390#endif
391
392 /*
393 * PC Arch.
394 */
395 rc = CFGMR3InsertNode(pDevices, "pcarch", &pDev);
396 UPDATERC();
397 rc = CFGMR3InsertNode(pDev, "0", &pInst);
398 UPDATERC();
399 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
400 UPDATERC();
401 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
402 UPDATERC();
403
404 /*
405 * PC Bios.
406 */
407 rc = CFGMR3InsertNode(pDevices, "pcbios", &pDev);
408 UPDATERC();
409 rc = CFGMR3InsertNode(pDev, "0", &pInst);
410 UPDATERC();
411 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
412 UPDATERC();
413 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
414 UPDATERC();
415 rc = CFGMR3InsertInteger(pCfg, "RamSize", cbMem);
416 UPDATERC();
417 rc = CFGMR3InsertString(pCfg, "BootDevice0", "IDE");
418 UPDATERC();
419 rc = CFGMR3InsertString(pCfg, "BootDevice1", "NONE");
420 UPDATERC();
421 rc = CFGMR3InsertString(pCfg, "BootDevice2", "NONE");
422 UPDATERC();
423 rc = CFGMR3InsertString(pCfg, "BootDevice3", "NONE");
424 UPDATERC();
425 rc = CFGMR3InsertString(pCfg, "HardDiskDevice", "piix3ide");
426 UPDATERC();
427 rc = CFGMR3InsertString(pCfg, "FloppyDevice", "i82078");
428 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC();
429 RTUUID Uuid;
430 RTUuidClear(&Uuid);
431 rc = CFGMR3InsertBytes(pCfg, "UUID", &Uuid, sizeof(Uuid)); UPDATERC();
432 /* Bios logo. */
433 rc = CFGMR3InsertInteger(pCfg, "FadeIn", 0);
434 UPDATERC();
435 rc = CFGMR3InsertInteger(pCfg, "FadeOut", 0);
436 UPDATERC();
437 rc = CFGMR3InsertInteger(pCfg, "LogoTime", 0);
438 UPDATERC();
439 rc = CFGMR3InsertString(pCfg, "LogoFile", "");
440 UPDATERC();
441
442 /*
443 * ACPI
444 */
445 rc = CFGMR3InsertNode(pDevices, "acpi", &pDev); UPDATERC();
446 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
447 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
448 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
449 rc = CFGMR3InsertInteger(pCfg, "RamSize", cbMem); UPDATERC();
450 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC();
451 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 7); UPDATERC();
452 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC();
453
454 /*
455 * DMA
456 */
457 rc = CFGMR3InsertNode(pDevices, "8237A", &pDev); UPDATERC();
458 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
459 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
460
461 /*
462 * PCI bus.
463 */
464 rc = CFGMR3InsertNode(pDevices, "pci", &pDev); /* piix3 */
465 UPDATERC();
466 rc = CFGMR3InsertNode(pDev, "0", &pInst);
467 UPDATERC();
468 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
469 UPDATERC();
470 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
471 UPDATERC();
472 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC();
473
474 /*
475 * PS/2 keyboard & mouse
476 */
477 rc = CFGMR3InsertNode(pDevices, "pckbd", &pDev);
478 UPDATERC();
479 rc = CFGMR3InsertNode(pDev, "0", &pInst);
480 UPDATERC();
481 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
482 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
483 UPDATERC();
484
485 /*
486 * Floppy
487 */
488 rc = CFGMR3InsertNode(pDevices, "i82078", &pDev); UPDATERC();
489 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
490 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); UPDATERC();
491 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
492 rc = CFGMR3InsertInteger(pCfg, "IRQ", 6); UPDATERC();
493 rc = CFGMR3InsertInteger(pCfg, "DMA", 2); UPDATERC();
494 rc = CFGMR3InsertInteger(pCfg, "MemMapped", 0 ); UPDATERC();
495 rc = CFGMR3InsertInteger(pCfg, "IOBase", 0x3f0); UPDATERC();
496
497 /*
498 * i8254 Programmable Interval Timer And Dummy Speaker
499 */
500 rc = CFGMR3InsertNode(pDevices, "i8254", &pDev);
501 UPDATERC();
502 rc = CFGMR3InsertNode(pDev, "0", &pInst);
503 UPDATERC();
504 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
505 UPDATERC();
506
507 /*
508 * i8259 Programmable Interrupt Controller.
509 */
510 rc = CFGMR3InsertNode(pDevices, "i8259", &pDev);
511 UPDATERC();
512 rc = CFGMR3InsertNode(pDev, "0", &pInst);
513 UPDATERC();
514 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
515 UPDATERC();
516 rc = CFGMR3InsertNode(pInst, "Config", &pCfg);
517 UPDATERC();
518
519 /*
520 * APIC.
521 */
522 rc = CFGMR3InsertNode(pDevices, "apic", &pDev); UPDATERC();
523 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
524 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
525 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
526 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); UPDATERC();
527
528 if (fIOAPIC)
529 {
530 /*
531 * I/O Advanced Programmable Interrupt Controller.
532 */
533 rc = CFGMR3InsertNode(pDevices, "ioapic", &pDev); UPDATERC();
534 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
535 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
536 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
537 }
538
539
540 /*
541 * RTC MC146818.
542 */
543 rc = CFGMR3InsertNode(pDevices, "mc146818", &pDev); UPDATERC();
544 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
545 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
546
547 /*
548 * VGA.
549 */
550 rc = CFGMR3InsertNode(pDevices, "vga", &pDev); UPDATERC();
551 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
552 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
553 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 2); UPDATERC();
554 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC();
555 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
556 rc = CFGMR3InsertInteger(pCfg, "VRamSize", 8 * _1M); UPDATERC();
557 rc = CFGMR3InsertInteger(pCfg, "CustomVideoModes", 0);
558 rc = CFGMR3InsertInteger(pCfg, "HeightReduction", 0); UPDATERC();
559 //rc = CFGMR3InsertInteger(pCfg, "MonitorCount", 1); UPDATERC();
560
561 /*
562 * IDE controller.
563 */
564 rc = CFGMR3InsertNode(pDevices, "piix3ide", &pDev); /* piix3 */
565 UPDATERC();
566 rc = CFGMR3InsertNode(pDev, "0", &pInst);
567 UPDATERC();
568 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */
569 UPDATERC();
570 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
571 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 1); UPDATERC();
572 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 1); UPDATERC();
573
574 /*
575 * Network card.
576 */
577 rc = CFGMR3InsertNode(pDevices, "pcnet", &pDev); UPDATERC();
578 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
579 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
580 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 3); UPDATERC();
581 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC();
582 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
583 rc = CFGMR3InsertInteger(pCfg, "Am79C973", 1); UPDATERC();
584 RTMAC Mac;
585 Mac.au16[0] = 0x0080;
586 Mac.au16[2] = Mac.au16[1] = 0x8086;
587 rc = CFGMR3InsertBytes(pCfg, "MAC", &Mac, sizeof(Mac)); UPDATERC();
588
589 /*
590 * VMM Device
591 */
592 rc = CFGMR3InsertNode(pDevices, "VMMDev", &pDev); UPDATERC();
593 rc = CFGMR3InsertNode(pDev, "0", &pInst); UPDATERC();
594 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATERC();
595 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ UPDATERC();
596 rc = CFGMR3InsertInteger(pInst, "PCIDeviceNo", 4); UPDATERC();
597 rc = CFGMR3InsertInteger(pInst, "PCIFunctionNo", 0); UPDATERC();
598
599 /*
600 * ...
601 */
602
603#undef UPDATERC
604 return rcAll;
605}
606
607static void syntax(void)
608{
609 RTPrintf("Syntax: tstAnimate < -r <raw-mem-file> | -z <saved-state> > \n"
610 " [-o <rawmem offset>]\n"
611 " [-s <script file>]\n"
612 " [-m <memory size>]\n"
613 " [-w <warp drive percent>]\n"
614 " [-p]\n"
615 "\n"
616 "The script is on the form:\n"
617 "<reg>=<value>\n");
618}
619
620
621/**
622 * Entry point.
623 */
624extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
625{
626 int rcRet = 1;
627 int rc;
628 RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
629
630 /*
631 * Parse input.
632 */
633 if (argc <= 1)
634 {
635 syntax();
636 return 1;
637 }
638
639 bool fPowerOn = false;
640 uint32_t u32WarpDrive = 100; /* % */
641 uint64_t cbMem = ~0ULL;
642 const char *pszSavedState = NULL;
643 const char *pszRawMem = NULL;
644 uint64_t offRawMem = 0;
645 const char *pszScript = NULL;
646 for (int i = 1; i < argc; i++)
647 {
648 if (argv[i][0] == '-')
649 {
650 /* check that it's on short form */
651 if (argv[i][2])
652 {
653 if ( strcmp(argv[i], "--help")
654 && strcmp(argv[i], "-help"))
655 RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]);
656 else
657 syntax();
658 return 1;
659 }
660
661 /* check for 2nd argument */
662 switch (argv[i][1])
663 {
664 case 'r':
665 case 'o':
666 case 'c':
667 case 'm':
668 case 'w':
669 case 'z':
670 if (i + 1 < argc)
671 break;
672 RTPrintf("tstAnimate: Syntax error: '%s' takes a 2nd argument.\n", argv[i]);
673 return 1;
674 }
675
676 /* process argument */
677 switch (argv[i][1])
678 {
679 case 'r':
680 pszRawMem = argv[++i];
681 break;
682
683 case 'z':
684 pszSavedState = argv[++i];
685 break;
686
687 case 'o':
688 {
689 rc = RTStrToUInt64Ex(argv[++i], NULL, 0, &offRawMem);
690 if (RT_FAILURE(rc))
691 {
692 RTPrintf("tstAnimate: Syntax error: Invalid offset given to -o.\n");
693 return 1;
694 }
695 break;
696 }
697
698 case 'm':
699 {
700 char *pszNext;
701 rc = RTStrToUInt64Ex(argv[++i], &pszNext, 0, &cbMem);
702 if (RT_FAILURE(rc))
703 {
704 RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n");
705 return 1;
706 }
707 switch (*pszNext)
708 {
709 case 'G': cbMem *= _1G; pszNext++; break;
710 case 'M': cbMem *= _1M; pszNext++; break;
711 case 'K': cbMem *= _1K; pszNext++; break;
712 case '\0': break;
713 default:
714 RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n");
715 return 1;
716 }
717 if (*pszNext)
718 {
719 RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n");
720 return 1;
721 }
722 break;
723 }
724
725 case 's':
726 pszScript = argv[++i];
727 break;
728
729 case 'p':
730 fPowerOn = true;
731 break;
732
733 case 'w':
734 {
735 rc = RTStrToUInt32Ex(argv[++i], NULL, 0, &u32WarpDrive);
736 if (RT_FAILURE(rc))
737 {
738 RTPrintf("tstAnimate: Syntax error: Invalid number given to -w.\n");
739 return 1;
740 }
741 break;
742 }
743
744 case 'h':
745 case 'H':
746 case '?':
747 syntax();
748 return 1;
749
750 default:
751 RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]);
752 return 1;
753 }
754 }
755 else
756 {
757 RTPrintf("tstAnimate: Syntax error at arg no. %d '%s'.\n", i, argv[i]);
758 syntax();
759 return 1;
760 }
761 }
762
763 /*
764 * Check that the basic requirements are met.
765 */
766 if (pszRawMem && pszSavedState)
767 {
768 RTPrintf("tstAnimate: Syntax error: Either -z or -r, not both.\n");
769 return 1;
770 }
771 if (!pszRawMem && !pszSavedState)
772 {
773 RTPrintf("tstAnimate: Syntax error: The -r argument is compulsory.\n");
774 return 1;
775 }
776
777 /*
778 * Open the files.
779 */
780 RTFILE FileRawMem = NIL_RTFILE;
781 if (pszRawMem)
782 {
783 rc = RTFileOpen(&FileRawMem, pszRawMem, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
784 if (RT_FAILURE(rc))
785 {
786 RTPrintf("tstAnimate: error: Failed to open '%s': %Rrc\n", pszRawMem, rc);
787 return 1;
788 }
789 }
790 RTFILE FileScript = NIL_RTFILE;
791 if (pszScript)
792 {
793 rc = RTFileOpen(&FileScript, pszScript, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
794 if (RT_FAILURE(rc))
795 {
796 RTPrintf("tstAnimate: error: Failed to open '%s': %Rrc\n", pszScript, rc);
797 return 1;
798 }
799 }
800
801 /*
802 * Figure the memsize if not specified.
803 */
804 if (cbMem == ~0ULL)
805 {
806 if (FileRawMem != NIL_RTFILE)
807 {
808 rc = RTFileGetSize(FileRawMem, &cbMem);
809 AssertReleaseRC(rc);
810 cbMem -= offRawMem;
811 cbMem &= ~(PAGE_SIZE - 1);
812 }
813 else
814 {
815 RTPrintf("tstAnimate: error: too lazy to figure out the memsize in a saved state.\n");
816 return 1;
817 }
818 }
819 RTPrintf("tstAnimate: info: cbMem=0x%llx bytes\n", cbMem);
820
821 /*
822 * Open a release log.
823 */
824 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
825 PRTLOGGER pRelLogger;
826 rc = RTLogCreate(&pRelLogger, RTLOGFLAGS_PREFIX_TIME_PROG, "all", "VBOX_RELEASE_LOG",
827 RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_FILE, "./tstAnimate.log");
828 if (RT_SUCCESS(rc))
829 RTLogRelSetDefaultInstance(pRelLogger);
830 else
831 RTPrintf("tstAnimate: rtLogCreateEx failed - %Rrc\n", rc);
832
833 /*
834 * Create empty VM.
835 */
836 PVM pVM;
837 PUVM pUVM;
838 rc = VMR3Create(1, NULL, NULL, NULL, cfgmR3CreateDefault, &cbMem, &pVM, &pUVM);
839 if (RT_SUCCESS(rc))
840 {
841 /*
842 * Load memory.
843 */
844 if (FileRawMem != NIL_RTFILE)
845 rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)loadMem, 3, pVM, FileRawMem, &offRawMem);
846 else
847 rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)SSMR3Load,
848 7, pVM, pszSavedState, (uintptr_t)NULL /*pStreamOps*/, (uintptr_t)NULL /*pvUser*/,
849 SSMAFTER_DEBUG_IT, (uintptr_t)NULL /*pfnProgress*/, (uintptr_t)NULL /*pvProgressUser*/);
850 if (RT_SUCCESS(rc))
851 {
852 /*
853 * Load register script.
854 */
855 if (FileScript != NIL_RTFILE)
856 rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)scriptRun, 2, pVM, FileScript);
857 if (RT_SUCCESS(rc))
858 {
859 if (fPowerOn)
860 {
861 /*
862 * Adjust warpspeed?
863 */
864 if (u32WarpDrive != 100)
865 {
866 rc = TMR3SetWarpDrive(pUVM, u32WarpDrive);
867 if (RT_FAILURE(rc))
868 RTPrintf("warning: TMVirtualSetWarpDrive(,%u) -> %Rrc\n", u32WarpDrive, rc);
869 }
870
871 /*
872 * Start the thing with single stepping and stuff enabled.
873 * (Try make sure we don't execute anything in raw mode.)
874 */
875 RTPrintf("info: powering on the VM...\n");
876 RTLogGroupSettings(NULL, "+REM_DISAS.e.l.f");
877#ifdef VBOX_WITH_REM
878 rc = REMR3DisasEnableStepping(pVM, true);
879#else
880 rc = VERR_NOT_IMPLEMENTED; /** @todo need some EM single-step indicator */
881#endif
882 if (RT_SUCCESS(rc))
883 {
884 rc = EMR3SetExecutionPolicy(pUVM, EMEXECPOLICY_RECOMPILE_RING0, true); AssertReleaseRC(rc);
885 rc = EMR3SetExecutionPolicy(pUVM, EMEXECPOLICY_RECOMPILE_RING3, true); AssertReleaseRC(rc);
886 DBGFR3Info(pUVM, "cpumguest", "verbose", NULL);
887 if (fPowerOn)
888 rc = VMR3PowerOn(pUVM);
889 if (RT_SUCCESS(rc))
890 {
891 RTPrintf("info: VM is running\n");
892 signal(SIGINT, SigInterrupt);
893 while (!g_fSignaled)
894 RTThreadSleep(1000);
895 }
896 else
897 RTPrintf("error: Failed to power on the VM: %Rrc\n", rc);
898 }
899 else
900 RTPrintf("error: Failed to enabled singlestepping: %Rrc\n", rc);
901 }
902 else
903 {
904 /*
905 * Don't start it, just enter the debugger.
906 */
907 RTPrintf("info: entering debugger...\n");
908 DBGFR3Info(pUVM, "cpumguest", "verbose", NULL);
909 signal(SIGINT, SigInterrupt);
910 while (!g_fSignaled)
911 RTThreadSleep(1000);
912 }
913 RTPrintf("info: shutting down the VM...\n");
914 }
915 /* execScript complains */
916 }
917 else if (FileRawMem == NIL_RTFILE) /* loadMem complains, SSMR3Load doesn't */
918 RTPrintf("tstAnimate: error: SSMR3Load failed: rc=%Rrc\n", rc);
919 rcRet = RT_SUCCESS(rc) ? 0 : 1;
920
921 /*
922 * Cleanup.
923 */
924 rc = VMR3Destroy(pUVM);
925 if (!RT_SUCCESS(rc))
926 {
927 RTPrintf("tstAnimate: error: failed to destroy vm! rc=%Rrc\n", rc);
928 rcRet++;
929 }
930
931 VMR3ReleaseUVM(pUVM);
932 }
933 else
934 {
935 RTPrintf("tstAnimate: fatal error: failed to create vm! rc=%Rrc\n", rc);
936 rcRet++;
937 }
938
939 return rcRet;
940}
941
942
943#if !defined(VBOX_WITH_HARDENING) || !defined(RT_OS_WINDOWS)
944/**
945 * Main entry point.
946 */
947int main(int argc, char **argv, char **envp)
948{
949 return TrustedMain(argc, argv, envp);
950}
951#endif
952
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