SchOS/kernel/net/lwip/arch/cc.h
Nexoniarz 26bca020b6 licence: SchOS is GPL-2.0-or-later, no longer Apache-2.0
Nexoniarz is the sole author and SchOS was never published under
Apache-2.0, so this is a straight relicence. LICENSE is the FSF GPLv2 text,
every first-party SPDX header moves to GPL-2.0-or-later, and NOTICE,
README.md, docs/licensing.md and the site say so. projects/schfs-linux
follows the rest of the tree.

The GPL gives copyleft: a fork has to ship its source. It also lifts the
old "Linux drivers, never" rule, since GPL-2.0-only code combines with
GPL-2.0-or-later. "Or later" leaves room for GPLv3, but one binary still
has to pick one version, so docs/licensing.md now keeps Apache-2.0 and
GPLv3 code out of the kernel to keep Linux code possible there. BSD
4-clause code goes from "avoid" to "no", because the advertising clause
is GPL-incompatible.

LDLS still ships no .ko. That boundary is now project policy rather than
a legal requirement, and ldls.md, devices.md and licensing.md section 6
say so. refmod declares license=GPL, and ldls-check passes (27 checks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 08:48:45 +02:00

98 lines
4 KiB
C

// 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 "types.h"
#include "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 <inttypes.h> 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