mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 13:26:48 +00:00
Support virtio console device
This commit is contained in:
parent
e9544d489f
commit
01e485b96e
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -628,6 +628,18 @@ dependencies = [
|
|||||||
"spin 0.9.8",
|
"spin 0.9.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jinux-console"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"component",
|
||||||
|
"jinux-frame",
|
||||||
|
"jinux-util",
|
||||||
|
"log",
|
||||||
|
"spin 0.9.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jinux-frame"
|
name = "jinux-frame"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -757,6 +769,7 @@ dependencies = [
|
|||||||
"int-to-c-enum",
|
"int-to-c-enum",
|
||||||
"intrusive-collections",
|
"intrusive-collections",
|
||||||
"jinux-block",
|
"jinux-block",
|
||||||
|
"jinux-console",
|
||||||
"jinux-frame",
|
"jinux-frame",
|
||||||
"jinux-input",
|
"jinux-input",
|
||||||
"jinux-network",
|
"jinux-network",
|
||||||
@ -812,11 +825,13 @@ name = "jinux-virtio"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"align_ext",
|
"align_ext",
|
||||||
|
"bit_field",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"bytes",
|
"bytes",
|
||||||
"component",
|
"component",
|
||||||
"int-to-c-enum",
|
"int-to-c-enum",
|
||||||
"jinux-block",
|
"jinux-block",
|
||||||
|
"jinux-console",
|
||||||
"jinux-frame",
|
"jinux-frame",
|
||||||
"jinux-input",
|
"jinux-input",
|
||||||
"jinux-network",
|
"jinux-network",
|
||||||
|
@ -39,6 +39,7 @@ members = [
|
|||||||
"framework/libs/ktest",
|
"framework/libs/ktest",
|
||||||
"framework/libs/tdx-guest",
|
"framework/libs/tdx-guest",
|
||||||
"services/comps/block",
|
"services/comps/block",
|
||||||
|
"services/comps/console",
|
||||||
"services/comps/framebuffer",
|
"services/comps/framebuffer",
|
||||||
"services/comps/input",
|
"services/comps/input",
|
||||||
"services/comps/network",
|
"services/comps/network",
|
||||||
|
@ -4,6 +4,7 @@ std = { name = "jinux-std" }
|
|||||||
virtio = { name = "jinux-virtio" }
|
virtio = { name = "jinux-virtio" }
|
||||||
input = { name = "jinux-input" }
|
input = { name = "jinux-input" }
|
||||||
block = { name = "jinux-block" }
|
block = { name = "jinux-block" }
|
||||||
|
console = { name = "jinux-console" }
|
||||||
time = { name = "jinux-time" }
|
time = { name = "jinux-time" }
|
||||||
framebuffer = { name = "jinux-framebuffer" }
|
framebuffer = { name = "jinux-framebuffer" }
|
||||||
network = { name = "jinux-network" }
|
network = { name = "jinux-network" }
|
||||||
|
@ -19,6 +19,10 @@ pub const DEVICE_ARGS: &[&str] = &[
|
|||||||
"virtio-keyboard-device",
|
"virtio-keyboard-device",
|
||||||
"-device",
|
"-device",
|
||||||
"virtio-net-device,netdev=net01",
|
"virtio-net-device,netdev=net01",
|
||||||
|
"-device",
|
||||||
|
"virtio-serial-device",
|
||||||
|
"-device",
|
||||||
|
"virtconsole,chardev=mux",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn create_bootdev_image(path: PathBuf) -> PathBuf {
|
pub fn create_bootdev_image(path: PathBuf) -> PathBuf {
|
||||||
|
@ -43,6 +43,10 @@ pub const NOIOMMU_DEVICE_ARGS: &[&str] = &[
|
|||||||
"virtio-keyboard-pci,disable-legacy=on,disable-modern=off",
|
"virtio-keyboard-pci,disable-legacy=on,disable-modern=off",
|
||||||
"-device",
|
"-device",
|
||||||
"virtio-net-pci,netdev=net01,disable-legacy=on,disable-modern=off",
|
"virtio-net-pci,netdev=net01,disable-legacy=on,disable-modern=off",
|
||||||
|
"-device",
|
||||||
|
"virtio-serial-pci,disable-legacy=on,disable-modern=off",
|
||||||
|
"-device",
|
||||||
|
"virtconsole,chardev=mux",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const IOMMU_DEVICE_ARGS: &[&str] = &[
|
pub const IOMMU_DEVICE_ARGS: &[&str] = &[
|
||||||
@ -53,6 +57,10 @@ pub const IOMMU_DEVICE_ARGS: &[&str] = &[
|
|||||||
"-device",
|
"-device",
|
||||||
"virtio-net-pci,netdev=net01,disable-legacy=on,disable-modern=off,iommu_platform=on,ats=on",
|
"virtio-net-pci,netdev=net01,disable-legacy=on,disable-modern=off,iommu_platform=on,ats=on",
|
||||||
"-device",
|
"-device",
|
||||||
|
"virtio-serial-pci,disable-legacy=on,disable-modern=off,iommu_platform=on,ats=on",
|
||||||
|
"-device",
|
||||||
|
"virtconsole,chardev=mux",
|
||||||
|
"-device",
|
||||||
"intel-iommu,intremap=on,device-iotlb=on",
|
"intel-iommu,intremap=on,device-iotlb=on",
|
||||||
"-device",
|
"-device",
|
||||||
"ioh3420,id=pcie.0,chassis=1",
|
"ioh3420,id=pcie.0,chassis=1",
|
||||||
|
@ -93,10 +93,12 @@ pub const COMMON_ARGS: &[&str] = &[
|
|||||||
"-m",
|
"-m",
|
||||||
"2G",
|
"2G",
|
||||||
"-nographic", // TODO: figure out why grub can't shown up without it
|
"-nographic", // TODO: figure out why grub can't shown up without it
|
||||||
"-monitor",
|
|
||||||
"vc",
|
|
||||||
"-serial",
|
"-serial",
|
||||||
"mon:stdio",
|
"chardev:mux",
|
||||||
|
"-monitor",
|
||||||
|
"chardev:mux",
|
||||||
|
"-chardev",
|
||||||
|
"stdio,id=mux,mux=on,signal=off,logfile=qemu.log",
|
||||||
"-display",
|
"-display",
|
||||||
"none",
|
"none",
|
||||||
"-device",
|
"-device",
|
||||||
|
16
services/comps/console/Cargo.toml
Normal file
16
services/comps/console/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "jinux-console"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bitflags = "1.3"
|
||||||
|
spin = "0.9.4"
|
||||||
|
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||||
|
jinux-util = { path = "../../libs/jinux-util" }
|
||||||
|
component = { path = "../../libs/comp-sys/component" }
|
||||||
|
log = "0.4"
|
||||||
|
|
||||||
|
[features]
|
71
services/comps/console/src/lib.rs
Normal file
71
services/comps/console/src/lib.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//! The console device of jinux
|
||||||
|
#![no_std]
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
|
#![feature(fn_traits)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::{collections::BTreeMap, fmt::Debug, string::String, sync::Arc, vec::Vec};
|
||||||
|
use core::any::Any;
|
||||||
|
|
||||||
|
use component::{init_component, ComponentInitError};
|
||||||
|
use jinux_frame::sync::SpinLock;
|
||||||
|
use spin::Once;
|
||||||
|
|
||||||
|
pub type ConsoleCallback = dyn Fn(&[u8]) + Send + Sync;
|
||||||
|
|
||||||
|
pub trait AnyConsoleDevice: Send + Sync + Any + Debug {
|
||||||
|
fn send(&self, buf: &[u8]);
|
||||||
|
fn recv(&self, buf: &mut [u8]) -> Option<usize>;
|
||||||
|
fn register_callback(&self, callback: &'static ConsoleCallback);
|
||||||
|
fn handle_irq(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_device(name: String, device: Arc<dyn AnyConsoleDevice>) {
|
||||||
|
COMPONENT
|
||||||
|
.get()
|
||||||
|
.unwrap()
|
||||||
|
.console_table
|
||||||
|
.lock()
|
||||||
|
.insert(name, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_device(str: &str) -> Option<Arc<dyn AnyConsoleDevice>> {
|
||||||
|
COMPONENT
|
||||||
|
.get()
|
||||||
|
.unwrap()
|
||||||
|
.console_table
|
||||||
|
.lock()
|
||||||
|
.get(str)
|
||||||
|
.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_devices() -> Vec<(String, Arc<dyn AnyConsoleDevice>)> {
|
||||||
|
let consoles = COMPONENT.get().unwrap().console_table.lock();
|
||||||
|
consoles
|
||||||
|
.iter()
|
||||||
|
.map(|(name, device)| (name.clone(), device.clone()))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
static COMPONENT: Once<Component> = Once::new();
|
||||||
|
|
||||||
|
#[init_component]
|
||||||
|
fn component_init() -> Result<(), ComponentInitError> {
|
||||||
|
let a = Component::init()?;
|
||||||
|
COMPONENT.call_once(|| a);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Component {
|
||||||
|
console_table: SpinLock<BTreeMap<String, Arc<dyn AnyConsoleDevice>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component {
|
||||||
|
pub fn init() -> Result<Self, ComponentInitError> {
|
||||||
|
Ok(Self {
|
||||||
|
console_table: SpinLock::new(BTreeMap::new()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ align_ext = { path = "../../../framework/libs/align_ext" }
|
|||||||
jinux-input = { path = "../input" }
|
jinux-input = { path = "../input" }
|
||||||
jinux-block = { path = "../block" }
|
jinux-block = { path = "../block" }
|
||||||
jinux-network = { path = "../network" }
|
jinux-network = { path = "../network" }
|
||||||
|
jinux-console = { path = "../console" }
|
||||||
jinux-frame = { path = "../../../framework/jinux-frame" }
|
jinux-frame = { path = "../../../framework/jinux-frame" }
|
||||||
jinux-util = { path = "../../libs/jinux-util" }
|
jinux-util = { path = "../../libs/jinux-util" }
|
||||||
jinux-rights = { path = "../../libs/jinux-rights" }
|
jinux-rights = { path = "../../libs/jinux-rights" }
|
||||||
@ -21,6 +22,7 @@ typeflags-util = { path = "../../libs/typeflags-util" }
|
|||||||
pod = { git = "https://github.com/jinzhao-dev/pod", rev = "d7dba56" }
|
pod = { git = "https://github.com/jinzhao-dev/pod", rev = "d7dba56" }
|
||||||
component = { path = "../../libs/comp-sys/component" }
|
component = { path = "../../libs/comp-sys/component" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
bit_field = "0.10.1"
|
||||||
int-to-c-enum = { path = "../../libs/int-to-c-enum" }
|
int-to-c-enum = { path = "../../libs/int-to-c-enum" }
|
||||||
smoltcp = { version = "0.9.1", default-features = false, features = [
|
smoltcp = { version = "0.9.1", default-features = false, features = [
|
||||||
"alloc",
|
"alloc",
|
||||||
|
34
services/comps/virtio/src/device/console/config.rs
Normal file
34
services/comps/virtio/src/device/console/config.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use jinux_frame::io_mem::IoMem;
|
||||||
|
use jinux_util::safe_ptr::SafePtr;
|
||||||
|
use pod::Pod;
|
||||||
|
|
||||||
|
use crate::transport::VirtioTransport;
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
pub struct ConsoleFeatures: u64{
|
||||||
|
/// Configuration cols and rows are valid.
|
||||||
|
const VIRTIO_CONSOLE_F_SIZE = 1 << 0;
|
||||||
|
/// Device has support for multiple ports;
|
||||||
|
/// max_nr_ports is valid and control virtqueues will be used.
|
||||||
|
const VIRTIO_CONSOLE_F_MULTIPORT = 1 << 1;
|
||||||
|
/// Device has support for emergency write.
|
||||||
|
/// Configuration field emerg_wr is valid.
|
||||||
|
const VIRTIO_CONSOLE_F_EMERG_WRITE = 1 << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Pod, Clone, Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct VirtioConsoleConfig {
|
||||||
|
pub cols: u16,
|
||||||
|
pub row: u16,
|
||||||
|
pub max_nr_ports: u32,
|
||||||
|
pub emerg_wr: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtioConsoleConfig {
|
||||||
|
pub(super) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> {
|
||||||
|
let memory = transport.device_config_memory();
|
||||||
|
SafePtr::new(memory, 0)
|
||||||
|
}
|
||||||
|
}
|
147
services/comps/virtio/src/device/console/device.rs
Normal file
147
services/comps/virtio/src/device/console/device.rs
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
use core::hint::spin_loop;
|
||||||
|
|
||||||
|
use alloc::{boxed::Box, fmt::Debug, string::ToString, sync::Arc, vec::Vec};
|
||||||
|
use jinux_console::{AnyConsoleDevice, ConsoleCallback};
|
||||||
|
use jinux_frame::{config::PAGE_SIZE, io_mem::IoMem, sync::SpinLock, trap::TrapFrame};
|
||||||
|
use jinux_util::safe_ptr::SafePtr;
|
||||||
|
use log::debug;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
device::{console::config::ConsoleFeatures, VirtioDeviceError},
|
||||||
|
queue::VirtQueue,
|
||||||
|
transport::VirtioTransport,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{config::VirtioConsoleConfig, DEVICE_NAME};
|
||||||
|
|
||||||
|
pub struct ConsoleDevice {
|
||||||
|
config: SafePtr<VirtioConsoleConfig, IoMem>,
|
||||||
|
transport: Box<dyn VirtioTransport>,
|
||||||
|
receive_queue: SpinLock<VirtQueue>,
|
||||||
|
transmit_queue: SpinLock<VirtQueue>,
|
||||||
|
buffer: SpinLock<Box<[u8; PAGE_SIZE]>>,
|
||||||
|
callbacks: SpinLock<Vec<&'static ConsoleCallback>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AnyConsoleDevice for ConsoleDevice {
|
||||||
|
fn send(&self, value: &[u8]) {
|
||||||
|
let mut transmit_queue = self.transmit_queue.lock_irq_disabled();
|
||||||
|
transmit_queue.add(&[value], &[]).unwrap();
|
||||||
|
if transmit_queue.should_notify() {
|
||||||
|
transmit_queue.notify();
|
||||||
|
}
|
||||||
|
while !transmit_queue.can_pop() {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
transmit_queue.pop_used().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv(&self, buf: &mut [u8]) -> Option<usize> {
|
||||||
|
let mut receive_queue = self.receive_queue.lock_irq_disabled();
|
||||||
|
if !receive_queue.can_pop() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let (_, len) = receive_queue.pop_used().unwrap();
|
||||||
|
|
||||||
|
let mut recv_buffer = self.buffer.lock();
|
||||||
|
buf.copy_from_slice(&recv_buffer.as_ref()[..len as usize]);
|
||||||
|
receive_queue.add(&[], &[recv_buffer.as_mut()]).unwrap();
|
||||||
|
if receive_queue.should_notify() {
|
||||||
|
receive_queue.notify();
|
||||||
|
}
|
||||||
|
Some(len as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_callback(&self, callback: &'static (dyn Fn(&[u8]) + Send + Sync)) {
|
||||||
|
self.callbacks.lock().push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_irq(&self) {
|
||||||
|
let mut receive_queue = self.receive_queue.lock_irq_disabled();
|
||||||
|
if !receive_queue.can_pop() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let (_, len) = receive_queue.pop_used().unwrap();
|
||||||
|
let mut recv_buffer = self.buffer.lock();
|
||||||
|
let buffer = &recv_buffer.as_ref()[..len as usize];
|
||||||
|
let lock = self.callbacks.lock();
|
||||||
|
for callback in lock.iter() {
|
||||||
|
callback.call((buffer,));
|
||||||
|
}
|
||||||
|
receive_queue.add(&[], &[recv_buffer.as_mut()]).unwrap();
|
||||||
|
if receive_queue.should_notify() {
|
||||||
|
receive_queue.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ConsoleDevice {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_struct("ConsoleDevice")
|
||||||
|
.field("config", &self.config)
|
||||||
|
.field("transport", &self.transport)
|
||||||
|
.field("receive_queue", &self.receive_queue)
|
||||||
|
.field("transmit_queue", &self.transmit_queue)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConsoleDevice {
|
||||||
|
pub fn negotiate_features(features: u64) -> u64 {
|
||||||
|
let mut features = ConsoleFeatures::from_bits_truncate(features);
|
||||||
|
// A virtio console device may have multiple ports, but we only use one port to communicate now.
|
||||||
|
features.remove(ConsoleFeatures::VIRTIO_CONSOLE_F_MULTIPORT);
|
||||||
|
features.bits()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(mut transport: Box<dyn VirtioTransport>) -> Result<(), VirtioDeviceError> {
|
||||||
|
let config = VirtioConsoleConfig::new(transport.as_ref());
|
||||||
|
const RECV0_QUEUE_INDEX: u16 = 0;
|
||||||
|
const TRANSMIT0_QUEUE_INDEX: u16 = 1;
|
||||||
|
let receive_queue =
|
||||||
|
SpinLock::new(VirtQueue::new(RECV0_QUEUE_INDEX, 2, transport.as_mut()).unwrap());
|
||||||
|
let transmit_queue =
|
||||||
|
SpinLock::new(VirtQueue::new(TRANSMIT0_QUEUE_INDEX, 2, transport.as_mut()).unwrap());
|
||||||
|
|
||||||
|
let mut device = Self {
|
||||||
|
config,
|
||||||
|
transport,
|
||||||
|
receive_queue,
|
||||||
|
transmit_queue,
|
||||||
|
buffer: SpinLock::new(Box::new([0; PAGE_SIZE])),
|
||||||
|
callbacks: SpinLock::new(Vec::new()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut recv_lock = device.receive_queue.lock();
|
||||||
|
recv_lock
|
||||||
|
.add(&[], &[device.buffer.lock().as_mut()])
|
||||||
|
.unwrap();
|
||||||
|
if recv_lock.should_notify() {
|
||||||
|
recv_lock.notify();
|
||||||
|
}
|
||||||
|
drop(recv_lock);
|
||||||
|
device
|
||||||
|
.transport
|
||||||
|
.register_queue_callback(RECV0_QUEUE_INDEX, Box::new(handle_console_input), false)
|
||||||
|
.unwrap();
|
||||||
|
device
|
||||||
|
.transport
|
||||||
|
.register_cfg_callback(Box::new(config_space_change))
|
||||||
|
.unwrap();
|
||||||
|
device.transport.finish_init();
|
||||||
|
|
||||||
|
jinux_console::register_device(DEVICE_NAME.to_string(), Arc::new(device));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_console_input(_: &TrapFrame) {
|
||||||
|
jinux_console::get_device(&DEVICE_NAME.to_string())
|
||||||
|
.unwrap()
|
||||||
|
.handle_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_space_change(_: &TrapFrame) {
|
||||||
|
debug!("Virtio-Console device configuration space change");
|
||||||
|
}
|
4
services/comps/virtio/src/device/console/mod.rs
Normal file
4
services/comps/virtio/src/device/console/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod config;
|
||||||
|
pub mod device;
|
||||||
|
|
||||||
|
pub static DEVICE_NAME: &str = "Virtio-Console";
|
@ -2,6 +2,7 @@ use crate::queue::QueueError;
|
|||||||
use int_to_c_enum::TryFromInt;
|
use int_to_c_enum::TryFromInt;
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
|
pub mod console;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod network;
|
pub mod network;
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ use alloc::boxed::Box;
|
|||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use component::ComponentInitError;
|
use component::ComponentInitError;
|
||||||
use device::{
|
use device::{
|
||||||
block::device::BlockDevice, input::device::InputDevice, network::device::NetworkDevice,
|
block::device::BlockDevice, console::device::ConsoleDevice, input::device::InputDevice,
|
||||||
VirtioDeviceType,
|
network::device::NetworkDevice, VirtioDeviceType,
|
||||||
};
|
};
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use transport::{mmio::VIRTIO_MMIO_DRIVER, pci::VIRTIO_PCI_DRIVER, DeviceStatus};
|
use transport::{mmio::VIRTIO_MMIO_DRIVER, pci::VIRTIO_PCI_DRIVER, DeviceStatus};
|
||||||
@ -49,6 +49,7 @@ fn virtio_component_init() -> Result<(), ComponentInitError> {
|
|||||||
VirtioDeviceType::Block => BlockDevice::init(transport),
|
VirtioDeviceType::Block => BlockDevice::init(transport),
|
||||||
VirtioDeviceType::Input => InputDevice::init(transport),
|
VirtioDeviceType::Input => InputDevice::init(transport),
|
||||||
VirtioDeviceType::Network => NetworkDevice::init(transport),
|
VirtioDeviceType::Network => NetworkDevice::init(transport),
|
||||||
|
VirtioDeviceType::Console => ConsoleDevice::init(transport),
|
||||||
_ => {
|
_ => {
|
||||||
warn!("[Virtio]: Found unimplemented device:{:?}", device_type);
|
warn!("[Virtio]: Found unimplemented device:{:?}", device_type);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -82,6 +83,7 @@ fn negotiate_features(transport: &mut Box<dyn VirtioTransport>) {
|
|||||||
VirtioDeviceType::Network => NetworkDevice::negotiate_features(device_specified_features),
|
VirtioDeviceType::Network => NetworkDevice::negotiate_features(device_specified_features),
|
||||||
VirtioDeviceType::Block => BlockDevice::negotiate_features(device_specified_features),
|
VirtioDeviceType::Block => BlockDevice::negotiate_features(device_specified_features),
|
||||||
VirtioDeviceType::Input => InputDevice::negotiate_features(device_specified_features),
|
VirtioDeviceType::Input => InputDevice::negotiate_features(device_specified_features),
|
||||||
|
VirtioDeviceType::Console => ConsoleDevice::negotiate_features(device_specified_features),
|
||||||
_ => device_specified_features,
|
_ => device_specified_features,
|
||||||
};
|
};
|
||||||
let mut support_feature = Feature::from_bits_truncate(features);
|
let mut support_feature = Feature::from_bits_truncate(features);
|
||||||
|
@ -12,6 +12,7 @@ pod = { git = "https://github.com/jinzhao-dev/pod", rev = "d7dba56" }
|
|||||||
jinux-input = { path = "../../comps/input" }
|
jinux-input = { path = "../../comps/input" }
|
||||||
jinux-block = { path = "../../comps/block" }
|
jinux-block = { path = "../../comps/block" }
|
||||||
jinux-network = { path = "../../comps/network" }
|
jinux-network = { path = "../../comps/network" }
|
||||||
|
jinux-console = { path = "../../comps/console" }
|
||||||
jinux-time = { path = "../../comps/time" }
|
jinux-time = { path = "../../comps/time" }
|
||||||
jinux-virtio = { path = "../../comps/virtio" }
|
jinux-virtio = { path = "../../comps/virtio" }
|
||||||
jinux-rights = { path = "../jinux-rights" }
|
jinux-rights = { path = "../jinux-rights" }
|
||||||
|
@ -9,7 +9,9 @@ use crate::{
|
|||||||
pub static TTY_DRIVER: Once<Arc<TtyDriver>> = Once::new();
|
pub static TTY_DRIVER: Once<Arc<TtyDriver>> = Once::new();
|
||||||
|
|
||||||
pub(super) fn init() {
|
pub(super) fn init() {
|
||||||
register_console_input_callback(&serial_input_callback);
|
for (_, device) in jinux_console::all_devices() {
|
||||||
|
device.register_callback(&console_input_callback)
|
||||||
|
}
|
||||||
let tty_driver = Arc::new(TtyDriver::new());
|
let tty_driver = Arc::new(TtyDriver::new());
|
||||||
// FIXME: install n_tty into tty_driver?
|
// FIXME: install n_tty into tty_driver?
|
||||||
let n_tty = get_n_tty();
|
let n_tty = get_n_tty();
|
||||||
@ -66,6 +68,13 @@ impl TtyDriver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn console_input_callback(items: &[u8]) {
|
||||||
|
let tty_driver = get_tty_driver();
|
||||||
|
for item in items {
|
||||||
|
tty_driver.receive_char(*item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn serial_input_callback(item: u8) {
|
fn serial_input_callback(item: u8) {
|
||||||
let tty_driver = get_tty_driver();
|
let tty_driver = get_tty_driver();
|
||||||
tty_driver.receive_char(item);
|
tty_driver.receive_char(item);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user