vancouver: Improve locking scheme

This patch replaces the error-prone manual locking with the use of the
'Synced_interface' for the motherboard and the VCPU dispatcher. It also
removes all globally visible locks. Locks are now explicitly passed to
subsystems when needed.
This commit is contained in:
Norman Feske 2013-05-16 23:32:27 +02:00
parent c48a7aa27f
commit 89d0e68983
10 changed files with 167 additions and 141 deletions

View File

@ -33,7 +33,6 @@
extern char _binary_mono_tff_start;
Font default_font(&_binary_mono_tff_start);
extern Genode::Lock global_lock;
using Genode::env;
using Genode::Dataspace_client;
@ -154,12 +153,6 @@ void Vancouver_console::entry()
{
Logging::printf("Hello, this is VancouverConsole.\n");
/* register host operations */
_mb.bus_console.add(this, receive_static<MessageConsole>);
_mb.bus_memregion.add(this, receive_static<MessageMemRegion>);
/* create environment for input/output */
/*
* Init sessions to the required external services
*/
@ -187,7 +180,7 @@ void Vancouver_console::entry()
*/
unsigned long count = 0;
bool revoked = false;
Vancouver_keyboard vkeyb(_mb);
Vancouver_keyboard vkeyb(_motherboard);
Genode::uint64_t checksum1 = 0;
Genode::uint64_t checksum2 = 0;
@ -234,15 +227,13 @@ void Vancouver_console::entry()
/* if we copy the same data 10 times, unmap the text buffer from guest */
if (unchanged == 10) {
/* protect against thread interference */
global_lock.lock();
Genode::Lock::Guard guard(_console_lock);
env()->rm_session()->detach((void *)_guest_fb);
env()->rm_session()->attach_at(_fb_ds, (Genode::addr_t)_guest_fb);
unchanged = 0;
fb_active = false;
global_lock.unlock();
Logging::printf("Deactivated text buffer loop.\n");
}
} else unchanged = 0;
@ -252,8 +243,7 @@ void Vancouver_console::entry()
if (!revoked) {
/* protect against thread interference */
global_lock.lock();
Genode::Lock::Guard guard(_console_lock);
env()->rm_session()->detach((void *)_guest_fb);
env()->rm_session()->attach_at(framebuffer.dataspace(),
@ -269,13 +259,11 @@ void Vancouver_console::entry()
}
revoked = true;
global_lock.unlock();
}
}
framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height());
timer.msleep(10);
timer.msleep(100);
}
for (int i = 0, num_ev = input.flush(); i < num_ev; i++) {
@ -284,7 +272,7 @@ void Vancouver_console::entry()
/* update mouse model (PS2) */
unsigned mouse = mouse_value(ev);
MessageInput msg(0x10001, mouse);
_mb.bus_input.send(msg);
_motherboard()->bus_input.send(msg);
if (ev->type() == Input::Event::PRESS) {
if (ev->code() <= 0xee) {
@ -301,11 +289,21 @@ void Vancouver_console::entry()
}
Vancouver_console::Vancouver_console(Motherboard &mb, Genode::size_t vm_fb_size,
void Vancouver_console::register_host_operations(Motherboard &motherboard)
{
motherboard.bus_console. add(this, receive_static<MessageConsole>);
motherboard.bus_memregion.add(this, receive_static<MessageMemRegion>);
}
Vancouver_console::Vancouver_console(Synced_motherboard &mb,
Genode::Lock &console_lock,
Genode::size_t vm_fb_size,
Genode::Dataspace_capability fb_ds)
:
_startup_lock(Genode::Lock::LOCKED),
_vm_fb_size(vm_fb_size), _mb(mb), _fb_size(0), _pixels(0), _guest_fb(0),
_vm_fb_size(vm_fb_size), _motherboard(mb), _console_lock(console_lock),
_fb_size(0), _pixels(0), _guest_fb(0),
_regs(0), _fb_ds(fb_ds)
{
start();

View File

@ -29,8 +29,8 @@
#include <timer_session/connection.h>
#include <dataspace/client.h>
/* NOVA userland includes */
#include <nul/motherboard.h>
/* local includes */
#include <synced_motherboard.h>
/* includes for I/O */
#include <base/env.h>
@ -47,13 +47,14 @@ class Vancouver_console : public Thread<8192>, public StaticReceiver<Vancouver_c
private:
Genode::Lock _startup_lock;
Motherboard &_mb;
short *_pixels;
char *_guest_fb;
Synced_motherboard &_motherboard;
Genode::Lock &_console_lock;
short *_pixels;
char *_guest_fb;
unsigned long _fb_size;
Genode::Dataspace_capability _fb_ds;
Genode::size_t _vm_fb_size;
VgaRegs *_regs;
VgaRegs *_regs;
Framebuffer::Mode _fb_mode;
public:
@ -62,13 +63,17 @@ class Vancouver_console : public Thread<8192>, public StaticReceiver<Vancouver_c
bool receive(MessageConsole &msg);
bool receive(MessageMemRegion &msg);
void register_host_operations(Motherboard &);
/* initialisation */
void entry();
/**
* Constructor
*/
Vancouver_console(Motherboard &mb, Genode::size_t vm_fb_size,
Vancouver_console(Synced_motherboard &,
Genode::Lock &console_lock,
Genode::size_t vm_fb_size,
Genode::Dataspace_capability fb_ds);
};

View File

@ -31,15 +31,13 @@
static Genode::Native_utcb utcb_backup;
extern Genode::Lock timeouts_lock;
Vancouver_disk::Vancouver_disk(Motherboard &mb,
Vancouver_disk::Vancouver_disk(Synced_motherboard &mb,
char * backing_store_base,
char * backing_store_fb_base)
:
_startup_lock(Genode::Lock::LOCKED),
_mb(mb), _backing_store_base(backing_store_base),
_motherboard(mb), _backing_store_base(backing_store_base),
_backing_store_fb_base(backing_store_fb_base)
{
/* initialize struct with 0 size */
@ -53,13 +51,16 @@ Vancouver_disk::Vancouver_disk(Motherboard &mb,
}
void Vancouver_disk::register_host_operations(Motherboard &motherboard)
{
motherboard.bus_disk.add(this, receive_static<MessageDisk>);
}
void Vancouver_disk::entry()
{
Logging::printf("Hello, this is Vancouver_disk.\n");
/* attach to disk bus */
_mb.bus_disk.add(this, receive_static<MessageDisk>);
_startup_lock.unlock();
}
@ -124,7 +125,7 @@ bool Vancouver_disk::receive(MessageDisk &msg)
if (!read && !_diskcon[msg.disknr].ops.supported(Block::Packet_descriptor::WRITE)) {
MessageDiskCommit ro(msg.disknr, msg.usertag,
MessageDisk::DISK_STATUS_DEVICE);
_mb.bus_diskcommit.send(ro);
_motherboard()->bus_diskcommit.send(ro);
*Genode::Thread_base::myself()->utcb() = utcb_backup;
return true;
}
@ -177,29 +178,26 @@ bool Vancouver_disk::receive(MessageDisk &msg)
if (!p.succeeded()) {
Logging::printf("Operation failed.\n");
{
Genode::Lock::Guard guard(timeouts_lock);
MessageDiskCommit commit(msg.disknr, msg.usertag,
MessageDisk::DISK_STATUS_DEVICE);
_mb.bus_diskcommit.send(commit);
_motherboard()->bus_diskcommit.send(commit);
break;
}
}
}
{
Genode::Lock::Guard guard(timeouts_lock);
MessageDiskCommit commit(msg.disknr, msg.usertag,
MessageDisk::DISK_OK);
_mb.bus_diskcommit.send(commit);
_motherboard()->bus_diskcommit.send(commit);
}
} else {
Logging::printf("Operation failed.\n");
{
Genode::Lock::Guard guard(timeouts_lock);
MessageDiskCommit commit(msg.disknr, msg.usertag,
MessageDisk::DISK_STATUS_DEVICE);
_mb.bus_diskcommit.send(commit);
_motherboard()->bus_diskcommit.send(commit);
}
}

View File

@ -29,8 +29,10 @@
#include <block_session/connection.h>
#include <util/string.h>
/* local includes */
#include <synced_motherboard.h>
/* NOVA userland includes */
#include <nul/motherboard.h>
#include <host/dma.h>
static const bool read_only = false;
@ -48,17 +50,17 @@ class Vancouver_disk : public Genode::Thread<8192>, public StaticReceiver<Vancou
Genode::size_t blk_cnt;
} _diskcon[MAX_DISKS];
Genode::Lock _startup_lock;
Motherboard &_mb;
char *_backing_store_base;
char *_backing_store_fb_base;
Genode::Lock _startup_lock;
Synced_motherboard &_motherboard;
char *_backing_store_base;
char *_backing_store_fb_base;
public:
/**
* Constructor
*/
Vancouver_disk(Motherboard &mb,
Vancouver_disk(Synced_motherboard &,
char * backing_store_base,
char * backing_store_fb_base);
@ -67,6 +69,8 @@ class Vancouver_disk : public Genode::Thread<8192>, public StaticReceiver<Vancou
void entry();
bool receive(MessageDisk &msg);
void register_host_operations(Motherboard &);
};
#endif /* _DISK_H_ */

View File

@ -25,11 +25,9 @@
#include <host/keyboard.h>
#include <nul/vcpu.h>
extern Genode::Lock global_lock;
Vancouver_keyboard::Vancouver_keyboard(Motherboard &mb)
: _mb(mb), _flags(0) { }
Vancouver_keyboard::Vancouver_keyboard(Synced_motherboard &mb)
: _motherboard(mb), _flags(0) { }
void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
@ -93,19 +91,18 @@ void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
/* we send an empty event */
CpuEvent msg(VCpu::EVENT_DEBUG);
for (VCpu *vcpu = _mb.last_vcpu; vcpu; vcpu=vcpu->get_last())
for (VCpu *vcpu = _motherboard()->last_vcpu; vcpu; vcpu=vcpu->get_last())
vcpu->bus_event.send(msg);
}
/* reset */
else if ((_flags & KBFLAG_LWIN) && orig_keycode == Input::KEY_END) {
Genode::Lock::Guard guard(global_lock);
Logging::printf("Reset VM\n");
MessageLegacy msg2(MessageLegacy::RESET, 0);
_mb.bus_legacy.send_fifo(msg2);
_motherboard()->bus_legacy.send_fifo(msg2);
}
else _mb.bus_input.send(msg);
else _motherboard()->bus_input.send(msg);
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
}
@ -165,7 +162,7 @@ void Vancouver_keyboard::handle_keycode_release(unsigned keycode)
}
MessageInput msg(0x10000, _flags | keycode);
_mb.bus_input.send(msg);
_motherboard()->bus_input.send(msg);
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
}

