diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-01 03:44:57 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-01 03:44:57 +0200 |
| commit | 63d01e9d8eb6f3ccb6a96b7c577834276cf51add (patch) | |
| tree | f490b9969a8f781f48c2f168dc3e6c71c41339a9 /rsnix/src/interrupts.rs | |
| parent | rustfmt: reflow fat.rs/fs.rs formatting (diff) | |
| download | rs-dos-63d01e9d8eb6f3ccb6a96b7c577834276cf51add.tar.gz rs-dos-63d01e9d8eb6f3ccb6a96b7c577834276cf51add.zip | |
Clean up warnings, fix FAT32 multi-cluster dirs, prep for edition 2024
Warning cleanup (cargo check + clippy now 0 across the workspace):
- Migrate all 21 static_mut_refs sites to &raw mut accessors (fat, gop,
ps2, vt, ahci, interrupts, memory) so edition 2024 won't deny them
- panic = "abort" profiles: bare cargo check/build now works without
nightly/-Zbuild-std
- Wire TICKS in the timer ISR (it was never incremented, so the vt scroll
batching trigger was dead code)
- Clippy: efi_main becomes unsafe extern "efiapi" with a # Safety doc,
KeyBuf::new uses inline-const array repeat (no interior-mutable const),
editor main loop is a while-let, PIT control byte regrouped
- [workspace.lints.clippy] allows result_unit_err + needless_range_loop
(deliberate kernel style); large_enum_variant allowed on LineInput
- Drop now-stale static_mut_refs allow from the rsdos bin
FAT32 correctness fixes (both pre-existing, exposed by the SFN fix):
- Unique 8.3 short names: to_8_3() never disambiguated collisions, so
files sharing a long-name prefix got identical SFNs and fsck reported
duplicate directory entries. Add dir_short_names() + unique_short_name()
(~N tails, Windows-style) and force LFN when the SFN changes.
- Multi-cluster directories: scan_dir/dir_short_names stopped at the first
0x00 slot, hiding every entry written into a chained cluster (writes
failed with 'cannot write', duplicate SFNs accumulated); add_dir_entry
now packs the cluster (0xE5 deleted-markers) before extending so other
FAT readers (mtools, Windows) see the continuation too.
Other: delete dead fields (Disk.fis, Volume.fat_count), drop timer_irq/
keyboard_irq/rendered, refresh_and_exit is a documented unsafe fn, CONTEXT
.md corrected (stable toolchain, IRQ input, 4-crate layout), .gitignore
excludes .pi-subagents artifacts.
Validated: cargo check/clippy/fmt clean, make test-disk PASS on fresh and
reused images (incl. two directory-chain extensions and ~10 SFN tails),
editor round-trip smoke test PASS.
Diffstat (limited to 'rsnix/src/interrupts.rs')
| -rw-r--r-- | rsnix/src/interrupts.rs | 70 |
1 files changed, 10 insertions, 60 deletions
diff --git a/rsnix/src/interrupts.rs b/rsnix/src/interrupts.rs index 66dc59f..cbd234e 100644 --- a/rsnix/src/interrupts.rs +++ b/rsnix/src/interrupts.rs | |||
| @@ -98,7 +98,7 @@ fn pit_set_rate(hz: u64) { | |||
| 98 | let divisor = (PIT_FREQ / hz) as u16; | 98 | let divisor = (PIT_FREQ / hz) as u16; |
| 99 | unsafe { | 99 | unsafe { |
| 100 | // Mode 2, channel 0, lobyte/hibyte, binary | 100 | // Mode 2, channel 0, lobyte/hibyte, binary |
| 101 | asm!("out dx, al", in("dx") PIT_CMD, in("al") 0b00_11_010_0u8, | 101 | asm!("out dx, al", in("dx") PIT_CMD, in("al") 0b0011_0100u8, |
| 102 | options(nostack, preserves_flags)); | 102 | options(nostack, preserves_flags)); |
| 103 | asm!("out dx, al", in("dx") PIT_CH0, in("al") (divisor & 0xFF) as u8, | 103 | asm!("out dx, al", in("dx") PIT_CH0, in("al") (divisor & 0xFF) as u8, |
| 104 | options(nostack, preserves_flags)); | 104 | options(nostack, preserves_flags)); |
| @@ -122,47 +122,10 @@ unsafe impl Sync for KeyBuf {} | |||
| 122 | 122 | ||
| 123 | impl KeyBuf { | 123 | impl KeyBuf { |
| 124 | const fn new() -> Self { | 124 | const fn new() -> Self { |
| 125 | // UnsafeCell requires const initialisation in a const ctx. | 125 | // Inline-const array repeat (stable since 1.79): each element is a |
| 126 | // Build an array the long way — one cell at a time. | 126 | // fresh `UnsafeCell::new(0)` value, so no interior-mutable const. |
| 127 | const NEW_CELL: core::cell::UnsafeCell<u8> = core::cell::UnsafeCell::new(0); | ||
| 128 | // `[NEW_CELL; 256]` needs Clone, which UnsafeCell doesn't have. | ||
| 129 | // Use a union trick or just mark the whole buffer init with zeroes. | ||
| 130 | // SAFETY: we initialise via the const-fn path in init(). | ||
| 131 | Self { | 127 | Self { |
| 132 | buf: [ | 128 | buf: [const { core::cell::UnsafeCell::new(0) }; 256], |
| 133 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 134 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 135 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 136 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 137 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 138 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 139 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 140 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 141 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 142 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 143 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 144 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 145 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 146 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 147 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 148 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 149 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 150 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 151 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 152 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 153 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 154 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 155 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 156 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 157 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 158 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 159 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 160 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 161 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 162 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 163 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 164 | NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, NEW_CELL, | ||
| 165 | ], | ||
| 166 | head: AtomicU16::new(0), | 129 | head: AtomicU16::new(0), |
| 167 | tail: AtomicU16::new(0), | 130 | tail: AtomicU16::new(0), |
| 168 | } | 131 | } |
| @@ -297,7 +260,10 @@ struct IntFrame { | |||
| 297 | unsafe extern "C" fn isr_dispatch(frame: &IntFrame) { | 260 | unsafe extern "C" fn isr_dispatch(frame: &IntFrame) { |
| 298 | unsafe { | 261 | unsafe { |
| 299 | match frame.vector { | 262 | match frame.vector { |
| 300 | 32 => eoi(0), | 263 | 32 => { |
| 264 | TICKS.fetch_add(1, Ordering::Relaxed); | ||
| 265 | eoi(0); | ||
| 266 | } | ||
| 301 | 33 => { | 267 | 33 => { |
| 302 | let byte: u8; | 268 | let byte: u8; |
| 303 | core::arch::asm!("in al, dx", out("al") byte, in("dx") 0x60u16, | 269 | core::arch::asm!("in al, dx", out("al") byte, in("dx") 0x60u16, |
| @@ -311,22 +277,6 @@ unsafe extern "C" fn isr_dispatch(frame: &IntFrame) { | |||
| 311 | } | 277 | } |
| 312 | } | 278 | } |
| 313 | 279 | ||
| 314 | /// Timer IRQ (PIT channel 0 ~ 100 Hz). | ||
| 315 | fn timer_irq() { | ||
| 316 | eoi(0); | ||
| 317 | } | ||
| 318 | |||
| 319 | /// Keyboard IRQ — read scancode from port 0x60 and push to ring buffer. | ||
| 320 | fn keyboard_irq() { | ||
| 321 | let byte: u8; | ||
| 322 | unsafe { | ||
| 323 | asm!("in al, dx", out("al") byte, in("dx") 0x60, | ||
| 324 | options(nostack, preserves_flags)); | ||
| 325 | } | ||
| 326 | KEYBUF.push(byte); | ||
| 327 | eoi(1); | ||
| 328 | } | ||
| 329 | |||
| 330 | // --------------------------------------------------------------------------- | 280 | // --------------------------------------------------------------------------- |
| 331 | // Public API | 281 | // Public API |
| 332 | // --------------------------------------------------------------------------- | 282 | // --------------------------------------------------------------------------- |
| @@ -348,7 +298,7 @@ pub fn init() { | |||
| 348 | let cs = cs as u16; | 298 | let cs = cs as u16; |
| 349 | 299 | ||
| 350 | // Build the IDT. | 300 | // Build the IDT. |
| 351 | let idt_ptr = IDT.as_mut_ptr(); | 301 | let idt_ptr = core::ptr::addr_of_mut!(IDT[0]); |
| 352 | let spurious = isr_stub_spurious as *const () as u64; | 302 | let spurious = isr_stub_spurious as *const () as u64; |
| 353 | 303 | ||
| 354 | // Fill all 256 entries with the spurious handler. | 304 | // Fill all 256 entries with the spurious handler. |
| @@ -370,7 +320,7 @@ pub fn init() { | |||
| 370 | ]; | 320 | ]; |
| 371 | 321 | ||
| 372 | // Load IDT. | 322 | // Load IDT. |
| 373 | asm!("lidt [{}]", in(reg) &IDTR, options(nostack, preserves_flags)); | 323 | asm!("lidt [{}]", in(reg) core::ptr::addr_of!(IDTR), options(nostack, preserves_flags)); |
| 374 | 324 | ||
| 375 | // Remap PIC and mask everything. | 325 | // Remap PIC and mask everything. |
| 376 | remap_pic(); | 326 | remap_pic(); |
