VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c@ 69496

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

*: scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.3 KB
Line 
1/* $Id: VBoxGuest-haiku.c 69496 2017-10-28 14:55:58Z vboxsync $ */
2/** @file
3 * VBoxGuest kernel module, Haiku Guest Additions, implementation.
4 */
5
6/*
7 * Copyright (C) 2012-2017 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*
28 * This code is based on:
29 *
30 * VirtualBox Guest Additions for Haiku.
31 * Copyright (c) 2011 Mike Smith <[email protected]>
32 * François Revol <[email protected]>
33 *
34 * Permission is hereby granted, free of charge, to any person
35 * obtaining a copy of this software and associated documentation
36 * files (the "Software"), to deal in the Software without
37 * restriction, including without limitation the rights to use,
38 * copy, modify, merge, publish, distribute, sublicense, and/or sell
39 * copies of the Software, and to permit persons to whom the
40 * Software is furnished to do so, subject to the following
41 * conditions:
42 *
43 * The above copyright notice and this permission notice shall be
44 * included in all copies or substantial portions of the Software.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
47 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
48 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
49 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
50 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
51 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
52 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
53 * OTHER DEALINGS IN THE SOFTWARE.
54 */
55
56
57/*********************************************************************************************************************************
58* Header Files *
59*********************************************************************************************************************************/
60#define IN_VBOXGUEST
61#include <sys/param.h>
62#include <sys/types.h>
63#include <sys/uio.h>
64#include <OS.h>
65#include <Drivers.h>
66#include <KernelExport.h>
67#include <PCI.h>
68
69#include "VBoxGuest-haiku.h"
70#include "VBoxGuestInternal.h"
71#include <VBox/log.h>
72#include <iprt/assert.h>
73#include <iprt/initterm.h>
74#include <iprt/process.h>
75#include <iprt/mem.h>
76#include <iprt/memobj.h>
77#include <iprt/asm.h>
78#include <iprt/timer.h>
79#include <iprt/heap.h>
80
81
82/*********************************************************************************************************************************
83* Defined Constants And Macros *
84*********************************************************************************************************************************/
85#define MODULE_NAME VBOXGUEST_MODULE_NAME
86
87
88/*********************************************************************************************************************************
89* Internal Functions *
90*********************************************************************************************************************************/
91/*
92 * IRQ related functions.
93 */
94static void vgdrvHaikuRemoveIRQ(void *pvState);
95static int vgdrvHaikuAddIRQ(void *pvState);
96static int32 vgdrvHaikuISR(void *pvState);
97
98
99/*********************************************************************************************************************************
100* Global Variables *
101*********************************************************************************************************************************/
102static status_t std_ops(int32 op, ...);
103
104static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
105
106int32 api_version = B_CUR_DRIVER_API_VERSION;
107
108/** List of cloned device. Managed by the kernel. */
109//static struct clonedevs *g_pvgdrvHaikuClones;
110/** The dev_clone event handler tag. */
111//static eventhandler_tag g_vgdrvHaikuEHTag;
112/** selinfo structure used for polling. */
113//static struct selinfo g_SelInfo;
114/** PCI Bus Manager Module */
115static pci_module_info *gPCI;
116
117static struct vboxguest_module_info g_VBoxGuest =
118{
119 {
120 MODULE_NAME,
121 0,
122 std_ops
123 },
124 { 0 },
125 { 0 },
126 0,
127 RTLogBackdoorPrintf,
128 RTLogBackdoorPrintfV,
129 RTLogSetDefaultInstanceThread,
130 RTMemAllocExTag,
131 RTMemContAlloc,
132 RTMemContFree,
133 RTMemFreeEx,
134 RTMpIsCpuPossible,
135 RTMpNotificationDeregister,
136 RTMpNotificationRegister,
137 RTMpOnAll,
138 RTMpOnOthers,
139 RTMpOnSpecific,
140 RTPowerNotificationDeregister,
141 RTPowerNotificationRegister,
142 RTPowerSignalEvent,
143 RTR0AssertPanicSystem,
144 RTR0Init,
145 RTR0MemObjAddress,
146 RTR0MemObjAddressR3,
147 RTR0MemObjAllocContTag,
148 RTR0MemObjAllocLowTag,
149 RTR0MemObjAllocPageTag,
150 RTR0MemObjAllocPhysExTag,
151 RTR0MemObjAllocPhysNCTag,
152 RTR0MemObjAllocPhysTag,
153 RTR0MemObjEnterPhysTag,
154 RTR0MemObjFree,
155 RTR0MemObjGetPagePhysAddr,
156 RTR0MemObjIsMapping,
157 RTR0MemObjLockKernelTag,
158 RTR0MemObjLockUserTag,
159 RTR0MemObjMapKernelExTag,
160 RTR0MemObjMapKernelTag,
161 RTR0MemObjMapUserTag,
162 RTR0MemObjProtect,
163 RTR0MemObjReserveKernelTag,
164 RTR0MemObjReserveUserTag,
165 RTR0MemObjSize,
166 RTR0ProcHandleSelf,
167 RTR0Term,
168 RTR0TermForced,
169 RTProcSelf,
170 RTSemEventGetResolution,
171 RTSemEventMultiGetResolution,
172 RTSemEventMultiWaitEx,
173 RTSemEventMultiWaitExDebug,
174 RTSemEventWaitEx,
175 RTSemEventWaitExDebug,
176 RTThreadIsInInterrupt,
177 RTThreadPreemptDisable,
178 RTThreadPreemptIsEnabled,
179 RTThreadPreemptIsPending,
180 RTThreadPreemptIsPendingTrusty,
181 RTThreadPreemptIsPossible,
182 RTThreadPreemptRestore,
183 RTTimerGetSystemGranularity,
184 RTTimerReleaseSystemGranularity,
185 RTTimerRequestSystemGranularity,
186 RTSpinlockAcquire,
187 RTSpinlockRelease,
188 RTMemTmpAllocTag,
189 RTMemTmpFree,
190 RTLogDefaultInstance,
191 RTLogDefaultInstanceEx,
192 RTLogRelGetDefaultInstance,
193 RTLogRelGetDefaultInstanceEx,
194 RTErrConvertToErrno,
195 VGDrvCommonIoCtl,
196 VGDrvCommonCreateUserSession,
197 VGDrvCommonCloseSession,
198 VBoxGuestIDCOpen,
199 VBoxGuestIDCClose,
200 VBoxGuestIDCCall,
201 RTAssertMsg1Weak,
202 RTAssertMsg2Weak,
203 RTAssertMsg2WeakV,
204 RTAssertShouldPanic,
205 RTSemFastMutexCreate,
206 RTSemFastMutexDestroy,
207 RTSemFastMutexRelease,
208 RTSemFastMutexRequest,
209 RTSemMutexCreate,
210 RTSemMutexDestroy,
211 RTSemMutexRelease,
212 RTSemMutexRequest,
213 RTHeapSimpleRelocate,
214 RTHeapOffsetInit,
215 RTHeapSimpleInit,
216 RTHeapOffsetAlloc,
217 RTHeapSimpleAlloc,
218 RTHeapOffsetFree,
219 RTHeapSimpleFree
220};
221
222#if 0
223/**
224 * DEVFS event handler.
225 */
226static void vgdrvHaikuClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev)
227{
228 int iUnit;
229 int rc;
230
231 Log(("vgdrvHaikuClone: pszName=%s ppDev=%p\n", pszName, ppDev));
232
233 /*
234 * One device node per user, si_drv1 points to the session.
235 * /dev/vboxguest<N> where N = {0...255}.
236 */
237 if (!ppDev)
238 return;
239 if (strcmp(pszName, "vboxguest") == 0)
240 iUnit = -1;
241 else if (dev_stdclone(pszName, NULL, "vboxguest", &iUnit) != 1)
242 return;
243 if (iUnit >= 256)
244 {
245 Log(("vgdrvHaikuClone: iUnit=%d >= 256 - rejected\n", iUnit));
246 return;
247 }
248
249 Log(("vgdrvHaikuClone: pszName=%s iUnit=%d\n", pszName, iUnit));
250
251 rc = clone_create(&g_pvgdrvHaikuClones, &g_vgdrvHaikuDeviceHooks, &iUnit, ppDev, 0);
252 Log(("vgdrvHaikuClone: clone_create -> %d; iUnit=%d\n", rc, iUnit));
253 if (rc)
254 {
255 *ppDev = make_dev(&g_vgdrvHaikuDeviceHooks,
256 iUnit,
257 UID_ROOT,
258 GID_WHEEL,
259 0644,
260 "vboxguest%d", iUnit);
261 if (*ppDev)
262 {
263 dev_ref(*ppDev);
264 (*ppDev)->si_flags |= SI_CHEAPCLONE;
265 Log(("vgdrvHaikuClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
266 *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
267 (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL;
268 }
269 else
270 Log(("vgdrvHaikuClone: make_dev iUnit=%d failed\n", iUnit));
271 }
272 else
273 Log(("vgdrvHaikuClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
274 *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
275}
276#endif
277
278
279static status_t vgdrvHaikuDetach(void)
280{
281 struct VBoxGuestDeviceState *pState = &sState;
282
283 if (cUsers > 0)
284 return EBUSY;
285
286 /*
287 * Reverse what we did in vgdrvHaikuAttach.
288 */
289 vgdrvHaikuRemoveIRQ(pState);
290
291 if (pState->iVMMDevMemAreaId)
292 delete_area(pState->iVMMDevMemAreaId);
293
294 VGDrvCommonDeleteDevExt(&g_DevExt);
295
296#ifdef DO_LOG
297 RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
298 RTLogSetDefaultInstance(NULL);
299// RTLogDestroy(RTLogSetDefaultInstance(NULL));
300#endif
301
302 RTSpinlockDestroy(g_Spinlock);
303 g_Spinlock = NIL_RTSPINLOCK;
304
305 RTR0Term();
306 return B_OK;
307}
308
309
310/**
311 * Interrupt service routine.
312 *
313 * @returns Whether the interrupt was from VMMDev.
314 * @param pvState Opaque pointer to the device state.
315 */
316static int32 vgdrvHaikuISR(void *pvState)
317{
318 LogFlow((MODULE_NAME ":vgdrvHaikuISR pvState=%p\n", pvState));
319
320 bool fOurIRQ = VGDrvCommonISR(&g_DevExt);
321 if (fOurIRQ)
322 return B_HANDLED_INTERRUPT;
323 return B_UNHANDLED_INTERRUPT;
324}
325
326
327void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
328{
329 LogFlow(("VGDrvNativeISRMousePollEvent:\n"));
330
331 status_t err = B_OK;
332 //dprintf(MODULE_NAME ": isr mouse\n");
333
334 /*
335 * Wake up poll waiters.
336 */
337 //selwakeup(&g_SelInfo);
338 //XXX:notify_select_event();
339 RTSpinlockAcquire(g_Spinlock);
340
341 if (sState.selectSync)
342 {
343 //dprintf(MODULE_NAME ": isr mouse: notify\n");
344 notify_select_event(sState.selectSync, sState.selectEvent);
345 sState.selectEvent = (uint8_t)0;
346 sState.selectRef = (uint32_t)0;
347 sState.selectSync = NULL;
348 }
349 else
350 err = B_ERROR;
351
352 RTSpinlockRelease(g_Spinlock);
353}
354
355
356/**
357 * Sets IRQ for VMMDev.
358 *
359 * @returns Haiku error code.
360 * @param pvState Pointer to the state info structure.
361 */
362static int vgdrvHaikuAddIRQ(void *pvState)
363{
364 status_t err;
365 struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
366
367 AssertReturn(pState, VERR_INVALID_PARAMETER);
368
369 err = install_io_interrupt_handler(pState->iIrqResId, vgdrvHaikuISR, pState, 0);
370 if (err == B_OK)
371 return VINF_SUCCESS;
372 return VERR_DEV_IO_ERROR;
373}
374
375
376/**
377 * Removes IRQ for VMMDev.
378 *
379 * @param pvState Opaque pointer to the state info structure.
380 */
381static void vgdrvHaikuRemoveIRQ(void *pvState)
382{
383 struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
384 AssertPtr(pState);
385
386 remove_io_interrupt_handler(pState->iIrqResId, vgdrvHaikuISR, pState);
387}
388
389
390static status_t vgdrvHaikuAttach(const pci_info *pDevice)
391{
392 status_t status;
393 int rc;
394 int iResId;
395 struct VBoxGuestDeviceState *pState = &sState;
396 static const char *const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
397 PRTLOGGER pRelLogger;
398
399 AssertReturn(pDevice, B_BAD_VALUE);
400
401 cUsers = 0;
402
403 /*
404 * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
405 */
406 rc = RTR0Init(0);
407 if (RT_FAILURE(rc))
408 {
409 dprintf(MODULE_NAME ": RTR0Init failed: %d\n", rc);
410 return ENXIO;
411 }
412
413 rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "vgdrvHaiku");
414 if (RT_FAILURE(rc))
415 {
416 LogRel(("vgdrvHaikuAttach: RTSpinlock create failed. rc=%Rrc\n", rc));
417 return ENXIO;
418 }
419
420#ifdef DO_LOG
421 /*
422 * Create the release log.
423 * (We do that here instead of common code because we want to log
424 * early failures using the LogRel macro.)
425 */
426 rc = RTLogCreate(&pRelLogger, 0 | RTLOGFLAGS_PREFIX_THREAD /* fFlags */, "all",
427 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
428 RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER | RTLOGDEST_USER, NULL);
429 dprintf(MODULE_NAME ": RTLogCreate: %d\n", rc);
430 if (RT_SUCCESS(rc))
431 {
432 //RTLogGroupSettings(pRelLogger, g_szLogGrp);
433 //RTLogFlags(pRelLogger, g_szLogFlags);
434 //RTLogDestinations(pRelLogger, "/var/log/vboxguest.log");
435 RTLogRelSetDefaultInstance(pRelLogger);
436 RTLogSetDefaultInstance(pRelLogger); //XXX
437 }
438#endif
439
440 /*
441 * Allocate I/O port resource.
442 */
443 pState->uIOPortBase = pDevice->u.h0.base_registers[0];
444 /** @todo check flags for IO? */
445 if (pState->uIOPortBase)
446 {
447 /*
448 * Map the MMIO region.
449 */
450 uint32 phys = pDevice->u.h0.base_registers[1];
451 /** @todo Check flags for mem? */
452 pState->VMMDevMemSize = pDevice->u.h0.base_register_sizes[1];
453 pState->iVMMDevMemAreaId = map_physical_memory("VirtualBox Guest MMIO", phys, pState->VMMDevMemSize,
454 B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
455 &pState->pMMIOBase);
456 if (pState->iVMMDevMemAreaId > 0 && pState->pMMIOBase)
457 {
458 /*
459 * Call the common device extension initializer.
460 */
461 rc = VGDrvCommonInitDevExt(&g_DevExt, pState->uIOPortBase, pState->pMMIOBase, pState->VMMDevMemSize,
462#if ARCH_BITS == 64
463 VBOXOSTYPE_Haiku_x64,
464#else
465 VBOXOSTYPE_Haiku,
466#endif
467 VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
468 if (RT_SUCCESS(rc))
469 {
470 /*
471 * Add IRQ of VMMDev.
472 */
473 pState->iIrqResId = pDevice->u.h0.interrupt_line;
474 rc = vgdrvHaikuAddIRQ(pState);
475 if (RT_SUCCESS(rc))
476 {
477 LogRel((MODULE_NAME ": loaded successfully\n"));
478 return B_OK;
479 }
480
481 LogRel((MODULE_NAME ": VGDrvCommonInitDevExt failed.\n"));
482 VGDrvCommonDeleteDevExt(&g_DevExt);
483 }
484 else
485 LogRel((MODULE_NAME ": vgdrvHaikuAddIRQ failed.\n"));
486 }
487 else
488 LogRel((MODULE_NAME ": MMIO region setup failed.\n"));
489 }
490 else
491 LogRel((MODULE_NAME ": IOport setup failed.\n"));
492
493 RTR0Term();
494 return ENXIO;
495}
496
497
498static status_t vgdrvHaikuProbe(pci_info *pDevice)
499{
500 if ( pDevice->vendor_id == VMMDEV_VENDORID
501 && pDevice->device_id == VMMDEV_DEVICEID)
502 return B_OK;
503
504 return ENXIO;
505}
506
507
508status_t init_module(void)
509{
510 status_t err = B_ENTRY_NOT_FOUND;
511 pci_info info;
512 int ix = 0;
513
514 err = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI);
515 if (err != B_OK)
516 return err;
517
518 while ((*gPCI->get_nth_pci_info)(ix++, &info) == B_OK)
519 {
520 if (vgdrvHaikuProbe(&info) == 0)
521 {
522 /* We found it */
523 err = vgdrvHaikuAttach(&info);
524 return err;
525 }
526 }
527
528 return B_ENTRY_NOT_FOUND;
529}
530
531
532void uninit_module(void)
533{
534 vgdrvHaikuDetach();
535 put_module(B_PCI_MODULE_NAME);
536}
537
538
539static status_t std_ops(int32 op, ...)
540{
541 switch (op)
542 {
543 case B_MODULE_INIT:
544 return init_module();
545
546 case B_MODULE_UNINIT:
547 {
548 uninit_module();
549 return B_OK;
550 }
551
552 default:
553 return B_ERROR;
554 }
555}
556
557
558_EXPORT module_info *modules[] =
559{
560 (module_info *)&g_VBoxGuest,
561 NULL
562};
563
564/* Common code that depend on g_DevExt. */
565#include "VBoxGuestIDC-unix.c.h"
566
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