@@ -35,7 +35,7 @@ use crate::fs::FileSystemError;
3535use crate :: utils;
3636use crate :: utils:: Downcastable ;
3737
38- use crate :: mem:: paging:: VirtAddr ;
38+ use crate :: mem:: paging:: * ;
3939use crate :: utils:: sync:: Mutex ;
4040
4141use uapi:: drm:: * ;
@@ -50,28 +50,33 @@ trait ModeObject: Send + Sync + Downcastable {
5050 // Conversion methods:
5151
5252 /// Converts this mode object into a connector.
53- ///
54- /// # Panics
55- /// * Called on a non-connector mode object.
56- fn as_connector ( & self ) -> Arc < Connector > {
57- utils:: downcast :: < dyn ModeObject , Connector > ( & self . object ( ) ) . unwrap ( )
53+ fn as_connector ( & self ) -> Option < Arc < Connector > > {
54+ utils:: downcast :: < dyn ModeObject , Connector > ( & self . object ( ) )
5855 }
5956
6057 /// Converts this mode object into an encoder.
61- ///
62- /// # Panics
63- /// * Called on a non-encoder mode object.
64- fn as_encoder ( & self ) -> Arc < Encoder > {
65- utils:: downcast :: < dyn ModeObject , Encoder > ( & self . object ( ) ) . unwrap ( )
58+ fn as_encoder ( & self ) -> Option < Arc < Encoder > > {
59+ utils:: downcast :: < dyn ModeObject , Encoder > ( & self . object ( ) )
60+ }
61+
62+ /// Converts this mode object into a CRTC.
63+ fn as_crtc ( & self ) -> Option < Arc < Crtc > > {
64+ utils:: downcast :: < dyn ModeObject , Crtc > ( & self . object ( ) )
65+ }
66+
67+ /// Converts this mode object into a framebuffer.
68+ fn as_framebuffer ( & self ) -> Option < Arc < Framebuffer > > {
69+ utils:: downcast :: < dyn ModeObject , Framebuffer > ( & self . object ( ) )
6670 }
6771}
6872
6973trait DrmDevice : Send + Sync {
7074 /// Returns weather the DRM device supports creating dumb buffers.
7175 fn can_dumb_create ( & self ) -> bool ;
7276
73- fn dumb_create ( & self , width : u32 , height : u32 , bpp : u32 ) -> BufferObject ;
77+ fn dumb_create ( & self , width : u32 , height : u32 , bpp : u32 ) -> ( BufferObject , u32 ) ;
7478 fn framebuffer_create ( & self , buffer_object : & BufferObject , width : u32 , height : u32 , pitch : u32 ) ;
79+ fn commit ( & self , buffer_obj : & BufferObject ) ;
7580
7681 /// Returns tuple containing the minumum dimensions (`xmin`, `ymin`).
7782 fn min_dim ( & self ) -> ( usize , usize ) ;
@@ -84,21 +89,23 @@ trait DrmDevice: Send + Sync {
8489 fn driver_info ( & self ) -> ( & ' static str , & ' static str , & ' static str ) ;
8590}
8691
87- #[ derive( Clone ) ]
92+ #[ derive( Debug , Clone ) ]
8893struct BufferObject {
8994 width : u32 ,
9095 height : u32 ,
9196 size : usize ,
9297 mapping : usize ,
98+ memory : Vec < PhysFrame > ,
9399}
94100
95101impl BufferObject {
96- pub fn new ( width : u32 , height : u32 , size : usize ) -> Self {
102+ pub fn new ( width : u32 , height : u32 , size : usize , memory : Vec < PhysFrame > ) -> Self {
97103 Self {
98104 width,
99105 height,
100106 size,
101- mapping : 0 ,
107+ mapping : usize:: MAX ,
108+ memory,
102109 }
103110 }
104111}
@@ -248,17 +255,18 @@ impl ModeObject for Connector {
248255
249256/// Holds information in relation to the framebuffer; this includes the
250257/// size and pixel format.
251- #[ derive( Default ) ]
252258struct Framebuffer {
253259 sref : Weak < Self > ,
254260 object_id : u32 ,
261+ buffer_obj : BufferObject , // todo: this should be a reference not a clone.
255262}
256263
257264impl Framebuffer {
258- pub fn new ( object_id : u32 ) -> Arc < Self > {
265+ pub fn new ( object_id : u32 , buffer_obj : BufferObject ) -> Arc < Self > {
259266 Arc :: new_cyclic ( |sref| Self {
260267 sref : sref. clone ( ) ,
261268 object_id,
269+ buffer_obj,
262270 } )
263271 }
264272}
@@ -491,12 +499,41 @@ impl INodeInterface for Drm {
491499 Ok ( 0 )
492500 }
493501
502+ DRM_IOCTL_GET_CRTC => {
503+ let struc = VirtAddr :: new ( arg as u64 ) . read_mut :: < DrmModeCrtc > ( ) . unwrap ( ) ;
504+ let _object = self . find_object ( struc. crtc_id ) . unwrap ( ) . as_crtc ( ) . unwrap ( ) ;
505+
506+ log:: warn!( "drm::get_crtc: is a stub!" ) ;
507+ Ok ( 0 )
508+ }
509+
510+ DRM_IOCTL_SET_CRTC => {
511+ let struc = VirtAddr :: new ( arg as u64 ) . read_mut :: < DrmModeCrtc > ( ) . unwrap ( ) ;
512+ let _object = self . find_object ( struc. crtc_id ) . unwrap ( ) . as_crtc ( ) . unwrap ( ) ;
513+
514+ let object = self
515+ . find_object ( struc. fb_id )
516+ . unwrap ( )
517+ . as_framebuffer ( )
518+ . unwrap ( ) ;
519+
520+ self . device . commit ( & object. buffer_obj ) ;
521+ log:: warn!( "drm::set_crtc: is a stub!" ) ;
522+
523+ Ok ( 0 )
524+ }
525+
494526 DRM_IOCTL_GET_ENCODER => {
495527 let struc = VirtAddr :: new ( arg as u64 )
496528 . read_mut :: < DrmModeGetEncoder > ( )
497529 . unwrap ( ) ;
498530
499- let object = self . find_object ( struc. encoder_id ) . unwrap ( ) . as_encoder ( ) ;
531+ let object = self
532+ . find_object ( struc. encoder_id )
533+ . unwrap ( )
534+ . as_encoder ( )
535+ . unwrap ( ) ;
536+
500537 struc. crtc_id = object. current_crtc . id ( ) ;
501538
502539 let mut crtc_mask = 0 ;
@@ -522,7 +559,11 @@ impl INodeInterface for Drm {
522559 . read_mut :: < DrmModeGetConnector > ( )
523560 . unwrap ( ) ;
524561
525- let object = self . find_object ( struc. connector_id ) . unwrap ( ) . as_connector ( ) ;
562+ let object = self
563+ . find_object ( struc. connector_id )
564+ . unwrap ( )
565+ . as_connector ( )
566+ . unwrap ( ) ;
526567
527568 // Fill in the array contaning all of the possible encoders and its length.
528569 let encoder_ids_ptr = struc. encoders_ptr as * mut u32 ;
@@ -566,13 +607,16 @@ impl INodeInterface for Drm {
566607 . read_mut :: < DrmModeCreateDumb > ( )
567608 . unwrap ( ) ;
568609
569- let mut buffer = self
570- . device
571- . dumb_create ( struc. width , struc. height , struc. bpp ) ;
610+ let ( mut buffer, pitch ) =
611+ self . device
612+ . dumb_create ( struc. width , struc. height , struc. bpp ) ;
572613
573614 assert ! ( buffer. size < ( 1usize << 32 ) ) ;
574615
575616 buffer. mapping = self . mapping_alloc . alloc ( ) << 32 ;
617+
618+ struc. pitch = pitch;
619+ struc. size = buffer. size as _ ;
576620 struc. handle = self . create_handle ( buffer) ;
577621
578622 Ok ( 0 )
@@ -587,7 +631,7 @@ impl INodeInterface for Drm {
587631 self . device
588632 . framebuffer_create ( & handle, struc. width , struc. height , struc. pitch ) ;
589633
590- let fb = Framebuffer :: new ( self . allocate_object_id ( ) ) ;
634+ let fb = Framebuffer :: new ( self . allocate_object_id ( ) , handle . clone ( ) ) ;
591635 self . install_framebuffer ( fb. clone ( ) ) ;
592636
593637 struc. fb_id = fb. id ( ) ;
@@ -617,6 +661,22 @@ impl INodeInterface for Drm {
617661 }
618662 }
619663 }
664+
665+ fn mmap (
666+ & self ,
667+ offset : usize ,
668+ _size : usize ,
669+ _flags : aero_syscall:: MMapFlags ,
670+ ) -> fs:: Result < PhysFrame > {
671+ let buffers = self . buffers . lock ( ) ;
672+ let ( _, handle) = buffers
673+ . iter ( )
674+ . find ( |( _, h) | offset <= h. mapping + h. size && offset >= h. mapping )
675+ . unwrap ( ) ;
676+
677+ let index = ( offset - handle. mapping ) / Size4KiB :: SIZE as usize ;
678+ Ok ( handle. memory [ index] )
679+ }
620680}
621681
622682impl devfs:: Device for Drm {
@@ -1032,9 +1092,18 @@ fn make_dmt_modes(max_width: u16, max_height: u16) -> Vec<DrmModeInfo> {
10321092 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC )
10331093 ] ;
10341094
1035- modes
1095+ let mut result = modes
10361096 . iter ( )
10371097 . filter ( |e| e. hdisplay <= max_width && e. vdisplay <= max_height)
10381098 . cloned ( )
1039- . collect :: < Vec < _ > > ( )
1099+ . collect :: < Vec < _ > > ( ) ;
1100+
1101+ // Sort the modes by display size:
1102+ result. sort_by ( |e, f| {
1103+ ( e. hdisplay * e. vdisplay )
1104+ . partial_cmp ( & ( f. hdisplay * f. vdisplay ) )
1105+ . unwrap ( ) // unreachable
1106+ } ) ;
1107+
1108+ result
10401109}
0 commit comments