limine_protocol_for_rust/
lib.rs1#![no_std]
49
50mod util;
51
52use crate::util::null_terminated_string;
53use core::mem::MaybeUninit;
54use core::slice::from_raw_parts;
55
56pub const REQUEST_START_MARKER: [u64; 4] = [ 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, 0x785c6ed015d3e316, 0x181e920a7852b9d9 ];
57pub const REQUEST_END_MARKER: [u64; 2] = [ 0xadc0e0531bb10d03, 0x9572709f31764c62 ];
58
59
60pub const fn use_base_revision(revision: u64) -> [u64; 4]{
62 [ 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, revision, 0 ]
63}
64
65#[repr(C, align(8))]
66struct LimineReqId {
67 common_magic: [u64; 2],
68 other: [u64; 2]
69}
70
71impl LimineReqId {
72 const fn new(other: [u64; 2]) -> Self {
73 Self {
74 common_magic: [0xc7b1dd30df4c8b88, 0x0a82e883a194f07b],
75 other
76 }
77 }
78}
79
80macro_rules! gen_get_response {
81 ($get:ty) => {
82 pub fn get_response(&self) -> Option<&$get> {
83 unsafe {
84 if self.resp.assume_init() == 0 {
85 return None
86 }
87 (self.resp.assume_init() as *const $get).as_ref()
88 }
89 }
90 };
91}
92
93
94#[repr(C, align(8))]
95pub struct MemoryMapRequest {
96 id: LimineReqId,
97 revision: u64,
98 resp: MaybeUninit<usize>
99}
100
101impl MemoryMapRequest {
102 pub const fn new(revision: u64) -> Self {
103 Self {
104 id: LimineReqId::new([0x67cf3d9d378a806f, 0xe304acdfc50c3c62]),
105 revision,
106 resp: MaybeUninit::uninit()
107 }
108 }
109
110 gen_get_response!(MemoryMapResponse);
111}
112
113
114#[repr(C, align(8))]
115pub struct MemoryMapResponse {
116 revision: u64,
117 entry_count: u64,
118 entries: *const MemoryMapEntry
119}
120
121impl MemoryMapResponse {
122 pub fn get_entries(&self) -> &[MemoryMapEntry] {
123 unsafe {
124 from_raw_parts(self.entries, self.entry_count as usize)
125 }
126 }
127}
128
129#[repr(C, align(8))]
130pub struct MemoryMapEntry {
131 base: u64,
132 length: u64,
133 memmap_type: u64
134}
135
136impl MemoryMapEntry {
137 pub fn type_as_enum(&self) -> MemoryMapType {
138 match self.memmap_type {
139 0 => MemoryMapType::Usable,
140 1 => MemoryMapType::Reserved,
141 2 => MemoryMapType::AcpiReclaimable,
142 3 => MemoryMapType::AcpiNvs,
143 4 => MemoryMapType::BadMemory,
144 5 => MemoryMapType::BootloaderReclaimable,
145 6 => MemoryMapType::ExecutableAndModules,
146 7 => MemoryMapType::Framebuffer,
147 8 => MemoryMapType::AcpiTables,
148 _ => panic!("Obtained invalid MemoryMap Type")
149 }
150 }
151}
152
153pub enum MemoryMapType {
154 Usable,
155 Reserved,
156 AcpiReclaimable,
157 AcpiNvs,
158 BadMemory,
159 BootloaderReclaimable,
160 ExecutableAndModules,
161 Framebuffer,
162 AcpiTables
163}
164
165#[repr(C, align(8))]
166pub struct FramebufferRequest {
167 id: LimineReqId,
168 revision: u64,
169 resp: MaybeUninit<usize>
170}
171
172impl FramebufferRequest {
173 pub const fn new(revision: u64) -> Self {
174 Self {
175 id: LimineReqId::new([0x9d5827dcd881dd75, 0xa3148604f6fab11b]),
176 revision,
177 resp: MaybeUninit::uninit()
178 }
179 }
180
181 gen_get_response!(FramebufferResponse);
182}
183
184
185#[repr(C, align(8))]
186#[derive(Debug)]
187pub struct FramebufferResponse {
188 revision: u64,
189 entry_count: u64,
190 entries: *const Framebuffer
191}
192
193impl FramebufferResponse {
194 pub fn get_entries(&self) -> &[Framebuffer] {
195 unsafe {
196 from_raw_parts(self.entries, self.entry_count as usize)
197 }
198 }
199}
200
201#[repr(C, align(8))]
202#[derive(Debug)]
203pub struct Framebuffer {
204 pub address: usize,
205 pub width: u64,
206 pub height: u64,
207 pub pitch: u64,
208 pub bpp: u16,
209 pub memory_model: u8,
210 pub red_mask_size: u8,
211 pub red_mask_shift: u8,
212 pub green_mask_size: u8,
213 pub green_mask_shift: u8,
214 pub blue_mask_size: u8,
215 pub blue_mask_shift: u8,
216 _unused: [u8; 7],
217 pub edid_size: u64,
218 pub edid_address: usize,
219
220 pub mode_count: u64,
222 modes: *const VideoMode
223}
224
225impl Framebuffer {
226 pub fn get_modes(&self) -> &[VideoMode] {
227 unsafe {
228 from_raw_parts(self.modes, self.mode_count as usize)
229 }
230 }
231}
232
233#[repr(C, align(8))]
234pub struct VideoMode {
235 pitch: u64,
236 width: u64,
237 height: u64,
238 bpp: u16,
239 memory_model: u8,
240 red_mask_size: u8,
241 red_mask_shift: u8,
242 green_mask_size: u8,
243 green_mask_shift: u8,
244 blue_mask_size: u8,
245 blue_mask_shift: u8,
246}
247
248#[repr(C, align(8))]
249pub struct BootloaderInfoRequest{
250 id: LimineReqId,
251 revision: u64,
252 resp: MaybeUninit<usize>
253}
254
255impl BootloaderInfoRequest {
256 pub const fn new(revision: u64) -> Self {
257 Self {
258 id: LimineReqId::new([0xf55038d8e2a1202f, 0x279426fcf5f59740]),
259 revision,
260 resp: MaybeUninit::uninit()
261 }
262 }
263
264 gen_get_response!(BootloaderInfoResponse);
265}
266
267#[repr(C, align(8))]
268pub struct BootloaderInfoResponse {
269 revision: u64,
270 name: *const u8,
271 version: *const u8
272}
273
274impl BootloaderInfoResponse {
275 pub fn get_name(&self) -> &str {
276 null_terminated_string(self.name).unwrap()
277 }
278
279 pub fn get_version(&self) -> &str {
280 null_terminated_string(self.version).unwrap()
281 }
282}
283