View File

@ -21,8 +21,8 @@
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_
/* NOVA userland includes */
#include <nul/motherboard.h>
/* local includes */
#include <synced_motherboard.h>
/* includes for I/O */
#include <base/env.h>
@ -33,15 +33,15 @@ class Vancouver_keyboard
{
private:
Motherboard &_mb;
unsigned _flags;
Synced_motherboard &_motherboard;
unsigned _flags;
public:
/**
* Constructor
*/
Vancouver_keyboard(Motherboard &mb);
Vancouver_keyboard(Synced_motherboard &);
void handle_keycode_press(unsigned keycode);
void handle_keycode_release(unsigned keycode);

View File

@ -47,6 +47,7 @@
#include <nic_session/connection.h>
#include <os/config.h>
#include <os/alarm.h>
#include <os/synced_interface.h>
#include <timer_session/connection.h>
#include <nova_cpu_session/connection.h>
#include <rtc_session/connection.h>
@ -60,6 +61,7 @@
#include <sys/hip.h>
/* local includes */
#include <synced_motherboard.h>
#include <device_model_registry.h>
#include <boot_module_provider.h>
#include <console.h>
@ -84,29 +86,23 @@ Genode::Lock *utcb_lock()
return &inst;
}
/**
* Semaphore used as global lock
*
* Used for startup synchronization and coarse-grained locking.
*/
Genode::Lock global_lock(Genode::Lock::LOCKED);
Genode::Lock timeouts_lock(Genode::Lock::UNLOCKED);
/* timer service */
using Genode::Thread;
using Genode::Alarm_scheduler;
using Genode::Alarm;
typedef Genode::Synced_interface<TimeoutList<32, void> > Synced_timeout_list;
class Alarm_thread : Thread<4096>, public Alarm_scheduler
{
private:
Timer::Connection _timer;
Alarm::Time _curr_time; /* jiffies value */
Timer::Connection _timer;
Alarm::Time _curr_time; /* jiffies value */
Motherboard &_motherboard;
TimeoutList<32, void> &_timeouts;
Synced_motherboard &_motherboard;
Synced_timeout_list &_timeouts;
/**
* Thread entry function
@ -114,27 +110,19 @@ class Alarm_thread : Thread<4096>, public Alarm_scheduler
void entry()
{
while (true) {
unsigned long long now = _motherboard.clock()->time();
unsigned long long now = _motherboard()->clock()->time();
unsigned nr;
timeouts_lock.lock();
while ((nr = _timeouts()->trigger(now))) {
while ((nr = _timeouts.trigger(now))) {
MessageTimeout msg(nr, _timeouts()->timeout());
MessageTimeout msg(nr, _timeouts.timeout());
if (_timeouts.cancel(nr) < 0)
if (_timeouts()->cancel(nr) < 0)
Logging::printf("Timeout not cancelled.\n");
timeouts_lock.unlock();
_motherboard.bus_timeout.send(msg);
timeouts_lock.lock();
_motherboard()->bus_timeout.send(msg);
}
timeouts_lock.unlock();
_timer.usleep(1000);
}
}
@ -144,11 +132,11 @@ class Alarm_thread : Thread<4096>, public Alarm_scheduler
/**
* Constructor
*/
Alarm_thread(Motherboard &mb, TimeoutList<32, void> &timeouts)
Alarm_thread(Synced_motherboard &mb, Synced_timeout_list &timeouts)
: _curr_time(0), _motherboard(mb), _timeouts(timeouts) { start(); }
Alarm::Time curr_time() { return _curr_time; }
unsigned long long curr_time_long() { return _motherboard.clock()->time(); }
unsigned long long curr_time_long() { return _motherboard()->clock()->time(); }
};
@ -354,7 +342,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
/**
* Pointer to corresponding VCPU model
*/
VCpu * const _vcpu;
Genode::Synced_interface<VCpu> _vcpu;
Vcpu_thread _vcpu_thread;
@ -366,7 +354,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
/**
* Motherboard representing the inter-connections of all device models
*/
Motherboard &_motherboard;
Synced_motherboard &_motherboard;
/***************
@ -413,12 +401,10 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
if (skip == SKIP)
_skip_instruction(msg);
Genode::Lock::Guard guard(global_lock);
/**
* Send the message to the VCpu.
*/
if (!_vcpu->executor.send(msg, true))
if (!_vcpu()->executor.send(msg, true))
Logging::panic("nobody to execute %s at %x:%x\n",
__func__, msg.cpu->cs.sel, msg.cpu->eip);
@ -427,7 +413,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
*/
if (msg.mtr_in & MTD_INJ && msg.type != CpuMessage::TYPE_CHECK_IRQ) {
msg.type = CpuMessage::TYPE_CHECK_IRQ;
if (!_vcpu->executor.send(msg, true))
if (!_vcpu()->executor.send(msg, true))
Logging::panic("nobody to execute %s at %x:%x\n",
__func__, msg.cpu->cs.sel, msg.cpu->eip);
}
@ -437,7 +423,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
*/
if (msg.mtr_out & MTD_INJ) {
msg.type = CpuMessage::TYPE_CALC_IRQWINDOW;
if (!_vcpu->executor.send(msg, true))
if (!_vcpu()->executor.send(msg, true))
Logging::panic("nobody to execute %s at %x:%x\n",
__func__, msg.cpu->cs.sel, msg.cpu->eip);
}
@ -510,7 +496,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
MessageMemRegion mem_region(vm_fault_addr >> PAGE_SIZE_LOG2);
if (!_motherboard.bus_memregion.send(mem_region, false) ||
if (!_motherboard()->bus_memregion.send(mem_region, false) ||
!mem_region.ptr)
return false;
@ -564,7 +550,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
CpuMessage _win(CpuMessage::TYPE_CALC_IRQWINDOW,
static_cast<CpuState *>(utcb), utcb->mtd);
_win.mtr_out = MTD_INJ;
if (!_vcpu->executor.send(_win, true))
if (!_vcpu()->executor.send(_win, true))
Logging::panic("nobody to execute %s at %x:%x\n",
__func__, utcb->cs.sel, utcb->eip);
}
@ -588,8 +574,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
port, &utcb->eax, utcb->mtd);
_skip_instruction(msg);
{
Genode::Lock::Guard l(global_lock);
if (!_vcpu->executor.send(msg, true))
if (!_vcpu()->executor.send(msg, true))
Logging::panic("nobody to execute %s at %x:%x\n",
__func__, msg.cpu->cs.sel, msg.cpu->eip);
}
@ -812,13 +797,14 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
public:
Vcpu_dispatcher(VCpu *vcpu,
Vcpu_dispatcher(Genode::Lock &vcpu_lock,
VCpu *unsynchronized_vcpu,
Guest_memory &guest_memory,
Motherboard &motherboard,
Synced_motherboard &motherboard,
bool has_svm,
bool has_vmx)
:
_vcpu(vcpu),
_vcpu(vcpu_lock, unsynchronized_vcpu),
_vcpu_thread("vCPU thread"),
_guest_memory(guest_memory),
_motherboard(motherboard)
@ -949,7 +935,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
_vcpu_thread.start(sel_sm_ec() + 1);
/* handle cpuid overrides */
vcpu->executor.add(this, receive_static<CpuMessage>);
unsynchronized_vcpu->executor.add(this, receive_static<CpuMessage>);
}
/**
@ -1029,8 +1015,12 @@ class Machine : public StaticReceiver<Machine>
Genode::Rom_connection _hip_rom;
Hip * const _hip;
Clock _clock;
Motherboard _motherboard;
TimeoutList<32, void> _timeouts;
Genode::Lock _motherboard_lock;
Motherboard _unsynchronized_motherboard;
Synced_motherboard _motherboard;
Genode::Lock _timeouts_lock;
TimeoutList<32, void> _unsynchronized_timeouts;
Synced_timeout_list _timeouts;
Guest_memory &_guest_memory;
Boot_module_provider &_boot_modules;
Alarm_thread *_alarm_thread;
@ -1111,7 +1101,8 @@ class Machine : public StaticReceiver<Machine>
Logging::printf("OP_VCPU_CREATE_BACKEND\n");
Vcpu_dispatcher *vcpu_dispatcher =
new Vcpu_dispatcher(msg.vcpu, _guest_memory,
new Vcpu_dispatcher(_motherboard_lock, msg.vcpu,
_guest_memory,
_motherboard,
_hip->has_feature_svm(), _hip->has_feature_vmx());
@ -1137,11 +1128,11 @@ class Machine : public StaticReceiver<Machine>
if (verbose_debug)
Logging::printf("OP_VCPU_BLOCK\n");
global_lock.unlock();
_motherboard_lock.unlock();
bool res = (Nova::sm_ctrl(msg.value, Nova::SEMAPHORE_DOWN) == 0);
if (verbose_debug)
Logging::printf("woke up from vcpu sem, block on global_lock\n");
global_lock.lock();
_motherboard_lock.lock();
return res;
}
@ -1271,20 +1262,15 @@ class Machine : public StaticReceiver<Machine>
_alarm_thread = new Alarm_thread(_motherboard, _timeouts);
}
timeouts_lock.lock();
msg.nr = _timeouts.alloc();
timeouts_lock.unlock();
msg.nr = _timeouts()->alloc();
return true;
case MessageTimer::TIMER_REQUEST_TIMEOUT:
timeouts_lock.lock();
if (_timeouts.request(msg.nr, msg.abstime) < 0)
if (_timeouts()->request(msg.nr, msg.abstime) < 0)
Logging::printf("Could not program timeout.\n");
timeouts_lock.unlock();
return true;
default:
@ -1304,14 +1290,14 @@ class Machine : public StaticReceiver<Machine>
Logging::printf("No RTC present, returning dummy time.\n");
msg.wallclocktime = msg.timestamp = 0;
*Genode::Thread_base::myself()->utcb() = utcb_backup;
*Genode::Thread_base::myself()->utcb() = utcb_backup;
return true;
}
}
msg.wallclocktime = _rtc->get_current_time();
Logging::printf("Got time %llx\n", msg.wallclocktime);
msg.timestamp = _motherboard.clock()->clock(1000000U);
msg.timestamp = _unsynchronized_motherboard.clock()->clock(1000000U);
*Genode::Thread_base::myself()->utcb() = utcb_backup;
@ -1394,21 +1380,24 @@ class Machine : public StaticReceiver<Machine>
_hip_rom("hypervisor_info_page"),
_hip(Genode::env()->rm_session()->attach(_hip_rom.dataspace())),
_clock(_hip->tsc_freq*1000),
_motherboard(&_clock, _hip),
_motherboard_lock(Genode::Lock::LOCKED),
_unsynchronized_motherboard(&_clock, _hip),
_motherboard(_motherboard_lock, &_unsynchronized_motherboard),
_timeouts(_timeouts_lock, &_unsynchronized_timeouts),
_guest_memory(guest_memory),
_boot_modules(boot_modules)
{
_timeouts.init();
_timeouts()->init();
/* register host operations, called back by the VMM */
_motherboard.bus_hostop.add (this, receive_static<MessageHostOp>);
_motherboard.bus_disk.add (this, receive_static<MessageDisk>);
_motherboard.bus_timer.add (this, receive_static<MessageTimer>);
_motherboard.bus_time.add (this, receive_static<MessageTime>);
_motherboard.bus_network.add (this, receive_static<MessageNetwork>);
_motherboard.bus_hwpcicfg.add(this, receive_static<MessageHwPciConfig>);
_motherboard.bus_acpi.add (this, receive_static<MessageAcpi>);
_motherboard.bus_legacy.add (this, receive_static<MessageLegacy>);
_unsynchronized_motherboard.bus_hostop.add (this, receive_static<MessageHostOp>);
_unsynchronized_motherboard.bus_disk.add (this, receive_static<MessageDisk>);
_unsynchronized_motherboard.bus_timer.add (this, receive_static<MessageTimer>);
_unsynchronized_motherboard.bus_time.add (this, receive_static<MessageTime>);
_unsynchronized_motherboard.bus_network.add (this, receive_static<MessageNetwork>);
_unsynchronized_motherboard.bus_hwpcicfg.add(this, receive_static<MessageHwPciConfig>);
_unsynchronized_motherboard.bus_acpi.add (this, receive_static<MessageAcpi>);
_unsynchronized_motherboard.bus_legacy.add (this, receive_static<MessageLegacy>);
}
@ -1472,7 +1461,7 @@ class Machine : public StaticReceiver<Machine>
* We never pass any argument string to a device model because
* it is not examined by the existing device models.
*/
dmi->create(_motherboard, argv, "", 0);
dmi->create(_unsynchronized_motherboard, argv, "", 0);
if (node.is_last())
break;
@ -1485,7 +1474,7 @@ class Machine : public StaticReceiver<Machine>
void boot()
{
/* init VCPUs */
for (VCpu *vcpu = _motherboard.last_vcpu; vcpu; vcpu = vcpu->get_last()) {
for (VCpu *vcpu = _unsynchronized_motherboard.last_vcpu; vcpu; vcpu = vcpu->get_last()) {
/* init CPU strings */
const char *short_name = "NOVA microHV";
@ -1512,13 +1501,18 @@ class Machine : public StaticReceiver<Machine>
Logging::printf("RESET device state\n");
MessageLegacy msg2(MessageLegacy::RESET, 0);
_motherboard.bus_legacy.send_fifo(msg2);
_unsynchronized_motherboard.bus_legacy.send_fifo(msg2);
global_lock.unlock();
Logging::printf("INIT done\n");
_motherboard_lock.unlock();
}
Motherboard& get_mb() { return _motherboard; }
Synced_motherboard &motherboard() { return _motherboard; }
Motherboard &unsynchronized_motherboard() { return _unsynchronized_motherboard; }
Genode::Lock &motherboard_lock() { return _motherboard_lock; }
~Machine()
{
@ -1611,14 +1605,22 @@ int main(int argc, char **argv)
static Machine machine(boot_modules, guest_memory);
Genode::Lock fb_lock;
/* create console thread */
Vancouver_console vcon(machine.get_mb(), fb_size, guest_memory.fb_ds());
Vancouver_console vcon(machine.motherboard(),
fb_lock,
fb_size, guest_memory.fb_ds());
vcon.register_host_operations(machine.unsynchronized_motherboard());
/* create disk thread */
Vancouver_disk vdisk(machine.get_mb(),
Vancouver_disk vdisk(machine.motherboard(),
guest_memory.backing_store_local_base(),
guest_memory.backing_store_fb_local_base());
vdisk.register_host_operations(machine.unsynchronized_motherboard());
machine.setup_devices(Genode::config()->xml_node().sub_node("machine"));
Genode::printf("\n--- Booting VM ---\n");

View File

@ -24,8 +24,8 @@
extern const void * _forward_pkt;
Vancouver_network::Vancouver_network(Motherboard &mb, Nic::Session * nic)
: _mb(mb), _nic(nic)
Vancouver_network::Vancouver_network(Synced_motherboard &mb, Nic::Session *nic)
: _motherboard(mb), _nic(nic)
{
start();
}
@ -42,7 +42,7 @@ void Vancouver_network::entry()
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);
_motherboard()->bus_network.send(msg);
_forward_pkt = 0;
/* acknowledge received packet */

View File

@ -24,8 +24,8 @@
/* Genode includes */
#include <nic_session/connection.h>
/* NOVA userland includes */
#include <nul/motherboard.h>
/* local includes */
#include <synced_motherboard.h>
using Genode::List;
using Genode::Thread;
@ -34,8 +34,8 @@ class Vancouver_network : public Thread<4096>
{
private:
Motherboard &_mb;
Nic::Session *_nic;
Synced_motherboard &_motherboard;
Nic::Session *_nic;
public:
@ -45,7 +45,7 @@ class Vancouver_network : public Thread<4096>
/**
* Constructor
*/
Vancouver_network(Motherboard &mb, Nic::Session *nic);
Vancouver_network(Synced_motherboard &, Nic::Session *);
};
#endif /* _NETWORK_H_ */

View File

@ -0,0 +1,22 @@
/*
* \brief Synchronized access to Vancouver motherboard
* \author Norman Feske
* \date 2013-05-16
*/
/*
* 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.
*/
#ifndef _SYNCED_MOTHERBOARD_H_
#define _SYNCED_MOTHERBOARD_H_
#include <nul/motherboard.h>
#include <os/synced_interface.h>
typedef Genode::Synced_interface<Motherboard> Synced_motherboard;
#endif /* _SYNCED_MOTHERBOARD_H_ */