blob: 32b23eb6821a820a13cf3a19d1086adec1cbabcd [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/virtualization/bin/vmm/device/test_with_device.h"
#include <lib/zx/channel.h>
#include "src/virtualization/bin/vmm/device/config.h"
#include "src/virtualization/bin/vmm/device/virtio_queue.h"
zx_status_t TestWithDevice::WaitOnInterrupt() {
std::optional<zx_status_t> opt_status;
zx_signals_t signals = VirtioQueue::InterruptAction::TRY_INTERRUPT << kDeviceInterruptShift;
async::Wait wait(event_.get(), signals, 0 /*options*/,
[&](async_dispatcher_t* dispatcher, async::Wait* wait, zx_status_t status,
const zx_packet_signal_t* signal) {
opt_status = status;
QuitLoop();
});
zx_status_t status = wait.Begin(dispatcher());
if (status != ZX_OK) {
FX_LOGS(ERROR) << "Wait Begin failed: " << status;
return status;
}
if (RunLoopWithTimeout(zx::sec(10))) {
FX_LOGS(ERROR) << "Run loop timed out";
return ZX_ERR_TIMED_OUT;
}
if (!opt_status) {
FX_LOGS(ERROR) << "Optional status not available";
return ZX_ERR_INTERNAL;
}
if (opt_status != ZX_OK) {
FX_LOGS(ERROR) << "Optional status: " << status;
return opt_status.value();
}
event_.signal(signals, 0);
return ZX_OK;
}
zx_status_t TestWithDevice::MakeStartInfo(
size_t phys_mem_size, fuchsia::virtualization::hardware::StartInfo* start_info) {
// Setup device interrupt event.
zx_status_t status = zx::event::create(0, &event_);
if (status != ZX_OK) {
return status;
}
status = event_.duplicate(ZX_RIGHT_TRANSFER | ZX_RIGHT_SIGNAL, &start_info->event);
if (status != ZX_OK) {
return status;
}
// Setup guest physical memory.
zx::vmo vmo;
status = zx::vmo::create(phys_mem_size, 0, &vmo);
if (status != ZX_OK) {
FX_LOGS(ERROR) << "Failed to create VMO " << status;
return status;
}
status = vmo.duplicate(ZX_RIGHT_TRANSFER | ZX_RIGHTS_IO | ZX_RIGHT_MAP, &start_info->vmo);
if (status != ZX_OK) {
FX_LOGS(ERROR) << "Failed to duplicate VMO " << status;
return status;
}
return phys_mem_.Init(std::move(vmo));
}