blob: 7fd5c8721a4fa74bdce6a40a6c256c5e61c897a7 [file] [log] [blame]
// Copyright 2017 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 SRC_DEVICES_BUS_DRIVERS_PLATFORM_PLATFORM_BUS_H_
#define SRC_DEVICES_BUS_DRIVERS_PLATFORM_PLATFORM_BUS_H_
#include <fidl/fuchsia.boot/cpp/wire.h>
#include <fidl/fuchsia.hardware.platform.bus/cpp/driver/fidl.h>
#include <fidl/fuchsia.hardware.platform.bus/cpp/fidl.h>
#include <fidl/fuchsia.sysinfo/cpp/wire.h>
#include <lib/driver/compat/cpp/device_server.h>
#include <lib/driver/component/cpp/driver_base.h>
#include <lib/driver/node/cpp/add_child.h>
#include <lib/fdf/cpp/dispatcher.h>
#include <lib/fidl/cpp/wire/internal/transport_channel.h>
#include <lib/zbi-format/board.h>
#include <lib/zx/iommu.h>
#include <lib/zx/resource.h>
#include <lib/zx/result.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>
#include <fbl/array.h>
#include "platform-device.h"
namespace platform_bus {
class PlatformBus;
// This is the main class for the platform bus driver.
class PlatformBus : public fdf::DriverBase,
public fdf::WireServer<fuchsia_hardware_platform_bus::PlatformBus>,
public fdf::WireServer<fuchsia_hardware_platform_bus::Iommu>,
public fdf::WireServer<fuchsia_hardware_platform_bus::Firmware>,
public fidl::Server<fuchsia_hardware_platform_bus::InterruptAttributor>,
public fidl::WireServer<fuchsia_sysinfo::SysInfo> {
public:
PlatformBus(fdf::DriverStartArgs start_args,
fdf::UnownedSynchronizedDispatcher driver_dispatcher);
~PlatformBus() { FDF_LOG(INFO, "~PlatformBus()"); }
void Stop() override { FDF_LOG(INFO, "Stop()"); }
using fdf::DriverBase::dispatcher;
using fdf::DriverBase::driver_dispatcher;
using fdf::DriverBase::outgoing;
zx::result<> Start() override;
void PrepareStop(fdf::PrepareStopCompleter completer) override;
// fuchsia.hardware.platform.bus.PlatformBus implementation.
void NodeAdd(NodeAddRequestView request, fdf::Arena& arena,
NodeAddCompleter::Sync& completer) override;
void GetBoardInfo(fdf::Arena& arena, GetBoardInfoCompleter::Sync& completer) override;
void SetBoardInfo(SetBoardInfoRequestView request, fdf::Arena& arena,
SetBoardInfoCompleter::Sync& completer) override;
void SetBootloaderInfo(SetBootloaderInfoRequestView request, fdf::Arena& arena,
SetBootloaderInfoCompleter::Sync& completer) override;
void RegisterSysSuspendCallback(RegisterSysSuspendCallbackRequestView request, fdf::Arena& arena,
RegisterSysSuspendCallbackCompleter::Sync& completer) override;
void AddCompositeNodeSpec(AddCompositeNodeSpecRequestView request, fdf::Arena& arena,
AddCompositeNodeSpecCompleter::Sync& completer) override;
void handle_unknown_method(
fidl::UnknownMethodMetadata<fuchsia_hardware_platform_bus::PlatformBus> metadata,
fidl::UnknownMethodCompleter::Sync& completer) override;
// fuchsia.hardware.platform.bus.Iommu implementation.
void GetBti(GetBtiRequestView request, fdf::Arena& arena,
GetBtiCompleter::Sync& completer) override;
// fuchsia.hardware.platform.bus.Firmware implementation.
void GetFirmware(GetFirmwareRequestView request, fdf::Arena& arena,
GetFirmwareCompleter::Sync& completer) override;
// InterruptAttributor protocol implementation.
void GetInterruptInfo(GetInterruptInfoRequest& request,
GetInterruptInfoCompleter::Sync& completer) override;
// SysInfo protocol implementation.
void GetBoardName(GetBoardNameCompleter::Sync& completer) override;
void GetBoardRevision(GetBoardRevisionCompleter::Sync& completer) override;
void GetBootloaderVendor(GetBootloaderVendorCompleter::Sync& completer) override;
void GetInterruptControllerInfo(GetInterruptControllerInfoCompleter::Sync& completer) override;
void GetSerialNumber(GetSerialNumberCompleter::Sync& completer) override;
zx::result<zx::bti> GetBti(uint32_t iommu_index, uint32_t bti_id, std::string_view name);
zx::unowned_resource GetIrqResource() const;
zx::unowned_resource GetMmioResource() const;
zx::unowned_resource GetSmcResource() const;
struct BootItemResult {
zx::vmo vmo;
uint32_t length;
};
// Returns ZX_ERR_NOT_FOUND when boot item wasn't found.
zx::result<std::vector<BootItemResult>> GetBootItem(uint32_t type, std::optional<uint32_t> extra);
zx::result<fbl::Array<uint8_t>> GetBootItemArray(uint32_t type, std::optional<uint32_t> extra);
fidl::WireClient<fuchsia_hardware_platform_bus::SysSuspend>& suspend_cb() { return suspend_cb_; }
fuchsia_hardware_platform_bus::TemporaryBoardInfo board_info() { return board_info_; }
fdf::ServerBindingGroup<fuchsia_hardware_platform_bus::PlatformBus>& bindings() {
return bindings_;
}
fdf::ServerBindingGroup<fuchsia_hardware_platform_bus::Iommu>& iommu_bindings() {
return iommu_bindings_;
}
fdf::ServerBindingGroup<fuchsia_hardware_platform_bus::Firmware>& fw_bindings() {
return fw_bindings_;
}
fidl::ServerBindingGroup<fuchsia_hardware_platform_bus::InterruptAttributor>&
interrupt_bindings() {
return interrupt_bindings_;
}
fidl::ServerBindingGroup<fuchsia_sysinfo::SysInfo>& sysinfo_bindings() {
return sysinfo_bindings_;
}
bool suspend_enabled() const { return suspend_enabled_; }
fidl::UnownedClientEnd<fuchsia_driver_framework::Node> platform_node() const {
return platform_node_.node_.borrow();
}
private:
fidl::WireClient<fuchsia_hardware_platform_bus::SysSuspend> suspend_cb_;
DISALLOW_COPY_ASSIGN_AND_MOVE(PlatformBus);
zx::result<zbi_board_info_t> GetBoardInfo();
zx::result<> NodeAddInternal(fuchsia_hardware_platform_bus::Node& node);
fidl::ClientEnd<fuchsia_boot::Items> items_svc_;
fuchsia_hardware_platform_bus::TemporaryBoardInfo board_info_ = {};
// List to cache requests when board_name is not yet set.
std::vector<GetBoardNameCompleter::Async> board_name_completer_;
fuchsia_hardware_platform_bus::BootloaderInfo bootloader_info_ = {};
// List to cache requests when vendor is not yet set.
std::vector<GetBootloaderVendorCompleter::Async> bootloader_vendor_completer_;
fuchsia_sysinfo::wire::InterruptControllerType interrupt_controller_type_ =
fuchsia_sysinfo::wire::InterruptControllerType::kUnknown;
// Dummy IOMMU.
zx::iommu iommu_handle_;
std::map<std::pair<uint32_t, uint32_t>, zx::bti> cached_btis_;
fdf::OwnedChildNode sys_node_;
fdf::OwnedChildNode platform_node_;
fidl::ClientEnd<fuchsia_driver_framework::NodeController> pt_node_;
std::vector<std::unique_ptr<PlatformDevice>> devices_;
compat::DeviceServer device_server_;
fdf::ServerBindingGroup<fuchsia_hardware_platform_bus::PlatformBus> bindings_;
fdf::ServerBindingGroup<fuchsia_hardware_platform_bus::Iommu> iommu_bindings_;
fdf::ServerBindingGroup<fuchsia_hardware_platform_bus::Firmware> fw_bindings_;
fidl::ServerBindingGroup<fuchsia_hardware_platform_bus::InterruptAttributor> interrupt_bindings_;
fidl::ServerBindingGroup<fuchsia_sysinfo::SysInfo> sysinfo_bindings_;
bool suspend_enabled_ = false;
};
} // namespace platform_bus
#endif // SRC_DEVICES_BUS_DRIVERS_PLATFORM_PLATFORM_BUS_H_