@@ -25,22 +25,37 @@ use alloc::string::String;
2525use alloc:: sync:: { Arc , Weak } ;
2626use alloc:: vec:: Vec ;
2727use bit_field:: BitField ;
28+ use hashbrown:: HashMap ;
2829
2930use crate :: fs;
3031use crate :: fs:: devfs;
3132use crate :: fs:: inode:: INodeInterface ;
3233use crate :: fs:: FileSystemError ;
3334
35+ use crate :: utils;
36+ use crate :: utils:: Downcastable ;
37+
3438use crate :: mem:: paging:: VirtAddr ;
3539use crate :: utils:: sync:: Mutex ;
3640
3741use uapi:: drm:: * ;
3842
3943/// Represents modset objects visible to userspace; this includes connectors,
4044/// CRTCs, encoders, frambuffers and planes.
41- trait ModeObject : Send + Sync {
45+ trait ModeObject : Send + Sync + Downcastable {
4246 /// Returns the mode object's ID.
4347 fn id ( & self ) -> u32 ;
48+ fn object ( & self ) -> Arc < dyn ModeObject > ;
49+
50+ // Conversion methods:
51+
52+ /// 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 ( )
58+ }
4459}
4560
4661trait DrmDevice : Send + Sync {
@@ -80,51 +95,92 @@ trait DrmDevice: Send + Sync {
8095// Plane -> CRTCs -> Encoder -> Connector
8196// |============ LCD connector
8297
83- #[ derive( Default ) ]
8498struct Crtc {
85- id : u32 ,
99+ sref : Weak < Self > ,
100+
101+ object_id : u32 ,
102+ index : u32 ,
103+ }
104+
105+ impl Crtc {
106+ pub fn new ( drm : & Drm , object_id : u32 ) -> Arc < Self > {
107+ Arc :: new_cyclic ( |sref| Self {
108+ sref : sref. clone ( ) ,
109+
110+ object_id,
111+ index : drm. crtcs . lock ( ) . len ( ) as _ ,
112+ } )
113+ }
86114}
87115
88116impl ModeObject for Crtc {
89117 fn id ( & self ) -> u32 {
90- self . id
118+ self . object_id
119+ }
120+
121+ fn object ( & self ) -> Arc < dyn ModeObject > {
122+ self . sref . upgrade ( ) . unwrap ( ) . clone ( )
91123 }
92124}
93125
94- #[ derive( Default ) ]
95126struct Encoder {
96- id : u32 ,
127+ sref : Weak < Self > ,
128+ object_id : u32 ,
129+ // index: u32,
97130}
98131
99132impl ModeObject for Encoder {
100133 fn id ( & self ) -> u32 {
101- self . id
134+ self . object_id
135+ }
136+
137+ fn object ( & self ) -> Arc < dyn ModeObject > {
138+ self . sref . upgrade ( ) . unwrap ( ) . clone ( )
102139 }
103140}
104141
105142/// Represents a display connector; transmits the signal to the display, detects
106143/// display connection, removal and exposes the display's supported modes.
107- #[ derive( Default ) ]
108144struct Connector {
109- id : u32 ,
145+ sref : Weak < Self > ,
146+
147+ object_id : u32 ,
148+ }
149+
150+ impl Connector {
151+ pub fn new ( object_id : u32 ) -> Arc < Self > {
152+ Arc :: new_cyclic ( |sref| Self {
153+ sref : sref. clone ( ) ,
154+ object_id,
155+ } )
156+ }
110157}
111158
112159impl ModeObject for Connector {
113160 fn id ( & self ) -> u32 {
114- self . id
161+ self . object_id
162+ }
163+
164+ fn object ( & self ) -> Arc < dyn ModeObject > {
165+ self . sref . upgrade ( ) . unwrap ( ) . clone ( )
115166 }
116167}
117168
118169/// Holds information in relation to the framebuffer; this includes the
119170/// size and pixel format.
120171#[ derive( Default ) ]
121172struct Framebuffer {
122- id : u32 ,
173+ sref : Weak < Self > ,
174+ object_id : u32 ,
123175}
124176
125177impl ModeObject for Framebuffer {
126178 fn id ( & self ) -> u32 {
127- self . id
179+ self . object_id
180+ }
181+
182+ fn object ( & self ) -> Arc < dyn ModeObject > {
183+ self . sref . upgrade ( ) . unwrap ( ) . clone ( )
128184 }
129185}
130186
@@ -150,6 +206,18 @@ fn copy_field<T>(buffer: *mut T, buffer_size: &mut usize, value: &[T]) {
150206
151207static DRM_CARD_ID : AtomicUsize = AtomicUsize :: new ( 0 ) ;
152208
209+ struct IdAllocator ( AtomicUsize ) ;
210+
211+ impl IdAllocator {
212+ pub fn new ( ) -> Self {
213+ Self ( AtomicUsize :: new ( 0 ) )
214+ }
215+
216+ pub fn alloc ( & self ) -> usize {
217+ self . 0 . fetch_add ( 1 , Ordering :: SeqCst )
218+ }
219+ }
220+
153221/// The direct rendering manager (DRM) exposes the GPUs through the device filesystem. Each
154222/// GPU detected by the DRM is referred to as a DRM device and a device file (`/dev/dri/cardX`)
155223/// is created to interface with it; where X is a sequential number.
@@ -160,11 +228,14 @@ struct Drm {
160228 card_id : usize ,
161229 device : Arc < dyn DrmDevice > ,
162230
231+ id_alloc : IdAllocator ,
232+ mode_objs : Mutex < HashMap < u32 , Arc < dyn ModeObject > > > ,
233+
163234 // All of the mode objects:
164- crtcs : Mutex < Vec < Crtc > > ,
165- encoders : Mutex < Vec < Encoder > > ,
166- connectors : Mutex < Vec < Connector > > ,
167- framebuffers : Mutex < Vec < Framebuffer > > ,
235+ crtcs : Mutex < Vec < Arc < Crtc > > > ,
236+ encoders : Mutex < Vec < Arc < Encoder > > > ,
237+ connectors : Mutex < Vec < Arc < Connector > > > ,
238+ framebuffers : Mutex < Vec < Arc < Framebuffer > > > ,
168239}
169240
170241impl Drm {
@@ -176,6 +247,9 @@ impl Drm {
176247 card_id : DRM_CARD_ID . fetch_add ( 1 , Ordering :: SeqCst ) ,
177248 device,
178249
250+ id_alloc : IdAllocator :: new ( ) ,
251+ mode_objs : Mutex :: new ( HashMap :: new ( ) ) ,
252+
179253 crtcs : Mutex :: new ( alloc:: vec![ ] ) ,
180254 encoders : Mutex :: new ( alloc:: vec![ ] ) ,
181255 connectors : Mutex :: new ( alloc:: vec![ ] ) ,
@@ -184,19 +258,27 @@ impl Drm {
184258 }
185259
186260 /// Installs and initializes the CRTC identifier.
187- pub fn install_crtc ( & self , mut crtc : Crtc ) {
188- let mut crtcs = self . crtcs . lock ( ) ;
189-
190- crtc. id = crtcs. len ( ) as u32 ;
191- crtcs. push ( crtc) ;
261+ pub fn install_crtc ( & self , crtc : Arc < Crtc > ) {
262+ self . crtcs . lock ( ) . push ( crtc. clone ( ) ) ;
263+ self . install_object ( crtc)
192264 }
193265
194266 /// Installs and initializes the connector identifier.
195- pub fn install_connector ( & self , mut connector : Connector ) {
196- let mut connectors = self . connectors . lock ( ) ;
267+ pub fn install_connector ( & self , connector : Arc < Connector > ) {
268+ self . connectors . lock ( ) . push ( connector. clone ( ) ) ;
269+ self . install_object ( connector)
270+ }
271+
272+ pub fn allocate_object_id ( & self ) -> u32 {
273+ self . id_alloc . alloc ( ) as _
274+ }
197275
198- connector. id = connectors. len ( ) as u32 ;
199- connectors. push ( connector) ;
276+ fn install_object ( & self , object : Arc < dyn ModeObject > ) {
277+ self . mode_objs . lock ( ) . insert ( object. id ( ) , object. clone ( ) ) ;
278+ }
279+
280+ fn find_object ( & self , id : u32 ) -> Option < Arc < dyn ModeObject > > {
281+ self . mode_objs . lock ( ) . get ( & id) . map ( |obj| obj. clone ( ) )
200282 }
201283}
202284
@@ -250,7 +332,7 @@ impl INodeInterface for Drm {
250332 /// Copies the mode object IDs into the user provided buffer. For saftey, checkout
251333 /// the [`copy_field`] function.
252334 fn copy_mode_obj_id < T : ModeObject > (
253- obj : & Mutex < Vec < T > > ,
335+ obj : & Mutex < Vec < Arc < T > > > ,
254336 buffer : * mut u32 ,
255337 buffer_size : & mut u32 ,
256338 ) {
@@ -294,6 +376,8 @@ impl INodeInterface for Drm {
294376 . read_mut :: < DrmModeGetConnector > ( )
295377 . unwrap ( ) ;
296378
379+ let object = self . find_object ( struc. connector_id ) . unwrap ( ) . as_connector ( ) ;
380+
297381 Ok ( 0 )
298382 }
299383
0 commit comments