VirtualBox

source: vbox/trunk/include/VBox/vmm/iom.h@ 69206

Last change on this file since 69206 was 69107, checked in by vboxsync, 7 years ago

include/VBox/: (C) year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.1 KB
Line 
1/** @file
2 * IOM - Input / Output Monitor.
3 */
4
5/*
6 * Copyright (C) 2006-2017 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_vmm_iom_h
27#define ___VBox_vmm_iom_h
28
29#include <VBox/types.h>
30#include <VBox/dis.h>
31#include <VBox/vmm/dbgf.h>
32
33RT_C_DECLS_BEGIN
34
35
36/** @defgroup grp_iom The Input / Ouput Monitor API
37 * @ingroup grp_vmm
38 * @{
39 */
40
41/** @def IOM_NO_PDMINS_CHECKS
42 * Until all devices have been fully adjusted to PDM style, the pPdmIns
43 * parameter is not checked by IOM.
44 * @todo Check this again, now.
45 */
46#define IOM_NO_PDMINS_CHECKS
47
48/**
49 * Macro for checking if an I/O or MMIO emulation call succeeded.
50 *
51 * This macro shall only be used with the IOM APIs where it's mentioned
52 * in the return value description. And there it must be used to correctly
53 * determine if the call succeeded and things like the RIP needs updating.
54 *
55 *
56 * @returns Success indicator (true/false).
57 *
58 * @param rc The status code. This may be evaluated
59 * more than once!
60 *
61 * @remarks To avoid making assumptions about the layout of the
62 * VINF_EM_FIRST...VINF_EM_LAST range we're checking explicitly for
63 * each exact exception. However, for efficiency we ASSUME that the
64 * VINF_EM_LAST is smaller than most of the relevant status codes. We
65 * also ASSUME that the VINF_EM_RESCHEDULE_REM status code is the
66 * most frequent status code we'll enounter in this range.
67 *
68 * @todo Will have to add VINF_EM_DBG_HYPER_BREAKPOINT if the
69 * I/O port and MMIO breakpoints should trigger before
70 * the I/O is done. Currently, we don't implement these
71 * kind of breakpoints.
72 */
73#ifdef IN_RING3
74# define IOM_SUCCESS(rc) ( (rc) == VINF_SUCCESS \
75 || ( (rc) <= VINF_EM_LAST \
76 && (rc) != VINF_EM_RESCHEDULE_REM \
77 && (rc) >= VINF_EM_FIRST \
78 && (rc) != VINF_EM_RESCHEDULE_RAW \
79 && (rc) != VINF_EM_RESCHEDULE_HM \
80 ) \
81 )
82#else
83# define IOM_SUCCESS(rc) ( (rc) == VINF_SUCCESS \
84 || ( (rc) <= VINF_EM_LAST \
85 && (rc) != VINF_EM_RESCHEDULE_REM \
86 && (rc) >= VINF_EM_FIRST \
87 && (rc) != VINF_EM_RESCHEDULE_RAW \
88 && (rc) != VINF_EM_RESCHEDULE_HM \
89 ) \
90 || (rc) == VINF_IOM_R3_IOPORT_COMMIT_WRITE \
91 || (rc) == VINF_IOM_R3_MMIO_COMMIT_WRITE \
92 )
93#endif
94
95/** @name IOMMMIO_FLAGS_XXX
96 * @{ */
97/** Pass all reads thru unmodified. */
98#define IOMMMIO_FLAGS_READ_PASSTHRU UINT32_C(0x00000000)
99/** All read accesses are DWORD sized (32-bit). */
100#define IOMMMIO_FLAGS_READ_DWORD UINT32_C(0x00000001)
101/** All read accesses are DWORD (32-bit) or QWORD (64-bit) sized.
102 * Only accesses that are both QWORD sized and aligned are performed as QWORD.
103 * All other access will be done DWORD fashion (because it is way simpler). */
104#define IOMMMIO_FLAGS_READ_DWORD_QWORD UINT32_C(0x00000002)
105/** The read access mode mask. */
106#define IOMMMIO_FLAGS_READ_MODE UINT32_C(0x00000003)
107
108/** Pass all writes thru unmodified. */
109#define IOMMMIO_FLAGS_WRITE_PASSTHRU UINT32_C(0x00000000)
110/** All write accesses are DWORD (32-bit) sized and unspecified bytes are
111 * written as zero. */
112#define IOMMMIO_FLAGS_WRITE_DWORD_ZEROED UINT32_C(0x00000010)
113/** All write accesses are either DWORD (32-bit) or QWORD (64-bit) sized,
114 * missing bytes will be written as zero. Only accesses that are both QWORD
115 * sized and aligned are performed as QWORD, all other accesses will be done
116 * DWORD fashion (because it's way simpler). */
117#define IOMMMIO_FLAGS_WRITE_DWORD_QWORD_ZEROED UINT32_C(0x00000020)
118/** All write accesses are DWORD (32-bit) sized and unspecified bytes are
119 * read from the device first as DWORDs.
120 * @remarks This isn't how it happens on real hardware, but it allows
121 * simplifications of devices where reads doesn't change the device
122 * state in any way. */
123#define IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING UINT32_C(0x00000030)
124/** All write accesses are DWORD (32-bit) or QWORD (64-bit) sized and
125 * unspecified bytes are read from the device first as DWORDs. Only accesses
126 * that are both QWORD sized and aligned are performed as QWORD, all other
127 * accesses will be done DWORD fashion (because it's way simpler).
128 * @remarks This isn't how it happens on real hardware, but it allows
129 * simplifications of devices where reads doesn't change the device
130 * state in any way. */
131#define IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING UINT32_C(0x00000040)
132/** All write accesses are DWORD (32-bit) sized and aligned, attempts at other
133 * accesses are ignored.
134 * @remarks E1000, APIC */
135#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD UINT32_C(0x00000050)
136/** All write accesses are DWORD (32-bit) or QWORD (64-bit) sized and aligned,
137 * attempts at other accesses are ignored.
138 * @remarks Seemingly required by AHCI (although I doubt it's _really_
139 * required as EM/REM doesn't do the right thing in ring-3 anyway,
140 * esp. not in raw-mode). */
141#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD UINT32_C(0x00000060)
142/** The read access mode mask. */
143#define IOMMMIO_FLAGS_WRITE_MODE UINT32_C(0x00000070)
144
145/** Whether to do a DBGSTOP on complicated reads.
146 * What this includes depends on the read mode, but generally all misaligned
147 * reads as well as word and byte reads and maybe qword reads. */
148#define IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_READ UINT32_C(0x00000100)
149/** Whether to do a DBGSTOP on complicated writes.
150 * This depends on the write mode, but generally all writes where we have to
151 * supply bytes (zero them or read them). */
152#define IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_WRITE UINT32_C(0x00000200)
153
154/** Mask of valid flags. */
155#define IOMMMIO_FLAGS_VALID_MASK UINT32_C(0x00000373)
156/** @} */
157
158/**
159 * Checks whether the write mode allows aligned QWORD accesses to be passed
160 * thru to the device handler.
161 * @param a_fFlags The MMIO handler flags.
162 * @remarks The current implementation makes ASSUMPTIONS about the mode values!
163 */
164#define IOMMMIO_DOES_WRITE_MODE_ALLOW_QWORD(a_fFlags) RT_BOOL((a_fFlags) & UINT32_C(0x00000020))
165
166
167/**
168 * Port I/O Handler for IN operations.
169 *
170 * @returns VINF_SUCCESS or VINF_EM_*.
171 * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
172 *
173 * @param pDevIns The device instance.
174 * @param pvUser User argument.
175 * @param uPort Port number used for the IN operation.
176 * @param pu32 Where to store the result. This is always a 32-bit
177 * variable regardless of what @a cb might say.
178 * @param cb Number of bytes read.
179 * @remarks Caller enters the device critical section.
180 */
181typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb);
182/** Pointer to a FNIOMIOPORTIN(). */
183typedef FNIOMIOPORTIN *PFNIOMIOPORTIN;
184
185/**
186 * Port I/O Handler for string IN operations.
187 *
188 * @returns VINF_SUCCESS or VINF_EM_*.
189 * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
190 *
191 * @param pDevIns The device instance.
192 * @param pvUser User argument.
193 * @param uPort Port number used for the IN operation.
194 * @param pbDst Pointer to the destination buffer.
195 * @param pcTransfers Pointer to the number of transfer units to read, on
196 * return remaining transfer units.
197 * @param cb Size of the transfer unit (1, 2 or 4 bytes).
198 * @remarks Caller enters the device critical section.
199 */
200typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint8_t *pbDst,
201 uint32_t *pcTransfers, unsigned cb);
202/** Pointer to a FNIOMIOPORTINSTRING(). */
203typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING;
204
205/**
206 * Port I/O Handler for OUT operations.
207 *
208 * @returns VINF_SUCCESS or VINF_EM_*.
209 *
210 * @param pDevIns The device instance.
211 * @param pvUser User argument.
212 * @param uPort Port number used for the OUT operation.
213 * @param u32 The value to output.
214 * @param cb The value size in bytes.
215 * @remarks Caller enters the device critical section.
216 */
217typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb);
218/** Pointer to a FNIOMIOPORTOUT(). */
219typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT;
220
221/**
222 * Port I/O Handler for string OUT operations.
223 *
224 * @returns VINF_SUCCESS or VINF_EM_*.
225 *
226 * @param pDevIns The device instance.
227 * @param pvUser User argument.
228 * @param uPort Port number used for the OUT operation.
229 * @param pbSrc Pointer to the source buffer.
230 * @param pcTransfers Pointer to the number of transfer units to write, on
231 * return remaining transfer units.
232 * @param cb Size of the transfer unit (1, 2 or 4 bytes).
233 * @remarks Caller enters the device critical section.
234 */
235typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, const uint8_t *pbSrc,
236 uint32_t *pcTransfers, unsigned cb);
237/** Pointer to a FNIOMIOPORTOUTSTRING(). */
238typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING;
239
240
241/**
242 * Memory mapped I/O Handler for read operations.
243 *
244 * @returns VBox status code.
245 *
246 * @param pDevIns The device instance.
247 * @param pvUser User argument.
248 * @param GCPhysAddr Physical address (in GC) where the read starts.
249 * @param pv Where to store the result.
250 * @param cb Number of bytes read.
251 * @remarks Caller enters the device critical section.
252 */
253typedef DECLCALLBACK(int) FNIOMMMIOREAD(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
254/** Pointer to a FNIOMMMIOREAD(). */
255typedef FNIOMMMIOREAD *PFNIOMMMIOREAD;
256
257/**
258 * Memory mapped I/O Handler for write operations.
259 *
260 * @returns VBox status code.
261 *
262 * @param pDevIns The device instance.
263 * @param pvUser User argument.
264 * @param GCPhysAddr Physical address (in GC) where the read starts.
265 * @param pv Where to fetch the result.
266 * @param cb Number of bytes to write.
267 * @remarks Caller enters the device critical section.
268 */
269typedef DECLCALLBACK(int) FNIOMMMIOWRITE(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
270/** Pointer to a FNIOMMMIOWRITE(). */
271typedef FNIOMMMIOWRITE *PFNIOMMMIOWRITE;
272
273/**
274 * Memory mapped I/O Handler for memset operations, actually for REP STOS* instructions handling.
275 *
276 * @returns VBox status code.
277 *
278 * @param pDevIns The device instance.
279 * @param pvUser User argument.
280 * @param GCPhysAddr Physical address (in GC) where the write starts.
281 * @param u32Item Byte/Word/Dword data to fill.
282 * @param cbItem Size of data in u32Item parameter, restricted to 1/2/4 bytes.
283 * @param cItems Number of iterations.
284 * @remarks Caller enters the device critical section.
285 */
286typedef DECLCALLBACK(int) FNIOMMMIOFILL(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
287/** Pointer to a FNIOMMMIOFILL(). */
288typedef FNIOMMMIOFILL *PFNIOMMMIOFILL;
289
290VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
291VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
292VMM_INT_DECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, void *pvDst,
293 uint32_t *pcTransfers, unsigned cb);
294VMM_INT_DECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT uPort, void const *pvSrc,
295 uint32_t *pcTransfers, unsigned cb);
296VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
297VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
298VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue);
299VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue);
300VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault);
301VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags);
302VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags);
303VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys);
304VMMDECL(bool) IOMIsLockWriteOwner(PVM pVM);
305
306#ifdef IN_RC
307/** @defgroup grp_iom_rc The IOM Raw-Mode Context API
308 * @{
309 */
310VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
311/** @} */
312#endif /* IN_RC */
313
314
315
316#ifdef IN_RING3
317/** @defgroup grp_iom_r3 The IOM Host Context Ring-3 API
318 * @{
319 */
320VMMR3_INT_DECL(int) IOMR3Init(PVM pVM);
321VMMR3_INT_DECL(void) IOMR3Reset(PVM pVM);
322VMMR3_INT_DECL(void) IOMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
323VMMR3_INT_DECL(int) IOMR3Term(PVM pVM);
324VMMR3_INT_DECL(int) IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTHCPTR pvUser,
325 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
326 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStringCallback, R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStringCallback,
327 const char *pszDesc);
328VMMR3_INT_DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTRCPTR pvUser,
329 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
330 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback,
331 const char *pszDesc);
332VMMR3_INT_DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTR0PTR pvUser,
333 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
334 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback,
335 const char *pszDesc);
336VMMR3_INT_DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts);
337
338VMMR3_INT_DECL(int) IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
339 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
340 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
341 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback,
342 uint32_t fFlags, const char *pszDesc);
343VMMR3_INT_DECL(int) IOMR3MmioRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTR0PTR pvUser,
344 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
345 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
346 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback);
347VMMR3_INT_DECL(int) IOMR3MmioRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTGCPTR pvUser,
348 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
349 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
350 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback);
351VMMR3_INT_DECL(int) IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange);
352VMMR3_INT_DECL(int) IOMR3MmioExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cbRange,
353 uint32_t fFlags, const char *pszDesc,
354 RTR3PTR pvUserR3,
355 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR3,
356 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR3,
357 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR3,
358 RTR0PTR pvUserR0,
359 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0,
360 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0,
361 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0,
362 RTRCPTR pvUserRC,
363 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackRC,
364 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackRC,
365 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackRC);
366VMMR3_INT_DECL(int) IOMR3MmioExNotifyMapped(PVM pVM, void *pvUser, RTGCPHYS GCPhys);
367VMMR3_INT_DECL(void) IOMR3MmioExNotifyUnmapped(PVM pVM, void *pvUser, RTGCPHYS GCPhys);
368VMMR3_INT_DECL(void) IOMR3MmioExNotifyDeregistered(PVM pVM, void *pvUser);
369
370VMMR3_INT_DECL(VBOXSTRICTRC) IOMR3ProcessForceFlag(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rcStrict);
371
372VMMR3_INT_DECL(void) IOMR3NotifyBreakpointCountChange(PVM pVM, bool fPortIo, bool fMmio);
373VMMR3_INT_DECL(void) IOMR3NotifyDebugEventChange(PVM pVM, DBGFEVENT enmEvent, bool fEnabled);
374
375/** @} */
376#endif /* IN_RING3 */
377
378
379/** @} */
380
381RT_C_DECLS_END
382
383#endif
384
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