Skip to content

Commit 53034ec

Browse files
drm: initial implementation DRM_IOCTL_VERSION
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 9220f8b commit 53034ec

File tree

8 files changed

+246
-3
lines changed

8 files changed

+246
-3
lines changed

src/Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/aero_kernel/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ stivale-boot = "0.2.6"
3535
intrusive-collections = "0.9.2"
3636
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
3737
lai = { git = "https://github.com/aero-os/lai-rs" }
38+
uapi = { path = "../uapi" }
3839

3940
[dependencies.vte]
4041
git = "https://github.com/Andy-Python-Programmer/vte"

src/aero_kernel/src/drivers/drm.rs

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,62 @@
1+
/*
2+
* Copyright (C) 2021-2022 The Aero Project Developers.
3+
*
4+
* This file is part of The Aero Project.
5+
*
6+
* Aero is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Aero is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
120
use core::sync::atomic::{AtomicUsize, Ordering};
221

322
use alloc::string::String;
423
use alloc::sync::{Arc, Weak};
524

25+
use crate::fs;
626
use crate::fs::devfs;
727
use crate::fs::inode::INodeInterface;
828
use crate::fs::FileSystem;
929

10-
trait DrmDevice: Send + Sync {}
30+
use crate::mem::paging::VirtAddr;
31+
32+
use uapi::drm::*;
33+
34+
trait DrmDevice: Send + Sync {
35+
/// Returns a tuple containg the driver major, minor and patch level respectively.
36+
fn driver_version(&self) -> (usize, usize, usize);
37+
/// Returns a tuple contaning the driver name, desc and date respectively.
38+
fn driver_info(&self) -> (&'static str, &'static str, &'static str);
39+
}
40+
41+
fn copy_field(buffer: *mut u8, buffer_size: &mut usize, value: &[u8]) {
42+
// do not overflow the user buffer.
43+
let mut copy_len = value.len();
44+
45+
if *buffer_size > value.len() {
46+
copy_len = *buffer_size;
47+
}
48+
49+
// let userspace know exact length of driver value (which could be
50+
// larger than the userspace-supplied buffer).
51+
*buffer_size = value.len();
52+
53+
// finally, try filling in the user buffer.
54+
if copy_len != 0 && !buffer.is_null() {
55+
unsafe {
56+
core::ptr::copy_nonoverlapping(value.as_ptr(), buffer, copy_len);
57+
}
58+
}
59+
}
1160

1261
static DRM_CARD_ID: AtomicUsize = AtomicUsize::new(0);
1362

@@ -34,7 +83,32 @@ impl Drm {
3483
}
3584
}
3685

37-
impl INodeInterface for Drm {}
86+
impl INodeInterface for Drm {
87+
// The DRM is accessed using IOCTLs on a device representing a graphics
88+
// card.
89+
fn ioctl(&self, command: usize, arg: usize) -> fs::Result<usize> {
90+
match command {
91+
DRM_IOCTL_VERSION => {
92+
let struc = VirtAddr::new(arg as u64).read_mut::<DrmVersion>().unwrap();
93+
94+
let (major, minor, patch_level) = self.device.driver_version();
95+
let (name, desc, date) = self.device.driver_info();
96+
97+
struc.version_major = major as _;
98+
struc.version_minor = minor as _;
99+
struc.version_patch_level = patch_level as _;
100+
101+
copy_field(struc.name, &mut struc.name_len, name.as_bytes());
102+
copy_field(struc.desc, &mut struc.desc_len, desc.as_bytes());
103+
copy_field(struc.date, &mut struc.date_len, date.as_bytes());
104+
105+
Ok(0)
106+
}
107+
108+
_ => unimplemented!(),
109+
}
110+
}
111+
}
38112

39113
impl devfs::Device for Drm {
40114
fn device_marker(&self) -> usize {
@@ -52,7 +126,15 @@ impl devfs::Device for Drm {
52126

53127
struct RawFramebuffer {}
54128

55-
impl DrmDevice for RawFramebuffer {}
129+
impl DrmDevice for RawFramebuffer {
130+
fn driver_version(&self) -> (usize, usize, usize) {
131+
(0, 0, 1)
132+
}
133+
134+
fn driver_info(&self) -> (&'static str, &'static str, &'static str) {
135+
("rawfb_gpu", "rawfb gpu", "0")
136+
}
137+
}
56138

57139
fn init() {
58140
let dri = devfs::DEV_FILESYSTEM

src/aero_kernel/src/drivers/lai.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
/*
2+
* Copyright (C) 2021-2022 The Aero Project Developers.
3+
*
4+
* This file is part of The Aero Project.
5+
*
6+
* Aero is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Aero is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
120
use alloc::sync::Arc;
221

322
use crate::acpi::aml;

src/uapi/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "uapi"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Anhad Singh <[email protected]>"]
6+
7+
[dependencies]

src/uapi/src/drm.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
3+
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
4+
* Copyright (C) 2021-2022 The Aero Project Developers.
5+
*
6+
* All rights reserved.
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a
9+
* copy of this software and associated documentation files (the "Software"),
10+
* to deal in the Software without restriction, including without limitation
11+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
12+
* and/or sell copies of the Software, and to permit persons to whom the
13+
* Software is furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice (including the next
16+
* paragraph) shall be included in all copies or substantial portions of the
17+
* Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22+
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23+
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25+
* OTHER DEALINGS IN THE SOFTWARE.
26+
*/
27+
28+
use crate::ioctl;
29+
use core::ffi;
30+
31+
pub const DRM_IOCTL_BASE: usize = 'd' as usize;
32+
33+
// Functions to generate the IOCTl numbers:
34+
#[inline]
35+
pub const fn drm_io(nr: usize) -> usize {
36+
ioctl::io(DRM_IOCTL_BASE, nr)
37+
}
38+
39+
#[inline]
40+
pub const fn drm_ior<T>(nr: usize) -> usize {
41+
ioctl::ior::<T>(DRM_IOCTL_BASE, nr)
42+
}
43+
44+
#[inline]
45+
pub const fn drm_iow<T>(nr: usize) -> usize {
46+
ioctl::iow::<T>(DRM_IOCTL_BASE, nr)
47+
}
48+
49+
#[inline]
50+
pub const fn drm_iowr<T>(nr: usize) -> usize {
51+
ioctl::iowr::<T>(DRM_IOCTL_BASE, nr)
52+
}
53+
54+
// DRM structures:
55+
#[repr(C)]
56+
pub struct DrmVersion {
57+
pub version_major: ffi::c_int,
58+
pub version_minor: ffi::c_int,
59+
pub version_patch_level: ffi::c_int,
60+
61+
pub name_len: usize,
62+
pub name: *mut u8, // name of the driver
63+
64+
pub date_len: usize,
65+
pub date: *mut u8, // buffer to hold date
66+
67+
pub desc_len: usize,
68+
pub desc: *mut u8, // buffer to hold desc
69+
}
70+
71+
// DRM IOCTL constants:
72+
pub const DRM_IOCTL_VERSION: usize = drm_iowr::<DrmVersion>(0x00);

