summaryrefslogtreecommitdiffstats
path: root/rsnix/src/interrupts.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-01 03:44:57 +0200
committersalmonik <salmonik@tuta.io>2026-08-01 03:44:57 +0200
commit63d01e9d8eb6f3ccb6a96b7c577834276cf51add (patch)
treef490b9969a8f781f48c2f168dc3e6c71c41339a9 /rsnix/src/interrupts.rs
parentrustfmt: reflow fat.rs/fs.rs formatting (diff)
downloadrs-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.rs70
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
123impl KeyBuf { 123impl 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 {
297unsafe extern "C" fn isr_dispatch(frame: &IntFrame) { 260unsafe 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).
315fn timer_irq() {
316 eoi(0);
317}
318
319/// Keyboard IRQ — read scancode from port 0x60 and push to ring buffer.
320fn 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();