blob: 73b5a039ea57e29166ac9bab8a3e944654ccfce9 [file] [log] [blame]
// Copyright 2022 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/connectivity/ethernet/drivers/gvnic/pagelist.h"
#include "src/connectivity/ethernet/drivers/gvnic/bigendian.h"
uint32_t PageList::next_id_ = 0;
PageList::PageList(std::unique_ptr<dma_buffer::BufferFactory>& buffer_factory, zx::bti& bti,
std::unique_ptr<dma_buffer::ContiguousBuffer>& scratch_page) {
zx_status_t status;
id_ = next_id_++;
// TODO(charlieross): Once the requirements for these pagelists are better understood, support
// making smaller pagelists. But for now, make em big.
length_ = static_cast<uint32_t>(scratch_page->size()) /
sizeof(uint64_t); // Make it as large as we can.
status = buffer_factory->CreatePaged(bti, zx_system_get_page_size() * length_,
/*enable_cache*/ true, &pages_);
ZX_ASSERT_MSG(status == ZX_OK,
"buffer_factory->CreatePaged(bti, zx_system_get_page_size() * length_, true, "
"&pages_): FAILED (%s)",
zx_status_get_string(status));
// Can't just memcpy. Need to assign individually to get the BigEndian goodness.
auto const pl_addrs_tgt = reinterpret_cast<BigEndian<uint64_t>*>(scratch_page->virt());
auto const pl_addrs_src = pages_->phys();
for (uint32_t i = 0; i < length_; i++) {
pl_addrs_tgt[i] = pl_addrs_src[i];
}
}
uint32_t PageList::id() { return id_; }
uint32_t PageList::length() { return length_; }
const dma_buffer::PagedBuffer* PageList::pages() { return pages_.get(); }