// 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.
resource 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.
    zx.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.
    zx.handle:EVENT event;

    /// The VMO used to represent guest physical memory.
    zx.handle:VMO vmo;
};

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 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, zx.handle:SOCKET socket) -> ();
};

/// Provides a way for VirtioInput to listen to keyboard events.
[Discoverable]
protocol KeyboardListener {
    /// Called when a view receives keyboard events.
    OnKeyboardEvent(fuchsia.ui.input.KeyboardEvent event);
};

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

    /// Called when a view receives pointer events.
    OnPointerEvent(fuchsia.ui.input.PointerEvent event);
};

[Discoverable]
protocol VirtioGpu {
    compose VirtioDevice;

    /// Start the GPU device.
    Start(StartInfo start_info, KeyboardListener? keyboard_listener,
          PointerListener? pointer_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,
          zx.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(zx.handle:VMO vmo) -> (uint32 vfd_id);
};

[Discoverable]
protocol VirtioWayland {
    compose VirtioDevice;

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

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