Skip to main content

multiboot2/
vbe_info.rs

1//! Module for [`VBEInfoTag`].
2
3use crate::{TagHeader, TagType};
4use core::fmt;
5use multiboot2_common::{MaybeDynSized, Tag};
6
7/// This tag contains VBE metadata, VBE controller information returned by the
8/// VBE Function 00h and VBE mode information returned by the VBE Function 01h.
9#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[repr(C, align(8))]
11pub struct VBEInfoTag {
12    header: TagHeader,
13    mode: u16,
14    interface_segment: u16,
15    interface_offset: u16,
16    interface_length: u16,
17    control_info: VBEControlInfo,
18    mode_info: VBEModeInfo,
19}
20
21impl VBEInfoTag {
22    /// Constructs a new tag.
23    #[must_use]
24    pub fn new(
25        mode: u16,
26        interface_segment: u16,
27        interface_offset: u16,
28        interface_length: u16,
29        control_info: VBEControlInfo,
30        mode_info: VBEModeInfo,
31    ) -> Self {
32        Self {
33            header: TagHeader::new(Self::ID, size_of::<Self>().try_into().unwrap()),
34            mode,
35            interface_segment,
36            interface_offset,
37            interface_length,
38            control_info,
39            mode_info,
40        }
41    }
42
43    /// Indicates current video mode in the format specified in VBE 3.0.
44    #[must_use]
45    pub const fn mode(&self) -> u16 {
46        self.mode
47    }
48
49    /// Returns the segment of the table of a protected mode interface defined in VBE 2.0+.
50    ///
51    /// If the information for a protected mode interface is not available
52    /// this field is set to zero.
53    #[must_use]
54    pub const fn interface_segment(&self) -> u16 {
55        self.interface_segment
56    }
57    /// Returns the segment offset of the table of a protected mode interface defined in VBE 2.0+.
58    ///
59    /// If the information for a protected mode interface is not available
60    /// this field is set to zero.
61    #[must_use]
62    pub const fn interface_offset(&self) -> u16 {
63        self.interface_offset
64    }
65    /// Returns the segment length of the table of a protected mode interface defined in VBE 2.0+.
66    ///
67    /// If the information for a protected mode interface is not available
68    /// this field is set to zero.
69    #[must_use]
70    pub const fn interface_length(&self) -> u16 {
71        self.interface_length
72    }
73    /// Returns VBE controller information returned by the VBE Function `00h`.
74    #[must_use]
75    pub const fn control_info(&self) -> VBEControlInfo {
76        self.control_info
77    }
78    /// Returns VBE mode information returned by the VBE Function `01h`.
79    #[must_use]
80    pub const fn mode_info(&self) -> VBEModeInfo {
81        self.mode_info
82    }
83}
84
85impl MaybeDynSized for VBEInfoTag {
86    type Header = TagHeader;
87
88    const BASE_SIZE: usize = size_of::<Self>();
89}
90
91impl Tag for VBEInfoTag {
92    type IDType = TagType;
93
94    const ID: TagType = TagType::Vbe;
95}
96
97/// VBE controller information.
98///
99/// The capabilities of the display controller, the revision level of the
100/// VBE implementation, and vendor specific information to assist in supporting all display
101/// controllers in the field are listed here.
102///
103/// The purpose of this struct is to provide information to the kernel about the general
104/// capabilities of the installed VBE software and hardware.
105#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
106#[repr(C, packed)]
107pub struct VBEControlInfo {
108    /// VBE Signature aka "VESA".
109    pub signature: [u8; 4],
110
111    /// The VBE version.
112    pub version: u16,
113
114    /// A far pointer the the OEM String.
115    pub oem_string_ptr: u32,
116
117    /// Capabilities of the graphics controller.
118    pub capabilities: VBECapabilities,
119
120    /// Far pointer to the video mode list.
121    pub mode_list_ptr: u32,
122
123    /// Number of 64KiB memory blocks (Added for VBE 2.0+).
124    pub total_memory: u16,
125
126    /// VBE implementation software revision.
127    pub oem_software_revision: u16,
128
129    /// Far pointer to the vendor name string.
130    pub oem_vendor_name_ptr: u32,
131
132    /// Far pointer to the product name string.
133    pub oem_product_name_ptr: u32,
134
135    /// Far pointer to the product revision string.
136    pub oem_product_revision_ptr: u32,
137
138    /// Reserved for VBE implementation scratch area.
139    reserved: [u8; 222],
140
141    /// Data area for OEM strings.
142    oem_data: [u8; 256],
143}
144
145impl fmt::Debug for VBEControlInfo {
146    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
147        f.debug_struct("VBEControlInfo")
148            .field("signature", &self.signature)
149            .field("version", &{ self.version })
150            .field("oem_string_ptr", &{ self.oem_string_ptr })
151            .field("capabilities", &{ self.capabilities })
152            .field("mode_list_ptr", &{ self.mode_list_ptr })
153            .field("total_memory", &{ self.total_memory })
154            .field("oem_software_revision", &{ self.oem_software_revision })
155            .field("oem_vendor_name_ptr", &{ self.oem_vendor_name_ptr })
156            .field("oem_product_name_ptr", &{ self.oem_product_name_ptr })
157            .field("oem_product_revision_ptr", &{
158                self.oem_product_revision_ptr
159            })
160            .finish()
161    }
162}
163
164impl Default for VBEControlInfo {
165    fn default() -> Self {
166        Self {
167            signature: Default::default(),
168            version: 0,
169            oem_string_ptr: 0,
170            capabilities: Default::default(),
171            mode_list_ptr: 0,
172            total_memory: 0,
173            oem_software_revision: 0,
174            oem_vendor_name_ptr: 0,
175            oem_product_name_ptr: 0,
176            oem_product_revision_ptr: 0,
177            reserved: [0; 222],
178            oem_data: [0; 256],
179        }
180    }
181}
182
183/// Extended information about a specific VBE display mode from the
184/// mode list returned by `VBEControlInfo` (VBE Function `00h`).
185#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
186#[repr(C, packed)]
187pub struct VBEModeInfo {
188    /// Mode attributes.
189    pub mode_attributes: VBEModeAttributes,
190
191    /// Window A attributes.
192    pub window_a_attributes: VBEWindowAttributes,
193
194    /// Window B attributes.
195    pub window_b_attributes: VBEWindowAttributes,
196
197    /// Window granularity (Measured in Kilobytes.)
198    pub window_granularity: u16,
199
200    /// Window size.
201    pub window_size: u16,
202
203    /// Window A start segment.
204    pub window_a_segment: u16,
205
206    /// Window B start segment.
207    pub window_b_segment: u16,
208
209    /// Real mode pointer to window function.
210    pub window_function_ptr: u32,
211
212    /// Bytes per scan line
213    pub pitch: u16,
214
215    /// Horizontal and vertical resolution in pixels or characters.
216    pub resolution: (u16, u16),
217
218    /// Character cell width and height in pixels.
219    pub character_size: (u8, u8),
220
221    /// Number of memory planes.
222    pub number_of_planes: u8,
223
224    /// Bits per pixel
225    pub bpp: u8,
226
227    /// Number of banks
228    pub number_of_banks: u8,
229
230    /// Memory model type
231    pub memory_model: VBEMemoryModel,
232
233    /// Bank size (Measured in Kilobytes.)
234    pub bank_size: u8,
235
236    /// Number of images.
237    pub number_of_image_pages: u8,
238
239    /// Reserved for page function.
240    reserved0: u8,
241
242    /// Red colour field.
243    pub red_field: VBEField,
244
245    /// Green colour field.
246    pub green_field: VBEField,
247
248    /// Blue colour field.
249    pub blue_field: VBEField,
250
251    /// Reserved colour field.
252    pub reserved_field: VBEField,
253
254    /// Direct colour mode attributes.
255    pub direct_color_attributes: VBEDirectColorAttributes,
256
257    /// Physical address for flat memory frame buffer
258    pub framebuffer_base_ptr: u32,
259
260    /// A pointer to the start of off screen memory.
261    ///
262    /// # Deprecated
263    ///
264    /// In VBE3.0 and above these fields are reserved and unused.
265    pub offscreen_memory_offset: u32,
266
267    /// The amount of off screen memory in 1k units.
268    ///
269    /// # Deprecated
270    ///
271    /// In VBE3.0 and above these fields are reserved and unused.
272    pub offscreen_memory_size: u16,
273
274    /// Remainder of mode info block
275    reserved1: [u8; 206],
276}
277
278impl fmt::Debug for VBEModeInfo {
279    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280        f.debug_struct("VBEModeInfo")
281            .field("mode_attributes", &{ self.mode_attributes })
282            .field("window_a_attributes", &self.window_a_attributes)
283            .field("window_b_attributes", &self.window_b_attributes)
284            .field("window_granularity", &{ self.window_granularity })
285            .field("window_size", &{ self.window_size })
286            .field("window_a_segment", &{ self.window_a_segment })
287            .field("window_b_segment", &{ self.window_b_segment })
288            .field("window_function_ptr", &{ self.window_function_ptr })
289            .field("pitch", &{ self.pitch })
290            .field("resolution", &{ self.resolution })
291            .field("character_size", &self.character_size)
292            .field("number_of_planes", &self.number_of_planes)
293            .field("bpp", &self.bpp)
294            .field("number_of_banks", &self.number_of_banks)
295            .field("memory_model", &self.memory_model)
296            .field("bank_size", &self.bank_size)
297            .field("number_of_image_pages", &self.number_of_image_pages)
298            .field("red_field", &self.red_field)
299            .field("green_field", &self.green_field)
300            .field("blue_field", &self.blue_field)
301            .field("reserved_field", &self.reserved_field)
302            .field("direct_color_attributes", &self.direct_color_attributes)
303            .field("framebuffer_base_ptr", &{ self.framebuffer_base_ptr })
304            .field("offscreen_memory_offset", &{ self.offscreen_memory_offset })
305            .field("offscreen_memory_size", &{ self.offscreen_memory_size })
306            .finish()
307    }
308}
309
310impl Default for VBEModeInfo {
311    fn default() -> Self {
312        Self {
313            mode_attributes: Default::default(),
314            window_a_attributes: Default::default(),
315            window_b_attributes: Default::default(),
316            window_granularity: 0,
317            window_size: 0,
318            window_a_segment: 0,
319            window_b_segment: 0,
320            window_function_ptr: 0,
321            pitch: 0,
322            resolution: (0, 0),
323            character_size: (0, 0),
324            number_of_planes: 0,
325            bpp: 0,
326            number_of_banks: 0,
327            memory_model: Default::default(),
328            bank_size: 0,
329            number_of_image_pages: 0,
330            reserved0: 0,
331            red_field: Default::default(),
332            green_field: Default::default(),
333            blue_field: Default::default(),
334            reserved_field: Default::default(),
335            direct_color_attributes: Default::default(),
336            framebuffer_base_ptr: 0,
337            offscreen_memory_offset: 0,
338            offscreen_memory_size: 0,
339            reserved1: [0; 206],
340        }
341    }
342}
343
344/// A VBE colour field.
345///
346/// Describes the size and position of some colour capability.
347#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
348#[repr(C, packed)]
349pub struct VBEField {
350    /// The size, in bits, of the color components of a direct color pixel.
351    pub size: u8,
352
353    /// define the bit position within the direct color pixel or YUV pixel of
354    /// the least significant bit of the respective color component.
355    pub position: u8,
356}
357
358bitflags! {
359    /// The Capabilities field indicates the support of specific features in the graphics environment.
360    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
361    #[repr(transparent)]
362    pub struct VBECapabilities: u32 {
363        /// Can the DAC be switched between 6 and 8 bit modes.
364        const SWITCHABLE_DAC = 0x1;
365
366        /// Is the controller VGA compatible.
367        const NOT_VGA_COMPATIBLE = 0x2;
368
369        /// The operating behaviour of the RAMDAC.
370        ///
371        /// When writing lots of information to the RAMDAC, use the blank bit in Function `09h`.
372        const RAMDAC_FIX = 0x4;
373    }
374}
375
376bitflags! {
377    /// A Mode attributes bitfield.
378    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
379    #[repr(transparent)]
380    pub struct VBEModeAttributes: u16 {
381        /// Mode supported by hardware configuration.
382        const SUPPORTED = 0x1;
383
384        /// TTY Output functions supported by BIOS
385        const TTY_SUPPORTED = 0x4;
386
387        /// Color support.
388        const COLOR = 0x8;
389
390        /// Mode type (text or graphics).
391        const GRAPHICS = 0x10;
392
393        /// VGA compatibility.
394        const NOT_VGA_COMPATIBLE = 0x20;
395
396        /// VGA Window compatibility.
397        ///
398        /// If this is set, the window A and B fields of VBEModeInfo are invalid.
399        const NO_VGA_WINDOW = 0x40;
400
401        /// Linear framebuffer availability.
402        ///
403        /// Set if a linear framebuffer is available for this mode.
404        const LINEAR_FRAMEBUFFER = 0x80;
405    }
406}
407
408bitflags! {
409    /// The WindowAttributes describe the characteristics of the CPU windowing
410    /// scheme such as whether the windows exist and are read/writeable, as follows:
411    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
412    #[repr(transparent)]
413    pub struct VBEWindowAttributes: u8 {
414        /// Relocatable window(s) supported?
415        const RELOCATABLE = 0x1;
416
417        /// Window is readable?
418        const READABLE = 0x2;
419
420        /// Window is writable?
421        const WRITABLE = 0x4;
422    }
423}
424
425bitflags! {
426    /// The DirectColorModeInfo field describes important characteristics of direct color modes.
427    ///
428    /// Bit D0 specifies whether the color ramp of the DAC is fixed or
429    /// programmable. If the color ramp is fixed, then it can not be changed.
430    /// If the color ramp is programmable, it is assumed that the red, green,
431    /// and blue lookup tables can be loaded by using VBE Function `09h`
432    /// (it is assumed all color ramp data is 8 bits per primary).
433    /// Bit D1 specifies whether the bits in the Rsvd field of the direct color
434    /// pixel can be used by the application or are reserved, and thus unusable.
435    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
436    #[repr(transparent)]
437    pub struct VBEDirectColorAttributes: u8 {
438        /// Color ramp is fixed when cleared and programmable when set.
439        const PROGRAMMABLE = 0x1;
440
441        /// Bits in Rsvd field when cleared are reserved and usable when set.
442        const RESERVED_USABLE = 0x2;
443    }
444}
445
446/// The MemoryModel field specifies the general type of memory organization used in modes.
447#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
448#[repr(u8)]
449#[expect(missing_docs)]
450pub enum VBEMemoryModel {
451    #[default]
452    Text = 0x00,
453    CGAGraphics = 0x01,
454    HerculesGraphics = 0x02,
455    Planar = 0x03,
456    PackedPixel = 0x04,
457    Unchained = 0x05,
458    DirectColor = 0x06,
459    YUV = 0x07,
460}