1use crate::{TagHeader, TagType};
4use core::fmt;
5use core::mem;
6use multiboot2_common::{MaybeDynSized, Tag};
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
11#[repr(C, align(8))]
12pub struct VBEInfoTag {
13 header: TagHeader,
14 mode: u16,
15 interface_segment: u16,
16 interface_offset: u16,
17 interface_length: u16,
18 control_info: VBEControlInfo,
19 mode_info: VBEModeInfo,
20}
21
22impl VBEInfoTag {
23 #[must_use]
25 pub fn new(
26 mode: u16,
27 interface_segment: u16,
28 interface_offset: u16,
29 interface_length: u16,
30 control_info: VBEControlInfo,
31 mode_info: VBEModeInfo,
32 ) -> Self {
33 Self {
34 header: TagHeader::new(Self::ID, mem::size_of::<Self>().try_into().unwrap()),
35 mode,
36 interface_segment,
37 interface_offset,
38 interface_length,
39 control_info,
40 mode_info,
41 }
42 }
43
44 #[must_use]
46 pub const fn mode(&self) -> u16 {
47 self.mode
48 }
49
50 #[must_use]
55 pub const fn interface_segment(&self) -> u16 {
56 self.interface_segment
57 }
58 #[must_use]
63 pub const fn interface_offset(&self) -> u16 {
64 self.interface_offset
65 }
66 #[must_use]
71 pub const fn interface_length(&self) -> u16 {
72 self.interface_length
73 }
74 #[must_use]
76 pub const fn control_info(&self) -> VBEControlInfo {
77 self.control_info
78 }
79 #[must_use]
81 pub const fn mode_info(&self) -> VBEModeInfo {
82 self.mode_info
83 }
84}
85
86impl MaybeDynSized for VBEInfoTag {
87 type Header = TagHeader;
88
89 const BASE_SIZE: usize = mem::size_of::<Self>();
90
91 fn dst_len(_: &TagHeader) {}
92}
93
94impl Tag for VBEInfoTag {
95 type IDType = TagType;
96
97 const ID: TagType = TagType::Vbe;
98}
99
100#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
109#[repr(C, packed)]
110pub struct VBEControlInfo {
111 pub signature: [u8; 4],
113
114 pub version: u16,
116
117 pub oem_string_ptr: u32,
119
120 pub capabilities: VBECapabilities,
122
123 pub mode_list_ptr: u32,
125
126 pub total_memory: u16,
128
129 pub oem_software_revision: u16,
131
132 pub oem_vendor_name_ptr: u32,
134
135 pub oem_product_name_ptr: u32,
137
138 pub oem_product_revision_ptr: u32,
140
141 reserved: [u8; 222],
143
144 oem_data: [u8; 256],
146}
147
148impl fmt::Debug for VBEControlInfo {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 f.debug_struct("VBEControlInfo")
151 .field("signature", &self.signature)
152 .field("version", &{ self.version })
153 .field("oem_string_ptr", &{ self.oem_string_ptr })
154 .field("capabilities", &{ self.capabilities })
155 .field("mode_list_ptr", &{ self.mode_list_ptr })
156 .field("total_memory", &{ self.total_memory })
157 .field("oem_software_revision", &{ self.oem_software_revision })
158 .field("oem_vendor_name_ptr", &{ self.oem_vendor_name_ptr })
159 .field("oem_product_name_ptr", &{ self.oem_product_name_ptr })
160 .field("oem_product_revision_ptr", &{
161 self.oem_product_revision_ptr
162 })
163 .finish()
164 }
165}
166
167impl Default for VBEControlInfo {
168 fn default() -> Self {
169 Self {
170 signature: Default::default(),
171 version: 0,
172 oem_string_ptr: 0,
173 capabilities: Default::default(),
174 mode_list_ptr: 0,
175 total_memory: 0,
176 oem_software_revision: 0,
177 oem_vendor_name_ptr: 0,
178 oem_product_name_ptr: 0,
179 oem_product_revision_ptr: 0,
180 reserved: [0; 222],
181 oem_data: [0; 256],
182 }
183 }
184}
185
186#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
189#[repr(C, packed)]
190pub struct VBEModeInfo {
191 pub mode_attributes: VBEModeAttributes,
193
194 pub window_a_attributes: VBEWindowAttributes,
196
197 pub window_b_attributes: VBEWindowAttributes,
199
200 pub window_granularity: u16,
202
203 pub window_size: u16,
205
206 pub window_a_segment: u16,
208
209 pub window_b_segment: u16,
211
212 pub window_function_ptr: u32,
214
215 pub pitch: u16,
217
218 pub resolution: (u16, u16),
220
221 pub character_size: (u8, u8),
223
224 pub number_of_planes: u8,
226
227 pub bpp: u8,
229
230 pub number_of_banks: u8,
232
233 pub memory_model: VBEMemoryModel,
235
236 pub bank_size: u8,
238
239 pub number_of_image_pages: u8,
241
242 reserved0: u8,
244
245 pub red_field: VBEField,
247
248 pub green_field: VBEField,
250
251 pub blue_field: VBEField,
253
254 pub reserved_field: VBEField,
256
257 pub direct_color_attributes: VBEDirectColorAttributes,
259
260 pub framebuffer_base_ptr: u32,
262
263 pub offscreen_memory_offset: u32,
269
270 pub offscreen_memory_size: u16,
276
277 reserved1: [u8; 206],
279}
280
281impl fmt::Debug for VBEModeInfo {
282 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
283 f.debug_struct("VBEModeInfo")
284 .field("mode_attributes", &{ self.mode_attributes })
285 .field("window_a_attributes", &self.window_a_attributes)
286 .field("window_b_attributes", &self.window_b_attributes)
287 .field("window_granularity", &{ self.window_granularity })
288 .field("window_size", &{ self.window_size })
289 .field("window_a_segment", &{ self.window_a_segment })
290 .field("window_b_segment", &{ self.window_b_segment })
291 .field("window_function_ptr", &{ self.window_function_ptr })
292 .field("pitch", &{ self.pitch })
293 .field("resolution", &{ self.resolution })
294 .field("character_size", &self.character_size)
295 .field("number_of_planes", &self.number_of_planes)
296 .field("bpp", &self.bpp)
297 .field("number_of_banks", &self.number_of_banks)
298 .field("memory_model", &self.memory_model)
299 .field("bank_size", &self.bank_size)
300 .field("number_of_image_pages", &self.number_of_image_pages)
301 .field("red_field", &self.red_field)
302 .field("green_field", &self.green_field)
303 .field("blue_field", &self.blue_field)
304 .field("reserved_field", &self.reserved_field)
305 .field("direct_color_attributes", &self.direct_color_attributes)
306 .field("framebuffer_base_ptr", &{ self.framebuffer_base_ptr })
307 .field("offscreen_memory_offset", &{ self.offscreen_memory_offset })
308 .field("offscreen_memory_size", &{ self.offscreen_memory_size })
309 .finish()
310 }
311}
312
313impl Default for VBEModeInfo {
314 fn default() -> Self {
315 Self {
316 mode_attributes: Default::default(),
317 window_a_attributes: Default::default(),
318 window_b_attributes: Default::default(),
319 window_granularity: 0,
320 window_size: 0,
321 window_a_segment: 0,
322 window_b_segment: 0,
323 window_function_ptr: 0,
324 pitch: 0,
325 resolution: (0, 0),
326 character_size: (0, 0),
327 number_of_planes: 0,
328 bpp: 0,
329 number_of_banks: 0,
330 memory_model: Default::default(),
331 bank_size: 0,
332 number_of_image_pages: 0,
333 reserved0: 0,
334 red_field: Default::default(),
335 green_field: Default::default(),
336 blue_field: Default::default(),
337 reserved_field: Default::default(),
338 direct_color_attributes: Default::default(),
339 framebuffer_base_ptr: 0,
340 offscreen_memory_offset: 0,
341 offscreen_memory_size: 0,
342 reserved1: [0; 206],
343 }
344 }
345}
346
347#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
351#[repr(C, packed)]
352pub struct VBEField {
353 pub size: u8,
355
356 pub position: u8,
359}
360
361bitflags! {
362 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
364 #[repr(transparent)]
365 pub struct VBECapabilities: u32 {
366 const SWITCHABLE_DAC = 0x1;
368
369 const NOT_VGA_COMPATIBLE = 0x2;
371
372 const RAMDAC_FIX = 0x4;
376 }
377}
378
379bitflags! {
380 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
382 #[repr(transparent)]
383 pub struct VBEModeAttributes: u16 {
384 const SUPPORTED = 0x1;
386
387 const TTY_SUPPORTED = 0x4;
389
390 const COLOR = 0x8;
392
393 const GRAPHICS = 0x10;
395
396 const NOT_VGA_COMPATIBLE = 0x20;
398
399 const NO_VGA_WINDOW = 0x40;
403
404 const LINEAR_FRAMEBUFFER = 0x80;
408 }
409}
410
411bitflags! {
412 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
415 #[repr(transparent)]
416 pub struct VBEWindowAttributes: u8 {
417 const RELOCATABLE = 0x1;
419
420 const READABLE = 0x2;
422
423 const WRITEABLE = 0x4;
425 }
426}
427
428bitflags! {
429 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
439 #[repr(transparent)]
440 pub struct VBEDirectColorAttributes: u8 {
441 const PROGRAMMABLE = 0x1;
443
444 const RESERVED_USABLE = 0x2;
446 }
447}
448
449#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
451#[repr(u8)]
452#[allow(missing_docs)]
453#[allow(clippy::upper_case_acronyms)]
454pub enum VBEMemoryModel {
455 #[default]
456 Text = 0x00,
457 CGAGraphics = 0x01,
458 HerculesGraphics = 0x02,
459 Planar = 0x03,
460 PackedPixel = 0x04,
461 Unchained = 0x05,
462 DirectColor = 0x06,
463 YUV = 0x07,
464}