blob: e0944be4657459ecb211ec59e94eb1a6ca5e4640 [file] [log] [blame] [edit]
// 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 "device-resources.h"
#include <utility>
namespace {
template <typename T>
bool CopyResources(size_t in_count, const T* in_list, fbl::Array<T>* out) {
if (!in_count) {
return true;
}
fbl::AllocChecker ac;
out->reset(new (&ac) T[in_count], in_count);
if (!ac.check()) {
return false;
}
memcpy(out->begin(), in_list, in_count * sizeof(T));
return true;
}
} // namespace
namespace platform_bus {
zx_status_t DeviceResources::Init(const pbus_dev_t* pdev) {
if (!CopyResources(pdev->mmio_count, pdev->mmio_list, &mmios_) ||
!CopyResources(pdev->irq_count, pdev->irq_list, &irqs_) ||
!CopyResources(pdev->bti_count, pdev->bti_list, &btis_) ||
!CopyResources(pdev->smc_count, pdev->smc_list, &smcs_) ||
!CopyResources(pdev->metadata_count, pdev->metadata_list, &metadata_) ||
!CopyResources(pdev->boot_metadata_count, pdev->boot_metadata_list, &boot_metadata_)) {
return ZX_ERR_NO_MEMORY;
}
if (!CopyMetadataDataBuffers()) {
return ZX_ERR_NO_MEMORY;
}
return ZX_OK;
}
bool DeviceResources::CopyMetadataDataBuffers() {
// Each pbus_metadata_t struct contains a data_buffer pointer. We need to copy the
// buffer into our own array and overwrite the existing pointer.
fbl::AllocChecker ac;
metadata_data_buffers_.reset(new (&ac) fbl::Array<uint8_t>[metadata_count()], metadata_count());
if (!ac.check()) {
return false;
}
for (size_t i = 0; i < metadata_count(); i++) {
size_t data_len = metadata(i).data_size;
auto data_buffer = static_cast<const uint8_t*>(metadata(i).data_buffer);
if (!CopyResources(data_len, data_buffer, &metadata_data_buffers_[i])) {
return false;
}
metadata_[i].data_buffer = metadata_data_buffers_[i].get();
}
return true;
}
} // namespace platform_bus