Skip to content

Commit

Permalink
implement virtio support
Browse files Browse the repository at this point in the history
  • Loading branch information
tombl committed Dec 7, 2024
1 parent ad47e85 commit 982c619
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 28 deletions.
2 changes: 1 addition & 1 deletion arch/wasm/configs/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EMBEDDED=y
CONFIG_VIRTIO_WASM=y
# CONFIG_COMPAT_32BIT_TIME is not set
# CONFIG_BLOCK is not set
# CONFIG_BINFMT_SCRIPT is not set
# CONFIG_COREDUMP is not set
CONFIG_SLOB=y
Expand All @@ -30,6 +29,7 @@ CONFIG_SLOB=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FW_LOADER is not set
# CONFIG_ALLOW_DEV_COREDUMP is not set
CONFIG_VIRTIO_BLK=y
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_TTY is not set
Expand Down
52 changes: 45 additions & 7 deletions arch/wasm/drivers/virtio_wasm.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define DEBUG
#define pr_fmt(fmt) "virtio-wasm: " fmt

#include <asm/wasm_imports.h>
Expand All @@ -11,13 +12,17 @@
#include <linux/virtio_ring.h>
#include <linux/virtio.h>

void wasm_import(virtio, get_config)(u32 id, unsigned offset, void *buf,
unsigned len);
void wasm_import(virtio, set_config)(u32 id, unsigned offset, const void *buf,
unsigned len);
int wasm_import(virtio, get_features)(u32 id, u64 *features);
int wasm_import(virtio, set_features)(u32 id, u64 features);
int wasm_import(virtio, set_vring_enable)(u32 id, u32 index, bool enable);
int wasm_import(virtio, set_vring_num)(u32 id, u32 index, u32 num);
int wasm_import(virtio, set_vring_addr)(u32 id, u32 index, dma_addr_t desc,
dma_addr_t used, dma_addr_t avail);
int wasm_import(virtio, set_interrupt_addrs)(u32 id, bool *is_config,
int wasm_import(virtio, configure_interrupt)(u32 id, u32 irq, bool *is_config,
bool *is_vring);
int wasm_import(virtio, notify)(u32 id, u32 index);

Expand All @@ -37,6 +42,20 @@ struct virtio_wasm_device {
bool interrupt_is_vring;
};

static void vw_get(struct virtio_device *vdev, unsigned offset, void *buf,
unsigned len)
{
struct virtio_wasm_device *vw_dev = to_virtio_wasm_device(vdev);
wasm_virtio_get_config(vw_dev->host_id, offset, buf, len);
}

static void vw_set(struct virtio_device *vdev, unsigned offset, const void *buf,
unsigned len)
{
struct virtio_wasm_device *vw_dev = to_virtio_wasm_device(vdev);
wasm_virtio_set_config(vw_dev->host_id, offset, buf, len);
}

static bool vw_notify(struct virtqueue *vq)
{
struct virtio_wasm_device *vw_dev = to_virtio_wasm_device(vq->vdev);
Expand All @@ -51,12 +70,31 @@ static u8 vw_get_status(struct virtio_device *vdev)
static void vw_set_status(struct virtio_device *vdev, u8 status)
{
struct virtio_wasm_device *vw_dev = to_virtio_wasm_device(vdev);
vw_dev->status = status;
if (vw_dev->status != status) {
const char *name = dev_name(&vdev->dev);
vw_dev->status = status;
switch (status) {
case VIRTIO_CONFIG_S_ACKNOWLEDGE:
pr_debug("device %s: acknowledge\n", name);
break;
case VIRTIO_CONFIG_S_DRIVER:
pr_debug("device %s: driver\n", name);
break;
case VIRTIO_CONFIG_S_FAILED:
pr_debug("device %s: failed\n", name);
break;
case VIRTIO_CONFIG_S_DRIVER_OK:
pr_debug("device %s: driver ok\n", name);
break;
case VIRTIO_CONFIG_S_FEATURES_OK:
pr_debug("device %s: features ok\n", name);
break;
}
}
}
static void vw_reset(struct virtio_device *vdev)
{
struct virtio_wasm_device *vw_dev = to_virtio_wasm_device(vdev);
vw_dev->status = 0;
vw_set_status(vdev, 0);
}

static void vw_del_vqs(struct virtio_device *vdev)
Expand Down Expand Up @@ -187,8 +225,8 @@ static const char *vw_bus_name(struct virtio_device *vdev)
}

static const struct virtio_config_ops virtio_wasm_config_ops = {
// .get = vw_get,
// .set = vw_set,
.get = vw_get,
.set = vw_set,
.get_status = vw_get_status,
.set_status = vw_set_status,
.reset = vw_reset,
Expand Down Expand Up @@ -242,7 +280,7 @@ static int virtio_wasm_probe(struct platform_device *pdev)
if (rc)
goto error;

rc = wasm_virtio_set_interrupt_addrs(vw_dev->host_id,
rc = wasm_virtio_configure_interrupt(vw_dev->host_id, vw_dev->irq,
&vw_dev->interrupt_is_config,
&vw_dev->interrupt_is_vring);
if (rc)
Expand Down
1 change: 1 addition & 0 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#define DEBUG
/*
* drivers/base/dd.c - The core device/driver interactions.
*
Expand Down
3 changes: 3 additions & 0 deletions drivers/virtio/virtio_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
*
* Copyright 2007 Rusty Russell IBM Corporation
*/
#define DEBUG
#define pr_fmt(fmt) "vring: " fmt

#include <linux/virtio.h>
#include <linux/virtio_ring.h>
#include <linux/virtio_config.h>
Expand Down
11 changes: 9 additions & 2 deletions tools/wasm/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,14 @@ export class Machine extends EventEmitter<{
},
rng: {
compatible: "virtio,wasm",
"host-id": 0x1234,
"host-id": 0,
"virtio-device-id": 4, // entropy
},
// blk: {
// compatible: "virtio,wasm",
// "host-id": 1,
// "virtio-device-id": 2, // block
// },
};
}

Expand Down Expand Up @@ -134,12 +139,14 @@ export class Machine extends EventEmitter<{
boot_console_close,
}),
virtio: {
get_config: unavailable,
set_config: unavailable,
get_features: unavailable,
set_features: unavailable,
set_vring_enable: unavailable,
set_vring_num: unavailable,
set_vring_addr: unavailable,
set_interrupt_addrs: unavailable,
configure_interrupt: unavailable,
notify: unavailable,
},
} satisfies Imports;
Expand Down
17 changes: 15 additions & 2 deletions tools/wasm/src/wasm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,20 @@ export interface Imports {
spawn_worker(fn: number, arg: number, comm: number, commLen: number): void;
};
virtio: {
get_config(
dev: number,
offset: number,
buf_addr: number,
buf_len: number,
): void;
set_config(
dev: number,
offset: number,
buf_addr: number,
buf_len: number,
): void;
get_features(dev: number, features_addr: number): number;
set_features(dev: number, features: number): number;
set_features(dev: number, features: bigint): number;
set_vring_enable(dev: number, vq: number, enable: number): number;
set_vring_num(dev: number, vq: number, num: number): number;
set_vring_addr(
Expand All @@ -34,8 +46,9 @@ export interface Imports {
used: number,
avail: number,
): number;
set_interrupt_addrs(
configure_interrupt(
dev: number,
irq: number,
is_config_addr: number,
is_vring_addr: number,
): number;
Expand Down
Loading

0 comments on commit 982c619

Please sign in to comment.