using System.Runtime.InteropServices; namespace XFESystem.NativeKernel; // These are unmanaged pointers/integers only. Never pass Zero-library strings, // arrays or objects into the separately linked Microsoft .NET runtime module. public static unsafe class RuntimeBridge { [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_virtual_reserve")] public static void* VirtualReserve(ulong bytes, ulong alignment) { ulong flags = Native.IrqSave(); void* result = (void*)VirtualMemory.Reserve(bytes, alignment); Native.IrqRestore(flags); return result; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_virtual_commit")] public static int VirtualCommit(void* address, ulong bytes) { ulong flags = Native.IrqSave(); int result = VirtualMemory.Commit((ulong)address, bytes) ? 1 : 0; Native.IrqRestore(flags); return result; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_virtual_decommit")] public static int VirtualDecommit(void* address, ulong bytes) { ulong flags = Native.IrqSave(); int result = VirtualMemory.Decommit((ulong)address, bytes) ? 1 : 0; Native.IrqRestore(flags); return result; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_virtual_release")] public static int VirtualRelease(void* address, ulong bytes) { ulong flags = Native.IrqSave(); int result = VirtualMemory.Release((ulong)address, bytes) ? 1 : 0; Native.IrqRestore(flags); return result; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_virtual_protect")] public static int VirtualProtect(void* address, ulong bytes, uint protection) { ulong flags = Native.IrqSave(); int result = VirtualMemory.Protect((ulong)address, bytes, protection) ? 1 : 0; Native.IrqRestore(flags); return result; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_alloc_pages")] public static void* AllocatePages(ulong pages) { if (pages == 0 || pages > 0xffffffffUL) return null; ulong flags = Native.IrqSave(); ulong physical = PhysicalMemory.Allocate((uint)pages); void* result = physical == 0 ? null : (void*)PhysicalMemory.ToVirtual(physical); Native.IrqRestore(flags); return result; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_free_pages")] public static int FreePages(void* address, ulong pages) { ulong value = (ulong)address; if (address == null || pages == 0 || pages > 0xffffffffUL || value < PhysicalMemory.Hhdm) return 0; ulong flags = Native.IrqSave(); int result = PhysicalMemory.Release(value - PhysicalMemory.Hhdm, (uint)pages) ? 1 : 0; Native.IrqRestore(flags); return result; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_mono_ns")] public static ulong MonotonicNanoseconds() => MonotonicClock.Nanoseconds(); [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_clock_ready")] public static int ClockReady() => MonotonicClock.Ready ? 1 : 0; [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_framebuffer_info")] public static int GetFramebuffer(NativeFrameSurface* surface) { if (surface == null || !Framebuffer.Ready || Kernel.Boot == null || Kernel.Boot->Framebuffer == null) return 0; LimineFramebuffer* source = Kernel.Boot->Framebuffer; surface->Address = (ulong)Framebuffer.Address; surface->MappedBytes = (ulong)Framebuffer.Pitch * Framebuffer.Height; surface->Width = Framebuffer.Width; surface->Height = Framebuffer.Height; surface->PitchBytes = Framebuffer.Pitch; surface->BitsPerPixel = source->BitsPerPixel; surface->RedMaskSize = source->RedSize; surface->RedMaskShift = source->RedShift; surface->GreenMaskSize = source->GreenSize; surface->GreenMaskShift = source->GreenShift; surface->BlueMaskSize = source->BlueSize; surface->BlueMaskShift = source->BlueShift; return 1; } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_write")] public static void Write(byte* bytes, ulong length) { if (bytes == null || length > 1024 * 1024) return; for (ulong i = 0; i < length; i++) Serial.Byte(bytes[i]); } [UnmanagedCallersOnly(EntryPoint = "xfe_runtime_halt")] public static void Halt(byte* reason) { Serial.Write("XFE_RUNTIME_FATAL "); if (reason != null) for (uint i = 0; i < 256 && reason[i] != 0; i++) Serial.Byte(reason[i]); Serial.Line(""); Framebuffer.BootStage(100, true); for (;;) Native.Halt(); } }