// Copyright 2018 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.

library fuchsia.hardware.platform.bus;

using fuchsia.hardware.platform.device;
using zx;

struct PbusMmio {
    /// Physical address of MMIO region.
    /// Does not need to be page aligned.
    zx.paddr base;
    /// Length of MMIO region in bytes.
    /// Does not need to be page aligned.
    uint64 length;
};

struct PbusIrq {
    uint32 irq;
    /// `ZX_INTERRUPT_MODE_*` flags
    uint32 mode;
};

struct PbusBti {
    uint32 iommu_index;
    uint32 bti_id;
};

struct PbusSmc {
    /// The device is granted the ability to make SMC calls with service call numbers ranging from
    /// service_call_num_base to service_call_num_base + count - 1.
    uint32 service_call_num_base;
    uint32 count;
    /// The device has exclusive access to this smc range.
    bool exclusive;
};

/// Device metadata.
struct PbusMetadata {
    /// Metadata type.
    uint32 type;
    /// Pointer to metadata.
    [Buffer] vector<uint8> data;
};

/// Device metadata to be passed from bootloader via a ZBI record.
struct PbusBootMetadata {
    /// Metadata type (matches `zbi_header_t.type` for bootloader metadata).
    uint32 zbi_type;
    /// Matches `zbi_header_t.extra` for bootloader metadata.
    /// Used in cases where bootloader provides multiple metadata records of the same type.
    uint32 zbi_extra;
};

struct PbusDev {
    string name;
    /// `BIND_PLATFORM_DEV_VID`
    uint32 vid;
    /// `BIND_PLATFORM_DEV_PID`
    uint32 pid;
    /// `BIND_PLATFORM_DEV_DID`
    uint32 did;
    /// Instance ID. Contributes to device-name if non-zero.
    /// `BIND_PLATFORM_DEV_INSTANCE_ID`
    uint32 instance_id;
    vector<PbusMmio> mmio;
    vector<PbusIrq> irq;
    vector<PbusBti> bti;
    vector<PbusSmc> smc;
    vector<PbusMetadata> metadata;
    vector<PbusBootMetadata> boot_metadata;
};

/// Subset of pdev_board_info_t to be set by the board driver.
struct PbusBoardInfo {
    /// Board name from the boot image platform ID record,
    /// (or from the BIOS on x86 platforms).
    string:32 board_name;
    /// Board specific revision number.
    uint32 board_revision;
};

struct PbusBootloaderInfo {
    string:32 vendor;
};

[Transport = "Banjo", BanjoLayout = "ddk-callback"]
protocol PbusSysSuspend {
    Callback(uint8 requested_state, bool enable_wake,
             uint8 suspend_reason) -> (zx.status out_status, uint8 out_state);
};

[Transport = "Banjo", BanjoLayout="ddk-protocol", DefaultProtocol]
protocol PBus {
    /// Adds a new platform device to the bus, using configuration provided by |dev|.
    /// Platform devices are created in their own separate devhosts.
    DeviceAdd(PbusDev dev) -> (zx.status s);
    /// Adds a device for binding a protocol implementation driver.
    /// These devices are added in the same devhost as the platform bus.
    /// After the driver binds to the device it calls `pbus_register_protocol()`
    /// to register its protocol with the platform bus.
    /// `pbus_protocol_device_add()` blocks until the protocol implementation driver
    /// registers its protocol (or times out).
    ProtocolDeviceAdd(uint32 proto_id, PbusDev dev) -> (zx.status s);
    /// Called by protocol implementation drivers to register their protocol
    /// with the platform bus.
    RegisterProtocol(uint32 proto_id, [Buffer] vector<uint8> protocol) -> (zx.status s);
    /// Board drivers may use this to get information about the board, and to
    /// differentiate between multiple boards that they support.
    GetBoardInfo() -> (zx.status s, fuchsia.hardware.platform.device.PdevBoardInfo info);
    /// Board drivers may use this to set information about the board
    /// (like the board revision number).
    /// Platform device drivers can access this via `pdev_get_board_info()`.
    SetBoardInfo(PbusBoardInfo info) -> (zx.status s);
    /// Board drivers may use this to set information about the bootloader.
    SetBootloaderInfo(PbusBootloaderInfo info) -> (zx.status s);
    RegisterSysSuspendCallback(PbusSysSuspend suspend_cb) -> (zx.status s);
    /// Adds a composite platform device to the bus. The platform device specified by |dev|
    /// is the zeroth fragment and the |fragments| array specifies fragments 1 through n.
    /// The composite device is started in a the devhost of the fragment with index
    /// |coresident_device_index|, or a new devhost if |coresident_device_index| is UINT32_MAX.
    /// |coresident_device_index| is not allowed to be zero, since we don't want platform device
    /// drivers running in the platform bus's devhost.
    // Note: fragments is of type device_fragment_t*.
    // TODO(fxb/69023): restore type.
    CompositeDeviceAdd(PbusDev dev, uint64 fragments, uint64 fragments_count,
                       uint32 coresident_device_index) -> (zx.status s);
};
