pub(crate) fn probe_all_devices() {
info!("Probe platform devices...");
if !rdrive::is_initialized() {
warn!("rdrive is not initialized; skip platform device probe");
return;
}
rdrive::probe_all(false)
.unwrap_or_else(|err| panic!("failed to probe platform devices: {err:?}"));
}
#[cfg(feature = "display")]
pub(crate) fn init_display() {
if !rdrive::is_initialized() {
ax_display::init_display(core::iter::empty::<ax_display::ErasedDisplayDevice>());
return;
}
let devices = ax_driver::display::take_display_devices()
.unwrap_or_else(|err| panic!("failed to open display devices: {err:?}"))
.into_iter()
.map(adapt_display_device);
ax_display::init_display(devices);
}
#[cfg(feature = "display")]
fn adapt_display_device(
taken: ax_driver::display::TakenDisplayDevice,
) -> ax_display::ErasedDisplayDevice {
let name = alloc::string::String::from(taken.device.name());
let irq = resolve_display_irq(&name, taken.irq)
.unwrap_or_else(|err| panic!("failed to resolve display IRQ for {name}: {err:?}"));
let display = ax_display::rdif::RdifDisplayDevice::new_with_irq(taken.device, irq)
.unwrap_or_else(|err| panic!("failed to adapt display device: {err:?}"));
ax_display::ErasedDisplayDevice::new(display)
}
#[cfg(all(feature = "display", feature = "irq"))]
fn resolve_display_irq(
_name: &str,
irq: Option<ax_driver::BindingIrq>,
) -> Result<Option<irq_framework::IrqId>, irq_framework::IrqError> {
irq.map(crate::irq::resolve_binding_irq).transpose()
}
#[cfg(all(feature = "display", not(feature = "irq")))]
fn resolve_display_irq(
name: &str,
irq: Option<ax_driver::BindingIrq>,
) -> Result<Option<irq_framework::IrqId>, core::convert::Infallible> {
if irq.is_some() {
warn!("display device {name} has an IRQ binding but IRQ support is disabled");
}
Ok(None)
}
#[cfg(feature = "input")]
pub(crate) fn init_input() {
if !rdrive::is_initialized() {
ax_input::init_input(core::iter::empty::<ax_input::ErasedInputDevice>());
return;
}
let devices = ax_driver::input::take_input_devices()
.unwrap_or_else(|err| panic!("failed to open input devices: {err:?}"))
.into_iter()
.map(adapt_input_device);
ax_input::init_input(devices);
}
#[cfg(feature = "input")]
fn adapt_input_device(taken: ax_driver::input::TakenInputDevice) -> ax_input::ErasedInputDevice {
let name = alloc::string::String::from(taken.device.name());
let irq = resolve_input_irq(&name, taken.irq)
.unwrap_or_else(|err| panic!("failed to resolve input IRQ for {name}: {err:?}"));
ax_input::ErasedInputDevice::new(ax_input::rdif::RdifInputDevice::new_with_irq(
taken.device,
irq,
))
}
#[cfg(all(feature = "input", feature = "irq"))]
fn resolve_input_irq(
_name: &str,
irq: Option<ax_driver::BindingIrq>,
) -> Result<Option<irq_framework::IrqId>, irq_framework::IrqError> {
irq.map(crate::irq::resolve_binding_irq).transpose()
}
#[cfg(all(feature = "input", not(feature = "irq")))]
fn resolve_input_irq(
name: &str,
irq: Option<ax_driver::BindingIrq>,
) -> Result<Option<irq_framework::IrqId>, core::convert::Infallible> {
if irq.is_some() {
warn!("input device {name} has an IRQ binding but IRQ support is disabled");
}
Ok(None)
}
#[cfg(feature = "net")]
pub(crate) fn init_net() {
#[cfg(feature = "irq")]
ax_net::set_ethernet_irq_registrar(&crate::irq::NET_IRQ_REGISTRAR);
register_unix_namespace();
let config = parse_network_config();
let (nics, wireless) = collect_net_devices();
ax_net::init_network(nics, config);
register_wireless_devices(wireless);
}
#[cfg(all(feature = "net", feature = "fs"))]
fn register_unix_namespace() {
ax_net::unix::register_unix_namespace(crate::unix_ns::AxFsUnixNamespace);
}
#[cfg(all(feature = "net", not(feature = "fs")))]
fn register_unix_namespace() {
}
#[cfg(feature = "net")]
fn parse_network_config() -> ax_net::NetworkConfig {
ax_net::NetworkConfig::default()
}
#[cfg(feature = "net")]
type WirelessDevice = (
alloc::boxed::Box<dyn ax_net::EthernetDriver>,
ax_net::NetConfig,
);
#[cfg(feature = "net")]
fn adapt_net_device(
net: rd_net::Net,
name: &'static str,
irq: Option<ax_driver::BindingIrq>,
nics: &mut alloc::vec::Vec<alloc::boxed::Box<dyn ax_net::EthernetDriver>>,
wireless: &mut alloc::vec::Vec<WirelessDevice>,
) {
let policy = if let Some(ctrl) = net.wifi_control() {
ctrl.set_rx_wake(ax_net::wake_net_task_irq);
ctrl.link_policy()
} else {
None
};
if let Some(handle) = net.wifi_control_handle() {
ax_net::register_wifi_control(name, handle);
}
let irq = resolve_net_irq(name, irq);
let driver = ax_net::RdNetDriver::new(name, net, irq)
.unwrap_or_else(|err| panic!("failed to adapt net device {name}: {err:?}"));
let driver = alloc::boxed::Box::new(driver) as alloc::boxed::Box<dyn ax_net::EthernetDriver>;
match policy {
Some(p) => wireless.push((
driver,
ax_net::NetConfig {
name: name.into(),
ip: p.ip,
prefix_len: p.prefix_len,
dhcp_server_client_ip: p.dhcp_server_client_ip,
dedicated_poll: true,
},
)),
None => nics.push(driver),
}
}
#[cfg(all(feature = "net", feature = "irq"))]
fn resolve_net_irq(name: &str, irq: Option<ax_driver::BindingIrq>) -> Option<irq_framework::IrqId> {
let irq = irq?;
match crate::irq::resolve_binding_irq(irq) {
Ok(id) => Some(id),
Err(err) => {
warn!("failed to resolve net IRQ for {name}: {err:?}");
None
}
}
}
#[cfg(all(feature = "net", not(feature = "irq")))]
fn resolve_net_irq(
_name: &str,
_irq: Option<ax_driver::BindingIrq>,
) -> Option<irq_framework::IrqId> {
None
}
#[cfg(feature = "net")]
fn register_wireless_devices(wireless: alloc::vec::Vec<WirelessDevice>) {
for (driver, config) in wireless {
ax_net::register_device_with_config(driver, config);
}
}
#[cfg(feature = "vsock")]
pub(crate) fn init_vsock() {
if !rdrive::is_initialized() {
ax_net::init_vsock(alloc::vec::Vec::new());
return;
}
let devices = ax_driver::vsock::take_vsock_devices()
.unwrap_or_else(|err| panic!("failed to open vsock devices: {err:?}"));
ax_net::init_vsock(devices);
}
#[cfg(feature = "net")]
fn collect_net_devices() -> (
alloc::vec::Vec<alloc::boxed::Box<dyn ax_net::EthernetDriver>>,
alloc::vec::Vec<WirelessDevice>,
) {
let mut nics = alloc::vec::Vec::new();
let mut wireless = alloc::vec::Vec::new();
if !rdrive::is_initialized() {
return (nics, wireless);
}
for dev in rdrive::get_list::<ax_driver::net::PlatformNetDevice>() {
let (net, name, irq) = ax_driver::net::take_rd_net_device(dev)
.unwrap_or_else(|err| panic!("failed to open net device: {err:?}"));
adapt_net_device(net, name, irq, &mut nics, &mut wireless);
}
(nics, wireless)
}