134 lines
3.3 KiB
C
134 lines
3.3 KiB
C
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
// Basic memory stubs
|
|
extern void* malloc(size_t size);
|
|
extern void free(void* ptr);
|
|
|
|
// Forward declare memset (defined below)
|
|
void* memset(void* s, int c, size_t n);
|
|
|
|
void* realloc(void* ptr, size_t size) {
|
|
// naive realloc: alloc new, no copy (dangerous if used), return new
|
|
// For Phase 8 we assume simple allocs.
|
|
// If we want real realloc, we need copy.
|
|
void* new_ptr = malloc(size);
|
|
// copy? we don't know old size using standard malloc API without tracking.
|
|
// ION slab is 2048.
|
|
return new_ptr;
|
|
}
|
|
|
|
void* calloc(size_t nmemb, size_t size) {
|
|
void* p = malloc(nmemb * size);
|
|
if (p) memset(p, 0, nmemb * size);
|
|
return p;
|
|
}
|
|
|
|
// LwIP Panic Handler (for Membrane stack)
|
|
extern void console_write(const void* p, size_t len);
|
|
|
|
void nexus_lwip_panic(const char* msg) {
|
|
const char* prefix = "\n[LwIP/Membrane] ASSERT FAIL: ";
|
|
console_write(prefix, 30);
|
|
|
|
// Print the message (assuming null-terminated)
|
|
const char* p = msg;
|
|
size_t len = 0;
|
|
while (p[len]) len++;
|
|
console_write(msg, len);
|
|
|
|
const char* suffix = "\n";
|
|
console_write(suffix, 1);
|
|
|
|
// Halt
|
|
while(1) {}
|
|
}
|
|
|
|
// String stubs
|
|
size_t strlen(const char* s) {
|
|
size_t i = 0;
|
|
while(s[i]) i++;
|
|
return i;
|
|
}
|
|
|
|
int strncmp(const char *s1, const char *s2, size_t n) {
|
|
for (size_t i = 0; i < n; i++) {
|
|
if (s1[i] != s2[i]) return (unsigned char)s1[i] - (unsigned char)s2[i];
|
|
if (s1[i] == 0) return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int atoi(const char* nptr) { return 0; }
|
|
|
|
// IO stubs
|
|
extern int write(int fd, const void *buf, size_t count);
|
|
|
|
int printf(const char *format, ...) {
|
|
write(1, format, strlen(format));
|
|
return 0;
|
|
}
|
|
|
|
int fwrite(const void *ptr, size_t size, size_t nmemb, void *stream) {
|
|
return write(1, ptr, size * nmemb);
|
|
}
|
|
|
|
int fflush(void *stream) { return 0; }
|
|
|
|
// System stubs
|
|
void exit(int status) { while(1); }
|
|
void (*signal(int sig, void (*func)(int)))(int) { return NULL; }
|
|
|
|
// LwIP Time
|
|
uint32_t sys_now() { return 0; }
|
|
|
|
// Utils
|
|
uint16_t htons(uint16_t h) {
|
|
return (h << 8) | (h >> 8);
|
|
}
|
|
|
|
void* memcpy(void* dest, const void* src, size_t n) {
|
|
uint8_t* d = dest;
|
|
const uint8_t* s = src;
|
|
for (size_t i = 0; i < n; i++) d[i] = s[i];
|
|
return dest;
|
|
}
|
|
|
|
void* memset(void* s, int c, size_t n) {
|
|
uint8_t* p = s;
|
|
for (size_t i = 0; i < n; i++) p[i] = (uint8_t)c;
|
|
return s;
|
|
}
|
|
|
|
int memcmp(const void *s1, const void *s2, size_t n) {
|
|
const unsigned char *p1 = (const unsigned char *)s1;
|
|
const unsigned char *p2 = (const unsigned char *)s2;
|
|
for (size_t i = 0; i < n; i++) {
|
|
if (p1[i] != p2[i]) return p1[i] - p2[i];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void *memmove(void *dest, const void *src, size_t n) {
|
|
char *d = (char *)dest;
|
|
const char *s = (const char *)src;
|
|
if (d < s) {
|
|
for (size_t i = 0; i < n; i++) d[i] = s[i];
|
|
} else {
|
|
for (size_t i = n; i > 0; i--) d[i - 1] = s[i - 1];
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
void console_write(const void* p, size_t len) {
|
|
// Phase 7: Direct UART access for Proof of Life
|
|
volatile char *uart = (volatile char *)0x10000000;
|
|
const char *buf = (const char *)p;
|
|
for (size_t i = 0; i < len; i++) {
|
|
if (buf[i] == '\n') *uart = '\r';
|
|
*uart = buf[i];
|
|
}
|
|
}
|
|
|
|
void ion_egress_to_port(uint16_t port, void* pkt);
|