Skip to content

Commit f661967

Browse files
author
T. Andrew Davis
committed
Refactor serial print usage across multiple files to unify imports from the mainloop::serial module
1 parent 19afec7 commit f661967

8 files changed

Lines changed: 135 additions & 45 deletions

File tree

network/src/driver/intel/e1000e.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//! Intel 82579 Datasheet, NETWORK_IMPL_GUIDE.md §8
77
88
use crate::driver::traits::{DriverInit, NetworkDriver, RxError, TxError};
9-
use crate::mainloop::bare_metal::serial_println;
9+
use crate::mainloop::serial::serial_println;
1010
use crate::types::MacAddress;
1111
use crate::asm::drivers::intel::{asm_intel_link_status, LinkStatusResult};
1212

network/src/driver/intel/init.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use crate::asm::drivers::intel::{
3838
disable_ulp, toggle_lanphypc, phy_is_accessible, acquire_swflag, release_swflag,
3939
};
4040
use crate::dma::DmaRegion;
41-
use crate::mainloop::bare_metal::{serial_print, serial_println, serial_print_decimal};
41+
use crate::mainloop::serial::{serial_print, serial_println, serial_print_decimal};
4242
use crate::types::MacAddress;
4343

4444
use super::regs;
@@ -219,7 +219,7 @@ pub unsafe fn init_e1000e(
219219
// DEBUG: Read RAL/RAH directly to see what UEFI programmed
220220
{
221221
use crate::asm::core::mmio::{read32};
222-
use crate::mainloop::bare_metal::serial_print_hex;
222+
use crate::mainloop::serial::serial_print_hex;
223223
let ral = read32(mmio_base + 0x5400);
224224
let rah = read32(mmio_base + 0x5404);
225225
serial_print(" [DEBUG] RAL0=0x");

network/src/driver/unified.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use crate::boot::handoff::{BootHandoff, NIC_TYPE_INTEL, NIC_TYPE_VIRTIO};
1515

1616
// Use the known-working serial functions from bare_metal
17-
use crate::mainloop::bare_metal::{serial_print, serial_println};
17+
use crate::mainloop::serial::{serial_print, serial_println};
1818

1919
use crate::driver::intel::{E1000eConfig, E1000eDriver, E1000eError};
2020
use crate::driver::traits::{NetworkDriver, RxError, TxError};

network/src/mainloop/context.rs

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use smoltcp::iface::SocketHandle;
77
use smoltcp::wire::IpAddress;
88

9+
use crate::device::UnifiedBlockDevice;
10+
911
/// Timeout configuration for network operations.
1012
#[derive(Clone, Copy)]
1113
pub struct Timeouts {
@@ -38,16 +40,61 @@ impl Timeouts {
3840
}
3941
}
4042

41-
/// Configuration for the download operation.
43+
/// Full download configuration.
4244
#[derive(Clone)]
4345
pub struct DownloadConfig<'a> {
4446
/// URL to download
4547
pub url: &'a str,
48+
/// Write to disk?
49+
pub write_to_disk: bool,
50+
/// Target start sector for ISO
51+
pub target_start_sector: u64,
52+
/// Sector for manifest (raw write)
53+
pub manifest_sector: u64,
54+
/// ESP start LBA (for FAT32 manifest)
55+
pub esp_start_lba: u64,
56+
/// Partition UUID
57+
pub partition_uuid: [u8; 16],
58+
/// ISO name for manifest
59+
pub iso_name: &'a str,
60+
/// Expected ISO size (0 = unknown)
61+
pub expected_size: u64,
4662
}
4763

4864
impl<'a> DownloadConfig<'a> {
49-
pub fn new(url: &'a str) -> Self {
50-
Self { url }
65+
/// Simple config for download-only (no disk write).
66+
pub fn download_only(url: &'a str) -> Self {
67+
Self {
68+
url,
69+
write_to_disk: false,
70+
target_start_sector: 0,
71+
manifest_sector: 0,
72+
esp_start_lba: 0,
73+
partition_uuid: [0u8; 16],
74+
iso_name: "",
75+
expected_size: 0,
76+
}
77+
}
78+
79+
/// Full config for download + disk write + manifest.
80+
pub fn full(
81+
url: &'a str,
82+
target_start_sector: u64,
83+
manifest_sector: u64,
84+
esp_start_lba: u64,
85+
partition_uuid: [u8; 16],
86+
iso_name: &'a str,
87+
) -> Self {
88+
Self {
89+
url,
90+
write_to_disk: true,
91+
target_start_sector,
92+
manifest_sector,
93+
esp_start_lba,
94+
partition_uuid,
95+
iso_name,
96+
expected_size: 0,
97+
}
5198
}
5299
}
53100

@@ -57,14 +104,16 @@ pub struct Context<'a> {
57104
pub timeouts: Timeouts,
58105
/// TSC frequency
59106
pub tsc_freq: u64,
60-
/// Download URL
61-
pub url: &'a str,
107+
/// Full configuration
108+
pub config: DownloadConfig<'a>,
62109
/// DHCP socket handle
63110
pub dhcp_handle: Option<SocketHandle>,
64111
/// DNS socket handle
65112
pub dns_handle: Option<SocketHandle>,
66113
/// TCP socket handle
67114
pub tcp_handle: Option<SocketHandle>,
115+
/// Block device for disk writes
116+
pub blk_device: Option<UnifiedBlockDevice>,
68117
/// Resolved IP address (from DNS)
69118
pub resolved_ip: Option<IpAddress>,
70119
/// Resolved port
@@ -73,30 +122,57 @@ pub struct Context<'a> {
73122
pub url_path: &'a str,
74123
/// Host portion of URL
75124
pub url_host: &'a str,
76-
/// Content-Length from HTTP response (if known)
125+
/// Content-Length from HTTP response
77126
pub content_length: Option<u64>,
78-
/// Total bytes downloaded so far
127+
/// Total bytes downloaded
79128
pub bytes_downloaded: u64,
129+
/// Total bytes written to disk
130+
pub bytes_written: u64,
131+
/// Current write sector
132+
pub current_write_sector: u64,
133+
/// DNS servers from DHCP
134+
pub dns_servers: [Option<IpAddress>; 3],
80135
}
81136

82137
impl<'a> Context<'a> {
83138
/// Create new context.
84-
pub fn new(url: &'a str, tsc_freq: u64) -> Self {
139+
pub fn new(config: DownloadConfig<'a>, tsc_freq: u64) -> Self {
140+
let start_sector = config.target_start_sector;
85141
Self {
86142
timeouts: Timeouts::new(tsc_freq),
87143
tsc_freq,
88-
url,
144+
config,
89145
dhcp_handle: None,
90146
dns_handle: None,
91147
tcp_handle: None,
148+
blk_device: None,
92149
resolved_ip: None,
93150
resolved_port: 80,
94151
url_path: "",
95152
url_host: "",
96153
content_length: None,
97154
bytes_downloaded: 0,
155+
bytes_written: 0,
156+
current_write_sector: start_sector,
157+
dns_servers: [None; 3],
98158
}
99159
}
160+
161+
/// Set block device for disk writes.
162+
pub fn with_block_device(mut self, device: UnifiedBlockDevice) -> Self {
163+
self.blk_device = Some(device);
164+
self
165+
}
166+
167+
/// Get URL from config.
168+
pub fn url(&self) -> &str {
169+
self.config.url
170+
}
171+
172+
/// Check if disk write is enabled.
173+
pub fn should_write_to_disk(&self) -> bool {
174+
self.config.write_to_disk && self.blk_device.is_some()
175+
}
100176
}
101177

102178
/// Read TSC (Time Stamp Counter).

network/src/mainloop/orchestrator.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use smoltcp::wire::{EthernetAddress, HardwareAddress};
1111

1212
use crate::driver::traits::NetworkDriver;
1313
use crate::mainloop::adapter::SmoltcpAdapter;
14-
use crate::mainloop::context::Context;
14+
use crate::mainloop::context::{Context, DownloadConfig};
1515
use crate::mainloop::serial;
1616
use crate::mainloop::state::{State, StepResult};
1717
use crate::mainloop::states::InitState;
@@ -75,7 +75,8 @@ pub fn download<D: NetworkDriver>(
7575
let tcp_handle = sockets.add(tcp_socket);
7676

7777
// Context
78-
let mut ctx = Context::new(url, tsc_freq);
78+
let config = DownloadConfig::download_only(url);
79+
let mut ctx = Context::new(config, tsc_freq);
7980
ctx.dhcp_handle = Some(dhcp_handle);
8081
ctx.tcp_handle = Some(tcp_handle);
8182

network/src/mainloop/states/dhcp.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,16 @@ impl<D: NetworkDriver> State<D> for DhcpState {
100100
iface.routes_mut().add_default_ipv4_route(router).ok();
101101
}
102102

103+
// Store DNS servers in context
103104
for (i, dns) in config.dns_servers.iter().enumerate() {
104105
serial::print("[DHCP] DNS ");
105106
serial::print_u32(i as u32);
106107
serial::print(": ");
107108
serial::print_ipv4(&dns.0);
108109
serial::println("");
110+
if i < 3 {
111+
ctx.dns_servers[i] = Some(smoltcp::wire::IpAddress::Ipv4(*dns));
112+
}
109113
}
110114

111115
self.got_ip = true;

network/src/mainloop/states/init.rs

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,48 +51,57 @@ impl<D: NetworkDriver> State<D> for InitState {
5151
serial::println("=====================================");
5252
serial::println("");
5353

54-
let url = ctx.url;
55-
serial::print("[INIT] URL: ");
56-
serial::println(url);
57-
58-
// Parse URL: http://host[:port]/path
59-
let url_without_scheme = if url.starts_with("https://") {
60-
ctx.resolved_port = 443;
61-
&url[8..]
62-
} else if url.starts_with("http://") {
63-
ctx.resolved_port = 80;
64-
&url[7..]
65-
} else {
66-
serial::println("[INIT] ERROR: URL must start with http:// or https://");
67-
return (Box::new(super::FailedState::new("invalid URL scheme")), StepResult::Failed("invalid URL"));
54+
// Parse URL by computing indices first, avoiding borrow conflicts.
55+
// URL format: scheme://host[:port]/path
56+
let (scheme_end, default_port) = {
57+
let url = ctx.config.url;
58+
if url.starts_with("https://") {
59+
(8usize, 443u16)
60+
} else if url.starts_with("http://") {
61+
(7usize, 80u16)
62+
} else {
63+
serial::println("[INIT] ERROR: URL must start with http:// or https://");
64+
return (Box::new(super::FailedState::new("invalid URL scheme")), StepResult::Failed("invalid URL"));
65+
}
6866
};
6967

70-
let (host_port, path) = match url_without_scheme.find('/') {
71-
Some(idx) => (&url_without_scheme[..idx], &url_without_scheme[idx..]),
72-
None => (url_without_scheme, "/"),
68+
// Compute indices for host and path
69+
let url = ctx.config.url;
70+
let rest = &url[scheme_end..];
71+
72+
let (host_end, path_start) = match rest.find('/') {
73+
Some(idx) => (scheme_end + idx, scheme_end + idx),
74+
None => (url.len(), url.len()),
7375
};
7476

75-
let host = match host_port.find(':') {
76-
Some(idx) => {
77-
if let Some(port) = parse_port(&host_port[idx + 1..]) {
78-
ctx.resolved_port = port;
79-
}
80-
&host_port[..idx]
77+
let host_port_slice = &url[scheme_end..host_end];
78+
let (host_slice_end, port) = match host_port_slice.find(':') {
79+
Some(colon_idx) => {
80+
let port_str = &host_port_slice[colon_idx + 1..];
81+
let port = parse_port(port_str).unwrap_or(default_port);
82+
(scheme_end + colon_idx, port)
8183
}
82-
None => host_port,
84+
None => (host_end, default_port),
8385
};
8486

85-
// Store parsed URL parts in context
86-
ctx.url_host = host;
87-
ctx.url_path = path;
87+
// Assign using direct indexing
88+
ctx.resolved_port = port;
89+
ctx.url_host = &ctx.config.url[scheme_end..host_slice_end];
90+
ctx.url_path = if path_start < ctx.config.url.len() {
91+
&ctx.config.url[path_start..]
92+
} else {
93+
"/"
94+
};
8895

96+
serial::print("[INIT] URL: ");
97+
serial::println(ctx.config.url);
8998
serial::print("[INIT] Host: ");
90-
serial::println(host);
99+
serial::println(ctx.url_host);
91100
serial::print("[INIT] Port: ");
92101
serial::print_u32(ctx.resolved_port as u32);
93102
serial::println("");
94103
serial::print("[INIT] Path: ");
95-
serial::println(path);
104+
serial::println(ctx.url_path);
96105
serial::print("[INIT] TSC freq: ");
97106
serial::print_u32((ctx.tsc_freq / 1_000_000) as u32);
98107
serial::println(" MHz");

network/src/pci/capability.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ impl Iterator for WalkCaps {
311311
/// Dump all capabilities to serial (uses crate's serial_println if available).
312312
#[cfg(feature = "serial_debug")]
313313
pub fn dump_capabilities(addr: PciAddr) {
314-
use crate::mainloop::bare_metal::{serial_print, serial_print_hex, serial_println};
314+
use crate::mainloop::serial::{serial_print, serial_print_hex, serial_println};
315315

316316
serial_print("PCI ");
317317
serial_print_hex(addr.bus as u64);

0 commit comments

Comments
 (0)