Skip to content

Commit d4eddcc

Browse files
committed
Split off UI from OS and redesign it.
This gets rid of the last parts of the OS struct.
1 parent c2ea82d commit d4eddcc

15 files changed

Lines changed: 702 additions & 457 deletions

File tree

pixie-shared/src/util.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,42 @@ pub struct BytesFmt(pub u64);
22

33
impl core::fmt::Display for BytesFmt {
44
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5+
let w = f.width().unwrap_or(0);
6+
let prc = f.precision().unwrap_or(2);
57
if self.0 < 1 << 10 {
6-
write!(f, "{} B", self.0)
8+
write!(f, "{:1$} B", self.0, w.saturating_sub(2))
79
} else if self.0 < 1 << 20 {
8-
write!(f, "{:.2} KiB", self.0 as f64 / (1i64 << 10) as f64)
10+
write!(
11+
f,
12+
"{:1$.2$} KiB",
13+
self.0 as f64 / (1i64 << 10) as f64,
14+
w.saturating_sub(4),
15+
prc
16+
)
917
} else if self.0 < 1 << 30 {
10-
write!(f, "{:.2} MiB", self.0 as f64 / (1i64 << 20) as f64)
18+
write!(
19+
f,
20+
"{:1$.2$} MiB",
21+
self.0 as f64 / (1i64 << 20) as f64,
22+
w.saturating_sub(4),
23+
prc
24+
)
1125
} else if self.0 < 1 << 40 {
12-
write!(f, "{:.2} GiB", self.0 as f64 / (1i64 << 30) as f64)
26+
write!(
27+
f,
28+
"{:1$.2$} GiB",
29+
self.0 as f64 / (1i64 << 30) as f64,
30+
w.saturating_sub(4),
31+
prc
32+
)
1333
} else {
14-
write!(f, "{:.2} TiB", self.0 as f64 / (1i64 << 40) as f64)
34+
write!(
35+
f,
36+
"{:1$.2$} TiB",
37+
self.0 as f64 / (1i64 << 40) as f64,
38+
w.saturating_sub(4),
39+
prc
40+
)
1541
}
1642
}
1743
}

pixie-uefi/src/flash.rs

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use alloc::boxed::Box;
22
use alloc::collections::BTreeMap;
3-
use alloc::rc::Rc;
43
use alloc::vec::Vec;
5-
use core::cell::RefCell;
4+
use core::cell::{Cell, RefCell};
5+
use core::fmt::Write;
66
use core::mem;
77
use core::net::SocketAddrV4;
88

@@ -12,13 +12,13 @@ use lz4_flex::decompress;
1212
use pixie_shared::chunk_codec::Decoder;
1313
use pixie_shared::util::BytesFmt;
1414
use pixie_shared::{ChunkHash, Image, TcpRequest, UdpRequest, CHUNKS_PORT, MAX_CHUNK_SIZE};
15-
use uefi::proto::console::text::Color;
1615

1716
use crate::os::boot_options::BootOptions;
1817
use crate::os::error::{Error, Result};
1918
use crate::os::executor::Executor;
2019
use crate::os::net::{TcpStream, UdpSocket, ETH_PACKET_SIZE};
21-
use crate::os::{disk, memory, UefiOS};
20+
use crate::os::ui::{update_content, DrawArea};
21+
use crate::os::{disk, memory};
2222
use crate::MIN_MEMORY;
2323

