From 2dde56422dcfb94affee2baffc8d240ad16ad4b2 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Thu, 1 Jan 2026 15:04:47 +0800 Subject: dev(device): implement VirtIO See dev log for detail --- include/drivers/plic.h | 2 +- include/drivers/uart.h | 26 +++++++++++- include/drivers/virtio.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++ include/kernel/proc.h | 2 + include/kernel/syscall.h | 1 + include/user/user.h | 3 +- 6 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 include/drivers/virtio.h (limited to 'include') diff --git a/include/drivers/plic.h b/include/drivers/plic.h index 8e8d986..11e8c8a 100644 --- a/include/drivers/plic.h +++ b/include/drivers/plic.h @@ -1,7 +1,7 @@ #pragma once #include "common/types.h" -namespace PILC +namespace PLIC { // Global initialization (executed only once by hart 0) void init(); diff --git a/include/drivers/uart.h b/include/drivers/uart.h index cb84bde..26c2394 100644 --- a/include/drivers/uart.h +++ b/include/drivers/uart.h @@ -1,11 +1,35 @@ #pragma once #include "common/types.h" +#define UART0 0x10000000L +#define RHR 0 // Receive Holding Register (read mode) +#define THR 0 // Transmit Holding Register (write mode) +#define IER 1 // Interrupt Enable Register +#define FCR 2 // FIFO Control Register +#define ISR 2 // Interrupt Status Register +#define LCR 3 // Line Control Register +#define LSR 5 // Line Status Register + +#define LSR_RX_READY 0x01 // input is waiting to be read from RHR +#define LSR_TX_IDLE 0x20 // THR can accept another character to send + +#define UART_RX_BUF_SIZE 128 + +// ANSI Escape Codes for Modern Terminal Colors +#define ANSI_RESET "\033[0m" +#define ANSI_RED "\033[31m" +#define ANSI_GREEN "\033[32m" +#define ANSI_YELLOW "\033[33m" +#define ANSI_BLUE "\033[34m" +#define ANSI_CLEAR "\033[2J\033[1;1H" + namespace Drivers { void uart_init(); - void uart_putc(char c); + void uart_intr(); + int console_read(uint64 target, int len); + void uart_putc(char c); void uart_puts(const char *s); void uart_put_int(int value); void print_hex(uint64 value); diff --git a/include/drivers/virtio.h b/include/drivers/virtio.h new file mode 100644 index 0000000..308dae0 --- /dev/null +++ b/include/drivers/virtio.h @@ -0,0 +1,102 @@ +#pragma once +#include "common/types.h" + +// VirtIO MMIO Base Address +#define VIRTIO0 0x10001000 + +// MMIO Registers (Modern / Version 2) +#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_DEVICE_FEATURES_SEL 0x014 +#define VIRTIO_MMIO_DRIVER_FEATURES 0x020 +#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024 +#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 + +// 64-bit Queue Address Registers (Modern) +#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 +#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 +#define VIRTIO_MMIO_QUEUE_DRIVER_LOW 0x090 +#define VIRTIO_MMIO_QUEUE_DRIVER_HIGH 0x094 +#define VIRTIO_MMIO_QUEUE_DEVICE_LOW 0x0a0 +#define VIRTIO_MMIO_QUEUE_DEVICE_HIGH 0x0a4 + +// Status Bits +#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 + +// Feature Bits +#define VIRTIO_BLK_F_RO 5 +#define VIRTIO_BLK_F_SCSI 7 +#define VIRTIO_BLK_F_CONFIG_WCE 11 +#define VIRTIO_BLK_F_MQ 12 +#define VIRTIO_F_ANY_LAYOUT 27 +#define VIRTIO_RING_F_INDIRECT_DESC 28 +#define VIRTIO_RING_F_EVENT_IDX 29 +#define VIRTIO_F_VERSION_1 32 + +// Descriptor Flags +#define VRING_DESC_F_NEXT 1 +#define VRING_DESC_F_WRITE 2 + +#define NUM_DESCS 8 + +#define VIRTIO_BLK_T_IN 0 +#define VIRTIO_BLK_T_OUT 1 + +// Device Configuration Layout (Offset 0x100) +#define VIRTIO_MMIO_CONFIG 0x100 + +namespace VirtIO +{ + struct VRingDesc + { + uint64 addr; + uint32 len; + uint16 flags; + uint16 next; + }; + + struct VRingAvail + { + uint16 flags; + uint16 idx; + uint16 ring[NUM_DESCS]; + }; + + struct VRingUsedElem + { + uint32 id; + uint32 len; + }; + + struct VRingUsed + { + uint16 flags; + uint16 idx; + struct VRingUsedElem ring[NUM_DESCS]; + }; + + struct __attribute__((packed)) BlockRequest + { + uint32 type; // 0=Read, 1=Write + uint32 reserved; + uint64 sector; + }; + + void init(); + void intr(); + void rw(int write, uint64 blockno, char *buf); + void test_rw(); +} \ No newline at end of file diff --git a/include/kernel/proc.h b/include/kernel/proc.h index d63ccf7..cbf2902 100644 --- a/include/kernel/proc.h +++ b/include/kernel/proc.h @@ -17,6 +17,8 @@ namespace ProcManager void sleep(void *chan, Spinlock *lk); void wakeup(void *chan); + + int growproc(int n); } void forkret(); diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h index 222f2f4..1fcd1ff 100644 --- a/include/kernel/syscall.h +++ b/include/kernel/syscall.h @@ -22,6 +22,7 @@ #define SYS_link 20 #define SYS_mkdir 21 #define SYS_close 22 +#define SYS_disk_test 23 #ifndef __ASSEMBLER__ void syscall(); diff --git a/include/user/user.h b/include/user/user.h index 7ab4923..7624a21 100644 --- a/include/user/user.h +++ b/include/user/user.h @@ -24,6 +24,7 @@ extern "C" { int sleep(int ticks); int uptime(); - + // Debug void putc(char c); + int disk_test(); } \ No newline at end of file -- cgit v1.2.3