|
| 1 | +use core::ffi::c_void; |
1 | 2 | use core::fmt;
|
| 3 | +use core::ptr::NonNull; |
| 4 | +use core::sync::atomic::{AtomicBool, Ordering}; |
2 | 5 |
|
3 | 6 | use one_shot_mutex::OneShotMutex;
|
| 7 | +use uefi::table::boot::{EventType, Tpl}; |
| 8 | +use uefi::table::{Boot, SystemTable}; |
| 9 | +use uefi::Event; |
4 | 10 |
|
5 |
| -pub struct Console(()); |
| 11 | +use crate::arch; |
| 12 | + |
| 13 | +pub enum Console { |
| 14 | + None, |
| 15 | + BootServices, |
| 16 | + Native { console: arch::Console }, |
| 17 | +} |
| 18 | + |
| 19 | +impl Console { |
| 20 | + const fn new() -> Self { |
| 21 | + Self::None |
| 22 | + } |
| 23 | + |
| 24 | + fn exit_boot_services(&mut self) { |
| 25 | + assert!(matches!(self, Self::BootServices { .. })); |
| 26 | + *self = Self::Native { |
| 27 | + console: arch::Console::default(), |
| 28 | + }; |
| 29 | + } |
| 30 | + |
| 31 | + fn init(&mut self) { |
| 32 | + assert!(matches!(self, Console::None)); |
| 33 | + unsafe { |
| 34 | + uefi_services::system_table() |
| 35 | + .boot_services() |
| 36 | + .create_event( |
| 37 | + EventType::SIGNAL_EXIT_BOOT_SERVICES, |
| 38 | + Tpl::NOTIFY, |
| 39 | + Some(exit_boot_services), |
| 40 | + None, |
| 41 | + ) |
| 42 | + .unwrap(); |
| 43 | + } |
| 44 | + *self = Console::BootServices; |
| 45 | + } |
| 46 | +} |
6 | 47 |
|
7 | 48 | impl fmt::Write for Console {
|
8 | 49 | fn write_str(&mut self, s: &str) -> fmt::Result {
|
9 |
| - uefi_services::system_table().stdout().write_str(s)?; |
| 50 | + match self { |
| 51 | + Console::None => { |
| 52 | + self.init(); |
| 53 | + self.write_str(s)?; |
| 54 | + } |
| 55 | + Console::BootServices => uefi_services::system_table().stdout().write_str(s)?, |
| 56 | + Console::Native { console } => console.write_bytes(s.as_bytes()), |
| 57 | + } |
10 | 58 | Ok(())
|
11 | 59 | }
|
12 | 60 | }
|
13 | 61 |
|
14 |
| -pub static CONSOLE: OneShotMutex<Console> = OneShotMutex::new(Console(())); |
| 62 | +unsafe extern "efiapi" fn exit_boot_services(_e: Event, _ctx: Option<NonNull<c_void>>) { |
| 63 | + CONSOLE.lock().exit_boot_services(); |
| 64 | +} |
| 65 | + |
| 66 | +pub static CONSOLE: OneShotMutex<Console> = OneShotMutex::new(Console::new()); |
0 commit comments