Skip to content

Commit a720000

Browse files
drm: keep track of the mode objs in map
Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
1 parent 6a32810 commit a720000

File tree

2 files changed

+114
-30
lines changed

2 files changed

+114
-30
lines changed

src/aero_kernel/src/drivers/drm/mod.rs

Lines changed: 110 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,37 @@ use alloc::string::String;
2525
use alloc::sync::{Arc, Weak};
2626
use alloc::vec::Vec;
2727
use bit_field::BitField;
28+
use hashbrown::HashMap;
2829

2930
use crate::fs;
3031
use crate::fs::devfs;
3132
use crate::fs::inode::INodeInterface;
3233
use crate::fs::FileSystemError;
3334

35+
use crate::utils;
36+
use crate::utils::Downcastable;
37+
3438
use crate::mem::paging::VirtAddr;
3539
use crate::utils::sync::Mutex;
3640

3741
use 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

4661
trait DrmDevice: Send + Sync {
@@ -80,51 +95,92 @@ trait DrmDevice: Send + Sync {
8095
// Plane -> CRTCs -> Encoder -> Connector
8196
// |============ LCD connector
8297

83-
#[derive(Default)]
8498
struct 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

88116
impl 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)]
95126
struct Encoder {
96-
id: u32,
127+
sref: Weak<Self>,
128+
object_id: u32,
129+
// index: u32,
97130
}
98131

99132
impl 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)]
108144
struct 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

112159
impl 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)]
121172
struct Framebuffer {
122-
id: u32,
173+
sref: Weak<Self>,
174+
object_id: u32,
123175
}
124176

125177
impl 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

151207
static 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

170241
impl 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

src/aero_kernel/src/drivers/drm/rawfb.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,17 @@ impl DrmDevice for RawFramebuffer {
5252
}
5353

5454
fn init() {
55-
let crtc = Crtc::default();
56-
let connector = Connector::default();
55+
let rfb = Drm::new(Arc::new(RawFramebuffer {}));
56+
57+
let crtc = Crtc::new(&rfb, rfb.allocate_object_id());
58+
let connector = Connector::new(rfb.allocate_object_id());
5759

5860
let dri = devfs::DEV_FILESYSTEM
5961
.root_dir()
6062
.inode()
6163
.mkdir("dri")
6264
.expect("devfs: failed to create DRM directory");
6365

64-
let rfb = Drm::new(Arc::new(RawFramebuffer {}));
65-
6666
rfb.install_crtc(crtc);
6767
rfb.install_connector(connector);
6868

0 commit comments

Comments
 (0)