// SPDX-License-Identifier: GPL-2.0-or-later // // lwIP's compiler/platform header for SchOS. // // lwIP includes this before anything else and expects it to supply the fixed // width types, the byte order, the diagnostic macros and the packing // attributes. Everything here is either a typedef onto the kernel's own types // or a one-line macro; there is no logic, by design -- this file is the seam // between two codebases and the fewer decisions it makes, the better. #ifndef LWIP_ARCH_CC_H #define LWIP_ARCH_CC_H #include "core/types.h" #include "core/defs.h" // There is no libc under the kernel, so every header lwIP would normally reach // for has to be switched off and its contents supplied here instead. That is // the contract arch.h states: set LWIP_NO_STDINT_H and you own the types, set // LWIP_NO_LIMITS_H and you own the limits, and so on. #define LWIP_NO_STDINT_H 1 #define LWIP_NO_INTTYPES_H 1 #define LWIP_NO_LIMITS_H 1 #define LWIP_NO_CTYPE_H 1 #define LWIP_NO_UNISTD_H 1 // lwIP's own type names. Written against the kernel's types rather than C99 // spellings, because the kernel already has names for these and introducing a // second set that must agree is one more thing to get wrong. typedef uchar u8_t; typedef char s8_t; typedef ushort u16_t; typedef short s16_t; typedef uint u32_t; typedef int s32_t; typedef uint64 u64_t; typedef int64 s64_t; #define LWIP_HAVE_INT64 1 typedef unsigned long mem_ptr_t; // must be able to hold a pointer // ssize_t is the kernel's, not lwIP's. Defining SSIZE_MAX is how arch.h is // told that: it only declares its own `typedef int ssize_t` when this is // absent, and that would collide with the kernel's 64-bit one. #define SSIZE_MAX 0x7fffffffffffffffL #define INT_MAX 0x7fffffff // Format specifiers, since is switched off above. The kernel's // cprintf understands %d and %x and nothing wider, which is why these are the // plain forms rather than the length-qualified ones a hosted printf would use. #define X8_F "x" #define U16_F "d" #define S16_F "d" #define X16_F "x" #define U32_F "d" #define S32_F "d" #define X32_F "x" #define SZT_F "d" // x86 is little-endian. Getting this wrong does not fail to compile; it fails // on the wire, as every checksum and every port number arriving byte-swapped. #define BYTE_ORDER LITTLE_ENDIAN // On-the-wire structures must not be padded. lwIP wraps every such struct in // these, and a compiler that ignored them would silently move every field in // every header lwIP parses. #define PACK_STRUCT_BEGIN #define PACK_STRUCT_STRUCT __attribute__((packed)) #define PACK_STRUCT_END #define PACK_STRUCT_FIELD(x) x // Diagnostics. cprintf is the kernel's console printf. #define LWIP_PLATFORM_DIAG(x) do { cprintf x; } while (0) #define LWIP_PLATFORM_ASSERT(x) \ do { cprintf("lwip assert: %s at %s:%d\n", (x), __FILE__, __LINE__); \ panic("lwip assertion"); } while (0) // lwIP is single-threaded here (NO_SYS=1) but is still entered from two places: // the network thread and any syscall that touches a socket. Both take the same // lock, and these are what lwIP itself uses to bracket its critical sections. // See kernel/net/lwip/sys_arch.c. void lwip_sys_lock(void); void lwip_sys_unlock(void); typedef int sys_prot_t; #define SYS_ARCH_DECL_PROTECT(lev) #define SYS_ARCH_PROTECT(lev) lwip_sys_lock() #define SYS_ARCH_UNPROTECT(lev) lwip_sys_unlock() // lwIP calls these for its own buffers. The kernel has no malloc, so lwIP is // configured (MEM_LIBC_MALLOC 0) to use its own pool allocator out of a static // heap instead -- these exist only because a few optional modules reference // them, and reaching one is a bug rather than a fallback. // Spelled with the underlying type rather than lwIP's u32_t: this header is // included *before* lwIP's arch.h defines u32_t, so naming it here would be a // forward reference to a typedef that does not exist yet. #define LWIP_RAND() (lwip_rand_seed()) u32_t lwip_rand_seed(void); #endif