blob: 152f49b3c39fc07a8ef4aa99e68e6620660b23f8 [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.
#pragma once
#include <stdint.h>
#include <threads.h>
#include <ddk/device.h>
#include <ddktl/device.h>
#include <ddktl/protocol/canvas.h>
#include <ddktl/protocol/clk.h>
#include <ddktl/protocol/gpio.h>
#include <ddktl/protocol/i2c.h>
#include <ddktl/protocol/iommu.h>
#include <ddktl/protocol/mailbox.h>
#include <ddktl/protocol/platform-bus.h>
#include <ddktl/protocol/scpi.h>
#include <ddktl/protocol/usb-mode-switch.h>
#include <fbl/array.h>
#include <fbl/mutex.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <lib/sync/completion.h>
#include <lib/zx/handle.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>
#include "platform-device.h"
#include "proxy-protocol.h"
namespace platform_bus {
class PlatformBus;
using PlatformBusType = ddk::Device<PlatformBus, ddk::GetProtocolable>;
// This is the main class for the platform bus driver.
class PlatformBus : public PlatformBusType, public ddk::PlatformBusProtocol<PlatformBus>,
public ddk::IommuProtocol<PlatformBus> {
public:
static zx_status_t Create(zx_device_t* parent, const char* name, zx::vmo zbi);
// Device protocol implementation.
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out);
void DdkRelease();
// Platform bus protocol implementation.
zx_status_t SetProtocol(uint32_t proto_id, void* protocol);
zx_status_t WaitProtocol(uint32_t proto_id);
zx_status_t DeviceAdd(const pbus_dev_t* dev, uint32_t flags);
zx_status_t DeviceEnable(uint32_t vid, uint32_t pid, uint32_t did, bool enable);
const char* GetBoardName();
zx_status_t SetBoardInfo(const pbus_board_info_t* info);
// IOMMU protocol implementation.
zx_status_t GetBti(uint32_t iommu_index, uint32_t bti_id, zx_handle_t* out_handle);
// Returns the resource handle to be used for creating MMIO regions and IRQs.
// Currently this just returns the root resource, but we may change this to a more
// limited resource in the future.
zx_handle_t GetResource() const { return get_root_resource(); }
// Helper for PlatformDevice.
zx_status_t GetBoardInfo(pdev_board_info_t* out_info);
// Protocol accessors for PlatformDevice.
inline ddk::CanvasProtocolProxy* canvas() const { return canvas_.get(); }
inline ddk::ClkProtocolProxy* clk() const { return clk_.get(); }
inline ddk::GpioProtocolProxy* gpio() const { return gpio_.get(); }
inline ddk::I2cProtocolProxy* i2c() const { return i2c_.get(); }
inline ddk::ScpiProtocolProxy* scpi() const { return scpi_.get(); }
inline ddk::UmsProtocolProxy* ums() const { return ums_.get(); }
inline const uint8_t* metadata() const { return metadata_.get(); }
inline size_t metadata_size() const { return metadata_.size(); }
private:
explicit PlatformBus(zx_device_t* parent);
DISALLOW_COPY_ASSIGN_AND_MOVE(PlatformBus);
zx_status_t Init(zx::vmo zbi);
// Reads the platform ID and driver metadata records from the boot image.
zx_status_t ReadZbi(zx::vmo zbi);
pdev_board_info_t board_info_;
// Protocols that are optionally provided by the board driver.
fbl::unique_ptr<ddk::CanvasProtocolProxy> canvas_;
fbl::unique_ptr<ddk::ClkProtocolProxy> clk_;
fbl::unique_ptr<ddk::GpioProtocolProxy> gpio_;
fbl::unique_ptr<ddk::IommuProtocolProxy> iommu_;
fbl::unique_ptr<ddk::I2cProtocolProxy> i2c_;
fbl::unique_ptr<ddk::ScpiProtocolProxy> scpi_;
fbl::unique_ptr<ddk::MailboxProtocolProxy> mailbox_;
fbl::unique_ptr<ddk::UmsProtocolProxy> ums_;
// Completion used by WaitProtocol().
sync_completion_t proto_completion_ __TA_GUARDED(mutex_);
fbl::Mutex mutex_;
// Metadata extracted from ZBI.
fbl::Array<uint8_t> metadata_;
// List of platform devices.
fbl::Vector<fbl::unique_ptr<PlatformDevice>> devices_;
// Dummy IOMMU.
zx::handle iommu_handle_;
};
} // namespace platform_bus
__BEGIN_CDECLS
zx_status_t platform_bus_create(void* ctx, zx_device_t* parent, const char* name,
const char* args, zx_handle_t rpc_channel);
__END_CDECLS