rumpk/libs/membrane/sys_arch.c

137 lines
3.9 KiB
C

// SPDX-License-Identifier: LSL-1.0
// Copyright (c) 2026 Markus Maiwald
// Stewardship: Self Sovereign Society Foundation
//
// This file is part of the Nexus Sovereign Core.
// See legal/LICENSE_SOVEREIGN.md for license terms.
/**
* @file sys_arch.c
* @brief lwIP System Architecture Layer (NO_SYS Mode)
*
* The Membrane Graft: This provides the minimal OS abstraction layer
* required by lwIP in NO_SYS=1 mode (single-threaded, event-driven).
*
* Architecture Philosophy:
* - NO threading primitives (NO_SYS=1)
* - Time via kernel syscall (not rdtime)
* - No critical sections needed (single fiber context)
*/
#include <stdarg.h>
#include <stddef.h>
#include "lwip/opt.h"
#include "lwip/arch.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
extern int vprintf(const char *format, va_list args);
// =========================================================
// External Kernel Interface
// =========================================================
// Syscall to get monotonic time in nanoseconds from kernel
extern uint64_t syscall_get_time_ns(void);
// Console output for diagnostics
extern void console_write(const void* p, unsigned long len);
// =========================================================
// Time Source (The Heartbeat)
// =========================================================
/**
* sys_now - Required by lwIP for timeout tracking
* @return Current time in milliseconds
*
* CRITICAL: This must be monotonic and never wrap backwards.
* We use the kernel's high-resolution timer via syscall.
*/
u32_t sys_now(void) {
// Get nanoseconds from kernel, convert to milliseconds
uint64_t ns = syscall_get_time_ns();
return (u32_t)(ns / 1000000ULL);
}
// =========================================================
// Initialization
// =========================================================
/**
* sys_init - Called once during lwIP startup
*
* In NO_SYS mode, this is a no-op. No threads to initialize.
*/
void sys_init(void) {
// Membrane is already initialized by ion_user_init()
// Nothing to do here for lwIP
}
// =========================================================
// Critical Sections (NO-OP in Single-Threaded Mode)
// =========================================================
#if SYS_LIGHTWEIGHT_PROT
/**
* sys_arch_protect - Enter critical section
* @return Protection state (unused in NO_SYS mode)
*
* NO_SYS mode runs in a single fiber context.
* No preemption possible within the Membrane event loop.
*/
sys_prot_t sys_arch_protect(void) {
return 0;
}
/**
* sys_arch_unprotect - Exit critical section
* @param pval Protection state to restore
*/
void sys_arch_unprotect(sys_prot_t pval) {
(void)pval; // Unused
}
#endif /* SYS_LIGHTWEIGHT_PROT */
// =========================================================
// Diagnostics (Optional)
// =========================================================
// =========================================================
// Diagnostics
// =========================================================
/**
* lwip_platform_diag - Output diagnostic message
* Used by LWIP_PLATFORM_DIAG() macro
*/
void lwip_platform_diag(const char *fmt, ...) {
console_write("<<<LwIP>>> ", 11);
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
// =========================================================
// Assertions (Contract Enforcement)
// =========================================================
/**
* lwip_platform_assert - Handle failed assertions
* @param msg Assertion message
*
* Note: Mapped via LWIP_PLATFORM_ASSERT macro in cc.h
*/
void lwip_platform_assert_impl(const char *msg) {
const char panic_msg[] = "[lwIP ASSERT FAILED]\n";
console_write(panic_msg, sizeof(panic_msg) - 1);
console_write(msg, __builtin_strlen(msg));
// Trigger kernel panic via syscall
extern void syscall_panic(void) __attribute__((noreturn));
syscall_panic();
}