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
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ QEMUOPTS = -machine virt -bios none -kernel $(TARGET) -m 128M -smp $(CPUS) -nogr
QEMUOPTS += -global virtio-mmio.force-legacy=false
QEMUOPTS += -drive file=./fs.img,if=none,format=raw,id=x0
QEMUOPTS += -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
QEMUOPTS += -netdev user,id=net0
QEMUOPTS += -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1
ifndef CPUS
CPUS := 1
endif
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/include/mem_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
/* virtio mmio interface */
#define VIRTIO0 0x10001000
#define VIRTIO0_IRQ 1
#define VIRTIO1 0x10002000
#define VIRTIO1_IRQ 2

/* core local interruptor (CLINT), which contains the timer. */
#define CLINT 0x2000000L
Expand Down
5 changes: 4 additions & 1 deletion arch/riscv/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <printf.h>
#include <plic.h>
#include <virtio_disk.h>
#include <virtio_net.h>
#include <debug.h>

extern void kernel_vec(void);
Expand Down Expand Up @@ -42,6 +43,8 @@ static int dev_intr(uint64 scause)
uart_intr();
} else if(irq == VIRTIO0_IRQ) {
virtio_disk_intr();
} else if(irq == VIRTIO1_IRQ) {
virtio_net_intr();
/*
* irq 0 is reserved to mean “no interrupt”.
* see here: https://five-embeddev.com/riscv-priv-isa-manual/Priv-v1.12/plic.html#interrupt-identifiers-ids
Expand Down Expand Up @@ -179,4 +182,4 @@ void trap_init_lock(void)
void trap_init(void)
{
stvec_w((uint64)kernel_vec);
}
}
2 changes: 1 addition & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ CFLAGS_file.o :=
obj-y += string.o palloc.o spinlock.o thread.o \
sleeplock.o switchto.o trampoline.o process.o\
plic.o console.o printf.o scheduler.o \
exec.o sysfile.o syscall.o sysproc.o driver.o main.o
exec.o sysfile.o syscall.o sysproc.o driver.o virtio_net.o main.o
2 changes: 1 addition & 1 deletion kernel/fs/virtio_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void virtio_disk_init(void)

if(*R(VIRTIO_MMIO_MAGIC_VALUE) != 0x74726976 ||
*R(VIRTIO_MMIO_VERSION) != 2 ||
*R(VIRTIO_MMIO_DEVICE_ID) != 2 ||
*R(VIRTIO_MMIO_DEVICE_ID) != VIRTIO_DEVICE_BLOCK ||
*R(VIRTIO_MMIO_VENDOR_ID) != 0x554d4551) {
panic("could not find virtio disk");
}
Expand Down
70 changes: 70 additions & 0 deletions kernel/include/virtio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#ifndef __CAFFEINIX_KERNEL_VIRTIO_H
#define __CAFFEINIX_KERNEL_VIRTIO_H

#include <typedefs.h>

#define VIRTIO_MMIO_MAGIC_VALUE 0x000
#define VIRTIO_MMIO_VERSION 0x004
#define VIRTIO_MMIO_DEVICE_ID 0x008
#define VIRTIO_MMIO_VENDOR_ID 0x00c
#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
#define VIRTIO_MMIO_QUEUE_SEL 0x030
#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034
#define VIRTIO_MMIO_QUEUE_NUM 0x038
#define VIRTIO_MMIO_QUEUE_READY 0x044
#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050
#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060
#define VIRTIO_MMIO_INTERRUPT_ACK 0x064
#define VIRTIO_MMIO_STATUS 0x070
#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080
#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
#define VIRTIO_MMIO_DRIVER_DESC_LOW 0x090
#define VIRTIO_MMIO_DRIVER_DESC_HIGH 0x094
#define VIRTIO_MMIO_DEVICE_DESC_LOW 0x0a0
#define VIRTIO_MMIO_DEVICE_DESC_HIGH 0x0a4
#define VIRTIO_MMIO_CONFIG 0x100

#define VIRTIO_DEVICE_NET 1
#define VIRTIO_DEVICE_BLOCK 2

#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
#define VIRTIO_CONFIG_S_DRIVER 2
#define VIRTIO_CONFIG_S_DRIVER_OK 4
#define VIRTIO_CONFIG_S_FEATURES_OK 8

#define VIRTIO_F_ANY_LAYOUT 27
#define VIRTIO_RING_F_INDIRECT_DESC 28
#define VIRTIO_RING_F_EVENT_IDX 29

#define VIRTIO_DES_NUM 8

struct virtq_desc {
uint64 addr;
uint32 len;
uint16 flags;
uint16 next;
};

#define VRING_DESC_F_NEXT 1
#define VRING_DESC_F_WRITE 2

struct virtq_avail {
uint16 flags;
uint16 idx;
uint16 ring[VIRTIO_DES_NUM];
uint16 unused;
};

struct virtq_used_elem {
uint32 id;
uint32 len;
};

struct virtq_used {
uint16 flags;
uint16 idx;
struct virtq_used_elem ring[VIRTIO_DES_NUM];
};

#endif
66 changes: 2 additions & 64 deletions kernel/include/virtio_disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,16 @@

#include <riscv.h>
#include <typedefs.h>
#include <virtio.h>

/* Block size */
#define BSIZE 1024

#define VIRTIO_MMIO_MAGIC_VALUE 0x000 // 0x74726976
#define VIRTIO_MMIO_VERSION 0x004 // version; should be 2
#define VIRTIO_MMIO_DEVICE_ID 0x008 // device type; 1 is net, 2 is disk
#define VIRTIO_MMIO_VENDOR_ID 0x00c // 0x554d4551
#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
#define VIRTIO_MMIO_QUEUE_SEL 0x030 // select queue, write-only
#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 // max size of current queue, read-only
#define VIRTIO_MMIO_QUEUE_NUM 0x038 // size of current queue, write-only
#define VIRTIO_MMIO_QUEUE_READY 0x044 // ready bit
#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 // write-only
#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 // read-only
#define VIRTIO_MMIO_INTERRUPT_ACK 0x064 // write-only
#define VIRTIO_MMIO_STATUS 0x070 // read/write
#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 // physical address for descriptor table, write-only
#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
#define VIRTIO_MMIO_DRIVER_DESC_LOW 0x090 // physical address for available ring, write-only
#define VIRTIO_MMIO_DRIVER_DESC_HIGH 0x094
#define VIRTIO_MMIO_DEVICE_DESC_LOW 0x0a0 // physical address for used ring, write-only
#define VIRTIO_MMIO_DEVICE_DESC_HIGH 0x0a4

/* status register bits, from qemu virtio_config.h */
#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
#define VIRTIO_CONFIG_S_DRIVER 2
#define VIRTIO_CONFIG_S_DRIVER_OK 4
#define VIRTIO_CONFIG_S_FEATURES_OK 8

/* device feature bits */
#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
#define VIRTIO_BLK_F_MQ 12 /* support more than one vq */
#define VIRTIO_F_ANY_LAYOUT 27
#define VIRTIO_RING_F_INDIRECT_DESC 28
#define VIRTIO_RING_F_EVENT_IDX 29

/* this many virtio descriptors.must be a power of two. */
#define VIRTIO_DES_NUM 8

struct virtq_desc {
uint64 addr;
uint32 len;
uint16 flags;
uint16 next;
};
#define VRING_DESC_F_NEXT 1 // chained with another descriptor
#define VRING_DESC_F_WRITE 2 // device writes (vs read)

// the (entire) avail ring, from the spec.
struct virtq_avail {
uint16 flags; // always zero
uint16 idx; // driver will write ring[idx] next
uint16 ring[VIRTIO_DES_NUM]; // descriptor numbers of chain heads
uint16 unused;
};

// one entry in the "used" ring, with which the
// device tells the driver about completed requests.
struct virtq_used_elem {
uint32 id; // index of start of completed descriptor chain
uint32 len;
};

struct virtq_used {
uint16 flags; // always zero
uint16 idx; // device increments when it adds a ring[] entry
struct virtq_used_elem ring[VIRTIO_DES_NUM];
};

// these are specific to virtio block devices, e.g. disks,
// described in Section 5.2 of the spec.
Expand All @@ -97,4 +35,4 @@ void virtio_disk_rw(struct bio *b, int write);
void virtio_disk_init(void);
void virtio_disk_intr(void);

#endif
#endif
32 changes: 32 additions & 0 deletions kernel/include/virtio_net.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef __CAFFEINIX_KERNEL_VIRTIO_NET_H
#define __CAFFEINIX_KERNEL_VIRTIO_NET_H

#include <virtio.h>

#define VIRTIO_NET_F_CSUM 0
#define VIRTIO_NET_F_GUEST_CSUM 1
#define VIRTIO_NET_F_MAC 5
#define VIRTIO_NET_F_GUEST_TSO4 7
#define VIRTIO_NET_F_GUEST_TSO6 8
#define VIRTIO_NET_F_GUEST_ECN 9
#define VIRTIO_NET_F_GUEST_UFO 10
#define VIRTIO_NET_F_HOST_TSO4 11
#define VIRTIO_NET_F_HOST_TSO6 12
#define VIRTIO_NET_F_HOST_ECN 13
#define VIRTIO_NET_F_HOST_UFO 14
#define VIRTIO_NET_F_MRG_RXBUF 15
#define VIRTIO_NET_F_STATUS 16
#define VIRTIO_NET_F_CTRL_VQ 17
#define VIRTIO_NET_F_CTRL_RX 18
#define VIRTIO_NET_F_CTRL_VLAN 19
#define VIRTIO_NET_F_GUEST_ANNOUNCE 21
#define VIRTIO_NET_F_MQ 22
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23

#define VIRTIO_NET_RX_QUEUE 0
#define VIRTIO_NET_TX_QUEUE 1

void virtio_net_init(void);
void virtio_net_intr(void);

#endif
4 changes: 3 additions & 1 deletion kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <inode.h>
#include <file.h>
#include <mystring.h>
#include <virtio_net.h>

volatile static uint8 start = 0;
extern char end[];
Expand All @@ -48,6 +49,7 @@ void main(void)
iinit();
file_init();
virtio_disk_init();
virtio_net_init();

printf("Hello! Caffeinix\n");
// thread_test();
Expand All @@ -68,4 +70,4 @@ void main(void)
scheduler();

while(1);
}
}
5 changes: 3 additions & 2 deletions kernel/plic.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ void plic_init(void)
{
*(uint32*)(PLIC + UART0_IRQ*4) = 1;
*(uint32*)(PLIC + VIRTIO0_IRQ*4) = 1;
*(uint32*)(PLIC + VIRTIO1_IRQ*4) = 1;
}

void plic_init_hart(void)
{
int hart = cpuid();

/* set enable bits for this hart's S-mode for the uart and virtio disk. */
*(uint32*)PLIC_SENABLE(hart) = (1 << UART0_IRQ) | (1 << VIRTIO0_IRQ);
/* set enable bits for this hart's S-mode external devices. */
*(uint32*)PLIC_SENABLE(hart) = (1 << UART0_IRQ) | (1 << VIRTIO0_IRQ) | (1 << VIRTIO1_IRQ);

/* set this hart's S-mode priority threshold to 0. */
*(uint32*)PLIC_SPRIORITY(hart) = 0;
Expand Down
Loading