blob: a8684574aee81a4ff940208a2bd565f59481cb26 [file] [log] [blame]
// Copyright 2016 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 "utils.h"
#include <ddk/driver.h>
#include <limits.h>
#include <zircon/types.h>
#include <zx/process.h>
#include <zx/vmar.h>
#include <zx/vmo.h>
#include <fbl/auto_call.h>
#include "trace.h"
namespace virtio {
zx_status_t map_contiguous_memory(size_t size, uintptr_t* _va, zx_paddr_t* _pa) {
zx_handle_t vmo_handle;
zx_status_t r = zx_vmo_create_contiguous(get_root_resource(), size, 0, &vmo_handle);
if (r) {
VIRTIO_ERROR("zx_vmo_create_contiguous failed %d\n", r);
return r;
}
zx::vmo vmo(vmo_handle);
uintptr_t va;
const uint32_t flags = ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE;
r = zx::vmar::root_self().map(0, vmo, 0, size, flags, &va);
if (r) {
VIRTIO_ERROR("zx_process_map_vm failed %d size: %zu\n", r, size);
return r;
}
auto ac = fbl::MakeAutoCall([va, size]() {
zx::vmar::root_self().unmap(va, size);
});
// TODO: add when LOCK operation implemented in kernel
#if 0
r = vmo.op_range(ZX_VMO_OP_LOCK, 0, size, nullptr, 0);
if (r) {
VIRTIO_ERROR("zx_vmo_op_range LOCK failed %d\n", r);
return r;
}
#endif
zx_paddr_t pa;
r = vmo.op_range(ZX_VMO_OP_LOOKUP, 0, PAGE_SIZE, &pa, sizeof(pa));
if (r) {
VIRTIO_ERROR("zx_vmo_op_range LOOKUP failed %d\n", r);
return r;
}
ac.cancel();
*_va = va;
*_pa = pa;
return ZX_OK;
}
} // namespace virtio