mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-27 21:58:20 +00:00
112 lines
2.5 KiB
Zig
112 lines
2.5 KiB
Zig
const r = @import("root");
|
|
const pl = r.pl;
|
|
const amd64 = r.arch;
|
|
const std = @import("std");
|
|
const tsc = @import("tsc.zig");
|
|
const pvclock = @import("pvclock.zig");
|
|
pub const apic = @import("apic.zig");
|
|
pub const smp = @import("smp.zig");
|
|
|
|
const ki = r.ke.private;
|
|
|
|
pub const name = "PC";
|
|
|
|
const com1 = 0x3F8;
|
|
|
|
const log = std.log.scoped(.@"amd64/pc");
|
|
|
|
fn com1_init() linksection(r.init) void {
|
|
amd64.outb(com1 + 0x3, 0x80);
|
|
amd64.outb(com1 + 0x0, 0x0c);
|
|
amd64.outb(com1 + 0x1, 0x00);
|
|
amd64.outb(com1 + 0x3, 0x03);
|
|
amd64.outb(com1 + 0x2, 0xc7);
|
|
amd64.outb(com1 + 0x4, 0x00);
|
|
}
|
|
|
|
fn com1_write(c: u8) void {
|
|
while ((amd64.inb(com1 + 0x5) & 0x20) == 0) {}
|
|
if (c == '\n') {
|
|
amd64.outb(com1, '\r');
|
|
}
|
|
amd64.outb(com1, c);
|
|
}
|
|
|
|
pub fn early_init(boot_info: *pl.BootInfo) linksection(r.init) void {
|
|
com1_init();
|
|
|
|
const f = amd64.cpu_features;
|
|
|
|
log.info("CPU: {s}", .{&f.brand_string});
|
|
log.info("vendor={s} family={x} features={}{}{}{}{}{}{}{}{}{}{}{}", .{
|
|
@tagName(f.vendor),
|
|
f.family,
|
|
@intFromBool(f.x2apic),
|
|
@intFromBool(f.five_level_paging),
|
|
@intFromBool(f.nx),
|
|
@intFromBool(f.pcid),
|
|
@intFromBool(f.pge),
|
|
@intFromBool(f.smap),
|
|
@intFromBool(f.smep),
|
|
@intFromBool(f.gib_pages),
|
|
@intFromBool(f.invariant_tsc),
|
|
@intFromBool(f.xsave),
|
|
@intFromBool(f.fxsave),
|
|
@intFromBool(f.tsc_deadline),
|
|
});
|
|
|
|
if (amd64.hypervisor.info) |h| {
|
|
log.info("running on hypervisor {s}", .{@tagName(h.vendor)});
|
|
}
|
|
_ = boot_info;
|
|
}
|
|
|
|
fn init_hypervisor(hv: amd64.hypervisor.Info) void {
|
|
switch (hv.data) {
|
|
.KVM => |kvm_info| {
|
|
if (kvm_info.features.clocksource2 == true) {
|
|
pvclock.init();
|
|
}
|
|
},
|
|
else => {},
|
|
}
|
|
}
|
|
|
|
pub fn init_ap() void {
|
|
if (amd64.cpu_features.x2apic) {
|
|
apic.enter_x2apic();
|
|
}
|
|
apic.init_local();
|
|
}
|
|
|
|
pub fn late_init(boot_info: *pl.BootInfo) linksection(r.init) void {
|
|
if (amd64.hypervisor.info) |hv| {
|
|
init_hypervisor(hv);
|
|
}
|
|
|
|
pl.acpi.init(boot_info);
|
|
|
|
tsc.init();
|
|
apic.init();
|
|
|
|
if (apic.apics.items.len != 0) {
|
|
smp.init();
|
|
}
|
|
|
|
if (amd64.cpu_features.x2apic) {
|
|
apic.enter_x2apic();
|
|
}
|
|
}
|
|
|
|
pub fn debug_write(c: u8) void {
|
|
com1_write(c);
|
|
}
|
|
|
|
pub fn arm_timer(deadline: r.Nanoseconds) void {
|
|
apic.arm_timer(deadline);
|
|
}
|
|
|
|
pub fn send_resched_ipi(target_cpu: u32) void {
|
|
apic.send_ipi(smp.cpu_id_to_apic_id[target_cpu], 240, 0);
|
|
}
|