VirtualBox

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

最後變更 在這個檔案從43366是 43366,由 vboxsync 提交於 13 年 前

Haiku Additions: cleanup, missed file.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette