1#![no_std]
35#![deny(missing_docs)]
36#![warn(
37 clippy::pedantic,
38 clippy::nursery,
39 clippy::unwrap_used,
40 clippy::expect_used
41)]
42#![allow(clippy::module_name_repetitions)]
43
44use core::{cell::UnsafeCell, fmt::Debug, ops::Deref};
45
46#[repr(transparent)]
47pub struct Request<T>(UnsafeCell<T>);
51
52impl<T> Request<T> {
53 pub(crate) const fn new(req: T) -> Self {
56 Self(UnsafeCell::new(req))
57 }
58}
59
60impl<T> Deref for Request<T> {
61 type Target = T;
62
63 fn deref(&self) -> &Self::Target {
64 unsafe { &*self.0.get() }
65 }
66}
67
68impl<T: Debug> Debug for Request<T> {
69 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
70 <T as Debug>::fmt(unsafe { &*self.0.get() }, f)
71 }
72}
73
74unsafe impl<T> Sync for Request<T> {}
75
76mod responses;
78pub use responses::*;
79
80mod requests;
82pub use requests::*;
83
84mod default_const;
85pub use default_const::ConstDefault;
86
87pub mod structures;
89
90#[cfg(test)]
91mod tests {
92 use crate::{
93 responses::{FramebufferResponse, SMPResponse, TerminalResponse},
94 structures::{framebuffer::Framebuffer, smpinfo::SMPInfo, terminal::Terminal},
95 };
96
97 extern "C" fn fake_write(_: *mut Terminal, _: *const u8, _: u64) {}
98
99 #[test]
100 fn terminal_get_slice() {
101 let mut framebuffer = Framebuffer::new_empty();
102 let tarray: [&Terminal; 1] = [&Terminal {
103 columns: 120,
104 rows: 80,
105 framebuffer: &mut framebuffer,
106 }];
107 let terminal = TerminalResponse {
108 revision: 1,
109 terminal_count: 1,
110 terminals: tarray.as_ptr() as *const *const Terminal,
111 write: fake_write,
112 };
113 let tarray_from_terminal = unsafe { terminal.get_terminals() }.unwrap();
114 assert_eq!(tarray.as_slice(), tarray_from_terminal);
115 }
116
117 #[test]
118 fn terminal_none_when_null() {
119 let terminal = TerminalResponse {
120 revision: 1,
121 terminal_count: 0,
122 terminals: core::ptr::null(),
123 write: fake_write,
124 };
125 assert!(unsafe { terminal.get_terminals() }.is_none());
126 }
127
128 #[test]
129 fn framebuffer_get_slice() {
130 let mut framebuffer_a = [&Framebuffer::new_empty(), &Framebuffer::new_empty()];
131 let framebuffer = FramebufferResponse {
132 revision: 1,
133 framebuffer_count: 2,
134 framebuffers: framebuffer_a.as_mut_ptr() as *mut *mut Framebuffer,
135 };
136 let fa_from_resp = unsafe { framebuffer.get_framebuffers() }.unwrap();
137 assert_eq!(framebuffer_a, fa_from_resp);
138 }
139
140 #[test]
141 fn framebuffer_none_when_null() {
142 let framebuffer = FramebufferResponse {
143 revision: 1,
144 framebuffer_count: 2,
145 framebuffers: core::ptr::null_mut(),
146 };
147 assert!(unsafe { framebuffer.get_framebuffers() }.is_none());
148 }
149
150 #[test]
151 fn smpinfo_get_slice() {
152 let c0 = SMPInfo::new_empty();
153 let mut c1 = SMPInfo::new_empty();
154 c1.processor_id = 1;
155 c1.lapic_id = 1;
156 let smps = [&c0, &c1];
157 let resp = SMPResponse {
158 revision: 1,
159 flags: 0,
160 bsp_lapic_id: 0,
161 cpu_count: 2,
162 cpus: smps.as_ptr() as *const *const SMPInfo,
163 };
164 let from_resp = unsafe { resp.get_cpu_info() }.unwrap();
165 assert_eq!(smps, from_resp);
166 }
167
168 #[test]
169 fn smpinfo_none_when_null() {
170 let resp = SMPResponse {
171 revision: 1,
172 flags: 0,
173 bsp_lapic_id: 0,
174 cpu_count: 2,
175 cpus: core::ptr::null(),
176 };
177 assert!(unsafe { resp.get_cpu_info() }.is_none())
178 }
179}