// Copyright 2022 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.
@available(added=HEAD)
library fuchsia.hardware.platform.bus;

using zx;
using fuchsia.driver.framework;
using fuchsia.hardware.power;

type Mmio = table {
    /// Physical address of MMIO region.
    /// Does not need to be page aligned.
    1: base uint64;
    /// Length of MMIO region in bytes.
    /// Does not need to be page aligned.
    2: length uint64;
    /// Name that can be used to retrieve the Mmio using
    /// [`fuchsia.hardware.platform.device/GetMmioByName`].
    /// It is valid for this to be empty, however the resource will only be able
    /// to be retrieved using [`fuchsia.hardware.platform.device/GetMmioById`].
    3: name string:fuchsia.driver.framework.MAX_RESOURCE_NAME_LENGTH;
};

type Irq = table {
    1: irq uint32;
    /// `ZX_INTERRUPT_MODE_*` flags
    2: mode uint32;

    /// Properties for this interrupt's fragment. Only used in DFv2.
    3: properties
            vector<fuchsia.driver.framework.NodeProperty>:fuchsia.driver.framework.MAX_PROPERTY_COUNT;
    /// Name that can be used to retrieve the irq using
    /// [`fuchsia.hardware.platform.device/GetInterruptByName`].
    /// It is valid for this to be empty, however the resource will only be able
    /// to be retrieved using [`fuchsia.hardware.platform.device/GetInterruptById`].
    4: name string:fuchsia.driver.framework.MAX_RESOURCE_NAME_LENGTH;
};

type Bti = table {
    1: iommu_index uint32;
    2: bti_id uint32;
    /// Name that can be used to retrieve the bti using
    /// [`fuchsia.hardware.platform.device/GetBtiByName`].
    /// It is valid for this to be empty, however the resource will only be able
    /// to be retrieved using [`fuchsia.hardware.platform.device/GetBtiById`].
    3: name string:fuchsia.driver.framework.MAX_RESOURCE_NAME_LENGTH;
};

type Smc = table {
    /// 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.
    1: service_call_num_base uint32;
    2: count uint32;
    /// The device has exclusive access to this smc range.
    3: exclusive bool;
    /// Name that can be used to retrieve the smc using
    /// [`fuchsia.hardware.platform.device/GetSmcByName`].
    /// It is valid for this to be empty, however the resource will only be able
    /// to be retrieved using [`fuchsia.hardware.platform.device/GetSmcById`].
    4: name string:fuchsia.driver.framework.MAX_RESOURCE_NAME_LENGTH;
};

/// Device metadata.
type Metadata = table {
    /// Metadata type.
    1: type uint32;
    /// Metadata.
    2: data vector<uint8>:MAX;
};

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

const MAX_INFO_STRING_LENGTH uint32 = 32;

/// Subset of pdev_board_info_t to be set by the board driver.
type BoardInfo = table {
    /// Board name from the boot image platform ID record,
    /// (or from the BIOS on x86 platforms).
    1: board_name string:MAX_INFO_STRING_LENGTH;
    /// Board specific revision number.
    2: board_revision uint32;
};

type BootloaderInfo = table {
    1: vendor string:MAX_INFO_STRING_LENGTH;
};

const MAX_POWER_CONFIGS uint32 = 32;

type Node = table {
    /// Name of the node.
    1: name string:fuchsia.driver.framework.MAX_NODE_NAME_LENGTH;
    /// `BIND_PLATFORM_DEV_VID`
    2: vid uint32;
    /// `BIND_PLATFORM_DEV_PID`
    3: pid uint32;
    /// `BIND_PLATFORM_DEV_DID`
    4: did uint32;
    /// Instance ID. Contributes to device-name if non-zero.
    /// `BIND_PLATFORM_DEV_INSTANCE_ID`
    5: instance_id uint32;
    /// MMIO regions.
    6: mmio vector<Mmio>:MAX;
    /// Interrupts.
    7: irq vector<Irq>:MAX;
    /// BTIs.
    8: bti vector<Bti>:MAX;
    /// SMC calls.
    9: smc vector<Smc>:MAX;
    /// Metadata
    10: metadata vector<Metadata>:MAX;
    /// Boot metadata (from ZBI items)
    11: boot_metadata vector<BootMetadata>:MAX;

    /// Other node properties beyond BIND_PLATFORM_DEV_VID, BIND_PLATFORM_DEV_PID, and BIND_PLATFORM_DEV_DID.
    12: properties
            vector<fuchsia.driver.framework.NodeProperty>:fuchsia.driver.framework.MAX_PROPERTY_COUNT;
    13: power_config
            vector<fuchsia.hardware.power.PowerElementConfiguration>:MAX_INFO_STRING_LENGTH;
};

/// This is originally from the Banjo fuchsia.hardware.platform.device library,
/// but it is temporarily included here until that is migrated to FIDL.
type TemporaryBoardInfo = struct {
    /// Vendor ID for the board.
    vid uint32;
    /// Product ID for the board.
    pid uint32;
    /// Board name from the boot image platform ID record,
    /// (or from the BIOS on x86 platforms).
    board_name string:32;
    /// Board specific revision number.
    board_revision uint32;
};

closed protocol SysSuspend {
    strict Callback(struct {
        requested_state uint8;
        enable_wake bool;
        suspend_reason uint8;
    }) -> (struct {
        out_status zx.Status;
        out_state uint8;
    });
};

@discoverable
@transport("Driver")
closed protocol PlatformBus {
    /// Adds a new platform device node to the bus, using configuration provided
    /// by |node|. Platform device nodes are created in their own separate
    /// devhosts.
    strict NodeAdd(struct {
        node Node;
    }) -> () error zx.Status;

    /// Board drivers may use this to get information about the board, and to
    /// differentiate between multiple boards that they support.
    strict GetBoardInfo() -> (struct {
        info TemporaryBoardInfo;
    }) error zx.Status;

    /// 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()`.
    strict SetBoardInfo(struct {
        info BoardInfo;
    }) -> () error zx.Status;
    /// Board drivers may use this to set information about the bootloader.
    strict SetBootloaderInfo(struct {
        info BootloaderInfo;
    }) -> () error zx.Status;

    strict RegisterSysSuspendCallback(resource struct {
        suspend_cb client_end:SysSuspend;
    }) -> () error zx.Status;

    /// Adds a composite node specification that has |node| as one of the
    /// composite node's parents. To accomplish this, this method does a couple
    /// of things. The method adds a platform device node specified by |node| as
    /// a child of the platform bus. Also, a
    /// `fuchsia.driver.framework.ParentSpec` is added to |spec| which matches
    /// the newly added platform device node. Composite bind rules should include
    /// a stanza that matches the properites of |node| in order for the bind
    /// rules to match against the `CompositeNodeSpec`.
    strict AddCompositeNodeSpec(struct {
        node Node;
        spec fuchsia.driver.framework.CompositeNodeSpec;
    }) -> () error zx.Status;
};

service Service {
    platform_bus client_end:PlatformBus;
};
