Skip to content

Commit 207f29e

Browse files
author
T. Andrew Davis
committed
well nice little hardware vs qemu reality check here will have to completely refactor the network stack and basically recreate the bootom ~30% of linux to get our hardware in a state where drivers can even exist before we try to do anything. Qemu abstracts this away for us but on real hardware WE CREATE REALITY and we cant assume to start working when reality isnt even established first this is gonna be some work... Im just happy get to it now and not after writing more features in qemu and then finding out i need to rewrite 40000 loc
1 parent 9b32f93 commit 207f29e

51 files changed

Lines changed: 7998 additions & 47 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bootloader/src/tui/distro_downloader/catalog.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ pub static DISTRO_CATALOG: &[DistroEntry] = &[
157157
"Tails",
158158
"Amnesic Incognito Live System - Privacy focused",
159159
"6.10",
160-
"http://mirror.freedif.org/Tails/tails/stable/tails-amd64-7.3.1/tails-amd64-7.3.1.iso",
160+
"http://mirror.freedif.org/Tails/tails/stable/tails-amd64-7.4/tails-amd64-7.4.iso",
161161
1_400_000_000,
162162
"tails-6.10.iso",
163163
DistroCategory::Privacy,
Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
# hwinit Extraction Inventory
2+
3+
## Purpose
4+
5+
This document catalogs every piece of code being extracted from the `network/` crate into the new `hwinit` crate. It exists so that future contributors understand *what* was moved, *why* it was moved, and *what assumptions* the network stack can make after the refactor.
6+
7+
If you're wondering why DMA setup isn't in your driver anymore: read this.
8+
9+
---
10+
11+
## Summary
12+
13+
| Category | Files | Lines (approx) | Destination |
14+
|-----------------|-------|----------------|-----------------------|
15+
| PCI ASM | 5 | 1,809 | `hwinit/asm/pci/` |
16+
| Core ASM | 6 | 605 | `hwinit/asm/cpu/`, `hwinit/asm/` |
17+
| PCI Rust | 3 | 494 | `hwinit/src/pci/` |
18+
| Core Rust | 6 | 340 | `hwinit/src/cpu/` |
19+
| Generic DMA | 1 | 182 | `hwinit/src/dma/` |
20+
| Partial Refactor| 4 | ~395 (extracted)| Various removals |
21+
| **Total** | **25**| **~3,825** | |
22+
23+
---
24+
25+
## Category 1: PCI ASM (1,809 lines)
26+
27+
These files implement PCI configuration space access at the assembly level. They are not network-specific. They are not driver-specific. They are how you talk to the PCI bus, period.
28+
29+
### Files (move entirely)
30+
31+
| Source File | Lines | Destination |
32+
|----------------------------------------|-------|-------------------------------------|
33+
| `network/asm/pci/legacy.s` | 387 | `hwinit/asm/pci/legacy.s` |
34+
| `network/asm/pci/bar.s` | 402 | `hwinit/asm/pci/bar.s` |
35+
| `network/asm/pci/capability.s` | 415 | `hwinit/asm/pci/capability.s` |
36+
| `network/asm/pci/ecam.s` | 184 | `hwinit/asm/pci/ecam.s` |
37+
| `network/asm/pci/virtio_cap.s` | 421 | `hwinit/asm/pci/virtio_cap.s` |
38+
39+
### Why these are platform-level
40+
41+
- **legacy.s**: CF8/CFC port I/O for PCI Type 1 configuration mechanism. This is how you read/write PCI config space on *any* x86 machine. Not network. Not block. Just PCI.
42+
43+
- **bar.s**: BAR sizing algorithm (write 0xFFFFFFFF, read back, decode). Needed to know how big MMIO regions are. Every PCI driver needs this, or none of them should implement it.
44+
45+
- **capability.s**: PCI capability chain walking. MSI, MSI-X, power management, VirtIO capabilities — all found by walking this chain. Generic infrastructure.
46+
47+
- **ecam.s**: PCIe Enhanced Configuration Access Mechanism. Memory-mapped config space access for extended registers (above 256 bytes). Platform topology feature.
48+
49+
- **virtio_cap.s**: Yes, this says "virtio" but it's capability discovery infrastructure that happens to understand VirtIO capability types. Block devices use the same mechanism.
50+
51+
### Functions exposed
52+
53+
```asm
54+
; From legacy.s
55+
asm_pci_cfg_read8, asm_pci_cfg_read16, asm_pci_cfg_read32
56+
asm_pci_cfg_write8, asm_pci_cfg_write16, asm_pci_cfg_write32
57+
asm_pci_make_addr
58+
59+
; From bar.s
60+
asm_pci_bar_read, asm_pci_bar_read64
61+
asm_pci_bar_size, asm_pci_bar_size64
62+
asm_pci_bar_type, asm_pci_bar_is_io, asm_pci_bar_is_64bit
63+
asm_pci_bar_base, asm_pci_bar_base64
64+
65+
; From capability.s
66+
asm_pci_has_capabilities, asm_pci_get_cap_ptr
67+
asm_pci_find_cap, asm_pci_read_cap_id, asm_pci_read_cap_next
68+
69+
; From ecam.s
70+
asm_pcie_ecam_read32, asm_pcie_ecam_write32, asm_pcie_calc_ecam_addr
71+
72+
; From virtio_cap.s
73+
asm_pci_find_virtio_cap, asm_virtio_pci_parse_cap
74+
asm_virtio_pci_read_bar, asm_virtio_pci_probe_caps
75+
```
76+
77+
---
78+
79+
## Category 2: Core ASM (605 lines)
80+
81+
CPU primitives that every bare-metal component needs. These aren't "network" primitives. They're "talking to x86 hardware" primitives.
82+
83+
### Files (move entirely)
84+
85+
| Source File | Lines | Destination |
86+
|----------------------------------------|-------|-------------------------------------|
87+
| `network/asm/core/barriers.s` | 74 | `hwinit/asm/cpu/barriers.s` |
88+
| `network/asm/core/cache.s` | 97 | `hwinit/asm/cpu/cache.s` |
89+
| `network/asm/core/delay.s` | 113 | `hwinit/asm/cpu/delay.s` |
90+
| `network/asm/core/mmio.s` | 125 | `hwinit/asm/mmio.s` |
91+
| `network/asm/core/pio.s` | 129 | `hwinit/asm/pio.s` |
92+
| `network/asm/core/tsc.s` | 67 | `hwinit/asm/cpu/tsc.s` |
93+
94+
### Why these are platform-level
95+
96+
- **barriers.s**: SFENCE, LFENCE, MFENCE. Memory ordering guarantees for DMA. *Every* DMA-capable driver needs these. Zero network-specific content.
97+
98+
- **cache.s**: CLFLUSH, CLFLUSHOPT. Cache line management for DMA coherency. Block devices need this. Graphics needs this. Not network-specific.
99+
100+
- **delay.s**: TSC-based timing delays. Hardware often needs "wait 10μs after reset" type sequencing. Universal requirement.
101+
102+
- **mmio.s**: Memory-mapped I/O read/write with volatile semantics. How you talk to device registers. Period.
103+
104+
- **pio.s**: Port I/O instructions (IN/OUT). Legacy hardware access. PCI CF8/CFC uses this.
105+
106+
- **tsc.s**: RDTSC and RDTSC+serialization. Cycle-accurate timing for timeouts, delays, performance measurement.
107+
108+
### Functions exposed
109+
110+
```asm
111+
; Barriers
112+
asm_bar_sfence, asm_bar_lfence, asm_bar_mfence
113+
114+
; Cache
115+
asm_cache_clflush, asm_cache_clflushopt, asm_cache_flush_range
116+
117+
; Delay
118+
asm_delay_tsc, asm_delay_us, asm_delay_ms
119+
120+
; MMIO
121+
asm_mmio_read8, asm_mmio_read16, asm_mmio_read32
122+
asm_mmio_write8, asm_mmio_write16, asm_mmio_write32
123+
124+
; PIO
125+
asm_pio_read8, asm_pio_read16, asm_pio_read32
126+
asm_pio_write8, asm_pio_write16, asm_pio_write32
127+
128+
; TSC
129+
asm_tsc_read, asm_tsc_read_serialized
130+
```
131+
132+
---
133+
134+
## Category 3: PCI Rust (494 lines)
135+
136+
Rust bindings and abstractions over the PCI ASM layer. Thin wrappers providing safe(ish) access to PCI configuration space.
137+
138+
### Files (move entirely)
139+
140+
| Source File | Lines | Destination |
141+
|----------------------------------------|-------|-------------------------------------|
142+
| `network/src/pci/mod.rs` | 18 | `hwinit/src/pci/mod.rs` |
143+
| `network/src/pci/config.rs` | 122 | `hwinit/src/pci/config.rs` |
144+
| `network/src/pci/capability.rs` | 354 | `hwinit/src/pci/capability.rs` |
145+
146+
### Why these are platform-level
147+
148+
- **config.rs**: `PciAddr` struct, `pci_cfg_read*`, `pci_cfg_write*`, standard offset constants. This is "how to address and access PCI devices" — pure platform infrastructure.
149+
150+
- **capability.rs**: Capability chain walking, VirtIO capability parsing. Used by both VirtIO-net and VirtIO-blk. Not network-specific.
151+
152+
- **mod.rs**: Re-exports. Follows the above.
153+
154+
### Types/Functions exposed
155+
156+
```rust
157+
// From config.rs
158+
pub struct PciAddr { bus, device, function }
159+
pub fn pci_cfg_read8(addr: PciAddr, offset: u8) -> u8
160+
pub fn pci_cfg_read16(addr: PciAddr, offset: u8) -> u16
161+
pub fn pci_cfg_read32(addr: PciAddr, offset: u8) -> u32
162+
pub fn pci_cfg_write8(addr: PciAddr, offset: u8, value: u8)
163+
pub fn pci_cfg_write16(addr: PciAddr, offset: u8, value: u16)
164+
pub fn pci_cfg_write32(addr: PciAddr, offset: u8, value: u32)
165+
pub mod offset { VENDOR_ID, DEVICE_ID, COMMAND, STATUS, ... }
166+
167+
// From capability.rs
168+
pub struct VirtioCapInfo { ... }
169+
pub struct VirtioPciCaps { ... }
170+
pub const VIRTIO_PCI_CAP_*
171+
```
172+
173+
---
174+
175+
## Category 4: Core Rust (340 lines)
176+
177+
Rust wrappers for CPU primitives. Thin, unsafe-wrapping convenience functions.
178+
179+
### Files (move entirely)
180+
181+
| Source File | Lines | Destination |
182+
|----------------------------------------------|-------|-------------------------------------|
183+
| `network/src/asm/core/mod.rs` | 9 | `hwinit/src/cpu/mod.rs` |
184+
| `network/src/asm/core/barriers.rs` | 57 | `hwinit/src/cpu/barriers.rs` |
185+
| `network/src/asm/core/cache.rs` | 40 | `hwinit/src/cpu/cache.rs` |
186+
| `network/src/asm/core/mmio.rs` | 96 | `hwinit/src/cpu/mmio.rs` |
187+
| `network/src/asm/core/pio.rs` | 88 | `hwinit/src/cpu/pio.rs` |
188+
| `network/src/asm/core/tsc.rs` | 50 | `hwinit/src/cpu/tsc.rs` |
189+
190+
### Why these are platform-level
191+
192+
Same reasoning as Core ASM — these are Rust bindings for CPU/platform primitives. They wrap the assembly. They're not network logic.
193+
194+
### Functions exposed
195+
196+
```rust
197+
// barriers.rs
198+
pub fn sfence(), pub fn lfence(), pub fn mfence()
199+
200+
// cache.rs
201+
pub unsafe fn clflush(addr: *const u8)
202+
pub unsafe fn clflushopt(addr: *const u8)
203+
pub unsafe fn flush_range(addr: *const u8, len: usize)
204+
205+
// mmio.rs
206+
pub unsafe fn read8(addr: u64) -> u8 // etc.
207+
pub unsafe fn write8(addr: u64, val: u8) // etc.
208+
209+
// pio.rs
210+
pub unsafe fn inb(port: u16) -> u8 // etc.
211+
pub unsafe fn outb(port: u16, val: u8) // etc.
212+
213+
// tsc.rs
214+
pub fn read_tsc() -> u64
215+
pub fn read_tsc_serialized() -> u64
216+
```
217+
218+
---
219+
220+
## Category 5: Generic DMA (182 lines)
221+
222+
DMA region definition and layout abstraction. This is "where do descriptors and buffers live in memory"infrastructure, not protocol.
223+
224+
### Files (move entirely)
225+
226+
| Source File | Lines | Destination |
227+
|----------------------------------------|-------|-------------------------------------|
228+
| `network/src/dma/region.rs` | 182 | `hwinit/src/dma/region.rs` |
229+
230+
### Why this is platform-level
231+
232+
`DmaRegion` is a container for:
233+
- CPU pointer to DMA-capable memory
234+
- Corresponding bus address
235+
- Layout constants (offsets for descriptors, buffers)
236+
237+
This is **not** network-specific. VirtIO-blk uses identical structures. NVMe would too. The layout constants currently in this file are network-specific and will be split:
238+
239+
- **Generic `DmaRegion` struct** → `hwinit/src/dma/region.rs`
240+
- **Network-specific layout constants**remain in `network/src/dma/` as driver config
241+
242+
### What moves
243+
244+
```rust
245+
// To hwinit
246+
pub struct DmaRegion {
247+
cpu_ptr: *mut u8,
248+
bus_addr: u64,
249+
size: usize,
250+
}
251+
252+
impl DmaRegion {
253+
pub const MIN_SIZE: usize = 2 * 1024 * 1024;
254+
pub unsafe fn new(cpu_ptr: *mut u8, bus_addr: u64, size: usize) -> Self;
255+
pub fn cpu_base(&self) -> *mut u8;
256+
pub fn bus_base(&self) -> u64;
257+
pub fn size(&self) -> usize;
258+
}
259+
```
260+
261+
### What stays in network
262+
263+
```rust
264+
// Network-specific layout (stays in network crate)
265+
pub const RX_DESC_OFFSET: usize = 0x0000;
266+
pub const TX_DESC_OFFSET: usize = 0x0800;
267+
// ... queue-specific offsets
268+
```
269+
270+
---
271+
272+
## Category 6: Partial Refactors (395 lines extracted)
273+
274+
These files contain *mixed* responsibilities. Some code is platform-level (PCI scanning, bus mastering), some is driver-level (vendor ID matching, driver instantiation).
275+
276+
### Files affected
277+
278+
| Source File | Total Lines | Extract | Keep | Notes |
279+
|------------------------------------------|-------------|---------|------|---------------------------------|
280+
| `network/src/boot/probe.rs` | 319 | ~100 | ~219 | PCI scan loops, enable_device |
281+
| `network/src/boot/block_probe.rs` | 426 | ~180 | ~246 | PCI scan loops, enable_pci_device |
282+
| `network/src/pci/mod.rs` | 18 | 18 | 0 | Entire file moves |
283+
| `network/src/dma/mod.rs` | 17 | ~8 | ~9 | Generic re-exports |
284+
| `network/src/boot/handoff.rs` | 581 | ~20 | ~561 | DMA validation constants |
285+
286+
### probe.rs — What gets extracted
287+
288+
```rust
289+
// REMOVE: PCI bus scanning (lines 122-173)
290+
// This triple-nested loop scanning bus/device/function belongs in hwinit.
291+
// Network should receive a list of pre-discovered, pre-enabled devices.
292+
293+
fn find_virtio_nic() -> Option<(PciAddr, u64)> {
294+
for bus in 0..=255u8 { // ← Platform concern
295+
for device in 0..32u8 { // ← Platform concern
296+
for function in 0..8u8 { // ← Platform concern
297+
// ... vendor ID checks, BAR reads
298+
}
299+
}
300+
}
301+
}
302+
303+
// REMOVE: enable_device calls (line 199-200, 222-223)
304+
// Bus mastering enablement is platform init, not driver logic.
305+
enable_device(info.pci_addr);
306+
pci_cfg_write16(pci_addr, offset::COMMAND, cmd | 0x06);
307+
```
308+
309+
### block_probe.rs — What gets extracted
310+
311+
```rust
312+
// REMOVE: PCI bus scanning (lines 131-196)
313+
// Identical pattern to probe.rs. Platform scans once, passes device list.
314+
315+
fn find_ahci_controller() -> Option<AhciInfo> {
316+
for bus in 0..=255u8 { ... } // ← Platform concern
317+
}
318+
319+
fn find_virtio_blk() -> Option<(PciAddr, u64)> {
320+
for bus in 0..=255u8 { ... } // ← Platform concern
321+
}
322+
323+
// REMOVE: enable_pci_device calls
324+
// Same story: platform enables, driver consumes.
325+
```
326+
327+
### handoff.rs — What gets extracted
328+
329+
```rust
330+
// MOVE to hwinit: DMA validation constants (lines 26-29)
331+
pub const MIN_DMA_SIZE: u64 = 2 * 1024 * 1024;
332+
// DMA policy is platform policy, not network policy.
333+
```
334+
335+
---
336+
337+
## What the Network Crate Loses
338+
339+
After this refactor, `network/` will **not** contain:
340+
341+
1. **PCI enumeration** — No bus/device/function scanning
342+
2. **PCI config access** — No direct CF8/CFC or ECAM reads
343+
3. **Bus mastering enablement** — No `COMMAND |= 0x06` writes
344+
4. **DMA allocation policy** — No "allocate below 4GB" logic
345+
5. **CPU primitives** — No SFENCE/LFENCE/TSC bindings
346+
6. **MMIO/PIO primitives** — No direct port/memory access wrappers
347+
7. **Cache management** — No CLFLUSH invocations for DMA prep
348+
349+
---
350+
351+
## What the Network Crate May Assume
352+
353+
After `hwinit` has run, network drivers may assume:
354+
355+
1. **Devices are pre-discovered** — Receive `PreparedDevice` structs with:
356+
- PCI address (bus/device/function)
357+
- MMIO base address (already decoded from BARs)
358+
- Device type/variant
359+
360+
2. **Bus mastering is enabled** — COMMAND register already has memory space and bus master bits set
361+
362+
3. **DMA is legal** — Memory regions are:
363+
- Allocated below 4GB (or IOMMU is configured for remapping)
364+
- Identity-mapped (bus address = physical address)
365+
- Cache-coherent or properly flushed
366+
367+
4. **IOMMU is configured** — If present, identity domain established
368+
369+
5. **Timing is calibrated** — TSC frequency known and validated
370+
371+
6. **Platform is sane** — No need for "defensive" PCI probing or "just in case" bus master re-enablement
372+
373+
---
374+
375+
## Verification Checklist
376+
377+
Before declaring Phase 1 complete, verify:
378+
379+
- [ ] All files listed above exist at the specified paths
380+
- [ ] Line counts are approximately correct (±10%)
381+
- [ ] No files are missing from inventory
382+
- [ ] Categories correctly classify platform vs. driver responsibility
383+
- [ ] "What network loses" list is complete
384+
- [ ] "What network may assume" captures all preconditions
385+
386+
---
387+
388+
*Last updated: 2026-01-16*
389+
*Phase: 1 — Documentation & Inventory*

0 commit comments

Comments
 (0)