1use core::{
5 result::Result,
6 sync::atomic::{AtomicUsize, Ordering},
7};
8
9use alloc::{boxed::Box, format, string::ToString, sync::Arc, vec};
10
11use crate::{
12 arch::io_mb,
13 device::{
14 Device,
15 manager::{DeviceManager, DriverPriority},
16 platform::{
17 PlatformDeviceDriver, PlatformDeviceInfo, resource::PlatformDeviceResourceType,
18 },
19 },
20 driver_initcall,
21 drivers::{
22 block::virtio_blk::VirtioBlockDevice, graphics::virtio_gpu::VirtioGpuDevice,
23 network::virtio_net::VirtioNetDevice, virtio_input::VirtioInputDevice,
24 virtio_rng::VirtioRngDevice,
25 },
26 early_println,
27};
28
29static BLOCK_COUNTER: AtomicUsize = AtomicUsize::new(0);
31static NET_COUNTER: AtomicUsize = AtomicUsize::new(0);
32static GPU_COUNTER: AtomicUsize = AtomicUsize::new(0);
33static INPUT_COUNTER: AtomicUsize = AtomicUsize::new(0);
34static RNG_COUNTER: AtomicUsize = AtomicUsize::new(0);
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum Register {
44 MagicValue = 0x00,
45 Version = 0x04,
46 DeviceId = 0x08,
47 VendorId = 0x0c,
48 DeviceFeatures = 0x10,
49 DeviceFeaturesSel = 0x14,
50 DriverFeatures = 0x20,
51 DriverFeaturesSel = 0x24,
52 GuestPageSize = 0x28,
53 QueueSel = 0x30,
54 QueueNumMax = 0x34,
55 QueueNum = 0x38,
56 QueueAlign = 0x3c,
57 QueuePfn = 0x40,
58 QueueReady = 0x44,
59 QueueNotify = 0x50,
60 InterruptStatus = 0x60,
61 InterruptAck = 0x64,
62 Status = 0x70,
63 QueueDescLow = 0x80,
64 QueueDescHigh = 0x84,
65 DriverDescLow = 0x90,
66 DriverDescHigh = 0x94,
67 DeviceDescLow = 0xa0,
68 DeviceDescHigh = 0xa4,
69 DeviceConfig = 0x100,
70}
71
72impl Register {
73 pub fn offset(&self) -> usize {
74 *self as usize
75 }
76
77 pub fn from_offset(offset: usize) -> Self {
78 match offset {
79 0x00 => Register::MagicValue,
80 0x04 => Register::Version,
81 0x08 => Register::DeviceId,
82 0x0c => Register::VendorId,
83 0x10 => Register::DeviceFeatures,
84 0x14 => Register::DeviceFeaturesSel,
85 0x20 => Register::DriverFeatures,
86 0x24 => Register::DriverFeaturesSel,
87 0x28 => Register::GuestPageSize,
88 0x30 => Register::QueueSel,
89 0x34 => Register::QueueNumMax,
90 0x38 => Register::QueueNum,
91 0x3c => Register::QueueAlign,
92 0x40 => Register::QueuePfn,
93 0x44 => Register::QueueReady,
94 0x50 => Register::QueueNotify,
95 0x60 => Register::InterruptStatus,
96 0x64 => Register::InterruptAck,
97 0x70 => Register::Status,
98 0x80 => Register::QueueDescLow,
99 0x84 => Register::QueueDescHigh,
100 0x90 => Register::DriverDescLow,
101 0x94 => Register::DriverDescHigh,
102 0xa0 => Register::DeviceDescLow,
103 0xa4 => Register::DeviceDescHigh,
104 _ => panic!("Invalid register offset"),
105 }
106 }
107}
108
109#[derive(Debug, Clone, Copy)]
115pub enum DeviceStatus {
116 Reset = 0x00,
117 Acknowledge = 0x01,
118 Driver = 0x02,
119 DriverOK = 0x04,
120 FeaturesOK = 0x08,
121 DeviceNeedReset = 0x40,
122 Failed = 0x80,
123}
124
125impl DeviceStatus {
126 pub fn is_set(&self, status: u32) -> bool {
138 (status & *self as u32) != 0
139 }
140
141 pub fn set(&self, status: &mut u32) {
150 *status |= *self as u32;
151 }
152
153 pub fn clear(&self, status: &mut u32) {
162 *status &= !(*self as u32);
163 }
164
165 pub fn toggle(&self, status: &mut u32) {
174 *status ^= *self as u32;
175 }
176
177 pub fn from_u32(status: u32) -> Self {
190 match status {
191 0x00 => DeviceStatus::Reset,
192 0x01 => DeviceStatus::Acknowledge,
193 0x02 => DeviceStatus::Driver,
194 0x04 => DeviceStatus::DriverOK,
195 0x08 => DeviceStatus::FeaturesOK,
196 0x40 => DeviceStatus::DeviceNeedReset,
197 0x80 => DeviceStatus::Failed,
198 _ => panic!("Invalid device status"),
199 }
200 }
201
202 pub fn to_u32(&self) -> u32 {
211 *self as u32
212 }
213}
214
215pub trait VirtioDevice {
221 #[cfg(not(debug_assertions))]
222 #[inline(never)]
223 fn write32_register_slowpath(&self, addr: usize, value: u32) {
224 io_mb();
225 unsafe { crate::arch::mmio::write32(addr, value) };
226 io_mb();
227 let status_addr = self.get_base_addr() + Register::Status.offset();
232 unsafe {
233 crate::arch::mmio::read32(status_addr);
234 }
235 io_mb();
236 }
237
238 fn debug_dump_mmio_state(&self, tag: &'static str) {
239 #[cfg(debug_assertions)]
240 {
241 let base = self.get_base_addr();
242 let magic = self.read32_register(Register::MagicValue);
243 let version = self.read32_register(Register::Version);
244 let device_id = self.read32_register(Register::DeviceId);
245 let vendor_id = self.read32_register(Register::VendorId);
246 let status = self.read32_register(Register::Status);
247 let isr = self.read32_register(Register::InterruptStatus);
248
249 crate::early_println!(
250 "[virtio][{}] base={:#x} magic=0x{:08x} ver={} dev_id={} vendor=0x{:08x} status=0x{:02x} isr=0x{:02x}",
251 tag,
252 base,
253 magic,
254 version,
255 device_id,
256 vendor_id,
257 status,
258 isr
259 );
260 }
261
262 #[cfg(not(debug_assertions))]
263 {
264 let _ = tag;
265 }
266 }
267
268 fn debug_log_status_transition(&self, tag: &'static str, old: u32, new: u32, readback: u32) {
269 #[cfg(debug_assertions)]
270 {
271 crate::early_println!(
272 "[virtio][{}] status: old=0x{:02x} -> write=0x{:02x} -> readback=0x{:02x}",
273 tag,
274 old,
275 new,
276 readback
277 );
278 }
279
280 #[cfg(not(debug_assertions))]
281 {
282 let _ = (tag, old, new, readback);
283 }
284 }
285
286 fn wait_for_status_zero(
287 &self,
288 tag: &'static str,
289 max_iters: usize,
290 ) -> Result<(), &'static str> {
291 for _ in 0..max_iters {
294 let status = self.read32_register(Register::Status) & 0xff;
295 if status == 0 {
296 return Ok(());
297 }
298 }
299 let final_status = self.read32_register(Register::Status) & 0xff;
300 crate::early_println!(
301 "[virtio][{}] reset wait timeout: status=0x{:02x}",
302 tag,
303 final_status
304 );
305 Err("Virtio device reset did not complete")
306 }
307
308 fn init(&mut self) -> Result<u32, &'static str> {
323 self.debug_dump_mmio_state("init:entry");
324
325 if self.read32_register(Register::MagicValue) != 0x74726976 {
327 self.set_failed();
328 return Err("Invalid Magic Value");
329 }
330
331 let version = self.read32_register(Register::Version);
333 if version != 2 {
334 self.set_failed();
335 return Err("Invalid Version");
336 }
337
338 if let Err(e) = self.reset() {
340 self.set_failed();
341 return Err(e);
342 }
343 self.acknowledge();
347 self.debug_dump_mmio_state("init:after_ack");
348
349 self.driver();
351 self.debug_dump_mmio_state("init:after_driver");
352
353 let negotiated_features = match self.negotiate_features() {
355 Ok(features) => features,
356 Err(e) => {
357 self.set_failed();
358 return Err(e);
359 }
360 };
361
362 for i in 0..self.get_virtqueue_count() {
364 if !self.setup_queue(i, self.get_virtqueue_size(i)) {
365 self.set_failed();
366 return Err("Failed to set up virtqueue");
367 }
368 }
369
370 self.driver_ok();
372 self.debug_dump_mmio_state("init:after_driver_ok");
373 Ok(negotiated_features)
374 }
375
376 fn is_modern_device(&self) -> bool {
377 self.read32_register(Register::Version) == 2
378 }
379
380 fn supports_feature(&self, feature: u32) -> bool {
381 let selector = feature / 32;
382 let bit = feature % 32;
383 self.write32_register(Register::DeviceFeaturesSel, selector);
384 let device_features = self.read32_register(Register::DeviceFeatures);
385 (device_features & (1u32 << bit)) != 0
386 }
387
388 fn reset(&mut self) -> Result<(), &'static str> {
390 let _old = self.read32_register(Register::Status);
393 self.write32_register(Register::Status, 0);
394 io_mb();
396
397 if cfg!(debug_assertions) {
403 early_println!("[virtio][reset] waiting for reset completion...");
404 }
405 self.wait_for_status_zero("reset", 100_000)?;
406
407 Ok(())
409 }
410
411 fn acknowledge(&mut self) {
413 let old = self.read32_register(Register::Status);
414 let mut status = old;
415 DeviceStatus::Acknowledge.set(&mut status);
416 self.write32_register(Register::Status, status);
417
418 let rb = self.read32_register(Register::Status);
419 self.debug_log_status_transition("ack", old, status, rb);
420 }
421
422 fn driver(&mut self) {
424 let old = self.read32_register(Register::Status);
425 let mut status = old;
426 DeviceStatus::Driver.set(&mut status);
427 self.write32_register(Register::Status, status);
428
429 let rb = self.read32_register(Register::Status);
430 self.debug_log_status_transition("driver", old, status, rb);
431 }
432
433 fn driver_ok(&mut self) {
435 let old = self.read32_register(Register::Status);
436 let mut status = old;
437 DeviceStatus::DriverOK.set(&mut status);
438 self.write32_register(Register::Status, status);
439
440 let rb = self.read32_register(Register::Status);
441 self.debug_log_status_transition("driver_ok", old, status, rb);
442 }
443
444 fn set_failed(&mut self) {
446 let old = self.read32_register(Register::Status);
447 let mut status = old;
448 DeviceStatus::Failed.set(&mut status);
449 self.write32_register(Register::Status, status);
450
451 let rb = self.read32_register(Register::Status);
452 self.debug_log_status_transition("failed", old, status, rb);
453 }
454
455 fn negotiate_features(&mut self) -> Result<u32, &'static str> {
465 let device_features = self.read32_register(Register::DeviceFeatures);
467 let driver_features = self.get_supported_features(device_features);
469 crate::early_println!(
470 "[virtio][feat] device_features=0x{:08x} driver_features=0x{:08x}",
471 device_features,
472 driver_features
473 );
474
475 #[cfg(test)]
476 {
477 use crate::early_println;
478 early_println!(
479 "[virtio] Negotiating features: device=0x{:x}, driver=0x{:x}",
480 device_features,
481 driver_features
482 );
483 }
484
485 self.write32_register(Register::DriverFeatures, driver_features);
487
488 let mut status = self.read32_register(Register::Status);
490 DeviceStatus::FeaturesOK.set(&mut status);
491 self.write32_register(Register::Status, status);
492
493 let final_status = self.read32_register(Register::Status);
495 let success = DeviceStatus::FeaturesOK.is_set(final_status);
496
497 #[cfg(test)]
498 {
499 use crate::early_println;
500 early_println!(
501 "[virtio] Feature negotiation result: success={}, status=0x{:x}",
502 success,
503 final_status
504 );
505 }
506
507 if success {
508 Ok(driver_features)
509 } else {
510 Err("Feature negotiation failed")
511 }
512 }
513
514 fn get_supported_features(&self, device_features: u32) -> u32 {
527 device_features
530 }
531
532 fn allow_ring_features(&self) -> bool {
533 self.is_modern_device()
534 && self.supports_feature(crate::drivers::virtio::features::VIRTIO_F_VERSION_1)
535 }
536
537 fn setup_queue(&mut self, queue_idx: usize, queue_size: usize) -> bool {
550 if queue_idx >= self.get_virtqueue_count() {
551 return false;
552 }
553
554 self.write32_register(Register::QueueSel, queue_idx as u32);
556 let ready = self.read32_register(Register::QueueReady);
558 if ready != 0 {
559 return false; }
561
562 let queue_size_max = self.read32_register(Register::QueueNumMax);
564 if queue_size > queue_size_max as usize {
565 return false; }
567
568 self.write32_register(Register::QueueNum, queue_size as u32);
570
571 let desc_addr = self.get_queue_desc_addr(queue_idx);
573 let driver_addr = self.get_queue_driver_addr(queue_idx);
574 let device_addr = self.get_queue_device_addr(queue_idx);
575
576 if desc_addr.is_none() || driver_addr.is_none() || device_addr.is_none() {
577 return false;
578 }
579
580 let desc_addr = desc_addr.unwrap();
581 let driver_addr = driver_addr.unwrap();
582 let device_addr = device_addr.unwrap();
583
584 let desc_addr_low = (desc_addr & 0xffffffff) as u32;
586 let desc_addr_high = (desc_addr >> 32) as u32;
587 self.write32_register(Register::QueueDescLow, desc_addr_low);
588 self.write32_register(Register::QueueDescHigh, desc_addr_high);
589
590 let driver_addr_low = (driver_addr & 0xffffffff) as u32;
592 let driver_addr_high = (driver_addr >> 32) as u32;
593 self.write32_register(Register::DriverDescLow, driver_addr_low);
594 self.write32_register(Register::DriverDescHigh, driver_addr_high);
595
596 let device_addr_low = (device_addr & 0xffffffff) as u32;
598 let device_addr_high = (device_addr >> 32) as u32;
599 self.write32_register(Register::DeviceDescLow, device_addr_low);
600 self.write32_register(Register::DeviceDescHigh, device_addr_high);
601
602 let status = self.read32_register(Register::Status);
604 if DeviceStatus::Failed.is_set(status) {
605 return false; }
607
608 self.write32_register(Register::QueueReady, 1);
610
611 let status = self.read32_register(Register::Status);
613 if DeviceStatus::Failed.is_set(status) {
614 return false; }
616
617 true
618 }
619
620 fn read_config<T: Sized>(&self, offset: usize) -> T {
632 let addr = self.get_base_addr() + Register::DeviceConfig.offset() + offset;
633 unsafe {
636 match core::mem::size_of::<T>() {
637 1 => {
638 let v = crate::arch::mmio::read8(addr);
639 core::mem::transmute_copy::<u8, T>(&v)
640 }
641 2 => {
642 let v = crate::arch::mmio::read16(addr);
643 core::mem::transmute_copy::<u16, T>(&v)
644 }
645 4 => {
646 let v = crate::arch::mmio::read32(addr);
647 core::mem::transmute_copy::<u32, T>(&v)
648 }
649 8 => {
650 let v = crate::arch::mmio::read64(addr);
651 core::mem::transmute_copy::<u64, T>(&v)
652 }
653 _ => {
654 let mut out = core::mem::MaybeUninit::<T>::uninit();
655 let dst = out.as_mut_ptr() as *mut u8;
656 for i in 0..core::mem::size_of::<T>() {
657 let b = crate::arch::mmio::read8(addr + i);
658 core::ptr::write(dst.add(i), b);
659 }
660 out.assume_init()
661 }
662 }
663 }
664 }
665
666 fn write_config<T: Sized>(&self, offset: usize, value: T) {
675 let addr = self.get_base_addr() + Register::DeviceConfig.offset() + offset;
676 unsafe {
679 match core::mem::size_of::<T>() {
680 1 => {
681 let v = core::mem::transmute_copy::<T, u8>(&value);
682 crate::arch::mmio::write8(addr, v);
683 }
684 2 => {
685 let v = core::mem::transmute_copy::<T, u16>(&value);
686 crate::arch::mmio::write16(addr, v);
687 }
688 4 => {
689 let v = core::mem::transmute_copy::<T, u32>(&value);
690 crate::arch::mmio::write32(addr, v);
691 }
692 8 => {
693 let v = core::mem::transmute_copy::<T, u64>(&value);
694 crate::arch::mmio::write64(addr, v);
695 }
696 _ => {
697 let src = &value as *const T as *const u8;
698 for i in 0..core::mem::size_of::<T>() {
699 let b = core::ptr::read(src.add(i));
700 crate::arch::mmio::write8(addr + i, b);
701 }
702 }
703 }
704 }
705 }
706
707 fn get_device_info(&self) -> (u32, u32) {
713 let device_id = self.read32_register(Register::DeviceId);
714 let vendor_id = self.read32_register(Register::VendorId);
715 (device_id, vendor_id)
716 }
717
718 fn get_interrupt_status(&self) -> u32 {
724 self.read32_register(Register::InterruptStatus)
725 }
726
727 fn process_interrupts(&mut self) -> u32 {
735 let status = self.get_interrupt_status();
736 if status != 0 {
737 self.write32_register(Register::InterruptAck, status & 0x03);
738 }
739 status
740 }
741
742 fn memory_barrier(&self) {
744 crate::arch::io_mb();
747 }
748
749 fn notify(&self, virtqueue_idx: usize) {
762 if virtqueue_idx >= self.get_virtqueue_count() {
763 panic!("Invalid virtqueue index");
764 }
765 io_mb();
767 self.write32_register(Register::QueueNotify, virtqueue_idx as u32);
768 io_mb();
769 }
770
771 fn read32_register(&self, register: Register) -> u32 {
781 let addr = self.get_base_addr() + register.offset();
782 io_mb();
783 let val = unsafe { crate::arch::mmio::read32(addr) };
784 io_mb();
785 val
786 }
787
788 fn write32_register(&self, register: Register, value: u32) {
795 let addr = self.get_base_addr() + register.offset();
796 #[cfg(not(debug_assertions))]
800 {
801 self.write32_register_slowpath(addr, value);
802 }
803
804 #[cfg(debug_assertions)]
805 {
806 io_mb();
807 unsafe { crate::arch::mmio::write32(addr, value) };
808 io_mb();
809 }
810
811 if register == Register::Status && (value & !0xff) != 0 {
812 crate::early_println!(
813 "[virtio][WARN] writing non-8bit value to Status: 0x{:08x} (base={:#x})",
814 value,
815 self.get_base_addr()
816 );
817 }
818 }
819
820 fn read64_register(&self, register: Register) -> u64 {
830 let addr = self.get_base_addr() + register.offset();
831 io_mb();
832 let val = unsafe { crate::arch::mmio::read64(addr) };
833 io_mb();
834 val
835 }
836
837 fn write64_register(&self, register: Register, value: u64) {
844 let addr = self.get_base_addr() + register.offset();
845 io_mb();
846 unsafe { crate::arch::mmio::write64(addr, value) };
847 io_mb();
848 }
849
850 fn get_base_addr(&self) -> usize;
853 fn get_virtqueue_count(&self) -> usize;
854 fn get_virtqueue_size(&self, queue_idx: usize) -> usize;
855
856 fn get_queue_desc_addr(&self, queue_idx: usize) -> Option<u64>;
858
859 fn get_queue_driver_addr(&self, queue_idx: usize) -> Option<u64>;
861
862 fn get_queue_device_addr(&self, queue_idx: usize) -> Option<u64>;
864}
865
866pub enum VirtioDeviceType {
872 Invalid = 0,
873 Net = 1,
874 Block = 2,
875 Console = 3,
876 Rng = 4,
877 GPU = 16,
878 Input = 18,
879}
880
881impl VirtioDeviceType {
882 pub fn from_u32(device_type: u32) -> Self {
894 match device_type {
895 0 => VirtioDeviceType::Invalid,
896 1 => VirtioDeviceType::Net,
897 2 => VirtioDeviceType::Block,
898 3 => VirtioDeviceType::Console,
899 4 => VirtioDeviceType::Rng,
900 16 => VirtioDeviceType::GPU,
901 18 => VirtioDeviceType::Input,
902 _ => panic!("Not supported device type"),
903 }
904 }
905}
906
907struct VirtioDeviceCommon {
913 base_addr: usize,
914}
915
916impl VirtioDeviceCommon {
917 pub fn new(base_addr: usize) -> Self {
927 Self { base_addr }
928 }
929}
930
931impl VirtioDevice for VirtioDeviceCommon {
932 fn init(&mut self) -> Result<u32, &'static str> {
933 Ok(0)
935 }
936
937 fn get_base_addr(&self) -> usize {
938 self.base_addr
939 }
940
941 fn get_virtqueue_count(&self) -> usize {
942 0
944 }
945
946 fn get_virtqueue_size(&self, _queue_idx: usize) -> usize {
947 0
949 }
950
951 fn get_queue_desc_addr(&self, _queue_idx: usize) -> Option<u64> {
952 None
954 }
955
956 fn get_queue_driver_addr(&self, _queue_idx: usize) -> Option<u64> {
957 None
959 }
960
961 fn get_queue_device_addr(&self, _queue_idx: usize) -> Option<u64> {
962 None
964 }
965}
966
967fn probe_fn(device: &PlatformDeviceInfo) -> Result<(), &'static str> {
968 let res = device.get_resources();
969 if res.is_empty() {
970 return Err("No resources found");
971 }
972
973 let mem_res = res
975 .iter()
976 .find(|r| r.res_type == PlatformDeviceResourceType::MEM)
977 .ok_or("Memory resource not found")?;
978
979 let base_addr = mem_res.start as usize;
980
981 let virtio_device = VirtioDeviceCommon::new(base_addr);
983 let device_type = VirtioDeviceType::from_u32(virtio_device.get_device_info().0);
985
986 match device_type {
987 VirtioDeviceType::Block => {
988 let id = BLOCK_COUNTER.fetch_add(1, Ordering::SeqCst);
989 let name = format!("vblk{}", id);
990 crate::early_println!(
991 "[Virtio] Detected Virtio Block Device at {:#x}, registering as {}",
992 base_addr,
993 name
994 );
995 let dev: Arc<dyn Device> = Arc::new(VirtioBlockDevice::new(base_addr));
996 DeviceManager::get_manager().register_device_with_name(name, dev);
997 }
998 VirtioDeviceType::Net => {
999 let id = NET_COUNTER.fetch_add(1, Ordering::SeqCst);
1000 let name = format!("veth{}", id);
1001 crate::early_println!(
1002 "[Virtio] Detected Virtio Network Device at {:#x}, registering as {}",
1003 base_addr,
1004 name
1005 );
1006 let dev = Arc::new(VirtioNetDevice::new(base_addr));
1007 dev.register_interface(&name);
1008
1009 if let Some(irq_resource) = device
1011 .get_resources()
1012 .iter()
1013 .find(|r| r.res_type == PlatformDeviceResourceType::IRQ)
1014 {
1015 let interrupt_id = irq_resource.start as u32;
1016 crate::early_println!("[Virtio] Net device interrupt ID: {}", interrupt_id);
1017
1018 if let Err(e) = dev.enable_interrupts(interrupt_id) {
1019 crate::early_println!("[Virtio] Failed to enable net interrupts: {}", e);
1020 } else if let Err(e) = crate::interrupt::InterruptManager::with_manager(|mgr| {
1021 mgr.register_interrupt_device(interrupt_id, dev.clone())
1022 }) {
1023 crate::early_println!(
1024 "[Virtio] Failed to register net interrupt device: {}",
1025 e
1026 );
1027 } else {
1028 crate::early_println!("[Virtio] Net interrupt device registered");
1029 }
1030 } else {
1031 crate::early_println!("[Virtio] No interrupt resource found for net device");
1032 }
1033
1034 DeviceManager::get_manager().register_device_with_name(name, dev);
1035 }
1036 VirtioDeviceType::GPU => {
1037 let id = GPU_COUNTER.fetch_add(1, Ordering::SeqCst);
1038 let name = format!("vfb{}", id);
1039 crate::early_println!(
1040 "[Virtio] Detected Virtio GPU Device at {:#x}, registering as {}",
1041 base_addr,
1042 name
1043 );
1044 let dev: Arc<dyn Device> = Arc::new(VirtioGpuDevice::new(base_addr));
1045 DeviceManager::get_manager().register_device_with_name(name, dev);
1046 }
1047 VirtioDeviceType::Input => {
1048 crate::early_println!("[Virtio] Detected Virtio Input Device at {:#x}", base_addr);
1049 let dev = Arc::new(VirtioInputDevice::new(base_addr));
1051
1052 if let Some(irq_resource) = device
1054 .get_resources()
1055 .iter()
1056 .find(|r| r.res_type == PlatformDeviceResourceType::IRQ)
1057 {
1058 let interrupt_id = irq_resource.start as u32;
1059 crate::early_println!("[Virtio] Input device interrupt ID: {}", interrupt_id);
1060
1061 if let Err(e) = dev.enable_interrupts(interrupt_id) {
1063 crate::early_println!("[Virtio] Failed to enable input interrupts: {}", e);
1064 } else {
1065 crate::early_println!(
1066 "[Virtio] Input interrupts enabled (ID: {})",
1067 interrupt_id
1068 );
1069
1070 if let Err(e) = crate::interrupt::InterruptManager::with_manager(|mgr| {
1072 mgr.register_interrupt_device(interrupt_id, dev.clone())
1073 }) {
1074 crate::early_println!(
1075 "[Virtio] Failed to register input interrupt device: {}",
1076 e
1077 );
1078 } else {
1079 crate::early_println!("[Virtio] Input interrupt device registered");
1080 }
1081 }
1082 } else {
1083 crate::early_println!("[Virtio] No interrupt resource found for input device");
1084 }
1085
1086 DeviceManager::get_manager().register_device(dev);
1088 }
1089 VirtioDeviceType::Rng => {
1090 let id = RNG_COUNTER.fetch_add(1, Ordering::SeqCst);
1091 crate::early_println!("[Virtio] Detected Virtio RNG Device at {:#x}", base_addr);
1092
1093 let rng_device = Arc::new(VirtioRngDevice::new(base_addr));
1095 crate::random::RandomManager::register_entropy_source(rng_device);
1096
1097 if id == 0 {
1099 let random_char_dev: Arc<dyn Device> =
1100 Arc::new(crate::random::RandomCharDevice::new());
1101 DeviceManager::get_manager()
1102 .register_device_with_name("random".to_string(), random_char_dev);
1103 crate::early_println!("[Virtio] Registered /dev/random character device");
1104 }
1105 }
1106 _ => {
1107 return Err("Unsupported device type");
1109 }
1110 }
1111
1112 Ok(())
1113}
1114
1115fn remove_fn(_device: &PlatformDeviceInfo) -> Result<(), &'static str> {
1116 Ok(())
1117}
1118
1119fn register_driver() {
1120 let driver = PlatformDeviceDriver::new("virtio-mmio", probe_fn, remove_fn, vec!["virtio,mmio"]);
1121 DeviceManager::get_manager().register_driver(Box::new(driver), DriverPriority::Standard)
1123}
1124
1125driver_initcall!(register_driver);
1126
1127#[cfg(test)]
1128mod tests;