src/uapi/src/ioctl.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* The generic ioctl numbering scheme doesn't really enforce
3+
* a type field. De facto, however, the top 8 bits of the lower 16
4+
* bits are indeed used as a type field, so we might just as well make
5+
* this explicit here. Please be sure to use the decoding functions
6+
* below from now on.
7+
*/
8+
pub const IOC_NRBITS: usize = 8;
9+
pub const IOC_TYPEBITS: usize = 8;
10+
pub const IOC_SIZEBITS: usize = 14;
11+
12+
pub const IOC_NRSHIFT: usize = 0;
13+
pub const IOC_TYPESHIFT: usize = IOC_NRSHIFT + IOC_NRBITS;
14+
pub const IOC_SIZESHIFT: usize = IOC_TYPESHIFT + IOC_TYPEBITS;
15+
pub const IOC_DIRSHIFT: usize = IOC_SIZESHIFT + IOC_SIZEBITS;
16+
17+
pub const IOC_NONE: usize = 0;
18+
pub const IOC_WRITE: usize = 1;
19+
pub const IOC_READ: usize = 2;
20+
21+
pub const fn ioc(dir: usize, ty: usize, nr: usize, size: usize) -> usize {
22+
((dir) << IOC_DIRSHIFT)
23+
| ((ty) << IOC_TYPESHIFT)
24+
| ((nr) << IOC_NRSHIFT)
25+
| ((size) << IOC_SIZESHIFT)
26+
}
27+
28+
/*
29+
* Used to create numbers.
30+
*
31+
* NOTE: `iow` means userland is writing and kernel is reading. `ior`
32+
* means userland is reading and kernel is writing.
33+
*/
34+
#[inline]
35+
pub const fn io(typ: usize, nr: usize) -> usize {
36+
ioc(IOC_NONE, typ, nr, 0)
37+
}
38+
39+
#[inline]
40+
pub const fn ior<T>(typ: usize, nr: usize) -> usize {
41+
ioc(IOC_READ, typ, nr, core::mem::size_of::<T>())
42+
}
43+
44+
#[inline]
45+
pub const fn iow<T>(typ: usize, nr: usize) -> usize {
46+
ioc(IOC_WRITE, typ, nr, core::mem::size_of::<T>())
47+
}
48+
49+
#[inline]
50+
pub const fn iowr<T>(typ: usize, nr: usize) -> usize {
51+
ioc(IOC_READ | IOC_WRITE, typ, nr, core::mem::size_of::<T>())
52+
}

src/uapi/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![feature(core_ffi_c)]
2+
#![no_std]
3+
4+
pub mod drm;
5+
pub mod ioctl;

0 commit comments

Comments
 (0)