Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions drivers/virtio/virtio_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,20 @@
next = vq->desc[curr_le].next;
last = !(vq->desc[curr_le].flags & VIRTQ_DESC_F_NEXT);
virtq_add_free_desc(vq, curr);
}
}

Check warning on line 58 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:58 please, no spaces at the start of a line

Check failure on line 58 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:58 code indent should use tabs where possible

vq->last_used_idx++;
vq->last_used_idx++;

Check warning on line 60 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:60 please, no spaces at the start of a line

Check failure on line 60 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:60 code indent should use tabs where possible

if (cbe.cb) {
cbe.cb(cbe.opaque, used_len);
}
}
}
if (vq->event_idx_enabled) {

Check warning on line 62 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:62 please, no spaces at the start of a line

Check failure on line 62 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:62 code indent should use tabs where possible
*vq->used_event = sys_cpu_to_le16(vq->last_used_idx);

Check warning on line 63 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:63 please, no spaces at the start of a line

Check failure on line 63 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:63 code indent should use tabs where possible
barrier_dmem_fence_full();

Check warning on line 64 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:64 please, no spaces at the start of a line

Check failure on line 64 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:64 code indent should use tabs where possible
Comment on lines +60 to +64

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Include barrier header for new fence usage

The new event-idx handling in virtio_isr() writes to used_event and then calls barrier_dmem_fence_full() (lines 62‑64), but drivers/virtio/virtio_common.c still only includes logging, byteorder, and virtio headers (lines 7‑11). None of those headers declare barrier_dmem_fence_full(), so this translation unit now lacks a prototype for that function and fails to compile with implicit declaration of function ‘barrier_dmem_fence_full’ when built with the default C standard. Please add #include <zephyr/sys/barrier.h> to this file’s include list.

Useful? React with 👍 / 👎.

}

Check warning on line 65 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:65 please, no spaces at the start of a line

Check failure on line 65 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:65 code indent should use tabs where possible

if (cbe.cb) {

Check warning on line 67 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:67 please, no spaces at the start of a line

Check failure on line 67 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:67 code indent should use tabs where possible
cbe.cb(cbe.opaque, used_len);

Check warning on line 68 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:68 please, no spaces at the start of a line

Check failure on line 68 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:68 code indent should use tabs where possible
}

Check warning on line 69 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:69 please, no spaces at the start of a line

Check failure on line 69 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:69 code indent should use tabs where possible
}

Check warning on line 70 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

drivers/virtio/virtio_common.c:70 please, no spaces at the start of a line

Check failure on line 70 in drivers/virtio/virtio_common.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CODE_INDENT

