Files
open-amp/lib/include/openamp/virtio_mmio.h
Andrew Davis fdb8bf3424 virtio_mmio: Statically allocate metal_io_regions
Make the metal_io_region for cfg_io and shm_io into full member structs
instead of just pointers. This means they will be allocated along with
the parent virtio_mmio_device struct and not need dynamically allocated
later.

Signed-off-by: Andrew Davis <afd@ti.com>
2024-07-05 09:41:06 +02:00

220 lines
6.0 KiB
C

/*
* Copyright (c) 2022 Wind River Systems, Inc.
* Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef OPENAMP_VIRTIO_MMIO_H
#define OPENAMP_VIRTIO_MMIO_H
#include <metal/device.h>
#include <openamp/virtio.h>
#include <openamp/virtqueue.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Enable support for legacy devices */
#define VIRTIO_MMIO_LEGACY
/* Control registers */
/* Magic value ("virt" string) - Read Only */
#define VIRTIO_MMIO_MAGIC_VALUE 0x000
#define VIRTIO_MMIO_MAGIC_VALUE_STRING ('v' | ('i' << 8) | ('r' << 16) | ('t' << 24))
/* Virtio device version - Read Only */
#define VIRTIO_MMIO_VERSION 0x004
/* Virtio device ID - Read Only */
#define VIRTIO_MMIO_DEVICE_ID 0x008
/* Virtio vendor ID - Read Only */
#define VIRTIO_MMIO_VENDOR_ID 0x00c
/*
* Bitmask of the features supported by the device (host)
* (32 bits per set) - Read Only
*/
#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
/* Device (host) features set selector - Write Only */
#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014
/*
* Bitmask of features activated by the driver (guest)
* (32 bits per set) - Write Only
*/
#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
/* Activated features set selector - Write Only */
#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024
#ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */
/* Guest's memory page size in bytes - Write Only */
#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028
#endif
/* Queue selector - Write Only */
#define VIRTIO_MMIO_QUEUE_SEL 0x030
/* Maximum size of the currently selected queue - Read Only */
#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034
/* Queue size for the currently selected queue - Write Only */
#define VIRTIO_MMIO_QUEUE_NUM 0x038
#ifdef VIRTIO_MMIO_LEGACY
/* Used Ring alignment for the currently selected queue - Write Only */
#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c
/* Guest's PFN for the currently selected queue - Read Write */
#define VIRTIO_MMIO_QUEUE_PFN 0x040
#endif
/* Ready bit for the currently selected queue - Read Write */
#define VIRTIO_MMIO_QUEUE_READY 0x044
/* Queue notifier - Write Only */
#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050
/* Interrupt status - Read Only */
#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060
/* Interrupt acknowledge - Write Only */
#define VIRTIO_MMIO_INTERRUPT_ACK 0x064
/* Device status register - Read Write */
#define VIRTIO_MMIO_STATUS 0x070
/* Selected queue's Descriptor Table address, 64 bits in two halves */
#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080
#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
/* Selected queue's Available Ring address, 64 bits in two halves */
#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090
#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094
/* Selected queue's Used Ring address, 64 bits in two halves */
#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0
#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4
/* Shared memory region id */
#define VIRTIO_MMIO_SHM_SEL 0x0ac
/* Shared memory region length, 64 bits in two halves */
#define VIRTIO_MMIO_SHM_LEN_LOW 0x0b0
#define VIRTIO_MMIO_SHM_LEN_HIGH 0x0b4
/* Shared memory region base address, 64 bits in two halves */
#define VIRTIO_MMIO_SHM_BASE_LOW 0x0b8
#define VIRTIO_MMIO_SHM_BASE_HIGH 0x0bc
/* Configuration atomicity value */
#define VIRTIO_MMIO_CONFIG_GENERATION 0x0fc
/*
* The config space is defined by each driver as
* the per-driver configuration space - Read Write
*/
#define VIRTIO_MMIO_CONFIG 0x100
/* Interrupt flags (re: interrupt status & acknowledge registers) */
#define VIRTIO_MMIO_INT_VRING (1 << 0)
#define VIRTIO_MMIO_INT_CONFIG (1 << 1)
/* Data buffer size for preallocated buffers before vring */
#define VIRTIO_MMIO_MAX_DATA_SIZE 128
/** @brief VIRTIO MMIO memory area */
struct virtio_mmio_dev_mem {
/** Memory region physical address */
void *base;
/** Memory region size */
size_t size;
};
/** @brief A VIRTIO MMIO device */
struct virtio_mmio_device {
/** Base virtio device structure */
struct virtio_device vdev;
/** Device configuration space metal_io_region */
struct metal_io_region cfg_io;
/** Pre-shared memory space metal_io_region */
struct metal_io_region shm_io;
/** VIRTIO device configuration space */
struct virtio_mmio_dev_mem cfg_mem;
/** VIRTIO device pre-shared memory */
struct virtio_mmio_dev_mem shm_mem;
/** VIRTIO_DEV_DRIVER or VIRTIO_DEV_DEVICE */
unsigned int device_mode;
/** Interrupt number */
unsigned int irq;
/** Custom user data */
void *user_data;
};
/**
* @brief Register a VIRTIO device with the VIRTIO stack.
*
* @param vdev Pointer to device structure.
* @param vq_num Number of virtqueues the device uses.
* @param vqs Array of pointers to vthe virtqueues used by the device.
*/
void virtio_mmio_register_device(struct virtio_device *vdev, int vq_num, struct virtqueue **vqs);
/**
* @brief Setup a virtqueue structure.
*
* @param vdev Pointer to device structure.
* @param idx Index of the virtqueue.
* @param vq Pointer to virtqueue structure.
* @param cb Pointer to virtqueue callback. Can be NULL.
* @param cb_arg Argument for the virtqueue callback.
* @param vq_name Name of the virtqueue.
*
* @return pointer to virtqueue structure.
*/
struct virtqueue *virtio_mmio_setup_virtqueue(struct virtio_device *vdev,
unsigned int idx,
struct virtqueue *vq,
void (*cb)(void *),
void *cb_arg,
const char *vq_name);
/**
* @brief VIRTIO MMIO device initialization.
*
* @param vmdev Pointer to virtio_mmio_device structure.
* @param virt_mem_ptr Guest virtio (shared) memory base address (virtual).
* @param cfg_mem_ptr Virtio device configuration memory base address (virtual).
* @param user_data Pointer to custom user data.
*
* @return int 0 for success.
*/
int virtio_mmio_device_init(struct virtio_mmio_device *vmdev, uintptr_t virt_mem_ptr,
uintptr_t cfg_mem_ptr, void *user_data);
/**
* @brief VIRTIO MMIO interrupt service routine.
*
* @param vdev Pointer to virtio_device structure.
*/
void virtio_mmio_isr(struct virtio_device *vdev);
#ifdef __cplusplus
}
#endif
#endif /* OPENAMP_VIRTIO_MMIO_H */