1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
use core::ffi::CStr;

#[allow(unused_imports)]
use crate::{
    requests::*,
    structures::{
        file::File,
        framebuffer::Framebuffer,
        memory_map_entry::MemoryMapEntry,
        smpinfo::SMPInfo,
        terminal::{Terminal, TerminalWriteFn},
    },
};

#[repr(C)]
#[derive(Debug)]
/// Response to [InfoRequest]
pub struct InfoResponse<'a> {
    /// The response revision number
    pub revision: u64,
    /// A null-terminated string of the bootloader's name
    pub name: &'a CStr,
    /// A null-terminated string of the bootloader's version
    pub version: &'a CStr,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [StackSizeRequest]
pub struct StackSizeResponse {
    /// The response revision number
    pub revision: u64,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [HHDMRequest]
pub struct HHDMResponse {
    /// The response revision number
    pub revision: u64,
    /// The offset of the HHDM
    pub offset: u64,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [TerminalRequest]
pub struct TerminalResponse {
    /// The response revision number
    pub revision: u64,
    /// The number of [Terminal]s in `terminals`
    pub terminal_count: u64,
    /// A pointer to an array of [Terminal] pointers
    pub terminals: *const *const Terminal,
    /// The terminal write function
    pub write: TerminalWriteFn,
}

impl TerminalResponse {
    /// Get the terminal slice
    ///
    /// # Safety
    /// The pointer must point to a valid array of [Terminal]s
    pub unsafe fn get_terminals(&self) -> Option<&[&Terminal]> {
        if self.terminals.is_null() {
            return None;
        }
        Some(core::slice::from_raw_parts(
            self.terminals as *const &Terminal,
            self.terminal_count as usize,
        ))
    }
}

#[repr(C)]
#[derive(Debug)]
/// Response to [FramebufferRequest]
pub struct FramebufferResponse {
    /// The response revision number
    pub revision: u64,
    /// The number of [Framebuffer]s in `framebuffers`
    pub framebuffer_count: u64,
    /// A pointer to an array of [Framebuffer] pointers
    pub framebuffers: *mut *mut Framebuffer,
}

impl FramebufferResponse {
    /// Get the framebuffer slice
    /// # Safety
    /// The pointer must point to a valid array of [Framebuffer]s
    pub unsafe fn get_framebuffers(&self) -> Option<&[&Framebuffer]> {
        if self.framebuffers.is_null() {
            return None;
        }
        Some(core::slice::from_raw_parts(
            self.framebuffers as *const &Framebuffer,
            self.framebuffer_count as usize,
        ))
    }
}

#[repr(C)]
#[derive(Debug)]
/// Response to [Level5PagingRequest]
pub struct Level5PagingResponse {
    /// The response revision number
    pub revision: u64,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [SMPRequest]
pub struct SMPResponse {
    /// The response revision number
    pub revision: u64,
    /// Flags for the bootloader
    /// `Bit 0` - X2APIC has been enabled
    pub flags: u32,
    /// The boot processor's local APIC ID
    pub bsp_lapic_id: u32,
    /// The amount of CPUs available
    pub cpu_count: u64,
    /// A pointer to an array of [SMPInfo]
    pub cpus: *const *const SMPInfo,
}

impl SMPResponse {
    /// Get the CPU info slice
    ///
    /// # Safety
    /// The pointer must point to a valid array of [SMPInfo]s
    pub unsafe fn get_cpu_info(&self) -> Option<&[&SMPInfo]> {
        if self.cpus.is_null() {
            return None;
        }

        Some(core::slice::from_raw_parts(
            self.cpus as *const &SMPInfo,
            self.cpu_count as usize,
        ))
    }
}

#[repr(C)]
#[derive(Debug)]
/// Response to [MemoryMapRequest]
pub struct MemoryMapResponse {
    /// The response revision number
    pub revision: u64,
    /// The amount of entries in the memory map
    pub entry_count: u64,
    /// An array of [MemoryMapEntry] pointers
    pub entries: *const *const MemoryMapEntry,
}

impl MemoryMapResponse {
    /// Get the memory map entry slice
    ///
    /// # Safety
    /// The pointer must point to a valid array of [MemoryMapEntry]
    pub unsafe fn get_memory_map(&self) -> Option<&[&MemoryMapEntry]> {
        if self.entries.is_null() {
            return None;
        }
        Some(core::slice::from_raw_parts(
            self.entries as *const &MemoryMapEntry,
            self.entry_count as usize,
        ))
    }
}

#[repr(C)]
#[derive(Debug)]
/// Response to [EntryPointRequest]
pub struct EntryPointResponse {
    /// The response revision number
    pub revision: u64,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [KernelFileRequest]
pub struct KernelFileResponse<'a> {
    /// The response revision number
    pub revision: u64,
    /// Pointer to the kernel file structure
    pub kernel_file: *const File<'a>,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [ModuleRequest]
pub struct ModuleResponse<'a> {
    /// The response revision number
    pub revision: u64,
    /// The number of modules
    pub module_count: u64,
    /// An array of [File] pointers
    pub modules: *const *const File<'a>,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [RSDPRequest]
pub struct RSDPResponse {
    /// The response revision number
    pub revision: u64,
    /// Address of the RSDP table
    pub address: Option<*const u8>,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [SMBIOSRequest]
pub struct SMBIOSResponse {
    /// The response revision number
    pub revision: u64,
    /// Address of the 32-bit SMBIOS entry point, null if not present
    pub entry_32: Option<*const u8>,
    /// Address of the 64-bit SMBIOS entry point, null if not present
    pub entry_64: Option<*const u8>,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [EfiSystemTableRequest]
pub struct EfiSystemTableResponse {
    /// The response revision number
    pub revision: u64,
    /// Address of the EFI System Table
    pub address: Option<*const u8>,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [BootTimeRequest]
pub struct BootTimeResponse {
    /// The response revision number
    pub revision: u64,
    /// The UNIX time on boot
    pub boot_time: i64,
}

#[repr(C)]
#[derive(Debug)]
/// Response to [KernelAddressRequest]
pub struct KernelAddressResponse {
    /// The response revision number
    pub revision: u64,
    /// The physical base of the kernel
    pub physical_base: u64,
    /// The virtual base of the kernel
    pub virtual_base: u64,
}