137 lines
3.9 KiB
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();
|
|
}
|