blob: 496c00e627e680e8927aefa7e9ac794eab662c73 [file] [log] [blame]
// Copyright 2019 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 <lib/driver-integration-test/fixture.h>
#include <memory.h>
#include <string.h>
#include <ddk/platform-defs.h>
#include <fbl/algorithm.h>
#include <lib/devmgr-launcher/launch.h>
#include <lib/zx/vmo.h>
#include <libzbi/zbi-cpp.h>
#include <zircon/assert.h>
#include <zircon/boot/image.h>
#include <zircon/status.h>
namespace driver_integration_test {
namespace {
constexpr char kBoardName[] = "driver-integration-test";
// This board driver knows how to intepret the metadata for which devices to
// spawn.
const zbi_platform_id_t kPlatformId = []() {
zbi_platform_id_t plat_id = {};
plat_id.vid = PDEV_VID_TEST;
plat_id.pid = PDEV_PID_INTEGRATION_TEST;
strcpy(plat_id.board_name, kBoardName);
return plat_id;
}();
zx_status_t GetBootdata(const fbl::Vector<board_test::DeviceEntry>& device_list,
zx::vmo* bootdata_out) {
const size_t metadata_size = sizeof(board_test::DeviceList) +
device_list.size() * sizeof(board_test::DeviceEntry);
ZX_ASSERT(metadata_size < 1024);
// Serialize to expected metadata format.
fbl::unique_ptr<uint8_t[]> metadata(new uint8_t[metadata_size]);
auto* devices = reinterpret_cast<board_test::DeviceList*>(metadata.get());
devices->count = device_list.size();
memcpy(devices->list, device_list.get(), devices->count * sizeof(board_test::DeviceEntry));
uint8_t zbi_buf[1024];
zbi::Zbi zbi(zbi_buf, sizeof(zbi_buf));
if (zbi.Reset() != ZBI_RESULT_OK) {
return ZX_ERR_INTERNAL;
}
if (zbi.AppendSection(sizeof(kPlatformId), ZBI_TYPE_PLATFORM_ID, 0, ZBI_FLAG_VERSION,
&kPlatformId) != ZBI_RESULT_OK) {
return ZX_ERR_INTERNAL;
}
if (zbi.AppendSection(static_cast<uint32_t>(metadata_size), ZBI_TYPE_DRV_BOARD_PRIVATE,
0, ZBI_FLAG_VERSION, metadata.get()) != ZBI_RESULT_OK) {
return ZX_ERR_INTERNAL;
}
zx::vmo zbi_vmo;
zx_status_t status = zx::vmo::create(zbi.Length(), 0, &zbi_vmo);
if (status != ZX_OK) {
return status;
}
status = zbi_vmo.write(zbi.Base(), 0, zbi.Length());
if (status != ZX_OK) {
return status;
}
*bootdata_out = std::move(zbi_vmo);
return ZX_OK;
}
} // namespace
zx_status_t IsolatedDevmgr::Create(IsolatedDevmgr::Args args,
IsolatedDevmgr* out) {
IsolatedDevmgr devmgr;
devmgr_launcher::Args devmgr_args;
devmgr_args.sys_device_driver = "/boot/driver/platform-bus.so";
devmgr_args.driver_search_paths.swap(args.driver_search_paths);
devmgr_args.load_drivers.swap(args.load_drivers);
zx_status_t status = GetBootdata(args.device_list, &devmgr_args.bootdata);
if (status != ZX_OK) {
return status;
}
status = devmgr_integration_test::IsolatedDevmgr::Create(std::move(devmgr_args),
&devmgr.devmgr_);
if (status != ZX_OK) {
return status;
}
*out = std::move(devmgr);
return ZX_OK;
}
} // namespace driver_integration_test