blob: 4dd7e968552a73333291ea74e64fcbdd445fdfae [file]
// Copyright 2026 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/devicetree/manager/publisher-dev.h"
#include <lib/driver/component/cpp/composite_node_spec.h>
#include <lib/driver/logging/cpp/logger.h>
#include <zircon/status.h>
namespace fdf_devicetree {
zx::result<> PublisherDev::AddPbusNode(fuchsia_hardware_platform_bus::Node& pbus_node,
std::vector<std::optional<std::string>> metadata_text,
std::vector<std::optional<std::string>> power_config_text) {
fdf::Arena arena('PBUS');
fidl::Arena fidl_arena;
auto result = pbus_.buffer(arena)->NodeAdd(fidl::ToWire(fidl_arena, pbus_node));
if (!result.ok()) {
fdf::error("NodeAdd request failed: {}", result.FormatDescription());
return zx::error(result.status());
}
if (result->is_error()) {
fdf::error("NodeAdd failed: {}", result->error_value());
return zx::error(result->error_value());
}
return zx::ok();
}
zx::result<> PublisherDev::AddBoardChildNode(BoardChildNode args) {
fuchsia_driver_framework::NodeAddArgs node_add_args;
node_add_args.name() = std::move(args.name);
if (args.driver_host) {
node_add_args.driver_host() = *args.driver_host;
}
node_add_args.properties2() = std::move(args.properties);
if (args.bus_info) {
node_add_args.bus_info() = std::move(*args.bus_info);
}
auto [client_end, server_end] =
fidl::Endpoints<fuchsia_driver_framework::NodeController>::Create();
auto result = fdf_node_->AddChild({std::move(node_add_args), std::move(server_end), {}});
if (result.is_error()) {
fdf::error("AddChild request failed: {}", result.error_value().FormatDescription());
return zx::error(ZX_ERR_INTERNAL);
}
return zx::ok();
}
zx::result<> PublisherDev::AddCompositeNodeSpec(
std::string name, std::vector<fuchsia_driver_framework::ParentSpec2> parents,
std::optional<std::string> driver_host) {
fuchsia_driver_framework::CompositeNodeSpec group{{
.name = name,
.parents2 = std::move(parents),
}};
if (driver_host) {
group.driver_host() = *driver_host;
}
auto devicegroup_result = mgr_->AddSpec({std::move(group)});
if (devicegroup_result.is_error()) {
fdf::error("Failed to create composite node: {}",
devicegroup_result.error_value().FormatDescription());
return zx::error(devicegroup_result.error_value().is_framework_error()
? devicegroup_result.error_value().framework_error().status()
: ZX_ERR_INVALID_ARGS);
}
return zx::ok();
}
zx::result<> PublisherDev::RegisterIommu(uint32_t iommu_id,
fuchsia_hardware_platform_bus::Iommu iommu) {
fdf::Arena arena('PBUS');
auto iommu_wire = iommu.stub_iommu()
? fuchsia_hardware_platform_bus::wire::Iommu::WithStubIommu({})
: fuchsia_hardware_platform_bus::wire::Iommu::WithArmSmmu(
arena, iommu.arm_smmu()->base_address());
auto result = pbus_.buffer(arena)->RegisterIommu(iommu_id, iommu_wire);
if (!result.ok()) {
fdf::error("Failed to publish iommu: {} : {}", iommu_id, result.FormatDescription());
return zx::error(result.status());
}
if (result->is_error()) {
fdf::error("Failed to publish iommu: {} : {}", iommu_id, result->error_value());
return zx::error(result->error_value());
}
return zx::ok();
}
} // namespace fdf_devicetree