VirtualBox

source: vbox/trunk/src/VBox/Devices/VMMDev/VMMDevTesting.cpp@ 41413

Last change on this file since 41413 was 41413, checked in by vboxsync, 13 years ago

VMMDevTesting.cpp: Output to log and release log.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.2 KB
Line 
1/* $Id: VMMDevTesting.cpp 41413 2012-05-23 09:45:54Z vboxsync $ */
2/** @file
3 * VMMDev - Testing Extensions.
4 */
5
6/*
7 * Copyright (C) 2010 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#define LOG_GROUP LOG_GROUP_DEV_VMM
23#include <VBox/VMMDev.h>
24#include <VBox/log.h>
25#include <VBox/err.h>
26
27#include <iprt/asm.h>
28#include <iprt/assert.h>
29#include <iprt/string.h>
30#include <iprt/time.h>
31#ifdef IN_RING3
32# include <iprt/stream.h>
33#endif
34
35#include "VMMDevState.h"
36#include "VMMDevTesting.h"
37
38
39#ifndef VBOX_WITHOUT_TESTING_FEATURES
40
41#define VMMDEV_TESTING_OUTPUT(a) \
42 do \
43 { \
44 LogAlways(a);\
45 LogRel(a);\
46 RTPrintf a; \
47 } while (0)
48
49/**
50 * @callback_method_impl{FNIOMMMIOWRITE}
51 */
52PDMBOTHCBDECL(int) vmmdevTestingMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
53{
54 switch (GCPhysAddr)
55 {
56 case VMMDEV_TESTING_MMIO_NOP:
57 switch (cb)
58 {
59 case 8:
60 case 4:
61 case 2:
62 case 1:
63 break;
64 default:
65 AssertFailed();
66 return VERR_INTERNAL_ERROR_5;
67 }
68 return VINF_SUCCESS;
69
70 default:
71 break;
72 }
73 return VINF_SUCCESS;
74}
75
76
77/**
78 * @callback_method_impl{FNIOMMMIOREAD}
79 */
80PDMBOTHCBDECL(int) vmmdevTestingMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
81{
82 switch (GCPhysAddr)
83 {
84 case VMMDEV_TESTING_MMIO_NOP:
85 switch (cb)
86 {
87 case 8:
88 *(uint64_t *)pv = VMMDEV_TESTING_NOP_RET | ((uint64_t)VMMDEV_TESTING_NOP_RET << 32);
89 break;
90 case 4:
91 *(uint32_t *)pv = VMMDEV_TESTING_NOP_RET;
92 break;
93 case 2:
94 *(uint16_t *)pv = (uint16_t)VMMDEV_TESTING_NOP_RET;
95 break;
96 case 1:
97 *(uint8_t *)pv = (uint8_t)VMMDEV_TESTING_NOP_RET;
98 break;
99 default:
100 AssertFailed();
101 return VERR_INTERNAL_ERROR_5;
102 }
103 return VINF_SUCCESS;
104
105
106 default:
107 break;
108 }
109
110 return VINF_IOM_MMIO_UNUSED_FF;
111}
112
113
114/**
115 * @callback_method_impl{FNIOMIOPORTOUT}
116 */
117PDMBOTHCBDECL(int) vmmdevTestingIoWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
118{
119 VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState *);
120
121 switch (Port)
122 {
123 case VMMDEV_TESTING_IOPORT_NOP:
124 switch (cb)
125 {
126 case 4:
127 case 2:
128 case 1:
129 break;
130 default:
131 AssertFailed();
132 return VERR_INTERNAL_ERROR_2;
133 }
134 return VINF_SUCCESS;
135
136 case VMMDEV_TESTING_IOPORT_TS_LOW:
137 break;
138
139 case VMMDEV_TESTING_IOPORT_TS_HIGH:
140 break;
141
142 case VMMDEV_TESTING_IOPORT_CMD:
143 if (cb == 4)
144 {
145 pThis->u32TestingCmd = u32;
146 pThis->offTestingData = 0;
147 RT_ZERO(pThis->TestingData);
148 return VINF_SUCCESS;
149 }
150 break;
151
152 case VMMDEV_TESTING_IOPORT_DATA:
153 {
154 uint32_t uCmd = pThis->u32TestingCmd;
155 uint32_t off = pThis->offTestingData;
156 switch (uCmd)
157 {
158 case VMMDEV_TESTING_CMD_INIT:
159 case VMMDEV_TESTING_CMD_SUB_NEW:
160 case VMMDEV_TESTING_CMD_FAILED:
161 if ( off < sizeof(pThis->TestingData.String.sz) - 1
162 && cb == 1)
163 {
164 if (u32)
165 {
166 pThis->TestingData.String.sz[off] = u32;
167 pThis->offTestingData = off + 1;
168 }
169 else
170 {
171#ifdef IN_RING3
172 switch (uCmd)
173 {
174 case VMMDEV_TESTING_CMD_INIT:
175 VMMDEV_TESTING_OUTPUT(("testing: INIT '%.*s'\n",
176 sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz));
177 break;
178 case VMMDEV_TESTING_CMD_SUB_NEW:
179 VMMDEV_TESTING_OUTPUT(("testing: SUB_NEW '%.*s'\n",
180 sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz));
181 break;
182 case VMMDEV_TESTING_CMD_FAILED:
183 VMMDEV_TESTING_OUTPUT(("testing: FAILED '%.*s'\n",
184 sizeof(pThis->TestingData.String.sz) - 1, pThis->TestingData.String.sz));
185 break;
186 }
187#else
188 return VINF_IOM_R3_IOPORT_WRITE;
189#endif
190 }
191 return VINF_SUCCESS;
192 }
193 break;
194
195 case VMMDEV_TESTING_CMD_TERM:
196 case VMMDEV_TESTING_CMD_SUB_DONE:
197 if ( off == 0
198 && cb == 4)
199 {
200#ifdef IN_RING3
201 pThis->TestingData.Error.c = u32;
202 if (uCmd == VMMDEV_TESTING_CMD_TERM)
203 VMMDEV_TESTING_OUTPUT(("testing: TERM - %u errors\n", u32));
204 else
205 VMMDEV_TESTING_OUTPUT(("testing: SUB_DONE - %u errors\n", u32));
206 return VINF_SUCCESS;
207#else
208 return VINF_IOM_R3_IOPORT_WRITE;
209#endif
210 }
211 break;
212
213 case VMMDEV_TESTING_CMD_VALUE:
214 if (cb == 4)
215 {
216 if (off == 0)
217 pThis->TestingData.Value.u64Value.s.Lo = u32;
218 else if (off == 4)
219 pThis->TestingData.Value.u64Value.s.Hi = u32;
220 else if (off == 8)
221 pThis->TestingData.Value.u32Unit = u32;
222 else
223 break;
224 pThis->offTestingData = off + 4;
225 return VINF_SUCCESS;
226 }
227 if ( off >= 12
228 && cb == 1
229 && off < sizeof(pThis->TestingData.Value.szName) - 1 - 12)
230 {
231 if (u32)
232 {
233 pThis->TestingData.Value.szName[off - 12] = u32;
234 pThis->offTestingData = off + 1;
235 }
236 else
237 {
238#ifdef IN_RING3
239 VMMDEV_TESTING_OUTPUT(("testing: VALUE '%.*s'%*s: %'9llu (%#llx) [%u]\n",
240 sizeof(pThis->TestingData.Value.szName) - 1, pThis->TestingData.Value.szName,
241 off - 12 > 48 ? 0 : 48 - (off - 12), "",
242 pThis->TestingData.Value.u64Value.u, pThis->TestingData.Value.u64Value.u,
243 pThis->TestingData.Value.u32Unit));
244#else
245 return VINF_IOM_R3_IOPORT_WRITE;
246#endif
247 }
248 return VINF_SUCCESS;
249
250#ifdef IN_RING3
251 pThis->TestingData.Error.c = u32;
252 if (uCmd == VMMDEV_TESTING_CMD_TERM)
253 VMMDEV_TESTING_OUTPUT(("testing: TERM - %u errors\n", u32));
254 else
255 VMMDEV_TESTING_OUTPUT(("testing: SUB_DONE - %u errors\n", u32));
256 return VINF_SUCCESS;
257#else
258 return VINF_IOM_R3_IOPORT_WRITE;
259#endif
260 }
261 break;
262
263 default:
264 break;
265 }
266 Log(("VMMDEV_TESTING_IOPORT_CMD: bad access; cmd=%#x off=%#x cb=%#x u32=%#x\n", uCmd, off, cb, u32));
267 return VINF_SUCCESS;
268 }
269
270 default:
271 break;
272 }
273
274 return VERR_IOM_IOPORT_UNUSED;
275}
276
277
278/**
279 * @callback_method_impl{FNIOMIOPORTIN}
280 */
281PDMBOTHCBDECL(int) vmmdevTestingIoRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
282{
283 VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState *);
284
285 switch (Port)
286 {
287 case VMMDEV_TESTING_IOPORT_NOP:
288 switch (cb)
289 {
290 case 4:
291 case 2:
292 case 1:
293 break;
294 default:
295 AssertFailed();
296 return VERR_INTERNAL_ERROR_2;
297 }
298 *pu32 = VMMDEV_TESTING_NOP_RET;
299 return VINF_SUCCESS;
300
301 case VMMDEV_TESTING_IOPORT_TS_LOW:
302 if (cb == 4)
303 {
304 uint64_t NowTS = RTTimeNanoTS();
305 *pu32 = (uint32_t)NowTS;
306 pThis->u32TestingHighTimestamp = (uint32_t)(NowTS >> 32);
307 return VINF_SUCCESS;
308 }
309 break;
310
311 case VMMDEV_TESTING_IOPORT_TS_HIGH:
312 if (cb == 4)
313 {
314 *pu32 = pThis->u32TestingHighTimestamp;
315 return VINF_SUCCESS;
316 }
317 break;
318
319 case VMMDEV_TESTING_IOPORT_CMD:
320 case VMMDEV_TESTING_IOPORT_DATA:
321 break;
322
323 default:
324 break;
325 }
326
327 return VERR_IOM_IOPORT_UNUSED;
328}
329
330
331#ifdef IN_RING3
332
333/**
334 * Initializes the testing part of the VMMDev if enabled.
335 *
336 * @returns VBox status code.
337 * @param pDevIns The VMMDev device instance.
338 */
339int vmmdevTestingInitialize(PPDMDEVINS pDevIns)
340{
341 VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState *);
342 if (!pThis->fTestingEnabled)
343 return VINF_SUCCESS;
344
345 /*
346 * Register a chunk of MMIO memory that we'll use for various
347 * tests interfaces.
348 */
349 int rc = PDMDevHlpMMIORegister(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NULL /*pvUser*/,
350 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
351 vmmdevTestingMmioWrite, vmmdevTestingMmioRead, "VMMDev Testing");
352 AssertRCReturn(rc, rc);
353 if (pThis->fRZEnabled)
354 {
355 rc = PDMDevHlpMMIORegisterR0(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NIL_RTR0PTR /*pvUser*/,
356 "vmmdevTestingMmioWrite", "vmmdevTestingMmioRead");
357 AssertRCReturn(rc, rc);
358 rc = PDMDevHlpMMIORegisterRC(pDevIns, VMMDEV_TESTING_MMIO_BASE, VMMDEV_TESTING_MMIO_SIZE, NIL_RTRCPTR /*pvUser*/,
359 "vmmdevTestingMmioWrite", "vmmdevTestingMmioRead");
360 AssertRCReturn(rc, rc);
361 }
362
363
364 /*
365 * Register the I/O ports used for testing.
366 */
367 rc = PDMDevHlpIOPortRegister(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NULL,
368 vmmdevTestingIoWrite,
369 vmmdevTestingIoRead,
370 NULL /*pfnOutStr*/,
371 NULL /*pfnInStr*/,
372 "VMMDev Testing");
373 AssertRCReturn(rc, rc);
374 if (pThis->fRZEnabled)
375 {
376 rc = PDMDevHlpIOPortRegisterR0(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NIL_RTR0PTR /*pvUser*/,
377 "vmmdevTestingIoWrite",
378 "vmmdevTestingIoRead",
379 NULL /*pszOutStr*/,
380 NULL /*pszInStr*/,
381 "VMMDev Testing");
382 AssertRCReturn(rc, rc);
383 rc = PDMDevHlpIOPortRegisterRC(pDevIns, VMMDEV_TESTING_IOPORT_BASE, VMMDEV_TESTING_IOPORT_COUNT, NIL_RTRCPTR /*pvUser*/,
384 "vmmdevTestingIoWrite",
385 "vmmdevTestingIoRead",
386 NULL /*pszOutStr*/,
387 NULL /*pszInStr*/,
388 "VMMDev Testing");
389 AssertRCReturn(rc, rc);
390 }
391
392 return VINF_SUCCESS;
393}
394
395#endif /* IN_RING3 */
396#endif /* !VBOX_WITHOUT_TESTING_FEATURES */
397
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