VirtualBox

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

Last change on this file since 73768 was 71925, checked in by vboxsync, 6 years ago

iom.h: Fixed buggy IOMMMIO_DOES_WRITE_MODE_ALLOW_QWORD macro (only affected NVMe I think).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.3 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 */
163#define IOMMMIO_DOES_WRITE_MODE_ALLOW_QWORD(a_fFlags) \
164 ( ((a_fFlags) & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_DWORD_QWORD_ZEROED \
165 || ((a_fFlags) & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING \
166 || ((a_fFlags) & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD )
167
168
169/**
170 * Port I/O Handler for IN operations.
171 *
172 * @returns VINF_SUCCESS or VINF_EM_*.
173 * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
174 *
175 * @param pDevIns The device instance.
176 * @param pvUser User argument.
177 * @param uPort Port number used for the IN operation.
178 * @param pu32 Where to store the result. This is always a 32-bit
179 * variable regardless of what @a cb might say.
180 * @param cb Number of bytes read.
181 * @remarks Caller enters the device critical section.
182 */
183typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb);
184/** Pointer to a FNIOMIOPORTIN(). */
185typedef FNIOMIOPORTIN *PFNIOMIOPORTIN;
186
187/**
188 * Port I/O Handler for string IN operations.
189 *
190 * @returns VINF_SUCCESS or VINF_EM_*.
191 * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
192 *
193 * @param pDevIns The device instance.
194 * @param pvUser User argument.
195 * @param uPort Port number used for the IN operation.
196 * @param pbDst Pointer to the destination buffer.
197 * @param pcTransfers Pointer to the number of transfer units to read, on
198 * return remaining transfer units.
199 * @param cb Size of the transfer unit (1, 2 or 4 bytes).
200 * @remarks Caller enters the device critical section.
201 */
202typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint8_t *pbDst,
203 uint32_t *pcTransfers, unsigned cb);
204/** Pointer to a FNIOMIOPORTINSTRING(). */
205typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING;
206
207/**
208 * Port I/O Handler for OUT operations.
209 *
210 * @returns VINF_SUCCESS or VINF_EM_*.
211 *
212 * @param pDevIns The device instance.
213 * @param pvUser User argument.
214 * @param uPort Port number used for the OUT operation.
215 * @param u32 The value to output.
216 * @param cb The value size in bytes.
217 * @remarks Caller enters the device critical section.
218 */
219typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb);
220/** Pointer to a FNIOMIOPORTOUT(). */
221typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT;
222
223/**
224 * Port I/O Handler for string OUT operations.
225 *
226 * @returns VINF_SUCCESS or VINF_EM_*.
227 *
228 * @param pDevIns The device instance.
229 * @param pvUser User argument.
230 * @param uPort Port number used for the OUT operation.
231 * @param pbSrc Pointer to the source buffer.
232 * @param pcTransfers Pointer to the number of transfer units to write, on
233 * return remaining transfer units.
234 * @param cb Size of the transfer unit (1, 2 or 4 bytes).
235 * @remarks Caller enters the device critical section.
236 */
237typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, const uint8_t *pbSrc,
238 uint32_t *pcTransfers, unsigned cb);
239/** Pointer to a FNIOMIOPORTOUTSTRING(). */
240typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING;
241
242
243/**
244 * Memory mapped I/O Handler for read operations.
245 *
246 * @returns VBox status code.
247 *
248 * @param pDevIns The device instance.
249 * @param pvUser User argument.
250 * @param GCPhysAddr Physical address (in GC) where the read starts.
251 * @param pv Where to store the result.
252 * @param cb Number of bytes read.
253 * @remarks Caller enters the device critical section.
254 */
255typedef DECLCALLBACK(int) FNIOMMMIOREAD(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
256/** Pointer to a FNIOMMMIOREAD(). */
257typedef FNIOMMMIOREAD *PFNIOMMMIOREAD;
258
259/**
260 * Memory mapped I/O Handler for write operations.
261 *
262 * @returns VBox status code.
263 *
264 * @param pDevIns The device instance.
265 * @param pvUser User argument.
266 * @param GCPhysAddr Physical address (in GC) where the read starts.
267 * @param pv Where to fetch the result.
268 * @param cb Number of bytes to write.
269 * @remarks Caller enters the device critical section.
270 */
271typedef DECLCALLBACK(int) FNIOMMMIOWRITE(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
272/** Pointer to a FNIOMMMIOWRITE(). */
273typedef FNIOMMMIOWRITE *PFNIOMMMIOWRITE;
274
275/**
276 * Memory mapped I/O Handler for memset operations, actually for REP STOS* instructions handling.
277 *
278 * @returns VBox status code.
279 *
280 * @param pDevIns The device instance.
281 * @param pvUser User argument.
282 * @param GCPhysAddr Physical address (in GC) where the write starts.
283 * @param u32Item Byte/Word/Dword data to fill.
284 * @param cbItem Size of data in u32Item parameter, restricted to 1/2/4 bytes.
285 * @param cItems Number of iterations.
286 * @remarks Caller enters the device critical section.
287 */
288typedef DECLCALLBACK(int) FNIOMMMIOFILL(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
289/** Pointer to a FNIOMMMIOFILL(). */
290typedef FNIOMMMIOFILL *PFNIOMMMIOFILL;
291
292VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
293VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
294VMM_INT_DECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, void *pvDst,
295 uint32_t *pcTransfers, unsigned cb);
296VMM_INT_DECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT uPort, void const *pvSrc,
297 uint32_t *pcTransfers, unsigned cb);
298VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
299VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
300VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue);
301VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue);
302VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault);
303VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags);
304VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags);
305VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys);
306VMMDECL(bool) IOMIsLockWriteOwner(PVM pVM);
307
308#ifdef IN_RC
309/** @defgroup grp_iom_rc The IOM Raw-Mode Context API
310 * @{
311 */
312VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
313/** @} */
314#endif /* IN_RC */
315
316
317
318#ifdef IN_RING3
319/** @defgroup grp_iom_r3 The IOM Host Context Ring-3 API
320 * @{
321 */
322VMMR3_INT_DECL(int) IOMR3Init(PVM pVM);
323VMMR3_INT_DECL(void) IOMR3Reset(PVM pVM);
324VMMR3_INT_DECL(void) IOMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
325VMMR3_INT_DECL(int) IOMR3Term(PVM pVM);
326VMMR3_INT_DECL(int) IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTHCPTR pvUser,
327 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
328 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStringCallback, R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStringCallback,
329 const char *pszDesc);
330VMMR3_INT_DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTRCPTR pvUser,
331 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
332 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback,
333 const char *pszDesc);
334VMMR3_INT_DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTR0PTR pvUser,
335 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
336 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback,
337 const char *pszDesc);
338VMMR3_INT_DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts);
339
340VMMR3_INT_DECL(int) IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
341 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
342 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
343 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback,
344 uint32_t fFlags, const char *pszDesc);
345VMMR3_INT_DECL(int) IOMR3MmioRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTR0PTR pvUser,
346 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
347 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
348 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback);
349VMMR3_INT_DECL(int) IOMR3MmioRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTGCPTR pvUser,
350 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
351 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
352 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback);
353VMMR3_INT_DECL(int) IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange);
354VMMR3_INT_DECL(int) IOMR3MmioExPreRegister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS cbRange,
355 uint32_t fFlags, const char *pszDesc,
356 RTR3PTR pvUserR3,
357 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR3,
358 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR3,
359 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR3,
360 RTR0PTR pvUserR0,
361 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0,
362 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0,
363 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0,
364 RTRCPTR pvUserRC,
365 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackRC,
366 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackRC,
367 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackRC);
368VMMR3_INT_DECL(int) IOMR3MmioExNotifyMapped(PVM pVM, void *pvUser, RTGCPHYS GCPhys);
369VMMR3_INT_DECL(void) IOMR3MmioExNotifyUnmapped(PVM pVM, void *pvUser, RTGCPHYS GCPhys);
370VMMR3_INT_DECL(void) IOMR3MmioExNotifyDeregistered(PVM pVM, void *pvUser);
371
372VMMR3_INT_DECL(VBOXSTRICTRC) IOMR3ProcessForceFlag(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rcStrict);
373
374VMMR3_INT_DECL(void) IOMR3NotifyBreakpointCountChange(PVM pVM, bool fPortIo, bool fMmio);
375VMMR3_INT_DECL(void) IOMR3NotifyDebugEventChange(PVM pVM, DBGFEVENT enmEvent, bool fEnabled);
376
377/** @} */
378#endif /* IN_RING3 */
379
380
381/** @} */
382
383RT_C_DECLS_END
384
385#endif
386
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use