//! RISC-V 64-bit platform-specific implementations. const boot = @import("riscv64/boot.zig"); const regs = @import("riscv64/regs.zig"); const std = @import("std"); const builtin = @import("builtin"); export const _ = boot.rv64_bsp_lower_entry; /// This CPU's HART (HARdware Thread) ID. pub threadlocal var t_hart_id: u32 = 0; /// RISC-V task context pub const Context = @import("riscv64/context.zig").Context; pub inline fn halt() noreturn { while (true) { _ = set_interrupt_mask(true); wait_for_interrupt(); } } pub inline fn set_interrupt_mask(mask: bool) bool { const old = interrupt_mask(); if (mask) { regs.SSTATUS.modify(.{}, .{ .SIE = true }); } else { regs.SSTATUS.modify(.{ .SIE = true }, .{}); } return old; } pub fn interrupt_mask() bool { return regs.SSTATUS.read().SIE; } pub inline fn wait_for_interrupt() void { asm volatile ("wfi"); } pub inline fn spin_hint() void { // Don't want to explicitly enable Zihintpause ext, so just paste this as raw opcode asm volatile (".word 0x0100000f"); } pub inline fn barrier(comptime ordering: std.builtin.AtomicOrder) void { switch (ordering) { .acquire => { asm volatile ("fence rw, w"); }, .release => { asm volatile ("fence w, rw"); }, .acq_rel, .seq_cst => { asm volatile ("fence rw, rw"); }, .unordered, .monotonic => {}, } asm volatile ("" ::: "memory"); } pub inline fn set_thread_pointer(tp: usize) void { asm volatile ("mv tp, %[tp]" : : [tp] "r" (tp), : "memory" ); }