mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
vbox: add network support
- support e1000 model by default and add support for pcnet model - add Genode xml config option to enable network models Fixes #1201
This commit is contained in:
parent
46124546f0
commit
c5380674df
@ -37,6 +37,8 @@ VBOX_CC_OPT += -DUSE_SDL
|
||||
|
||||
VBOX_CC_OPT += -DRTLOG_REL_ENABLED -DRT_STRICT -DVBOX_STRICT
|
||||
|
||||
# Enable Intel Network model E1000
|
||||
VBOX_CC_OPT += -DVBOX_WITH_E1000
|
||||
|
||||
VIRTUALBOX_VERSION_MAJOR := $(shell cat $(VIRTUALBOX_DIR)/Config.kmk | grep "VBOX_VERSION_MAJOR = " | grep -v "'VBOX_VERSION_MAJOR" | sed "s/^.*= //")
|
||||
VIRTUALBOX_VERSION_MINOR := $(shell cat $(VIRTUALBOX_DIR)/Config.kmk | grep "VBOX_VERSION_MINOR = " | grep -v "'VBOX_VERSION_MINOR" | sed "s/^.*= //")
|
||||
|
@ -23,6 +23,9 @@ SRC_CC += Devices/Storage/DevATA.cpp
|
||||
SRC_CC += Devices/Storage/Debug.cpp
|
||||
SRC_CC += Devices/Storage/fdc.c
|
||||
SRC_CC += Devices/Storage/DrvRawImage.cpp
|
||||
SRC_CC += Devices/Network/DevE1000.cpp
|
||||
SRC_CC += Devices/Network/DevE1000Phy.cpp
|
||||
SRC_CC += Devices/Network/DevEEPROM.cpp
|
||||
SRC_CC += Devices/Network/DevPCNet.cpp
|
||||
SRC_CC += Devices/VMMDev/VMMDev.cpp
|
||||
SRC_CC += Devices/VMMDev/VMMDevHGCM.cpp
|
||||
|
@ -11,6 +11,10 @@ SRC_CC += Devices/Serial/DrvRawFile.cpp
|
||||
SRC_CC += Devices/Serial/DrvHostSerial.cpp
|
||||
SRC_CC += Main/src-client/MouseImpl.cpp
|
||||
|
||||
SRC_CC += network.cpp
|
||||
|
||||
vpath network.cpp $(REP_DIR)/src/virtualbox
|
||||
|
||||
# includes needed by 'MouseImpl.cpp'
|
||||
INC_DIR += $(VBOX_DIR)/Main/include
|
||||
INC_DIR += $(VBOX_DIR)/Frontends/VBoxBFE
|
||||
|
@ -34,7 +34,9 @@ SRC_CC += Runtime/common/log/logrel.cpp \
|
||||
SRC_CC += Runtime/common/err/RTErrConvertFromErrno.cpp
|
||||
SRC_CC += Runtime/common/alloc/memcache.cpp
|
||||
SRC_CC += Runtime/common/alloc/heapoffset.cpp
|
||||
SRC_CC += Runtime/common/checksum/crc32.cpp
|
||||
SRC_CC += Runtime/common/checksum/md5.cpp
|
||||
SRC_CC += Runtime/common/checksum/ipv4.cpp
|
||||
SRC_CC += Runtime/common/log/log.cpp
|
||||
SRC_CC += Runtime/common/log/log.cpp
|
||||
SRC_CC += Runtime/common/log/logellipsis.cpp
|
||||
|
@ -1 +1 @@
|
||||
a1463e45f4bcb23ee32da9cce87bc1a85289e165
|
||||
64bd2d2de0305c36048e46c05af5bc6578533ed3
|
||||
|
@ -1,3 +1,5 @@
|
||||
set use_net 0
|
||||
|
||||
set build_components {
|
||||
core init virtualbox
|
||||
drivers/input
|
||||
@ -9,6 +11,8 @@ lappend_if [have_spec acpi] build_components drivers/acpi
|
||||
lappend_if [have_spec pci] build_components drivers/pci
|
||||
lappend_if [have_spec x86] build_components drivers/rtc
|
||||
|
||||
lappend_if [expr $use_net] build_components drivers/nic
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
@ -38,7 +42,7 @@ set config {
|
||||
|
||||
append_if [have_spec acpi] config {
|
||||
<start name="acpi" priority="-1">
|
||||
<resource name="RAM" quantum="5M"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<binary name="acpi_drv"/>
|
||||
<provides>
|
||||
<service name="PCI"/>
|
||||
@ -85,13 +89,25 @@ append_if [have_spec x86] config {
|
||||
</provides>
|
||||
</start>}
|
||||
|
||||
append_if [expr $use_net] config {
|
||||
<start name="nic_drv" priority="-1">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>
|
||||
}
|
||||
|
||||
append config {
|
||||
<start name="virtualbox" priority="-2">
|
||||
<resource name="RAM" quantum="1G"/>
|
||||
<config>
|
||||
<image type="iso" file="test.iso" />
|
||||
<!-- <ioapic/> -->
|
||||
<!-- <noacpi/> -->
|
||||
<!-- <noacpi/> -->}
|
||||
|
||||
append_if [expr $use_net] config {
|
||||
<net model="e1000"/>}
|
||||
|
||||
append config {
|
||||
<libc stdout="/dev/log" stderr="/dev/log">
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
@ -120,6 +136,8 @@ append boot_modules { ld.lib.so libc.lib.so libm.lib.so pthread.lib.so
|
||||
libc_lock_pipe.lib.so libc_terminal.lib.so
|
||||
libiconv.lib.so }
|
||||
|
||||
append_if [expr $use_net] boot_modules { nic_drv }
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -m 512 "
|
||||
|
@ -97,6 +97,11 @@ extern "C" int VBoxDevicesRegister(PPDMDEVREGCB pCallbacks, uint32_t u32Version)
|
||||
if (RT_FAILURE(rc))
|
||||
return rc;
|
||||
|
||||
/* Ethernet E1000 controller */
|
||||
rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceE1000);
|
||||
if (RT_FAILURE(rc))
|
||||
return rc;
|
||||
|
||||
/* Serial device */
|
||||
rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceSerialPort);
|
||||
if (RT_FAILURE(rc))
|
||||
|
@ -33,6 +33,7 @@ extern "C" int VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_t u32Version
|
||||
&g_DrvRawFile,
|
||||
&g_DrvHostSerial,
|
||||
&g_DrvVD,
|
||||
&g_DrvHostInterface,
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -161,10 +161,6 @@ DUMMY(-1, PGMGetHostMode)
|
||||
|
||||
CHECKED_DUMMY(0, poll) /* needed by 'DrvHostSerial.cpp' */
|
||||
DUMMY(-1, pthread_key_delete)
|
||||
DUMMY(-1, RTCrc32);
|
||||
DUMMY(-1, RTCrc32Start)
|
||||
DUMMY(-1, RTCrc32Finish)
|
||||
DUMMY(-1, RTCrc32Process)
|
||||
DUMMY(-1, RTMemExecFree)
|
||||
DUMMY(-1, RTMemPageFree)
|
||||
DUMMY(-1, RTPathAppend)
|
||||
@ -218,7 +214,6 @@ DUMMY(-1, RTAvlU32Insert)
|
||||
CHECKED_DUMMY( 0, IOMR3Init)
|
||||
int IOMR3IOPortRegisterR0() { return 0; }
|
||||
int IOMR3IOPortRegisterRC() { return 0; }
|
||||
DUMMY(-1, IOMR3MmioDeregister)
|
||||
CHECKED_DUMMY( 0, IOMR3MmioRegisterR0)
|
||||
CHECKED_DUMMY( 0, IOMR3MmioRegisterRC)
|
||||
void IOMR3Relocate() { }
|
||||
@ -281,6 +276,8 @@ DUMMY(-1, RTSymlinkCreate)
|
||||
DUMMY(-1, RTSymlinkRead)
|
||||
DUMMY(-1, RTSymlinkDelete)
|
||||
|
||||
DUMMY(-1, RTNetIPv6PseudoChecksumEx)
|
||||
|
||||
CHECKED_DUMMY(0, futimes)
|
||||
CHECKED_DUMMY(0, lutimes)
|
||||
|
||||
|
@ -257,6 +257,19 @@ class Guest_memory
|
||||
pfnReadCallback, pfnFillCallback, fFlags));
|
||||
}
|
||||
|
||||
|
||||
bool remove_mmio_mapping(RTGCPHYS const GCPhys, RTGCPHYS const size)
|
||||
{
|
||||
Region *r = _lookup(GCPhys, _mmio_regions, size);
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
_mmio_regions.remove(r);
|
||||
delete r;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void dump() const
|
||||
{
|
||||
Genode::printf("guest-physical to VMM-local RAM mappings:\n");
|
||||
|
@ -29,8 +29,9 @@ int IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart,
|
||||
R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback,
|
||||
uint32_t fFlags, const char *pszDesc)
|
||||
{
|
||||
PLOG("IOMR3MmioRegisterR3: GCPhys=0x%lx cb=0x%zx pszDesc=%s rd=%p wr=%p fl=%p",
|
||||
(long)GCPhysStart, (size_t)cbRange, pszDesc,
|
||||
PLOG("%s: GCPhys=0x%lx cb=0x%x pszDesc=%s rd=%p wr=%p fl=%p",
|
||||
__PRETTY_FUNCTION__,
|
||||
(long)GCPhysStart, cbRange, pszDesc,
|
||||
pfnWriteCallback, pfnReadCallback, pfnFillCallback);
|
||||
|
||||
REMR3NotifyHandlerPhysicalRegister(pVM, PGMPHYSHANDLERTYPE_MMIO,
|
||||
@ -45,6 +46,20 @@ int IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart,
|
||||
}
|
||||
|
||||
|
||||
int IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart,
|
||||
uint32_t cbRange)
|
||||
{
|
||||
PLOG("%s: GCPhys=0x%lx cb=0x%x", __PRETTY_FUNCTION__, GCPhysStart, cbRange);
|
||||
|
||||
bool status = guest_memory()->remove_mmio_mapping(GCPhysStart, cbRange);
|
||||
if (status)
|
||||
return VINF_SUCCESS;
|
||||
|
||||
|
||||
return !VINF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VBOXSTRICTRC IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue)
|
||||
{
|
||||
// PDBG("GCPhys=0x%x, u32Value=0x%x, cbValue=%zd", GCPhys, u32Value, cbValue);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <VBox/err.h>
|
||||
#include <VBox/vmm/pdmdev.h>
|
||||
|
||||
static bool verbose = false;
|
||||
|
||||
class Guest_ioports
|
||||
{
|
||||
struct Range;
|
||||
@ -263,8 +265,9 @@ IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns,
|
||||
R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStringCallback,
|
||||
const char *pszDesc)
|
||||
{
|
||||
PLOG("register I/O port range 0x%x-0x%x '%s'",
|
||||
PortStart, PortStart + cPorts - 1, pszDesc);
|
||||
if (verbose)
|
||||
PLOG("register I/O port range 0x%x-0x%x '%s'",
|
||||
PortStart, PortStart + cPorts - 1, pszDesc);
|
||||
|
||||
return guest_ioports()->add_range(pDevIns, PortStart, cPorts, pvUser,
|
||||
pfnOutCallback, pfnInCallback,
|
||||
@ -275,8 +278,9 @@ IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns,
|
||||
int IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart,
|
||||
RTUINT cPorts)
|
||||
{
|
||||
PLOG("deregister I/O port range 0x%x-0x%x",
|
||||
PortStart, PortStart + cPorts - 1);
|
||||
if (verbose)
|
||||
PLOG("deregister I/O port range 0x%x-0x%x",
|
||||
PortStart, PortStart + cPorts - 1);
|
||||
|
||||
return guest_ioports()->remove_range(pDevIns, PortStart, cPorts);
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ extern "C" char *getenv(const char *name)
|
||||
// "+rem_run.e.l.f"
|
||||
// "+pgm.e.l.f"
|
||||
"+pdm"
|
||||
// "+dev_pcnet.e.l.f"
|
||||
// "+dev_pic.e.l.f"
|
||||
// "+dev_apic.e.l.f"
|
||||
// "+dev_vmm.e.l.f"
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
/* libc includes */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* libc memory allocator */
|
||||
#include <libc_mem_alloc.h>
|
||||
@ -65,9 +66,7 @@ namespace {
|
||||
if (_argc >= MAX_ARGS - 1)
|
||||
throw Too_many_arguments();
|
||||
|
||||
/* XXX yes const-casting hurts but main() needs char**, if in
|
||||
* doubt we should strdup() here, right? */
|
||||
_argv[_argc++] = const_cast<char *>(arg);
|
||||
_argv[_argc++] = strdup(arg);
|
||||
}
|
||||
|
||||
char *** argvp() {
|
||||
@ -170,7 +169,7 @@ int main()
|
||||
try {
|
||||
Xml_node::Attribute overlay = node.attribute("overlay");
|
||||
overlay.value(c_type, sizeof(c_type));
|
||||
if (!strcmp(c_type, "yes"))
|
||||
if (!Genode::strcmp(c_type, "yes"))
|
||||
bOverlay = true;
|
||||
} catch (...) { }
|
||||
type.value(c_type, sizeof(c_type));
|
||||
@ -239,9 +238,35 @@ int main()
|
||||
}
|
||||
} catch(Genode::Xml_node::Nonexistent_sub_node) { }
|
||||
|
||||
PINF("start %s image '%s' with %zu MB guest memory=%zu and %u shared folders",
|
||||
/* network setup */
|
||||
unsigned net = 0;
|
||||
try {
|
||||
using namespace Genode;
|
||||
for (Xml_node node = config()->xml_node().sub_node("net");
|
||||
true; node = node.next("net")) {
|
||||
|
||||
net ++;
|
||||
|
||||
char buf [10];
|
||||
Genode::snprintf(buf, sizeof(buf), "-hifdev%d", net);
|
||||
args.add(buf);
|
||||
|
||||
/* read out network model, if not set use e1000 */
|
||||
try {
|
||||
Xml_node::Attribute model = node.attribute("model");
|
||||
char * c_model = new char[model.value_size() + 1];
|
||||
model.value(c_model, model.value_size() + 1);
|
||||
args.add(c_model);
|
||||
} catch(Genode::Xml_node::Nonexistent_attribute) {
|
||||
args.add("e1000");
|
||||
}
|
||||
}
|
||||
} catch(Genode::Xml_node::Nonexistent_sub_node) { }
|
||||
|
||||
PINF("start %s image '%s' with %zu MB guest memory=%zu, %u shared folders,"
|
||||
" %u network connections",
|
||||
c_type, c_file, vm_size / 1024 / 1024,
|
||||
Genode::env()->ram_session()->avail(), shares);
|
||||
Genode::env()->ram_session()->avail(), shares, net);
|
||||
|
||||
if (RT_FAILURE(RTR3InitExe(args.argc(), args.argvp(), 0))) {
|
||||
PERR("Intialization of VBox Runtime failed.");
|
||||
|
492
repos/ports/src/virtualbox/network.cpp
Normal file
492
repos/ports/src/virtualbox/network.cpp
Normal file
@ -0,0 +1,492 @@
|
||||
/**
|
||||
* Genode network session driver,
|
||||
* derived from src/VBox/Devices/Network/DrvTAP.cpp.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2012 Oracle Corporation
|
||||
*
|
||||
* This file is part of VirtualBox Open Source Edition (OSE), as
|
||||
* available from http://www.virtualbox.org. This file is free software;
|
||||
* you can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) as published by the Free Software
|
||||
* Foundation, in version 2 as it comes in the "COPYING" file of the
|
||||
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
||||
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Header Files *
|
||||
*******************************************************************************/
|
||||
#define LOG_GROUP LOG_GROUP_DRV_TUN
|
||||
#include <VBox/log.h>
|
||||
#include <VBox/vmm/pdmdrv.h>
|
||||
#include <VBox/vmm/pdmnetifs.h>
|
||||
#include <VBox/vmm/pdmnetinline.h>
|
||||
|
||||
#include <iprt/mem.h>
|
||||
#include <iprt/uuid.h>
|
||||
|
||||
#include "VBoxDD.h"
|
||||
|
||||
#include <nic_session/connection.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Structures and Typedefs *
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* TAP driver instance data.
|
||||
*
|
||||
* @implements PDMINETWORKUP
|
||||
*/
|
||||
typedef struct DRVTAP
|
||||
{
|
||||
/** The network interface. */
|
||||
PDMINETWORKUP INetworkUp;
|
||||
/** The network interface. */
|
||||
PPDMINETWORKDOWN pIAboveNet;
|
||||
/** Pointer to the driver instance. */
|
||||
PPDMDRVINS pDrvIns;
|
||||
/** Reader thread. */
|
||||
PPDMTHREAD pThread;
|
||||
|
||||
/** @todo The transmit thread. */
|
||||
/** Transmit lock used by drvTAPNetworkUp_BeginXmit. */
|
||||
RTCRITSECT XmitLock;
|
||||
|
||||
Nic::Session *nic_session;
|
||||
|
||||
PDMINETWORKCONFIG INetworkConfig;
|
||||
|
||||
} DRVTAP, *PDRVTAP;
|
||||
|
||||
|
||||
/** Converts a pointer to TAP::INetworkUp to a PRDVTAP. */
|
||||
#define PDMINETWORKUP_2_DRVTAP(pInterface) ( (PDRVTAP)((uintptr_t)pInterface - RT_OFFSETOF(DRVTAP, INetworkUp)) )
|
||||
#define PDMINETWORKCONFIG_2_DRVTAP(pInterface) ( (PDRVTAP)((uintptr_t)pInterface - RT_OFFSETOF(DRVTAP, INetworkConfig)) )
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Internal Functions *
|
||||
*******************************************************************************/
|
||||
|
||||
static int net_send_packet(void * packet, uint32_t packet_len, Nic::Session * nic) {
|
||||
|
||||
/* allocate transmit packet */
|
||||
Packet_descriptor tx_packet;
|
||||
try {
|
||||
tx_packet = nic->tx()->alloc_packet(packet_len);
|
||||
} catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
|
||||
PERR("tx packet alloc failed");
|
||||
return VERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* fill packet with content */
|
||||
char * stream_buffer = nic->tx()->packet_content(tx_packet);
|
||||
memcpy(stream_buffer, packet, packet_len);
|
||||
|
||||
nic->tx()->submit_packet(tx_packet);
|
||||
|
||||
/* wait for acknowledgement */
|
||||
Packet_descriptor ack_tx_packet = nic->tx()->get_acked_packet();
|
||||
|
||||
if (ack_tx_packet.size() != tx_packet.size() ||
|
||||
ack_tx_packet.offset() != tx_packet.offset())
|
||||
PERR("unexpected acked packet");
|
||||
|
||||
nic->tx()->release_packet(tx_packet);
|
||||
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
|
||||
*/
|
||||
static DECLCALLBACK(int) drvTAPNetworkUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
|
||||
{
|
||||
PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
|
||||
int rc = RTCritSectTryEnter(&pThis->XmitLock);
|
||||
if (RT_FAILURE(rc))
|
||||
{
|
||||
/** @todo XMIT thread */
|
||||
rc = VERR_TRY_AGAIN;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
|
||||
*/
|
||||
static DECLCALLBACK(int) drvTAPNetworkUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
|
||||
PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
|
||||
{
|
||||
PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
|
||||
Assert(RTCritSectIsOwner(&pThis->XmitLock));
|
||||
|
||||
/*
|
||||
* Allocate a scatter / gather buffer descriptor that is immediately
|
||||
* followed by the buffer space of its single segment. The GSO context
|
||||
* comes after that again.
|
||||
*/
|
||||
PPDMSCATTERGATHER pSgBuf = (PPDMSCATTERGATHER)RTMemAlloc( RT_ALIGN_Z(sizeof(*pSgBuf), 16)
|
||||
+ RT_ALIGN_Z(cbMin, 16)
|
||||
+ (pGso ? RT_ALIGN_Z(sizeof(*pGso), 16) : 0));
|
||||
if (!pSgBuf)
|
||||
return VERR_NO_MEMORY;
|
||||
|
||||
/*
|
||||
* Initialize the S/G buffer and return.
|
||||
*/
|
||||
pSgBuf->fFlags = PDMSCATTERGATHER_FLAGS_MAGIC | PDMSCATTERGATHER_FLAGS_OWNER_1;
|
||||
pSgBuf->cbUsed = 0;
|
||||
pSgBuf->cbAvailable = RT_ALIGN_Z(cbMin, 16);
|
||||
pSgBuf->pvAllocator = NULL;
|
||||
if (!pGso)
|
||||
pSgBuf->pvUser = NULL;
|
||||
else
|
||||
{
|
||||
pSgBuf->pvUser = (uint8_t *)(pSgBuf + 1) + pSgBuf->cbAvailable;
|
||||
*(PPDMNETWORKGSO)pSgBuf->pvUser = *pGso;
|
||||
}
|
||||
pSgBuf->cSegs = 1;
|
||||
pSgBuf->aSegs[0].cbSeg = pSgBuf->cbAvailable;
|
||||
pSgBuf->aSegs[0].pvSeg = pSgBuf + 1;
|
||||
|
||||
#if 0 /* poison */
|
||||
memset(pSgBuf->aSegs[0].pvSeg, 'F', pSgBuf->aSegs[0].cbSeg);
|
||||
#endif
|
||||
*ppSgBuf = pSgBuf;
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
|
||||
*/
|
||||
static DECLCALLBACK(int) drvTAPNetworkUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
|
||||
{
|
||||
PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
|
||||
Assert(RTCritSectIsOwner(&pThis->XmitLock));
|
||||
if (pSgBuf)
|
||||
{
|
||||
Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC);
|
||||
pSgBuf->fFlags = 0;
|
||||
RTMemFree(pSgBuf);
|
||||
}
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
|
||||
*/
|
||||
static DECLCALLBACK(int) drvTAPNetworkUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
|
||||
{
|
||||
PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
|
||||
|
||||
AssertPtr(pSgBuf);
|
||||
Assert((pSgBuf->fFlags & PDMSCATTERGATHER_FLAGS_MAGIC_MASK) == PDMSCATTERGATHER_FLAGS_MAGIC);
|
||||
Assert(RTCritSectIsOwner(&pThis->XmitLock));
|
||||
|
||||
/* Set an FTM checkpoint as this operation changes the state permanently. */
|
||||
PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_NETWORK);
|
||||
|
||||
int rc;
|
||||
if (!pSgBuf->pvUser)
|
||||
{
|
||||
Log2(("drvTAPSend: pSgBuf->aSegs[0].pvSeg=%p pSgBuf->cbUsed=%#x\n"
|
||||
"%.*Rhxd\n",
|
||||
pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pSgBuf->cbUsed, pSgBuf->aSegs[0].pvSeg));
|
||||
|
||||
rc = net_send_packet(pSgBuf->aSegs[0].pvSeg, pSgBuf->cbUsed, pThis->nic_session);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t abHdrScratch[256];
|
||||
uint8_t const *pbFrame = (uint8_t const *)pSgBuf->aSegs[0].pvSeg;
|
||||
PCPDMNETWORKGSO pGso = (PCPDMNETWORKGSO)pSgBuf->pvUser;
|
||||
uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, pSgBuf->cbUsed); Assert(cSegs > 1);
|
||||
rc = VINF_SUCCESS;
|
||||
for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
|
||||
{
|
||||
uint32_t cbSegFrame;
|
||||
void *pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)pbFrame, pSgBuf->cbUsed, abHdrScratch,
|
||||
iSeg, cSegs, &cbSegFrame);
|
||||
rc = net_send_packet(pvSegFrame, cbSegFrame, pThis->nic_session);
|
||||
if (RT_FAILURE(rc))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pSgBuf->fFlags = 0;
|
||||
RTMemFree(pSgBuf);
|
||||
|
||||
AssertRC(rc);
|
||||
if (RT_FAILURE(rc))
|
||||
rc = rc == VERR_NO_MEMORY ? VERR_NET_NO_BUFFER_SPACE : VERR_NET_DOWN;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
|
||||
*/
|
||||
static DECLCALLBACK(void) drvTAPNetworkUp_EndXmit(PPDMINETWORKUP pInterface)
|
||||
{
|
||||
PDRVTAP pThis = PDMINETWORKUP_2_DRVTAP(pInterface);
|
||||
RTCritSectLeave(&pThis->XmitLock);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
|
||||
*/
|
||||
static DECLCALLBACK(void) drvTAPNetworkUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
|
||||
{
|
||||
LogFlow(("drvTAPNetworkUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notification on link status changes.
|
||||
*
|
||||
* @param pInterface Pointer to the interface structure containing the called function pointer.
|
||||
* @param enmLinkState The new link state.
|
||||
* @thread EMT
|
||||
*/
|
||||
static DECLCALLBACK(void) drvTAPNetworkUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
|
||||
{
|
||||
LogFlow(("drvTAPNetworkUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
|
||||
/** @todo take action on link down and up. Stop the polling and such like. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static DECLCALLBACK(int) drvGetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)
|
||||
{
|
||||
PDRVTAP pThis = PDMINETWORKCONFIG_2_DRVTAP(pInterface);
|
||||
|
||||
static_assert (sizeof(*pMac) == sizeof(pThis->nic_session->mac_address()),
|
||||
"should be equal");
|
||||
memcpy(pMac, pThis->nic_session->mac_address().addr, sizeof(*pMac));
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Asynchronous I/O thread for handling receive.
|
||||
*
|
||||
* @returns VINF_SUCCESS (ignored).
|
||||
* @param Thread Thread handle.
|
||||
* @param pvUser Pointer to a DRVTAP structure.
|
||||
*/
|
||||
static DECLCALLBACK(int) drvTAPAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
|
||||
{
|
||||
PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
|
||||
LogFlow(("drvTAPAsyncIoThread: pThis=%p\n", pThis));
|
||||
|
||||
if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
|
||||
return VINF_SUCCESS;
|
||||
|
||||
Nic::Session * nic = pThis->nic_session;
|
||||
|
||||
while (pThread->enmState == PDMTHREADSTATE_RUNNING)
|
||||
{
|
||||
Packet_descriptor rx_packet = nic->rx()->get_packet();
|
||||
|
||||
/* send it to the network bus */
|
||||
char * rx_content = nic->rx()->packet_content(rx_packet);
|
||||
|
||||
int rc1 = pThis->pIAboveNet->pfnWaitReceiveAvail(pThis->pIAboveNet,
|
||||
RT_INDEFINITE_WAIT);
|
||||
if (RT_FAILURE(rc1))
|
||||
continue;
|
||||
|
||||
rc1 = pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, rx_content,
|
||||
rx_packet.size());
|
||||
AssertRC(rc1);
|
||||
|
||||
/* acknowledge received packet */
|
||||
nic->rx()->acknowledge_packet(rx_packet);
|
||||
}
|
||||
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unblock the send thread so it can respond to a state change.
|
||||
*
|
||||
* @returns VBox status code.
|
||||
* @param pDevIns The pcnet device instance.
|
||||
* @param pThread The send thread.
|
||||
*/
|
||||
static DECLCALLBACK(int) drvTapAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
|
||||
{
|
||||
PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
|
||||
Assert(!"Not implemented");
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* -=-=-=-=- PDMIBASE -=-=-=-=- */
|
||||
|
||||
/**
|
||||
* @interface_method_impl{PDMIBASE,pfnQueryInterface}
|
||||
*/
|
||||
static DECLCALLBACK(void *) drvTAPQueryInterface(PPDMIBASE pInterface, const char *pszIID)
|
||||
{
|
||||
PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
|
||||
PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
|
||||
|
||||
PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
|
||||
PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUp);
|
||||
PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
|
||||
|
||||
static DECLCALLBACK(void) drvTAPDestruct(PPDMDRVINS pDrvIns)
|
||||
{
|
||||
Assert(!"Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a TAP network transport driver instance.
|
||||
*
|
||||
* @copydoc FNPDMDRVCONSTRUCT
|
||||
*/
|
||||
static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
|
||||
{
|
||||
PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
|
||||
PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
|
||||
|
||||
/*
|
||||
* Init the static parts.
|
||||
*/
|
||||
pThis->pDrvIns = pDrvIns;
|
||||
|
||||
/* IBase */
|
||||
pDrvIns->IBase.pfnQueryInterface = drvTAPQueryInterface;
|
||||
/* INetwork */
|
||||
pThis->INetworkUp.pfnBeginXmit = drvTAPNetworkUp_BeginXmit;
|
||||
pThis->INetworkUp.pfnAllocBuf = drvTAPNetworkUp_AllocBuf;
|
||||
pThis->INetworkUp.pfnFreeBuf = drvTAPNetworkUp_FreeBuf;
|
||||
pThis->INetworkUp.pfnSendBuf = drvTAPNetworkUp_SendBuf;
|
||||
pThis->INetworkUp.pfnEndXmit = drvTAPNetworkUp_EndXmit;
|
||||
pThis->INetworkUp.pfnSetPromiscuousMode = drvTAPNetworkUp_SetPromiscuousMode;
|
||||
pThis->INetworkUp.pfnNotifyLinkChanged = drvTAPNetworkUp_NotifyLinkChanged;
|
||||
|
||||
/* INetworkConfig - used on Genode to request Mac address of nic_session */
|
||||
pThis->INetworkConfig.pfnGetMac = drvGetMac;
|
||||
|
||||
/*
|
||||
* Setup Genode nic_session connection
|
||||
*/
|
||||
Nic::Packet_allocator *tx_block_alloc =
|
||||
new (Genode::env()->heap()) Nic::Packet_allocator(Genode::env()->heap());
|
||||
|
||||
enum {
|
||||
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
|
||||
BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE,
|
||||
};
|
||||
|
||||
try {
|
||||
pThis->nic_session = new Nic::Connection(tx_block_alloc, BUF_SIZE,
|
||||
BUF_SIZE);
|
||||
} catch (...) {
|
||||
return VERR_HOSTIF_INIT_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that no-one is attached to us.
|
||||
*/
|
||||
AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
|
||||
("Configuration error: Not possible to attach anything to this driver!\n"),
|
||||
VERR_PDM_DRVINS_NO_ATTACH);
|
||||
|
||||
/*
|
||||
* Query the network port interface.
|
||||
*/
|
||||
pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN);
|
||||
if (!pThis->pIAboveNet)
|
||||
return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE,
|
||||
N_("Configuration error: The above device/driver didn't export the network port interface"));
|
||||
|
||||
/*
|
||||
* Create the transmit lock.
|
||||
*/
|
||||
int rc = RTCritSectInit(&pThis->XmitLock);
|
||||
AssertRCReturn(rc, rc);
|
||||
|
||||
/*
|
||||
* Create the async I/O thread.
|
||||
*/
|
||||
rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pThread, pThis, drvTAPAsyncIoThread, drvTapAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "TAP");
|
||||
AssertRCReturn(rc, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TAP network transport driver registration record.
|
||||
*/
|
||||
const PDMDRVREG g_DrvHostInterface =
|
||||
{
|
||||
/* u32Version */
|
||||
PDM_DRVREG_VERSION,
|
||||
/* szName */
|
||||
"HostInterface",
|
||||
/* szRCMod */
|
||||
"",
|
||||
/* szR0Mod */
|
||||
"",
|
||||
/* pszDescription */
|
||||
"Genode Network Session Driver",
|
||||
/* fFlags */
|
||||
PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
|
||||
/* fClass. */
|
||||
PDM_DRVREG_CLASS_NETWORK,
|
||||
/* cMaxInstances */
|
||||
~0U,
|
||||
/* cbInstance */
|
||||
sizeof(DRVTAP),
|
||||
/* pfnConstruct */
|
||||
drvTAPConstruct,
|
||||
/* pfnDestruct */
|
||||
drvTAPDestruct,
|
||||
/* pfnRelocate */
|
||||
NULL,
|
||||
/* pfnIOCtl */
|
||||
NULL,
|
||||
/* pfnPowerOn */
|
||||
NULL,
|
||||
/* pfnReset */
|
||||
NULL,
|
||||
/* pfnSuspend */
|
||||
NULL, /** @todo Do power on, suspend and resume handlers! */
|
||||
/* pfnResume */
|
||||
NULL,
|
||||
/* pfnAttach */
|
||||
NULL,
|
||||
/* pfnDetach */
|
||||
NULL,
|
||||
/* pfnPowerOff */
|
||||
NULL,
|
||||
/* pfnSoftReset */
|
||||
NULL,
|
||||
/* u32EndVersion */
|
||||
PDM_DRVREG_VERSION
|
||||
};
|
131
repos/ports/src/virtualbox/network.patch
Normal file
131
repos/ports/src/virtualbox/network.patch
Normal file
@ -0,0 +1,131 @@
|
||||
+++ src/app/virtualbox/src/VBox/Devices/Network/DevE1000.cpp
|
||||
@@ -7536,6 +7536,39 @@
|
||||
pState->INetworkConfig.pfnGetLinkState = e1kGetLinkState;
|
||||
pState->INetworkConfig.pfnSetLinkState = e1kSetLinkState;
|
||||
|
||||
+ /* For Genode attach already here to be able to overwrite mac address */
|
||||
+ rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
|
||||
+ if (RT_SUCCESS(rc))
|
||||
+ {
|
||||
+ /* Genode: read out the mac address from nic_session interface */
|
||||
+ PPDMINETWORKCONFIG pDrvConfig = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONFIG);
|
||||
+ Assert(pDrvConfig && pDrvConfig->pfnGetMac);
|
||||
+ pDrvConfig->pfnGetMac(pDrvConfig, &pState->macConfigured);
|
||||
+
|
||||
+ if (rc == VINF_NAT_DNS)
|
||||
+ {
|
||||
+ PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
|
||||
+ N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
|
||||
+ }
|
||||
+ pState->pDrvR3 = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKUP);
|
||||
+ AssertMsgReturn(pState->pDrvR3, ("Failed to obtain the PDMINETWORKUP interface!\n"),
|
||||
+ VERR_PDM_MISSING_INTERFACE_BELOW);
|
||||
+
|
||||
+ pState->pDrvR0 = PDMIBASER0_QUERY_INTERFACE(PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMIBASER0), PDMINETWORKUP);
|
||||
+ pState->pDrvRC = PDMIBASERC_QUERY_INTERFACE(PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMIBASERC), PDMINETWORKUP);
|
||||
+ }
|
||||
+ else if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
|
||||
+ || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
|
||||
+ {
|
||||
+ /* No error! */
|
||||
+ E1kLog(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
|
||||
+ }
|
||||
+ else
|
||||
+ return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
/* Initialize the EEPROM */
|
||||
pState->eeprom.init(pState->macConfigured);
|
||||
|
||||
@@ -7696,30 +7729,6 @@
|
||||
return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the status LUN"));
|
||||
pState->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS);
|
||||
|
||||
- rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
|
||||
- if (RT_SUCCESS(rc))
|
||||
- {
|
||||
- if (rc == VINF_NAT_DNS)
|
||||
- {
|
||||
- PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
|
||||
- N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
|
||||
- }
|
||||
- pState->pDrvR3 = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKUP);
|
||||
- AssertMsgReturn(pState->pDrvR3, ("Failed to obtain the PDMINETWORKUP interface!\n"),
|
||||
- VERR_PDM_MISSING_INTERFACE_BELOW);
|
||||
-
|
||||
- pState->pDrvR0 = PDMIBASER0_QUERY_INTERFACE(PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMIBASER0), PDMINETWORKUP);
|
||||
- pState->pDrvRC = PDMIBASERC_QUERY_INTERFACE(PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMIBASERC), PDMINETWORKUP);
|
||||
- }
|
||||
- else if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
|
||||
- || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
|
||||
- {
|
||||
- /* No error! */
|
||||
- E1kLog(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
|
||||
- }
|
||||
- else
|
||||
- return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
|
||||
-
|
||||
rc = RTSemEventCreate(&pState->hEventMoreRxDescAvail);
|
||||
if (RT_FAILURE(rc))
|
||||
return rc;
|
||||
+++ src/app/virtualbox/src/VBox/Devices/Network/DevPCNet.cpp
|
||||
@@ -5331,6 +5331,11 @@
|
||||
rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Network Port");
|
||||
if (RT_SUCCESS(rc))
|
||||
{
|
||||
+ /* Genode: read out the mac address from nic_session interface */
|
||||
+ PPDMINETWORKCONFIG pDrvConfig = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMINETWORKCONFIG);
|
||||
+ Assert(pDrvConfig && pDrvConfig->pfnGetMac);
|
||||
+ pDrvConfig->pfnGetMac(pDrvConfig, &pThis->MacConfigured);
|
||||
+
|
||||
if (rc == VINF_NAT_DNS)
|
||||
{
|
||||
#ifdef RT_OS_LINUX
|
||||
+++ src/app/virtualbox/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp
|
||||
@@ -1601,11 +1630,14 @@
|
||||
/*
|
||||
* Network adapters
|
||||
*/
|
||||
- rc = CFGMR3InsertNode(pDevices, "pcnet", &pDev); UPDATE_RC();
|
||||
for (ULONG ulInstance = 0; ulInstance < NetworkAdapterCount; ulInstance++)
|
||||
{
|
||||
if (g_aNetDevs[ulInstance].enmType != BFENETDEV::NOT_CONFIGURED)
|
||||
{
|
||||
+ /* On Genode we use pszName to select the device model */
|
||||
+ const char * device_model = g_aNetDevs[ulInstance].pszName;
|
||||
+ rc = CFGMR3InsertNode(pDevices, device_model, &pDev); UPDATE_RC();
|
||||
+
|
||||
char szInstance[4];
|
||||
RTStrPrintf(szInstance, sizeof(szInstance), "%lu", ulInstance);
|
||||
rc = CFGMR3InsertNode(pDev, szInstance, &pInst); UPDATE_RC();
|
||||
@@ -1616,6 +1650,10 @@
|
||||
rc = CFGMR3InsertNode(pInst, "Config", &pCfg); UPDATE_RC();
|
||||
rc = CFGMR3InsertBytes(pCfg, "MAC", &g_aNetDevs[ulInstance].Mac, sizeof(RTMAC));
|
||||
UPDATE_RC();
|
||||
+ if (!strcmp("e1000", device_model)) {
|
||||
+ rc = CFGMR3InsertInteger(pCfg, "CableConnected", 1); UPDATE_RC();
|
||||
+ rc = CFGMR3InsertInteger(pCfg, "AdapterType", 0); UPDATE_RC();
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Enable the packet sniffer if requested.
|
||||
@@ -1747,10 +1785,15 @@
|
||||
|
||||
|
||||
#else
|
||||
- FatalError("Name based HIF devices not implemented yet for this host platform\n");
|
||||
- return VERR_NOT_IMPLEMENTED;
|
||||
+// FatalError("Name based HIF devices not implemented yet for this host platform\n");
|
||||
+// return VERR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
+
|
||||
+ rc = CFGMR3InsertNode(pInst, "LUN#999", &pLunL0); UPDATE_RC();
|
||||
+ rc = CFGMR3InsertString(pLunL0, "Driver", "MainStatus"); UPDATE_RC();
|
||||
+ rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); UPDATE_RC();
|
||||
+ rc = CFGMR3InsertInteger(pCfg, "papLeds", (uintptr_t)&mapFDLeds[0]); UPDATE_RC();
|
||||
}
|
||||
else if (g_aNetDevs[ulInstance].enmType == BFENETDEV::INTNET)
|
||||
{
|
@ -57,7 +57,6 @@ int PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys,
|
||||
|
||||
try {
|
||||
guest_memory()->add_rom_mapping(GCPhys, cb, pvBinary, pDevIns);
|
||||
guest_memory()->dump();
|
||||
|
||||
/*
|
||||
* XXX Try to understand the fShadowed condition
|
||||
@ -256,8 +255,6 @@ int PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
|
||||
|
||||
guest_memory()->add_ram_mapping(GCPhys, cb, pv);
|
||||
|
||||
guest_memory()->dump();
|
||||
|
||||
REMR3NotifyPhysRamRegister(pVM, GCPhys, cb, REM_NOTIFY_PHYS_RAM_FLAGS_RAM);
|
||||
}
|
||||
catch (Guest_memory::Region_conflict) {
|
||||
|
Loading…
Reference in New Issue
Block a user