| // Copyright 2023 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. |
| |
| #ifndef LIB_DRIVER_DEVICETREE_MANAGER_H_ |
| #define LIB_DRIVER_DEVICETREE_MANAGER_H_ |
| |
| #include <fidl/fuchsia.driver.framework/cpp/fidl.h> |
| #include <fidl/fuchsia.hardware.platform.bus/cpp/driver/fidl.h> |
| #include <lib/devicetree/devicetree.h> |
| #include <lib/driver/incoming/cpp/namespace.h> |
| #include <lib/stdcompat/span.h> |
| #include <lib/zx/result.h> |
| |
| #include <unordered_map> |
| #include <vector> |
| |
| #include "sdk/lib/driver/devicetree/node.h" |
| #include "sdk/lib/driver/devicetree/visitor.h" |
| #include "sdk/lib/driver/devicetree/visitors/default.h" |
| |
| namespace fdf_devicetree { |
| |
| class Manager { |
| public: |
| static zx::result<Manager> CreateFromNamespace(fdf::Namespace& ns); |
| |
| // Create a new device tree manager using the given FDT blob. |
| explicit Manager(std::vector<uint8_t> fdt_blob) |
| : fdt_blob_(std::move(fdt_blob)), |
| tree_(devicetree::ByteView{fdt_blob_.data(), fdt_blob_.size()}) {} |
| |
| // This method does the following things - |
| // * Does the initial walk of the tree and discovers devices/nodes. |
| // * Calls |visitor.Visit()| for each node in the tree. |
| // If |visitor.Visit()| returns something that's not `zx::ok()`, then this |
| // will stop walking and return the error code. |
| // |
| // This method can be called with the |DefaultVisitor| or with a collection |
| // of visitors of user's choice. |
| // Example: |
| // auto result = manager.Walk(manager.default_visitor()) |
| // |
| // This needs to be called before |PublishDevices|. |
| zx::result<> Walk(Visitor& visitor); |
| |
| // Publish the discovered devices. |
| // |pbus| should be the platform bus. |
| // |parent_node| is the root node of the devicetree. This will eventually be |
| // used for housing the metadata nodes. |
| // |mgr| is the device group manager. |
| zx::result<> PublishDevices(fdf::ClientEnd<fuchsia_hardware_platform_bus::PlatformBus> pbus, |
| fidl::ClientEnd<fuchsia_driver_framework::CompositeNodeManager> mgr); |
| |
| const std::vector<std::unique_ptr<Node>>& nodes() { return nodes_publish_order_; } |
| |
| // Set of visitors to parse basic devicetree properties like bind property, |
| // MMIO register properties etc., of each node and publish the properties to |
| // |fdf_devicetree::Node|. |
| DefaultVisitor& default_visitor() { return default_visitor_; } |
| |
| private: |
| std::vector<uint8_t> fdt_blob_; |
| devicetree::Devicetree tree_; |
| |
| // List of nodes, in the order that they were seen in the tree. |
| std::vector<std::unique_ptr<Node>> nodes_publish_order_; |
| // Nodes by phandle. Note that not every node in the tree has a phandle. |
| std::unordered_map<uint32_t, Node*> nodes_by_phandle_; |
| uint32_t node_id_ = 0; |
| DefaultVisitor default_visitor_; |
| }; |
| |
| } // namespace fdf_devicetree |
| |
| #endif // LIB_DRIVER_DEVICETREE_MANAGER_H_ |