2424
async fn fetch_image(stream: &TcpStream) -> Result<Image> {
@@ -32,6 +32,7 @@ async fn fetch_image(stream: &TcpStream) -> Result<Image> {
3232
Ok(postcard::from_bytes(&buf)?)
3333
}
3434

35+
#[derive(Clone, PartialEq, Eq)]
3536
struct Stats {
3637
chunks: usize,
3738
unique: usize,
@@ -75,7 +76,7 @@ fn handle_packet(
7576
Ok(Some((pos, data)))
7677
}
7778

78-
pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
79+
pub async fn flash(server_addr: SocketAddrV4) -> Result<()> {
7980
let stream = TcpStream::connect(server_addr).await?;
8081
let image = fetch_image(&stream).await?;
8182
stream.shutdown().await;
@@ -93,49 +94,46 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
9394

9495
info!("Obtained chunks; {} distinct chunks", chunks_info.len());
9596

96-
let stats = Rc::new(RefCell::new(Stats {
97+
let stats = RefCell::new(Stats {
9798
chunks: image.disk.len(),
9899
unique: chunks_info.len(),
99100
fetch: 0,
100101
recv: 0,
101102
pack_recv: 0,
102103
requested: 0,
103-
}));
104-
105-
let stats2 = stats.clone();
106-
os.set_ui_drawer(move |os| {
107-
os.write_with_color(
108-
&format!("{} total chunks\n", stats2.borrow().chunks),
109-
Color::White,
110-
Color::Black,
111-
);
112-
os.write_with_color(
113-
&format!("{} unique chunks\n", stats2.borrow().unique),
114-
Color::White,
115-
Color::Black,
116-
);
117-
os.write_with_color(
118-
&format!("{} chunks to fetch\n", stats2.borrow().fetch),
119-
Color::White,
120-
Color::Black,
121-
);
122-
os.write_with_color(
123-
&format!("{} chunks received\n", stats2.borrow().recv),
124-
Color::White,
125-
Color::Black,
126-
);
127-
os.write_with_color(
128-
&format!("{} packets received\n", stats2.borrow().pack_recv),
129-
Color::White,
130-
Color::Black,
131-
);
132-
os.write_with_color(
133-
&format!("{} chunks requested\n", stats2.borrow().requested),
134-
Color::White,
135-
Color::Black,
136-
);
137104
});
138105

106+
let draw = |draw_area: &mut DrawArea| {
107+
draw_area.clear();
108+
writeln!(draw_area, "{} total chunks", stats.borrow().chunks).unwrap();
109+
writeln!(draw_area, "{} unique chunks", stats.borrow().unique).unwrap();
110+
writeln!(draw_area, "{} chunks to fetch", stats.borrow().fetch).unwrap();
111+
writeln!(draw_area, "{} chunks received", stats.borrow().recv).unwrap();
112+
writeln!(draw_area, "{} packets received", stats.borrow().pack_recv).unwrap();
113+
writeln!(draw_area, "{} chunks requested", stats.borrow().requested).unwrap();
114+
};
115+
116+
update_content(draw);
117+
118+
let done = Cell::new(false);
119+
120+
let draw_task = async {
121+
let mut last_stats = stats.borrow().clone();
122+
loop {
123+
if done.get() {
124+
break;
125+
}
126+
Executor::sleep_us(100_000).await;
127+
let stats = stats.borrow().clone();
128+
if stats == last_stats {
129+
continue;
130+
}
131+
update_content(draw);
132+
last_stats = stats;
133+
}
134+
Ok(())
135+
};
136+
139137
let mut disk = disk::Disk::largest();
140138

141139
for (hash, (size, csize, pos)) in mem::take(&mut chunks_info) {
@@ -158,6 +156,7 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
158156
chunks_info.insert(hash, (size, csize, pos));
159157
stats.borrow_mut().fetch = chunks_info.len();
160158
}
159+
update_content(draw);
161160
}
162161

163162
info!("Disk scanned; {} chunks to fetch", stats.borrow().fetch);
@@ -226,10 +225,11 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
226225
.send_to(server_addr, &postcard::to_allocvec(&msg)?)
227226
.await?;
228227
}
228+
done.set(true);
229229
Ok(())
230230
};
231231

232-
let ((), ()) = futures::try_join!(task1, task2)?;
232+
let ((), (), ()) = futures::try_join!(task1, task2, draw_task)?;
233233

234234
info!("Fetch complete, updating boot options");
235235

pixie-uefi/src/main.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use crate::flash::flash;
1616
use crate::os::error::{Error, Result};
1717
use crate::os::executor::Executor;
1818
use crate::os::net::{TcpStream, UdpSocket, ETH_PACKET_SIZE};
19-
use crate::os::UefiOS;
2019
use crate::register::register;
2120
use crate::store::store;
2221

@@ -96,7 +95,7 @@ async fn complete_action(stream: &TcpStream) -> Result<()> {
9695
Ok(())
9796
}
9897

99-
async fn run(os: UefiOS) -> Result<()> {
98+
async fn run() -> Result<()> {
10099
let server = server_discover().await?;
101100

102101
let mut last_was_wait = false;
@@ -113,9 +112,6 @@ async fn run(os: UefiOS) -> Result<()> {
113112
});
114113

115114
loop {
116-
// Clear any UI drawer.
117-
os.set_ui_drawer(|_| {});
118-
119115
if !last_was_wait {
120116
log::debug!("Sending request for command");
121117
}
@@ -147,9 +143,9 @@ async fn run(os: UefiOS) -> Result<()> {
147143
Action::Boot => power_control::reboot_to_os().await,
148144
Action::Restart => {}
149145
Action::Shutdown => shutdown().await,
150-
Action::Register => register(os, server).await?,
151-
Action::Store => store(os, server).await?,
152-
Action::Flash => flash(os, server).await?,
146+
Action::Register => register(server).await?,
147+
Action::Store => store(server).await?,
148+
Action::Flash => flash(server).await?,
153149
}
154150

155151
let tcp = TcpStream::connect(server).await?;
@@ -167,5 +163,5 @@ async fn run(os: UefiOS) -> Result<()> {
167163

168164
#[entry]
169165
fn main() -> Status {
170-
UefiOS::start(run)
166+
os::start(run)
171167
}

pixie-uefi/src/os/disk.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ use uefi::boot::{OpenProtocolParams, ScopedProtocol};
77
use uefi::proto::media::block::BlockIO;
88
use uefi::Handle;
99

10-
use crate::os::executor::Executor;
11-
1210
use super::error::Result;
11+
use crate::os::executor::Executor;
1312

1413
fn open_disk(handle: Handle) -> Result<ScopedProtocol<BlockIO>> {
1514
let image_handle = uefi::boot::image_handle();

0 commit comments

Comments
 (0)