mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
vancouver: Network support
Vancouver is now able to use the Intel 82576 device model from NUL to give VMs access to the network via the nic_bridge service. In order to integrate the device model, it had to be renamed to i82576 due to XML limitations. This is done by a patch applied via the 'make prepare' mechanism. Although current network card models in Vancouver panic if they can't get a MAC address, the OP_GET_MAC hostop now fails gracefully in the case where no nic_drv or nic_bridge is available.
This commit is contained in:
parent
1ca0a66ea9
commit
1c447d98e9
@ -12,6 +12,18 @@ $(call check_tool,git)
|
||||
#
|
||||
PORTS += $(VANCOUVER)
|
||||
|
||||
#
|
||||
# We need to execute some python scripts for preparing the i82576vf
|
||||
# device model.
|
||||
#
|
||||
PYTHON2 := $(notdir $(lastword $(shell which python2 python2.{4,5,6,7,8})))
|
||||
ifeq ($(PYTHON2),)
|
||||
prepare: python_not_installed
|
||||
python_not_installed:
|
||||
$(ECHO) "Error: Vancouver needs Python 2 to be installed"
|
||||
@false;
|
||||
endif
|
||||
|
||||
prepare:: $(CONTRIB_DIR)/$(VANCOUVER)
|
||||
|
||||
#
|
||||
@ -23,7 +35,20 @@ $(DOWNLOAD_DIR)/$(VANCOUVER)/.git:
|
||||
git reset --hard $(VANCOUVER_REV) && \
|
||||
cd ../.. && touch $@
|
||||
|
||||
I82576VF_DIR = $(CONTRIB_DIR)/$(VANCOUVER)/julian/model/82576vf
|
||||
|
||||
$(CONTRIB_DIR)/$(VANCOUVER)/.git: $(DOWNLOAD_DIR)/$(VANCOUVER)/.git
|
||||
$(VERBOSE)git clone $(DOWNLOAD_DIR)/$(VANCOUVER) $(CONTRIB_DIR)/$(VANCOUVER)
|
||||
$(VERBOSE)patch -d $(CONTRIB_DIR)/$(VANCOUVER) -N -p1 < src/vancouver/rename-82576-i82576.patch
|
||||
@# fix python version in code generator scripts
|
||||
$(VERBOSE)sed -i "s/env python2/env $(PYTHON2)/" $(I82576VF_DIR)/genreg.py
|
||||
$(VERBOSE)sed -i "s/env python2/env $(PYTHON2)/" $(I82576VF_DIR)/genreg2.py
|
||||
@# call code generators
|
||||
$(VERBOSE)cd $(I82576VF_DIR); \
|
||||
./genreg.py reg_pci.py ../../../vancouver/include/model/82576vfpci.inc
|
||||
$(VERBOSE)cd $(I82576VF_DIR); \
|
||||
./genreg.py reg_mmio.py ../../../vancouver/include/model/82576vfmmio.inc
|
||||
$(VERBOSE)cd $(I82576VF_DIR); \
|
||||
./genreg2.py reg_mmio.py ../../../vancouver/include/model/82576vfmmio_vnet.inc
|
||||
|
||||
$(CONTRIB_DIR)/$(VANCOUVER): $(CONTRIB_DIR)/$(VANCOUVER)/.git
|
||||
|
@ -1,19 +1,28 @@
|
||||
/*
|
||||
* \brief Meta-data registry about the device models of Vancouver
|
||||
* \author Norman Feske
|
||||
* \author Markus Partheymueller
|
||||
* \date 2011-11-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2012 Intel Corporation
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*
|
||||
* The code is partially based on the Vancouver VMM, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*
|
||||
* Modifications by Intel Corporation are contributed under the terms and
|
||||
* conditions of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* local includes */
|
||||
#include <device_model_registry.h>
|
||||
|
||||
|
||||
Device_model_registry *device_model_registry()
|
||||
{
|
||||
static Device_model_registry inst;
|
||||
@ -72,6 +81,8 @@ MODEL_INFO(pmtimer, "io_port")
|
||||
|
||||
MODEL_INFO(pcihostbridge, "bus_num", "bus_count", "io_base", "mem_base")
|
||||
|
||||
MODEL_INFO(i82576vf, "promisc", "mem_mmio", "mem_msix", "txpoll_us", "rx_map")
|
||||
|
||||
MODEL_INFO_NO_ARG(vbios_disk)
|
||||
MODEL_INFO_NO_ARG(vbios_keyboard)
|
||||
MODEL_INFO_NO_ARG(vbios_mem)
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include <rom_session/connection.h>
|
||||
#include <rm_session/connection.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <nic_session/connection.h>
|
||||
#include <os/config.h>
|
||||
#include <os/alarm.h>
|
||||
#include <timer_session/connection.h>
|
||||
@ -60,6 +62,7 @@
|
||||
#include <device_model_registry.h>
|
||||
#include <boot_module_provider.h>
|
||||
#include <console.h>
|
||||
#include <network.h>
|
||||
|
||||
enum {
|
||||
PAGE_SIZE_LOG2 = 12UL,
|
||||
@ -72,6 +75,12 @@ enum { verbose_debug = false };
|
||||
enum { verbose_npt = false };
|
||||
enum { verbose_io = false };
|
||||
|
||||
static Genode::Native_utcb utcb_backup;
|
||||
Genode::Lock *utcb_lock()
|
||||
{
|
||||
static Genode::Lock inst;
|
||||
return &inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore used as global lock
|
||||
@ -983,6 +992,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
}
|
||||
};
|
||||
|
||||
const void * _forward_pkt;
|
||||
|
||||
class Machine : public StaticReceiver<Machine>
|
||||
{
|
||||
@ -999,6 +1009,8 @@ class Machine : public StaticReceiver<Machine>
|
||||
|
||||
bool _alloc_fb_mem; /* For detecting FB alloc message */
|
||||
|
||||
Nic::Session *_nic;
|
||||
|
||||
public:
|
||||
|
||||
/*********************************************
|
||||
@ -1173,7 +1185,38 @@ class Machine : public StaticReceiver<Machine>
|
||||
|
||||
return true;
|
||||
}
|
||||
case MessageHostOp::OP_GET_MAC:
|
||||
{
|
||||
Genode::Allocator_avl * tx_block_alloc =
|
||||
new Genode::Allocator_avl(Genode::env()->heap());
|
||||
|
||||
try {
|
||||
_nic = new Nic::Connection(tx_block_alloc);
|
||||
} catch (...) {
|
||||
Logging::printf("No NIC connection possible!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
PINF("Our mac address is %2x:%2x:%2x:%2x:%2x:%2x\n",
|
||||
_nic->mac_address().addr[0],
|
||||
_nic->mac_address().addr[1],
|
||||
_nic->mac_address().addr[2],
|
||||
_nic->mac_address().addr[3],
|
||||
_nic->mac_address().addr[4],
|
||||
_nic->mac_address().addr[5]
|
||||
);
|
||||
msg.mac = ((Genode::uint64_t)_nic->mac_address().addr[0] & 0xff) << 40 |
|
||||
((Genode::uint64_t)_nic->mac_address().addr[1] & 0xff) << 32 |
|
||||
((Genode::uint64_t)_nic->mac_address().addr[2] & 0xff) << 24 |
|
||||
((Genode::uint64_t)_nic->mac_address().addr[3] & 0xff) << 16 |
|
||||
((Genode::uint64_t)_nic->mac_address().addr[4] & 0xff) << 8 |
|
||||
((Genode::uint64_t)_nic->mac_address().addr[5] & 0xff);
|
||||
|
||||
/* Start receiver thread for this MAC */
|
||||
Vancouver_network * netreceiver = new Vancouver_network(_motherboard, _nic);
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
||||
PWRN("HostOp %d not implemented", msg.type);
|
||||
@ -1233,9 +1276,47 @@ class Machine : public StaticReceiver<Machine>
|
||||
|
||||
bool receive(MessageNetwork &msg)
|
||||
{
|
||||
if (verbose_debug)
|
||||
PDBG("MessageNetwork");
|
||||
return false;
|
||||
if (msg.type != MessageNetwork::PACKET) return false;
|
||||
|
||||
Genode::Lock::Guard guard(*utcb_lock());
|
||||
utcb_backup = *Genode::Thread_base::myself()->utcb();
|
||||
|
||||
if (msg.buffer == _forward_pkt) {
|
||||
/* don't end in an endless forwarding loop */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* allocate transmit packet */
|
||||
Packet_descriptor tx_packet;
|
||||
try {
|
||||
tx_packet = _nic->tx()->alloc_packet(msg.len);
|
||||
} catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
|
||||
PERR("tx packet alloc failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* fill packet with content */
|
||||
char *tx_content = _nic->tx()->packet_content(tx_packet);
|
||||
_forward_pkt = tx_content;
|
||||
for (unsigned i = 0; i < msg.len; i++) {
|
||||
tx_content[i] = msg.buffer[i];
|
||||
}
|
||||
_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");
|
||||
}
|
||||
|
||||
/* release sent packet to free the space in the tx communication buffer */
|
||||
_nic->tx()->release_packet(tx_packet);
|
||||
|
||||
*Genode::Thread_base::myself()->utcb() = utcb_backup;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool receive(MessagePciConfig &msg)
|
||||
|
51
ports/src/vancouver/network.cc
Normal file
51
ports/src/vancouver/network.cc
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Network receive handler per MAC address
|
||||
* \author Markus Partheymueller
|
||||
* \date 2012-07-31
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Intel Corporation
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*
|
||||
* The code is partially based on the Vancouver VMM, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*
|
||||
* Modifications by Intel Corporation are contributed under the terms and
|
||||
* conditions of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* local includes */
|
||||
#include <network.h>
|
||||
|
||||
extern const void * _forward_pkt;
|
||||
|
||||
|
||||
Vancouver_network::Vancouver_network(Motherboard &mb, Nic::Session * nic)
|
||||
: _mb(mb), _nic(nic)
|
||||
{
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
void Vancouver_network::entry()
|
||||
{
|
||||
Logging::printf("Hello, this is the network receiver.\n");
|
||||
|
||||
while (true) {
|
||||
Packet_descriptor rx_packet = _nic->rx()->get_packet();
|
||||
|
||||
/* send it to the network bus */
|
||||
char * rx_content = _nic->rx()->packet_content(rx_packet);
|
||||
_forward_pkt = rx_content;
|
||||
MessageNetwork msg((unsigned char *)rx_content, rx_packet.size(), 0);
|
||||
_mb.bus_network.send(msg);
|
||||
_forward_pkt = 0;
|
||||
|
||||
/* acknowledge received packet */
|
||||
_nic->rx()->acknowledge_packet(rx_packet);
|
||||
}
|
||||
}
|
51
ports/src/vancouver/network.h
Normal file
51
ports/src/vancouver/network.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Network receive handler per MAC address
|
||||
* \author Markus Partheymueller
|
||||
* \date 2012-07-31
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Intel Corporation
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*
|
||||
* The code is partially based on the Vancouver VMM, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*
|
||||
* Modifications by Intel Corporation are contributed under the terms and
|
||||
* conditions of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _NETWORK_H_
|
||||
#define _NETWORK_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <nic_session/connection.h>
|
||||
|
||||
/* NOVA userland includes */
|
||||
#include <nul/motherboard.h>
|
||||
|
||||
using Genode::List;
|
||||
using Genode::Thread;
|
||||
|
||||
class Vancouver_network : public Thread<4096>
|
||||
{
|
||||
private:
|
||||
|
||||
Motherboard &_mb;
|
||||
Nic::Session *_nic;
|
||||
|
||||
public:
|
||||
|
||||
/* initialisation */
|
||||
void entry();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Vancouver_network(Motherboard &mb, Nic::Session *nic);
|
||||
};
|
||||
|
||||
#endif /* _NETWORK_H_ */
|
13
ports/src/vancouver/rename-82576-i82576.patch
Normal file
13
ports/src/vancouver/rename-82576-i82576.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/julian/model/82576vf.cc b/julian/model/82576vf.cc
|
||||
index b4d29a5..db8d2f3 100644
|
||||
--- a/julian/model/82576vf.cc
|
||||
+++ b/julian/model/82576vf.cc
|
||||
@@ -950,7 +950,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
-PARAM_HANDLER(82576vf,
|
||||
+PARAM_HANDLER(i82576vf,
|
||||
"82576vf:[promisc][,mem_mmio][,mem_msix][,txpoll_us][,rx_map] - attach an Intel 82576VF to the PCI bus.",
|
||||
"promisc - if !=0, be always promiscuous (use for Linux VMs that need it for bridging) (Default 1)",
|
||||
"txpoll_us - if !=0, map TX registers to guest and poll them every txpoll_us microseconds. (Default 0)",
|
@ -12,24 +12,21 @@ endif
|
||||
|
||||
LIBS += cxx env blit thread alarm signal server
|
||||
SRC_CC = main.cc nova_user_env.cc device_model_registry.cc
|
||||
SRC_CC += console.cc keyboard.cc
|
||||
SRC_CC += console.cc keyboard.cc network.cc
|
||||
SRC_BIN = mono.tff
|
||||
|
||||
#
|
||||
# '82576vfmmio.inc' is apparently missing from the NOVA userland distribution.
|
||||
# So let's skip building the 82576vf device model for now.
|
||||
#
|
||||
FILTER_OUT = model/82576vf.cc
|
||||
|
||||
MODEL_SRC_CC += $(notdir $(wildcard $(VANCOUVER_DIR)/model/*.cc))
|
||||
EXECUTOR_SRC_CC += $(notdir $(wildcard $(VANCOUVER_DIR)/executor/*.cc))
|
||||
SERVICE_SRC_CC += hostsink.cc
|
||||
|
||||
SRC_CC += $(filter-out $(FILTER_OUT),$(addprefix model/,$(MODEL_SRC_CC)))
|
||||
SRC_CC += $(CONTRIB_DIR)/julian/model/82576vf.cc
|
||||
SRC_CC += $(filter-out $(FILTER_OUT),$(addprefix executor/,$(EXECUTOR_SRC_CC)))
|
||||
SRC_CC += base/service/hostsink.cc base/lib/runtime/string.cc
|
||||
|
||||
INC_DIR += $(PRG_DIR)
|
||||
INC_DIR += $(CONTRIB_DIR)/julian/model
|
||||
INC_DIR += $(CONTRIB_DIR)/julian/include
|
||||
INC_DIR += $(VANCOUVER_DIR)/model
|
||||
INC_DIR += $(VANCOUVER_DIR)/executor
|
||||
INC_DIR += $(VANCOUVER_DIR)/include
|
||||
|
Loading…
x
Reference in New Issue
Block a user