multiboot2/
vbe_info.rs

1//! Module for [`VBEInfoTag`].
2
3use crate::{TagHeader, TagType};
4use core::fmt;
5use core::mem;
6use multiboot2_common::{MaybeDynSized, Tag};
7
8/// This tag contains VBE metadata, VBE controller information returned by the
9/// VBE Function 00h and VBE mode information returned by the VBE Function 01h.
10#[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    /// Constructs a new tag.
24    #[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    /// Indicates current video mode in the format specified in VBE 3.0.
45    #[must_use]
46    pub const fn mode(&self) -> u16 {
47        self.mode
48    }
49
50    /// Returns the segment of the table of a protected mode interface defined in VBE 2.0+.
51    ///
52    /// If the information for a protected mode interface is not available
53    /// this field is set to zero.
54    #[must_use]
55    pub const fn interface_segment(&self) -> u16 {
56        self.interface_segment
57    }
58    /// Returns the segment offset of the table of a protected mode interface defined in VBE 2.0+.
59    ///
60    /// If the information for a protected mode interface is not available
61    /// this field is set to zero.
62    #[must_use]
63    pub const fn interface_offset(&self) -> u16 {
64        self.interface_offset
65    }
66    /// Returns the segment length of the table of a protected mode interface defined in VBE 2.0+.
67    ///
68    /// If the information for a protected mode interface is not available
69    /// this field is set to zero.
70    #[must_use]
71    pub const fn interface_length(&self) -> u16 {
72        self.interface_length
73    }
74    /// Returns VBE controller information returned by the VBE Function `00h`.
75    #[must_use]
76    pub const fn control_info(&self) -> VBEControlInfo {
77        self.control_info
78    }
79    /// Returns VBE mode information returned by the VBE Function `01h`.
80    #[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/// VBE controller information.
101///
102/// The capabilities of the display controller, the revision level of the
103/// VBE implementation, and vendor specific information to assist in supporting all display
104/// controllers in the field are listed here.
105///
106/// The purpose of this struct is to provide information to the kernel about the general
107/// capabilities of the installed VBE software and hardware.
108#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
109#[repr(C, packed)]
110pub struct VBEControlInfo {
111    /// VBE Signature aka "VESA".
112    pub signature: [u8; 4],
113
114    /// The VBE version.
115    pub version: u16,
116
117    /// A far pointer the the OEM String.
118    pub oem_string_ptr: u32,
119
120    /// Capabilities of the graphics controller.
121    pub capabilities: VBECapabilities,
122
123    /// Far pointer to the video mode list.
124    pub mode_list_ptr: u32,
125
126    /// Number of 64KiB memory blocks (Added for VBE 2.0+).
127    pub total_memory: u16,
128
129    /// VBE implementation software revision.
130    pub oem_software_revision: u16,
131
132    /// Far pointer to the vendor name string.
133    pub oem_vendor_name_ptr: u32,
134
135    /// Far pointer to the product name string.
136    pub oem_product_name_ptr: u32,
137
138    /// Far pointer to the product revision string.
139    pub oem_product_revision_ptr: u32,
140
141    /// Reserved for VBE implementation scratch area.
142    reserved: [u8; 222],
143
144    /// Data area for OEM strings.
145    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/// Extended information about a specific VBE display mode from the
187/// mode list returned by `VBEControlInfo` (VBE Function `00h`).
188#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
189#[repr(C, packed)]
190pub struct VBEModeInfo {
191    /// Mode attributes.
192    pub mode_attributes: VBEModeAttributes,
193
194    /// Window A attributes.
195    pub window_a_attributes: VBEWindowAttributes,
196
197    /// Window B attributes.
198    pub window_b_attributes: VBEWindowAttributes,
199
200    /// Window granularity (Measured in Kilobytes.)
201    pub window_granularity: u16,
202
203    /// Window size.
204    pub window_size: u16,
205
206    /// Window A start segment.
207    pub window_a_segment: u16,
208
209    /// Window B start segment.
210    pub window_b_segment: u16,
211
212    /// Real mode pointer to window function.
213    pub window_function_ptr: u32,
214
215    /// Bytes per scan line
216    pub pitch: u16,
217
218    /// Horizontal and vertical resolution in pixels or characters.
219    pub resolution: (u16, u16),
220
221    /// Character cell width and height in pixels.
222    pub character_size: (u8, u8),
223
224    /// Number of memory planes.
225    pub number_of_planes: u8,
226
227    /// Bits per pixel
228    pub bpp: u8,
229
230    /// Number of banks
231    pub number_of_banks: u8,
232
233    /// Memory model type
234    pub memory_model: VBEMemoryModel,
235
236    /// Bank size (Measured in Kilobytes.)
237    pub bank_size: u8,
238
239    /// Number of images.
240    pub number_of_image_pages: u8,
241
242    /// Reserved for page function.
243    reserved0: u8,
244
245    /// Red colour field.
246    pub red_field: VBEField,
247
248    /// Green colour field.
249    pub green_field: VBEField,
250
251    /// Blue colour field.
252    pub blue_field: VBEField,
253
254    /// Reserved colour field.
255    pub reserved_field: VBEField,
256
257    /// Direct colour mode attributes.
258    pub direct_color_attributes: VBEDirectColorAttributes,
259
260    /// Physical address for flat memory frame buffer
261    pub framebuffer_base_ptr: u32,
262
263    /// A pointer to the start of off screen memory.
264    ///
265    /// # Deprecated
266    ///
267    /// In VBE3.0 and above these fields are reserved and unused.
268    pub offscreen_memory_offset: u32,
269
270    /// The amount of off screen memory in 1k units.
271    ///
272    /// # Deprecated
273    ///
274    /// In VBE3.0 and above these fields are reserved and unused.
275    pub offscreen_memory_size: u16,
276
277    /// Remainder of mode info block
278    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/// A VBE colour field.
348///
349/// Describes the size and position of some colour capability.
350#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
351#[repr(C, packed)]
352pub struct VBEField {
353    /// The size, in bits, of the color components of a direct color pixel.
354    pub size: u8,
355
356    /// define the bit position within the direct color pixel or YUV pixel of
357    /// the least significant bit of the respective color component.
358    pub position: u8,
359}
360
361bitflags! {
362    /// The Capabilities field indicates the support of specific features in the graphics environment.
363    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
364    #[repr(transparent)]
365    pub struct VBECapabilities: u32 {
366        /// Can the DAC be switched between 6 and 8 bit modes.
367        const SWITCHABLE_DAC = 0x1;
368
369        /// Is the controller VGA compatible.
370        const NOT_VGA_COMPATIBLE = 0x2;
371
372        /// The operating behaviour of the RAMDAC.
373        ///
374        /// When writing lots of information to the RAMDAC, use the blank bit in Function `09h`.
375        const RAMDAC_FIX = 0x4;
376    }
377}
378
379bitflags! {
380    /// A Mode attributes bitfield.
381    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
382    #[repr(transparent)]
383    pub struct VBEModeAttributes: u16 {
384        /// Mode supported by hardware configuration.
385        const SUPPORTED = 0x1;
386
387        /// TTY Output functions supported by BIOS
388        const TTY_SUPPORTED = 0x4;
389
390        /// Color support.
391        const COLOR = 0x8;
392
393        /// Mode type (text or graphics).
394        const GRAPHICS = 0x10;
395
396        /// VGA compatibility.
397        const NOT_VGA_COMPATIBLE = 0x20;
398
399        /// VGA Window compatibility.
400        ///
401        /// If this is set, the window A and B fields of VBEModeInfo are invalid.
402        const NO_VGA_WINDOW = 0x40;
403
404        /// Linear framebuffer availability.
405        ///
406        /// Set if a linear framebuffer is available for this mode.
407        const LINEAR_FRAMEBUFFER = 0x80;
408    }
409}
410
411bitflags! {
412    /// The WindowAttributes describe the characteristics of the CPU windowing
413    /// scheme such as whether the windows exist and are read/writeable, as follows:
414    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
415    #[repr(transparent)]
416    pub struct VBEWindowAttributes: u8 {
417        /// Relocatable window(s) supported?
418        const RELOCATABLE = 0x1;
419
420        /// Window is readable?
421        const READABLE = 0x2;
422
423        /// Window is writeable?
424        const WRITEABLE = 0x4;
425    }
426}
427
428bitflags! {
429    /// The DirectColorModeInfo field describes important characteristics of direct color modes.
430    ///
431    /// Bit D0 specifies whether the color ramp of the DAC is fixed or
432    /// programmable. If the color ramp is fixed, then it can not be changed.
433    /// If the color ramp is programmable, it is assumed that the red, green,
434    /// and blue lookup tables can be loaded by using VBE Function `09h`
435    /// (it is assumed all color ramp data is 8 bits per primary).
436    /// Bit D1 specifies whether the bits in the Rsvd field of the direct color
437    /// pixel can be used by the application or are reserved, and thus unusable.
438    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
439    #[repr(transparent)]
440    pub struct VBEDirectColorAttributes: u8 {
441        /// Color ramp is fixed when cleared and programmable when set.
442        const PROGRAMMABLE = 0x1;
443
444        /// Bits in Rsvd field when cleared are reserved and usable when set.
445        const RESERVED_USABLE = 0x2;
446    }
447}
448
449/// The MemoryModel field specifies the general type of memory organization used in modes.
450#[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}