diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-01 14:21:11 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-01 14:21:11 +0200 |
| commit | 6447eb12948d37b74adae2fdbf1db5a9d7b363d5 (patch) | |
| tree | 0aa03cc79db7ff49f5a64a484ff197ba05f9b6bc /rsnix/src/vt.rs | |
| parent | klog: kernel log ring + /dev/klog + klog shell command (diff) | |
| download | rs-dos-6447eb12948d37b74adae2fdbf1db5a9d7b363d5.tar.gz rs-dos-6447eb12948d37b74adae2fdbf1db5a9d7b363d5.zip | |
klog: [ssss.mmm] millisecond timestamps from the PIT
- interrupts::uptime_ms(): monotonic ms since boot — the 100 Hz PIT
tick (10 ms) plus interpolation from the PIT's live 1.19 MHz
down-counter (read twice around the tick load; a count jump means a
tick fired between reads) for true sub-ms resolution. TICKS widened
AtomicU16 -> AtomicU64 (u16 wrapped after ~11 min).
- PIT_READY gates interpolation until interrupts::init configures the
timer, so early-boot lines are deterministically [0000.000] instead
of uninitialised-PIT noise; klog clamps timestamps monotonic.
- The CMOS RTC cannot provide milliseconds (1 Hz BCD device, seconds
only) — millis come from the PIT.
- klog stores ms per line at append time; dump format is now
'[0000.123] 000000 === rsnix boot ===' (user-specified format).
Verified in QEMU: first line [0000.000], Phase-2 lines show real
monotonic ms (fs: vfs ready at [0000.519], self-test [0000.524]),
per-dump monotonicity, boot.log persists timestamps, test-disk round
trip fsck-clean.
Diffstat (limited to '')
| -rw-r--r-- | rsnix/src/vt.rs | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/rsnix/src/vt.rs b/rsnix/src/vt.rs index 709ea71..53821b7 100644 --- a/rsnix/src/vt.rs +++ b/rsnix/src/vt.rs | |||
| @@ -224,7 +224,13 @@ fn put_byte(b: u8) { | |||
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | fn param(i: usize, default: usize) -> usize { | 226 | fn param(i: usize, default: usize) -> usize { |
| 227 | unsafe { if i < NPARAMS { PARAMS[i] } else { default } } | 227 | unsafe { |
| 228 | if i < NPARAMS { | ||
| 229 | PARAMS[i] | ||
| 230 | } else { | ||
| 231 | default | ||
| 232 | } | ||
| 233 | } | ||
| 228 | } | 234 | } |
| 229 | 235 | ||
| 230 | /// Place a printable glyph at the cursor and advance (wrapping/scrolling). | 236 | /// Place a printable glyph at the cursor and advance (wrapping/scrolling). |
| @@ -409,7 +415,7 @@ fn newline() { | |||
| 409 | /// only the newly-exposed rows. | 415 | /// only the newly-exposed rows. |
| 410 | const SCROLL_BATCH: usize = 16; | 416 | const SCROLL_BATCH: usize = 16; |
| 411 | static mut PENDING_SCROLLS: usize = 0; | 417 | static mut PENDING_SCROLLS: usize = 0; |
| 412 | static mut LAST_SYNC_TICK: u16 = 0; | 418 | static mut LAST_SYNC_TICK: u64 = 0; |
| 413 | 419 | ||
| 414 | /// Shift the logical grid up one row; defer the framebuffer shift. | 420 | /// Shift the logical grid up one row; defer the framebuffer shift. |
| 415 | fn scroll_up() { | 421 | fn scroll_up() { |
| @@ -424,7 +430,7 @@ fn scroll_up() { | |||
| 424 | // Batch: sync when enough scrolls piled up, or when the stream | 430 | // Batch: sync when enough scrolls piled up, or when the stream |
| 425 | // pauses (~40 ms at the 100 Hz timer) so interactive output still | 431 | // pauses (~40 ms at the 100 Hz timer) so interactive output still |
| 426 | // appears promptly. | 432 | // appears promptly. |
| 427 | const TICK_LIMIT: u16 = 4; | 433 | const TICK_LIMIT: u64 = 4; |
| 428 | let now = crate::interrupts::TICKS.load(core::sync::atomic::Ordering::Relaxed); | 434 | let now = crate::interrupts::TICKS.load(core::sync::atomic::Ordering::Relaxed); |
| 429 | if PENDING_SCROLLS >= SCROLL_BATCH || now.wrapping_sub(LAST_SYNC_TICK) > TICK_LIMIT { | 435 | if PENDING_SCROLLS >= SCROLL_BATCH || now.wrapping_sub(LAST_SYNC_TICK) > TICK_LIMIT { |
| 430 | sync_scroll(); | 436 | sync_scroll(); |
