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();
}
}
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();
}
}