libdrm_amdgpu_sys/amdgpu/
vbios.rs1use crate::AMDGPU::*;
2use crate::*;
3
4use core::mem::{size_of, MaybeUninit};
5use core::ptr;
6
7use bindings::{AMDGPU_INFO_VBIOS, DRM_AMDGPU_INFO, drm_amdgpu_info};
8
9#[derive(Debug, Clone)]
11pub struct VbiosInfo {
12 pub name: String,
13 pub pn: String,
14 pub ver: String,
15 pub date: String,
16 pub size: u32,
17}
18
19impl DeviceHandle {
20 pub fn get_vbios_info(&self) -> Result<VbiosInfo, i32> {
21 let vbios = self.vbios_info()?;
22 let size = self.vbios_size()?;
23
24 let [name, pn, ver, date] = [
25 vbios.name.to_vec(),
26 vbios.vbios_pn.to_vec(),
27 vbios.vbios_ver_str.to_vec(),
28 vbios.date.to_vec(),
29 ]
30 .map(|v| {
31 if let Some(index) = v.iter().position(|&x| x == 0) {
32 String::from_utf8(v.get(..index).unwrap_or_default().to_vec())
33 } else {
34 String::from_utf8(v)
35 }.unwrap_or_default()
36 });
37
38 Ok(VbiosInfo { name, pn, ver, date, size })
39 }
40
41 unsafe fn query_vbios<T>(
42 &self,
43 info_id: ::core::ffi::c_uint,
44 ) -> Result<T, i32> { unsafe {
45 #[cfg(not(feature = "dynamic_loading"))]
46 let func = bindings::drmCommandWrite;
47 #[cfg(feature = "dynamic_loading")]
48 let func = self.libdrm.drmCommandWrite;
49
50 let mut vbios: MaybeUninit<T> = MaybeUninit::zeroed();
51 let mut device_info: MaybeUninit<drm_amdgpu_info> = MaybeUninit::zeroed();
52
53 {
54 let ptr = device_info.as_mut_ptr();
55
56 ptr::addr_of_mut!((*ptr).return_pointer).write(vbios.as_mut_ptr() as u64);
57 ptr::addr_of_mut!((*ptr).return_size).write(size_of::<T>() as u32);
58 ptr::addr_of_mut!((*ptr).query).write(AMDGPU_INFO_VBIOS);
59
60 ptr::addr_of_mut!((*ptr).__bindgen_anon_1.vbios_info.type_).write(info_id);
61 }
62
63 let r = func(
64 self.fd,
65 DRM_AMDGPU_INFO as ::core::ffi::c_ulong,
66 device_info.as_mut_ptr() as *mut ::core::ffi::c_void,
67 size_of::<drm_amdgpu_info>() as ::core::ffi::c_ulong,
68 );
69
70 let (_, vbios) = (device_info.assume_init(), vbios.assume_init());
71
72 query_error!(r);
73
74 Ok(vbios)
75 }}
76
77 pub fn vbios_info(&self) -> Result<bindings::drm_amdgpu_info_vbios, i32> {
78 use bindings::AMDGPU_INFO_VBIOS_INFO;
79
80 unsafe { Self::query_vbios(self, AMDGPU_INFO_VBIOS_INFO) }
81 }
82
83 pub fn vbios_size(&self) -> Result<u32, i32> {
84 use bindings::AMDGPU_INFO_VBIOS_SIZE;
85
86 unsafe { Self::query_vbios(self, AMDGPU_INFO_VBIOS_SIZE) }
87 }
88
89 unsafe fn get_vbios_image_with_size(&self, vbios_size: u32) -> Result<Vec<u8>, i32> { unsafe {
90 use bindings::AMDGPU_INFO_VBIOS_IMAGE;
91
92 #[cfg(not(feature = "dynamic_loading"))]
93 let func = bindings::drmCommandWrite;
94 #[cfg(feature = "dynamic_loading")]
95 let func = self.libdrm.drmCommandWrite;
96
97 let mut vbios_image = vec![0; vbios_size as usize];
98 let mut device_info: MaybeUninit<drm_amdgpu_info> = MaybeUninit::zeroed();
99
100 {
101 let ptr = device_info.as_mut_ptr();
102
103 ptr::addr_of_mut!((*ptr).return_pointer).write(vbios_image.as_mut_ptr() as u64);
104 ptr::addr_of_mut!((*ptr).return_size).write(vbios_size);
105 ptr::addr_of_mut!((*ptr).query).write(AMDGPU_INFO_VBIOS);
106
107 ptr::addr_of_mut!((*ptr).__bindgen_anon_1.vbios_info.type_)
108 .write(AMDGPU_INFO_VBIOS_IMAGE);
109 }
110
111 let r = func(
112 self.fd,
113 DRM_AMDGPU_INFO as ::core::ffi::c_ulong,
114 device_info.as_mut_ptr() as *mut ::core::ffi::c_void,
115 size_of::<drm_amdgpu_info>() as ::core::ffi::c_ulong,
116 );
117
118 let _ = device_info.assume_init();
119
120 query_error!(r);
121
122 Ok(vbios_image)
123 }}
124
125
126 pub fn get_vbios_image(&self) -> Result<Vec<u8>, i32> {
127 let size = self.vbios_size()?;
128
129 unsafe { self.get_vbios_image_with_size(size) }
130 }
131}