This commit is contained in:
Linehu
2026-08-09 22:20:01 +08:00
parent 8717ea8f20
commit 2a50fa58c7
185 changed files with 19890 additions and 710 deletions
+68 -4
View File
@@ -20,7 +20,8 @@ extern volatile struct limine_hhdm_request g_hhdm_request;
#define VIRTIO_MMIO_MAGIC 0x74726976 /* "virt" */
#define VIRTIO_MMIO_VERSION_MODERN 2
#define MAX_VIRTIO_DEVICES 4
/* VSCode Phase 1: 3 (blk/net/rootfs) → 8 slots for input/gpu/extra-rootfs. */
#define MAX_VIRTIO_DEVICES 8
/* 每个 virtio 设备的运行状态(框架层维护,后端无关) */
struct virtio_dev_state {
@@ -227,7 +228,13 @@ void virtio_mmio_write(u64 gpa, u64 value, int width) {
}
break;
default:
/* device config 空间写(多数设备 config 只读,忽略) */
/* VSCode Phase 2: device config 空间写。virtio-input 用此通道设置
* select/subsel 后再读结果;其它设备 config 只读(write_config=NULL)。 */
if (off >= VIRTIO_MMIO_CONFIG && off < VIRTIO_MMIO_CONFIG + s->be->config_len) {
if (s->be->write_config) {
s->be->write_config(off - VIRTIO_MMIO_CONFIG, v32);
}
}
break;
}
}
@@ -264,6 +271,35 @@ int virtio_queue_get_ptrs(u32 device_id, u32 queue_idx,
return 0;
}
/* VSCode Phase 2: 按 gpa_base 定位队列。用于两个 virtio-input(kbd+mouse),
* 它们 device_id 相同(VIRTIO_ID_INPUT=18),只能靠 gpa_base 区分。 */
int virtio_queue_get_ptrs_by_gpa(u64 gpa_base, u32 queue_idx,
struct virtq_desc **desc_out,
struct virtq_avail **avail_out,
struct virtq_used **used_out,
u32 *queue_num_out) {
struct virtio_dev_state *s = (struct virtio_dev_state *)0;
for (int i = 0; i < g_vdev_count; i++) {
if (g_vdevs[i].be && g_vdevs[i].be->gpa_base == gpa_base) {
s = &g_vdevs[i];
break;
}
}
if (!s || queue_idx >= 4) return -1;
if (!s->q[queue_idx].ready) return -2;
struct virtq_desc *desc = (struct virtq_desc *)virtio_gpa_to_host(s->q[queue_idx].desc_gpa);
struct virtq_avail *avail = (struct virtq_avail *)virtio_gpa_to_host(s->q[queue_idx].driver_gpa);
struct virtq_used *used = (struct virtq_used *)virtio_gpa_to_host(s->q[queue_idx].device_gpa);
if (!desc || !avail || !used) return -3;
if (desc_out) *desc_out = desc;
if (avail_out) *avail_out = avail;
if (used_out) *used_out = used;
if (queue_num_out) *queue_num_out = s->q[queue_idx].num ? s->q[queue_idx].num : s->be->queue_size;
return 0;
}
void virtio_queue_bump_used(struct virtq_used *used, u16 new_idx) {
if (!used) return;
__asm__ volatile("mfence" ::: "memory");
@@ -283,17 +319,34 @@ void virtio_mmio_raise_irq(u32 device_id) {
}
}
/* VSCode Phase 2: 按 gpa_base 触发中断(两个 virtio-input 同 device_id=18
* 但不同 gpa_base / irq,需要分别注入)。 */
void virtio_mmio_raise_irq_by_gpa(u64 gpa_base) {
for (int i = 0; i < g_vdev_count; i++) {
struct virtio_dev_state *s = &g_vdevs[i];
if (!s->be || s->be->gpa_base != gpa_base) continue;
s->interrupt_status |= 1;
if (s->be->irq != 0) {
vmx_guest_queue_irq(0x30 + s->be->irq);
}
return;
}
}
/* ===== 框架初始化 =====
*
* 注册 block 与 net 后端。后端结构体由 virtio_blk.c / virtio_net.c 提供。 */
extern struct virtio_backend g_virtio_blk_backend;
extern struct virtio_backend g_virtio_net_backend;
/* 后端初始化符号(定义于 virtio_blk.c / virtio_net.c)。
* 这里声明以便链接;具体注册在各自文件完成。 */
/* 后端初始化符号(定义于 virtio_blk.c / virtio_net.c / virtio_input.c /
* virtio_gpu.c)。这里声明以便链接;具体注册在各自文件完成。 */
void virtio_blk_backend_init(void);
void virtio_net_backend_init(void);
void virtio_rootfs_blk_init(void); /* memory-backed Arch rootfs (/dev/vdb) */
void virtio_input_backend_init(void); /* VSCode Phase 2: keyboard + mouse */
void virtio_gpu_backend_init(void); /* VSCode Phase 3: virtio-gpu 2D */
void virtio_extra_rootfs_blk_init(void); /* VSCode Phase 4: rw volume (/dev/vdc) */
void virtio_mmio_init(void) {
if (g_vio_ready) return;
@@ -305,6 +358,17 @@ void virtio_mmio_init(void) {
* Must come after blk/net so /dev/vda (SATA) and /dev/vdb (rootfs) order
* is deterministic. */
virtio_rootfs_blk_init();
/* VSCode Phase 2: virtio-input (keyboard + mouse). Safe no-op until the
* desktop enables input forwarding via the push_* API. */
virtio_input_backend_init();
/* VSCode Phase 3: virtio-gpu 2D (scanout compositing into surface pool).
* Safe no-op if the surface pool was not allocated (Linux guest not loaded
* or alloc failed) — scanout stays disabled. */
virtio_gpu_backend_init();
/* VSCode Phase 4: writable extra-rootfs volume (/dev/vdc, overlay upper).
* Safe no-op if no extra-rootfs boot module — guest probe sees bad magic
* on slot6 and skips it. */
virtio_extra_rootfs_blk_init();
g_vio_ready = 1;
log_info("[VIO] virtio-mmio backend init ok");