Sixty-five headers sat side by side in include/, so `#include "irq.h"` said nothing about where irq.h was or what it belonged to, and errno.h, stat.h and fcntl.h at the top shadowed the system's for any host tool built with -I./include. They are in folders now -- arch/ core/ fs/ dev/ gfx/ net/ uapi/ (and ldls/ for the Linux driver layer) -- and every include names the folder, as Linux's do: "core/proc.h". Done mechanically and checked the hard way: the kernel built from this tree disassembles identically to the one built from the tree before it. The full image boots, and userland is the same set of programs. Paths in docs and comments follow; docs/guides/layout.md has a table of what is where, and tools/fix-includes.py rewrites old-style includes from the folders in the tree, for code written before this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
98 lines
4 KiB
C
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 "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 <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
|