drivers/virtio/virtio_common.c:70 code indent should use tabs where possible
}
}
if (isr_status & VIRTIO_DEVICE_CONFIGURATION_INTERRUPT) {
LOG_ERR("device configuration change interrupt is currently unsupported");
Expand Down
48 changes: 29 additions & 19 deletions drivers/virtio/virtio_mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ LOG_MODULE_REGISTER(virtio_mmio, CONFIG_VIRTIO_LOG_LEVEL);
#define DEV_DATA(dev) ((struct virtio_mmio_data *)(dev)->data)

struct virtio_mmio_data {
DEVICE_MMIO_NAMED_RAM(reg_base);
DEVICE_MMIO_NAMED_RAM(reg_base);

struct virtq *virtqueues;
uint16_t virtqueue_count;
struct virtq *virtqueues;
uint16_t virtqueue_count;
bool event_idx_enabled;

struct k_spinlock isr_lock;
struct k_spinlock notify_lock;
struct k_spinlock isr_lock;
struct k_spinlock notify_lock;
};

struct virtio_mmio_config {
Expand Down Expand Up @@ -220,16 +221,18 @@ static int virtio_mmio_set_virtqueues(const struct device *dev, uint16_t queue_c
const uint16_t queue_size =
cb(i, virtio_mmio_read32(dev, VIRTIO_MMIO_QUEUE_SIZE_MAX), opaque);

ret = virtq_create(&data->virtqueues[i], queue_size);
if (ret != 0) {
goto fail;
}
created_queues++;
ret = virtq_create(&data->virtqueues[i], queue_size);
if (ret != 0) {
goto fail;
}
created_queues++;

ret = virtio_mmio_set_virtqueue(dev, i, &data->virtqueues[i]);
if (ret != 0) {
goto fail;
}
virtq_enable_event_idx(&data->virtqueues[i], data->event_idx_enabled);

ret = virtio_mmio_set_virtqueue(dev, i, &data->virtqueues[i]);
if (ret != 0) {
goto fail;
}
activated_queues++;
}

Expand Down Expand Up @@ -273,7 +276,9 @@ static DEVICE_API(virtio, virtio_mmio_driver_api) = {

static int virtio_mmio_init_common(const struct device *dev)
{
DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE);
struct virtio_mmio_data *data = dev->data;

DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE);

const uint32_t magic = virtio_mmio_read32(dev, VIRTIO_MMIO_MAGIC_VALUE);

Expand All @@ -300,12 +305,17 @@ static int virtio_mmio_init_common(const struct device *dev)

virtio_mmio_reset(dev);

virtio_mmio_write_status_bit(dev, DEVICE_STATUS_ACKNOWLEDGE);
virtio_mmio_write_status_bit(dev, DEVICE_STATUS_DRIVER);
virtio_mmio_write_status_bit(dev, DEVICE_STATUS_ACKNOWLEDGE);
virtio_mmio_write_status_bit(dev, DEVICE_STATUS_DRIVER);

virtio_mmio_write_driver_feature_bit(dev, VIRTIO_F_VERSION_1, true);
virtio_mmio_write_driver_feature_bit(dev, VIRTIO_F_VERSION_1, true);

return 0;
data->event_idx_enabled = virtio_mmio_read_device_feature_bit(dev, VIRTIO_RING_F_EVENT_IDX);
if (data->event_idx_enabled) {
virtio_mmio_write_driver_feature_bit(dev, VIRTIO_RING_F_EVENT_IDX, true);
}

return 0;
};

#define VIRTIO_MMIO_DEFINE(inst) \
Expand Down
52 changes: 30 additions & 22 deletions drivers/virtio/virtio_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,18 @@ struct virtio_pci_common_cfg {
#define VIRTIO_PCI_MSIX_NO_VECTOR 0xffff

struct virtio_pci_data {
volatile struct virtio_pci_common_cfg *common_cfg;
void *device_specific_cfg;
volatile uint8_t *isr_status;
volatile uint8_t *notify_cfg;
uint32_t notify_off_multiplier;

struct virtq *virtqueues;
uint16_t virtqueue_count;

struct k_spinlock isr_lock;
struct k_spinlock notify_lock;
volatile struct virtio_pci_common_cfg *common_cfg;
void *device_specific_cfg;
volatile uint8_t *isr_status;
volatile uint8_t *notify_cfg;
uint32_t notify_off_multiplier;

struct virtq *virtqueues;
uint16_t virtqueue_count;
bool event_idx_enabled;

struct k_spinlock isr_lock;
struct k_spinlock notify_lock;
};

struct virtio_pci_config {
Expand Down Expand Up @@ -284,16 +285,18 @@ static int virtio_pci_init_virtqueues(

uint16_t queue_size = cb(i, sys_le16_to_cpu(data->common_cfg->queue_size), opaque);

ret = virtq_create(&data->virtqueues[i], queue_size);
if (ret != 0) {
goto fail;
}
created_queues++;
ret = virtq_create(&data->virtqueues[i], queue_size);
if (ret != 0) {
goto fail;
}
created_queues++;

ret = virtio_pci_set_virtqueue(dev, i, &data->virtqueues[i]);
if (ret != 0) {
goto fail;
}
virtq_enable_event_idx(&data->virtqueues[i], data->event_idx_enabled);

ret = virtio_pci_set_virtqueue(dev, i, &data->virtqueues[i]);
if (ret != 0) {
goto fail;
}
activated_queues++;
}

Expand Down Expand Up @@ -534,9 +537,14 @@ static int virtio_pci_init_common(const struct device *dev)
return 1;
}

virtio_pci_write_driver_feature_bit(dev, VIRTIO_F_VERSION_1, 1);
virtio_pci_write_driver_feature_bit(dev, VIRTIO_F_VERSION_1, 1);

return 0;
data->event_idx_enabled = virtio_pci_read_device_feature_bit(dev, VIRTIO_RING_F_EVENT_IDX);
if (data->event_idx_enabled) {
virtio_pci_write_driver_feature_bit(dev, VIRTIO_RING_F_EVENT_IDX, 1);
}

return 0;
};

struct virtq *virtio_pci_get_virtqueue(const struct device *dev, uint16_t queue_idx)
Expand Down
28 changes: 25 additions & 3 deletions drivers/virtio/virtqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ int virtq_create(struct virtq *v, size_t size)
v->desc = (struct virtq_desc *)v_area;
v->avail = (struct virtq_avail *)((uint8_t *)v->desc + descriptor_table_size);
v->used = (struct virtq_used *)((uint8_t *)v->avail + available_ring_size + used_ring_pad);
v->recv_cbs = (struct virtq_receive_callback_entry *)((uint8_t *)v->used + used_ring_size);
v->recv_cbs = (struct virtq_receive_callback_entry *)((uint8_t *)v->used + used_ring_size);
v->used_event = &v->avail->ring[size];
v->avail_event = (uint16_t *)((uint8_t *)v->used->ring +
sizeof(struct virtq_used_elem) * size);
v->event_idx_enabled = false;

/*
* At the beginning of the descriptor table, the available ring and the used ring have to be
Expand Down Expand Up @@ -183,6 +187,24 @@ int virtq_get_free_desc(struct virtq *v, uint16_t *desc_idx, k_timeout_t timeout

void virtq_add_free_desc(struct virtq *v, uint16_t desc_idx)
{
k_stack_push(&v->free_desc_stack, desc_idx);
v->free_desc_n++;
k_stack_push(&v->free_desc_stack, desc_idx);
v->free_desc_n++;
}

void virtq_enable_event_idx(struct virtq *v, bool enable)
{
v->event_idx_enabled = enable;

if (enable) {
*v->used_event = sys_cpu_to_le16(v->last_used_idx);
} else {
*v->used_event = 0;
}

barrier_dmem_fence_full();
}

bool virtq_is_event_idx_enabled(const struct virtq *v)
{
return v->event_idx_enabled;
}
36 changes: 34 additions & 2 deletions include/zephyr/drivers/virtio/virtqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

#ifndef ZEPHYR_VIRTIO_VIRTQUEUE_H_
#define ZEPHYR_VIRTIO_VIRTQUEUE_H_
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <zephyr/kernel.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -190,7 +191,22 @@ struct virtq {
/**
* array with callbacks invoked after receiving buffers back from the device
*/
struct virtq_receive_callback_entry *recv_cbs;
struct virtq_receive_callback_entry *recv_cbs;

/**
* pointer to used_event field, valid if @ref event_idx_enabled is true
*/
uint16_t *used_event;

/**
* pointer to avail_event field, valid if @ref event_idx_enabled is true
*/
uint16_t *avail_event;

/**
* indicates whether @ref VIRTIO_RING_F_EVENT_IDX was negotiated for the queue
*/
bool event_idx_enabled;
};


Expand Down Expand Up @@ -267,6 +283,22 @@ void virtq_add_free_desc(struct virtq *v, uint16_t desc_idx);
*/
int virtq_get_free_desc(struct virtq *v, uint16_t *desc_idx, k_timeout_t timeout);

/**
* @brief Enables or disables @ref VIRTIO_RING_F_EVENT_IDX support for a queue.
*
* @param v virtqueue to update
* @param enable true when the feature was negotiated
*/
void virtq_enable_event_idx(struct virtq *v, bool enable);

/**
* @brief Returns true when @ref VIRTIO_RING_F_EVENT_IDX is enabled.
*
* @param v virtqueue to query
* @return true if event index support is enabled
*/
bool virtq_is_event_idx_enabled(const struct virtq *v);

/**
* @}
*/
Expand Down
Loading