mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-29 06:28:21 +00:00
feat(amd64): add a bunch of stuff
This commit is contained in:
@@ -1,22 +1,11 @@
|
||||
const amd64 = @import("arch");
|
||||
const kvm = amd64.hypervisor.kvm;
|
||||
const b = @import("base");
|
||||
const std = @import("std");
|
||||
const mm = b.mm;
|
||||
const ke = b.ke;
|
||||
|
||||
const PVClock = extern struct {
|
||||
version: u32,
|
||||
pad0: u32,
|
||||
tsc_timestamp: u64,
|
||||
system_time: u64,
|
||||
tsc_to_system_mul: u32,
|
||||
tsc_shift: i8,
|
||||
flags: u8,
|
||||
pad1: [2]u8,
|
||||
};
|
||||
|
||||
var pvclock: *PVClock = undefined;
|
||||
|
||||
var pvclock_src: kvm.PVClockSource = undefined;
|
||||
var pvclock_tc: ke.TimeCounter = .{
|
||||
.name = "pvclock",
|
||||
.quality = 75,
|
||||
@@ -27,35 +16,12 @@ var pvclock_tc: ke.TimeCounter = .{
|
||||
.n = 0,
|
||||
};
|
||||
|
||||
var time_at_boot: u64 = 0;
|
||||
|
||||
pub fn init() linksection(b.init) void {
|
||||
const page = mm.phys.alloc();
|
||||
pvclock = @ptrFromInt(mm.p2v(page));
|
||||
|
||||
amd64.write_msr(.KvmSystemTimeNew, page | 1);
|
||||
|
||||
time_at_boot = read_pvclock();
|
||||
|
||||
pvclock_src = kvm.PVClockSource.init(page, mm.p2v(page));
|
||||
ke.time.register_source(&pvclock_tc);
|
||||
}
|
||||
|
||||
fn read_pvclock() u64 {
|
||||
while (true) {
|
||||
const ver = b.mmio_read(u32, @intFromPtr(&pvclock.version));
|
||||
if (ver & 1 != 0) continue; // Update in progress.
|
||||
|
||||
const tsc_shift = b.mmio_read(i8, @intFromPtr(&pvclock.tsc_shift));
|
||||
|
||||
const tsc_delta = amd64.rdtsc() - b.mmio_read(u64, @intFromPtr(&pvclock.tsc_timestamp));
|
||||
const shifted = if (tsc_shift >= 0)
|
||||
tsc_delta << @intCast(tsc_shift)
|
||||
else
|
||||
tsc_delta >> @intCast(-tsc_shift);
|
||||
|
||||
const ns = b.mmio_read(u64, @intFromPtr(&pvclock.system_time)) +
|
||||
(shifted * @as(u128, b.mmio_read(u32, @intFromPtr(&pvclock.tsc_to_system_mul))) >> 32);
|
||||
|
||||
if (b.mmio_read(u32, @intFromPtr(&pvclock.version)) == ver) return @as(u64, @truncate(ns)) - time_at_boot;
|
||||
}
|
||||
return pvclock_src.read();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user