starnix_modules_magma/
init.rs1use crate::{GpuDeviceConfig, MagmaFile, get_magma_params};
6use anyhow::{Error, anyhow, bail};
7use bstr::BString;
8use starnix_core::device::DeviceOps;
9use starnix_core::task::{ArgNameAndValue, CurrentTask, Kernel};
10use starnix_core::vfs::{FileOps, NamespaceNode};
11
12use starnix_uapi::device_id::DeviceId;
13use starnix_uapi::errors::Errno;
14use starnix_uapi::open_flags::OpenFlags;
15
16const VENDOR_ARM: u16 = 0x13B5;
17const VENDOR_INTEL: u16 = 0x8086;
18
19fn parse_supported_vendors(args: &[&str]) -> Result<Vec<u16>, Error> {
20 let mut supported_vendors: Option<Vec<u16>> = None;
21 for &arg in args {
22 match ArgNameAndValue::from(arg) {
23 ArgNameAndValue { name: "supported_vendors", value: Some(vendors_arg) } => {
24 let vendors = vendors_arg
25 .split(',')
26 .map(|s| {
27 let trimmed =
28 s.strip_prefix("0x").or_else(|| s.strip_prefix("0X")).unwrap_or(s);
29 u16::from_str_radix(trimmed, 16).map_err(|_| {
30 anyhow!(
31 "supported vendors must be comma-separated hex IDs: 0x1234[,0xabcd]"
32 )
33 })
34 })
35 .collect::<Result<Vec<u16>, Error>>()?;
36 supported_vendors = Some(vendors);
37 }
38 _ => bail!("invalid magma argument: {arg}"),
39 }
40 }
41 Ok(supported_vendors.unwrap_or_else(|| vec![VENDOR_ARM, VENDOR_INTEL]))
42}
43
44pub fn validate_args(args: &[&str]) -> Result<(), Error> {
46 parse_supported_vendors(args).map(|_| ())
47}
48
49pub fn cmdline_params(args: &[&str]) -> Result<BString, Error> {
51 let vendors = parse_supported_vendors(args)?;
52 Ok(get_magma_params(&vendors))
53}
54
55pub fn module_init(kernel: &Kernel, args: &[&str]) -> Result<(), Error> {
57 let supported_vendors = parse_supported_vendors(args)?;
58 let registry = &kernel.device_registry;
59 let builder = MagmaDeviceBuilder { supported_vendors };
60
61 registry
62 .add_dyn_device(kernel, "magma0".into(), registry.objects.starnix_class(), builder)
63 .expect("can add magma0");
64 crate::gpu_class_directory::register_gpu_devices(kernel, GpuDeviceConfig::default());
65 Ok(())
66}
67
68#[derive(Clone)]
69struct MagmaDeviceBuilder {
70 supported_vendors: Vec<u16>,
71}
72
73impl DeviceOps for MagmaDeviceBuilder {
74 fn open(
75 &self,
76 current_task: &CurrentTask,
77 id: DeviceId,
78 node: &NamespaceNode,
79 flags: OpenFlags,
80 ) -> Result<Box<dyn FileOps>, Errno> {
81 MagmaFile::new_file(
82 current_task,
83 id,
84 &node.entry.node,
85 flags,
86 self.supported_vendors.clone(),
87 )
88 }
89}