// 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.virtualization.hardware;

using fuchsia.io;
using fuchsia.ui.gfx;
using fuchsia.ui.input;
using fuchsia.virtualization;
using fuchsia.hardware.ethernet;
using zx;

// The following EVENT_* constants indicate which user signal is associated with an event.
// The value 0 is `ZX_USER_SIGNAL_0`, 1 is `ZX_USER_SIGNAL_1` etc.

/// Set a flag to inspect queues on the next interrupt.
const uint32 EVENT_SET_QUEUE = 0;
/// Set a flag to inspect configs on the next interrupt.
const uint32 EVENT_SET_CONFIG = 1;
/// If a flag is set, send an interrupt to the device.
const uint32 EVENT_SET_INTERRUPT = 2;

/// Contains the details of a device trap.
struct Trap {
    /// The address of the device trap. This must be page-aligned.
    zx.gpaddr addr;

    /// The size of the device trap. This must be a multiple of the page size.
    uint64 size;
};

/// Contains the basic information required to start execution of a device.
struct StartInfo {
    /// The trap associated with a device. It is up to the device to set this
    /// trap during device setup.
    Trap trap;

    /// The guest associated with a device. This handle should be used to setup
    /// device traps, and then be released before device operation begins.
    handle<guest>? guest;

    /// The event associated with a device interrupt. This is how the device will
    /// notify the guest of events it should process.
    ///
    /// The meaning of the different signals that can be raised on the event are
    /// documented by the EVENT_* constants above.
    handle<event> event;

    /// The VMO used to represent guest physical memory.
    handle<vmo> vmo;
};

[FragileBase]
protocol VirtioDevice {
    /// Configure a `queue` for the device. This specifies the `size` and the
    /// guest physical addresses of the queue: `desc`, `avail`, and `used`.
    ConfigureQueue(uint16 queue, uint16 size, zx.gpaddr desc, zx.gpaddr avail,
                   zx.gpaddr used) -> ();

    /// Notify a `queue` for the device. Primarily used for black-box testing.
    NotifyQueue(uint16 queue);

    /// Ready a device. This provides the set of `negotiated_features` that the
    /// driver and device have agreed upon.
    Ready(uint32 negotiated_features) -> ();
};

[Discoverable]
protocol VirtioBalloon {
    compose VirtioDevice;

    /// Start the balloon device.
    Start(StartInfo start_info) -> ();

    /// Get memory statistics from the balloon device.
    GetMemStats() -> (zx.status status,
                      vector<fuchsia.virtualization.MemStat>? mem_stats);
};

[Discoverable]
protocol VirtioBlock {
    compose VirtioDevice;

    /// Start the block device.
    Start(StartInfo start_info,
          string:fuchsia.virtualization.MAX_BLOCK_DEVICE_ID_SIZE id,
          fuchsia.virtualization.BlockMode mode, fuchsia.virtualization.BlockFormat format,
          fuchsia.io.File file) -> (uint64 size);
};

[Discoverable]
protocol VirtioConsole {
    compose VirtioDevice;

    /// Start the console device. This uses `socket` to handle input and output.
    Start(StartInfo start_info, handle<socket> socket) -> ();
};

/// Provides a way for VirtioInput to listen to view events.
[Discoverable]
protocol ViewListener {
    /// Called when a View's size is changed.
    OnSizeChanged(fuchsia.ui.gfx.vec3 size);

    /// Called when a View receives input events.
    OnInputEvent(fuchsia.ui.input.InputEvent event);
};

[Discoverable]
protocol VirtioGpu {
    compose VirtioDevice;

    /// Start the GPU device.
    Start(StartInfo start_info, ViewListener? view_listener) -> ();

    /// Called when a device's configuration is changed.
    -> OnConfigChanged();
};

[Discoverable]
protocol VirtioInput {
    compose VirtioDevice;

    /// Start the input device.
    Start(StartInfo start_info) -> ();
};

[Discoverable]
protocol VirtioMagma {
    compose VirtioDevice;

    /// Start the magma device.
    Start(StartInfo start_info,
          handle<vmar> vmar,
          VirtioWaylandImporter? wayland_importer) -> (zx.status status);
};

[Discoverable]
protocol VirtioNet {
    compose VirtioDevice;

    /// Start the net device.
    Start(StartInfo start_info, fuchsia.hardware.ethernet.MacAddress mac_address) -> ();
};

[Discoverable]
protocol VirtioRng {
    compose VirtioDevice;

    /// Start the RNG device.
    Start(StartInfo start_info) -> ();
};

const uint32 kVirtioWaylandInvalidVfdId = 0;

// Provides an interface to import VMOs into the wayland device.
protocol VirtioWaylandImporter {
    // Import a VMO into Wayland for use as a VFD.
    Import(handle<vmo> vmo) -> (uint32 vfd_id);
};

[Discoverable]
protocol VirtioWayland {
    compose VirtioDevice;

    /// Start the wayland device.
    Start(StartInfo start_info,
          handle<vmar> vmar,
          fuchsia.virtualization.WaylandDispatcher dispatcher) -> ();

    // Get the VMO importer for this wayland device.
    GetImporter(request<VirtioWaylandImporter> importer);
};
