From c4ffcedbd09257c0897e4b63f5b03091e9501e97 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 15 Dec 2025 23:34:44 +0100 Subject: [PATCH] Port remaining drm ioctls to the new infrastructure --- src/header/sys_ioctl/redox/drm.rs | 168 ++------------------- src/header/sys_ioctl/redox/graphics_ipc.rs | 112 +++++++++++++- 2 files changed, 121 insertions(+), 159 deletions(-) diff --git a/src/header/sys_ioctl/redox/drm.rs b/src/header/sys_ioctl/redox/drm.rs index 07218e19cd..01b0d5afbf 100644 --- a/src/header/sys_ioctl/redox/drm.rs +++ b/src/header/sys_ioctl/redox/drm.rs @@ -125,169 +125,23 @@ impl Dev { } } -unsafe fn mode_card_res(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut res = buf.read::()?; - let count = dev.display_count()?; - let mut conn_ids = Vec::with_capacity(count); - let mut crtc_ids = Vec::with_capacity(count); - let mut enc_ids = Vec::with_capacity(count); - let mut fb_ids = Vec::with_capacity(count); - for i in 0..(count as u32) { - conn_ids.push(conn_id(i)); - crtc_ids.push(crtc_id(i)); - enc_ids.push(enc_id(i)); - fb_ids.push(fb_id(i)); - } - res.count_fbs = copy_array(&fb_ids, res.fb_id_ptr as *mut u32, res.count_fbs as usize) as u32; - res.count_crtcs = copy_array( - &crtc_ids, - res.crtc_id_ptr as *mut u32, - res.count_crtcs as usize, - ) as u32; - res.count_connectors = copy_array( - &conn_ids, - res.connector_id_ptr as *mut u32, - res.count_connectors as usize, - ) as u32; - res.count_encoders = copy_array( - &enc_ids, - res.encoder_id_ptr as *mut u32, - res.count_encoders as usize, - ) as u32; - res.min_width = 0; - res.max_width = 16384; - res.min_height = 0; - res.max_height = 16384; - buf.write(res)?; - Ok(0) -} - -unsafe fn mode_get_crtc(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut crtc = buf.read::()?; - let i = id_index(crtc.crtc_id); - let (width, height) = dev.display_size(i as usize)?; - //TOOD: connectors - crtc.fb_id = fb_id(i); - crtc.x = 0; - crtc.y = 0; - crtc.gamma_size = 0; - crtc.mode_valid = 0; - //TODO: mode - crtc.mode = Default::default(); - buf.write(crtc)?; - Ok(0) -} - -unsafe fn mode_get_encoder(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut enc = buf.read::()?; - let i = id_index(enc.encoder_id); - let (width, height) = dev.display_size(i as usize)?; - enc.crtc_id = crtc_id(i); - enc.possible_crtcs = (1 << i); - enc.possible_clones = (1 << i); - buf.write(enc)?; - Ok(0) -} - -unsafe fn mode_get_connector(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut conn = buf.read::()?; - let i = id_index(conn.connector_id); - let (width, height) = dev.display_size(i as usize)?; - conn.count_modes = 0; - conn.count_props = 0; - conn.count_encoders = copy_array( - &[enc_id(i)], - conn.encoders_ptr as *mut u32, - conn.count_encoders as usize, - ) as u32; - buf.write(conn)?; - Ok(0) -} - -unsafe fn mode_get_fb(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut fb = buf.read::()?; - let i = id_index(fb.fb_id); - let (width, height) = dev.display_size(i as usize)?; - fb.width = width; - fb.height = height; - fb.pitch = width * 4; //TODO: stride - fb.bpp = 32; - fb.depth = 24; - fb.handle = fb_handle_id(i); - buf.write(fb)?; - Ok(0) -} - -unsafe fn mode_get_plane_res(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut res = buf.read::()?; - let count = dev.display_count()?; - let mut ids = Vec::with_capacity(count); - for i in 0..(count as u32) { - ids.push(plane_id(i)); - } - res.count_planes = copy_array( - &ids, - res.plane_id_ptr as *mut u32, - res.count_planes as usize, - ) as u32; - buf.write(res)?; - Ok(0) -} - -unsafe fn mode_get_plane(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut plane = buf.read::()?; - let i = id_index(plane.plane_id); - let (width, height) = dev.display_size(i as usize)?; - plane.crtc_id = crtc_id(i); - plane.fb_id = fb_id(i); - plane.possible_crtcs = (1 << i); - plane.count_format_types = copy_array( - &[DRM_FORMAT_ARGB8888], - plane.format_type_ptr as *mut u32, - plane.count_format_types as usize, - ) as u32; - buf.write(plane)?; - Ok(0) -} - -unsafe fn mode_obj_get_properties(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut props = buf.read::()?; - //TODO - props.count_props = 0; - buf.write(props)?; - Ok(0) -} - -unsafe fn mode_get_fb2(dev: Dev, mut buf: IoctlBuffer) -> Result { - let mut fb = buf.read::()?; - let i = id_index(fb.fb_id); - let (width, height) = dev.display_size(i as usize)?; - fb.width = width; - fb.height = height; - fb.pixel_format = DRM_FORMAT_ARGB8888; - fb.handles[0] = fb_handle_id(i); - fb.pitches[0] = width * 4; - fb.offsets[0] = 0; - fb.modifier[0] = 0; - buf.write(fb)?; - Ok(0) -} - pub(super) unsafe fn ioctl(fd: c_int, func: u8, buf: IoctlBuffer) -> Result { let dev = Dev::new(fd)?; match func { 0x00 => dev.read_write_ioctl::(buf, ipc::VERSION), 0x0C => dev.read_write_ioctl::(buf, ipc::GET_CAP), 0x0D => dev.write_ioctl::(buf, ipc::SET_CLIENT_CAP), - 0xA0 => mode_card_res(dev, buf), - 0xA1 => mode_get_crtc(dev, buf), - 0xA6 => mode_get_encoder(dev, buf), - 0xA7 => mode_get_connector(dev, buf), - 0xAD => mode_get_fb(dev, buf), - 0xB5 => mode_get_plane_res(dev, buf), - 0xB6 => mode_get_plane(dev, buf), - 0xB9 => mode_obj_get_properties(dev, buf), - 0xCE => mode_get_fb2(dev, buf), + 0xA0 => dev.read_write_ioctl::(buf, ipc::MODE_CARD_RES), + 0xA1 => dev.read_write_ioctl::(buf, ipc::MODE_GET_CRTC), + 0xA6 => dev.read_write_ioctl::(buf, ipc::MODE_GET_ENCODER), + 0xA7 => dev.read_write_ioctl::(buf, ipc::MODE_GET_CONNECTOR), + 0xAD => dev.read_write_ioctl::(buf, ipc::MODE_GET_FB), + 0xB5 => dev.read_write_ioctl::(buf, ipc::MODE_GET_PLANE_RES), + 0xB6 => dev.read_write_ioctl::(buf, ipc::MODE_GET_PLANE), + 0xB9 => { + dev.read_write_ioctl::(buf, ipc::MODE_OBJ_GET_PROPERTIES) + } + 0xCE => dev.read_write_ioctl::(buf, ipc::MODE_GET_FB2), _ => { eprintln!("unimplemented DRM ioctl({}, 0x{:02x}, {:?})", fd, func, buf); Err(Errno(EINVAL)) diff --git a/src/header/sys_ioctl/redox/graphics_ipc.rs b/src/header/sys_ioctl/redox/graphics_ipc.rs index c37017845d..86938a053d 100644 --- a/src/header/sys_ioctl/redox/graphics_ipc.rs +++ b/src/header/sys_ioctl/redox/graphics_ipc.rs @@ -44,7 +44,7 @@ macro_rules! define_ioctl_data { ); }; (struct $ioctl_ty:ident, $mem_ty:ident { - $field:ident: $ty:ty [array<$el:ident, $counted_by:ident>], + $field:ident: $ty:ty [array<$el:ty, $counted_by:ident>], $($rest:tt)* } => ($($ioctl_fields:tt)*), @@ -60,7 +60,7 @@ macro_rules! define_ioctl_data { }; (struct $ioctl_ty:ident, $mem_ty:ident {} => ($($ioctl_field:ident: $ioctl_field_ty:ty,)*), - ($($counted_field:ident: $counted_ty:ty [array<$el:ident, $counted_by:ident>],)*), + ($($counted_field:ident: $counted_ty:ty [array<$el:ty, $counted_by:ident>],)*), ($($noncounted_field:ident: $noncounted_ty:ty,)*) ) => { pub use drm_sys::$ioctl_ty; @@ -236,6 +236,114 @@ define_ioctl_data! { } } +pub const MODE_GET_CRTC: u64 = 0xA1; +define_ioctl_data! { + struct drm_mode_crtc, DrmModeCrtc { + set_connectors_ptr: u64, + count_connectors: u32, + crtc_id: u32, + fb_id: u32, + x: u32, + y: u32, + gamma_size: u32, + mode_valid: u32, + mode: drm_sys::drm_mode_modeinfo, + } +} + +pub const MODE_GET_ENCODER: u64 = 0xA6; +define_ioctl_data! { + struct drm_mode_get_encoder, DrmModeGetEncoder { + encoder_id: u32, + encoder_type: u32, + crtc_id: u32, + possible_crtcs: u32, + possible_clones: u32, + } +} + +pub const MODE_GET_CONNECTOR: u64 = 0xA7; +define_ioctl_data! { + struct drm_mode_get_connector, DrmModeGetConnector { + encoders_ptr: u64 [array], + modes_ptr: u64 [array], + props_ptr: u64 [array], + prop_values_ptr: u64 [array], + count_modes: u32, + count_props: u32, + count_encoders: u32, + encoder_id: u32, + connector_id: u32, + connector_type: u32, + connector_type_id: u32, + connection: u32, + mm_width: u32, + mm_height: u32, + subpixel: u32, + pad: u32, + } +} + +pub const MODE_GET_FB: u64 = 0xAD; +define_ioctl_data! { + struct drm_mode_fb_cmd, DrmModeFbCmd { + fb_id: u32, + width: u32, + height: u32, + pitch: u32, + bpp: u32, + depth: u32, + handle: u32, + } +} + +pub const MODE_GET_PLANE_RES: u64 = 0xB5; +define_ioctl_data! { + struct drm_mode_get_plane_res, DrmModeGetPlaneRes { + plane_id_ptr: u64 [array], + count_planes: u32, + } +} + +pub const MODE_GET_PLANE: u64 = 0xB6; +define_ioctl_data! { + struct drm_mode_get_plane, DrmModeGetPlane { + plane_id: u32, + crtc_id: u32, + fb_id: u32, + possible_crtcs: u32, + gamma_size: u32, + count_format_types: u32, + format_type_ptr: u64 [array], + } +} + +pub const MODE_OBJ_GET_PROPERTIES: u64 = 0xB9; +define_ioctl_data! { + struct drm_mode_obj_get_properties, DrmModeObjGetProperties { + props_ptr: u64 [array], + prop_values_ptr: u64 [array], + count_props: u32, + obj_id: u32, + obj_type: u32, + } +} + +pub const MODE_GET_FB2: u64 = 0xCE; +define_ioctl_data! { + struct drm_mode_fb_cmd2, DrmModeFbCmd2 { + fb_id: u32, + width: u32, + height: u32, + pixel_format: u32, + flags: u32, + handles: [u32; 4], + pitches: [u32; 4], + offsets: [u32; 4], + modifier: [u64; 4], + } +} + // FIXME replace these with proper drm interfaces pub const DISPLAY_COUNT: u64 = 1; #[repr(C, packed)]