// 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 ddk.protocol.platform.bus;

using ddk.driver;
using ddk.protocol.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.
    usize 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.
    vector<voidptr> 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;
    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;
};

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


[Layout="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, vector<voidptr> 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, ddk.protocol.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. 
    CompositeDeviceAdd(PbusDev dev, vector<ddk.driver.DeviceFragment> fragments,
                       uint32 coresident_device_index) -> (zx.status s);
};
