This commit is contained in:
2026-09-17 03:19:43 +02:00
parent 6719239036
commit 27fe15f83d
85 changed files with 945 additions and 901 deletions
@@ -8,5 +8,5 @@ size_t arch_mem_page_bits();
size_t arch_mem_level_bits();
size_t arch_mem_num_levels();
uintptr_t arch_mem_hhdm_addr();
uintptr_t arch_vm_pfndb_addr();
uintptr_t arch_mem_pfndb_addr();
uintptr_t arch_mem_mapping_addr();
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <zinnia/percpu.h>
struct percpu* arch_percpu_get();
void arch_percpu_bsp_init();
void arch_percpu_init();
@@ -1,9 +1,10 @@
#pragma once
#include <stddef.h>
#include <zinnia/compiler.h>
#include <zinnia/usercopy.h>
#include <stddef.h>
void arch_usercopy_allow(bool state);
bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct usercopy_region** region);
bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct usercopy_region** region);
bool arch_usercopy_strlen(const __user char* str, size_t max, size_t* len, struct usercopy_region** region);
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include <zinnia/compiler.h>
#include <zinnia/panic.h>
#define assert(expr, msg, ...) \
({ \
if (__unlikely(!(expr))) { \
panic( \
"In function \"%s\" (%s:%u):\n" \
"Assertion \"%s\" failed!\n" msg, \
__FUNCTION__, \
__FILE__, \
__LINE__, \
#expr, \
##__VA_ARGS__ \
); \
} \
})
#ifndef NDEBUG
#define debug_assert(...) assert(__VA_ARGS__)
#else
#define debug_assert(...) ((void)0)
#endif
+2
View File
@@ -5,6 +5,8 @@
#ifdef __x86_64__
#define __ARCHCTL_SET_FSBASE 1
#define __ARCHCTL_SET_GSBASE 2
#define __ARCHCTL_GET_FSBASE 3
#define __ARCHCTL_GET_GSBASE 4
#endif
#endif
+3 -10
View File
@@ -1,8 +1,9 @@
#pragma once
#include <bits/mem.h>
#include <stddef.h>
#include <zinnia/errno.h>
#include <zinnia/types.h>
#include <arch/mem.h>
#include <stddef.h>
enum alloc_flags {
ALLOC_NOZERO = 1 << 0, // Don't zero out the allocated memory.
@@ -44,14 +45,6 @@ void slab_init();
void mem_phys_bootstrap(struct phys_mem* mem);
void mem_phys_init(struct phys_mem* map, size_t length);
uintptr_t arch_mem_hhdm_addr();
uintptr_t arch_vm_pfndb_addr();
uintptr_t arch_mem_mapping_addr();
size_t arch_mem_page_bits();
size_t arch_mem_page_size();
size_t arch_mem_level_bits();
size_t arch_mem_num_levels();
static inline size_t mem_high_shift() {
return arch_mem_level_bits() * arch_mem_num_levels() + arch_mem_page_bits();
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <zinnia/compiler.h>
#include <zinnia/panic.h>
#define assert(expr, msg, ...) \
({ \
if (__unlikely(!(expr))) { \
panic("Assertion \"%s\" failed: \"" msg "\" @ %s:%u\n", #expr, ##__VA_ARGS__, __FILE__, __LINE__); \
} \
})
#ifndef NDEBUG
#define debug_assert(...) assert(__VA_ARGS__)
#else
#define debug_assert(...) ((void)0)
#endif
+1
View File
@@ -0,0 +1 @@
#pragma once
+13 -13
View File
@@ -1,10 +1,10 @@
#pragma once
#include <zinnia/alloc.h>
#include <zinnia/errno.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <zinnia/alloc.h>
#include <zinnia/errno.h>
// FNV-1a hash over raw bytes.
static inline uint64_t hashmap_hash_default(const void* key, size_t len) {
@@ -25,7 +25,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
// Ensure a hash is never zero (zero is the empty sentinel).
#define _HASHMAP_FIXHASH(h) ((h) == 0 ? (uint64_t)1 : (h))
#define HASHMAP(K, V) \
#define hashmap(K, V) \
struct { \
K* keys; \
V* values; \
@@ -34,7 +34,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
size_t count; \
}
#define HASHMAP_INIT(map) \
#define hashmap_init(map) \
do { \
(map)->keys = nullptr; \
(map)->values = nullptr; \
@@ -43,7 +43,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
(map)->count = 0; \
} while (0)
#define HASHMAP_DESTROY(map) \
#define hashmap_destroy(map) \
do { \
mem_free((map)->keys); \
mem_free((map)->values); \
@@ -55,7 +55,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
(map)->count = 0; \
} while (0)
#define HASHMAP_COUNT(map) ((map)->count)
#define hashmap_count(map) ((map)->count)
// Internal: probe distance from ideal position.
#define _HASHMAP_PROBE_DIST(hash, pos, cap) (((pos) - ((hash) & ((cap) - 1))) & ((cap) - 1))
@@ -116,10 +116,10 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
} \
} while (0)
// Insert or update a key-value pair. Returns 0 or ENOMEM.
#define HASHMAP_INSERT(map, key, val, hash_fn, eq_fn) \
// Insert or update a key-value pair. Returns 0 or ZN_ERR_NO_MEMORY.
#define hashmap_insert(map, key, val, hash_fn, eq_fn) \
({ \
errno_t _status = 0; \
zn_status_t _status = 0; \
typeof(*(map)->keys) _k = (key); \
uint64_t _h = _HASHMAP_FIXHASH((hash_fn)(&_k, sizeof(_k))); \
/* Check for existing key first. */ \
@@ -144,7 +144,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
if ((map)->count * 4 >= (map)->capacity * 3 || (map)->capacity == 0) { \
_HASHMAP_GROW(map, hash_fn, eq_fn); \
if ((map)->keys == nullptr || (map)->values == nullptr || (map)->hashes == nullptr) { \
_status = ENOMEM; \
_status = ZN_ERR_NO_MEMORY; \
} \
} \
if (_status == 0) { \
@@ -155,7 +155,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
})
// Look up a key. Returns a pointer to the value, or nullptr if not found.
#define HASHMAP_GET(map, key, hash_fn, eq_fn) \
#define hashmap_get(map, key, hash_fn, eq_fn) \
({ \
typeof(*(map)->values)* _result = nullptr; \
if ((map)->capacity > 0) { \
@@ -180,7 +180,7 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
// Remove a key. Returns true if the key was found and removed.
// Uses backward-shift deletion to avoid tombstones.
#define HASHMAP_REMOVE(map, key, hash_fn, eq_fn) \
#define hashmap_remove(map, key, hash_fn, eq_fn) \
({ \
bool _removed = false; \
if ((map)->capacity > 0) { \
@@ -218,6 +218,6 @@ static inline bool hashmap_eq_default(const void* a, const void* b, size_t len)
// Iterate over all occupied entries. `idx` is a size_t loop variable.
// Access keys and values via (map)->keys[idx] and (map)->values[idx].
#define HASHMAP_FOREACH(map, idx) \
#define hashmap_foreach(map, idx) \
for (size_t idx = 0; idx < (map)->capacity; idx++) \
if ((map)->hashes[idx] != 0)
+6 -2
View File
@@ -2,7 +2,6 @@
#include <zinnia/compiler.h>
#include <zinnia/list.h>
#include <bits/irq.h>
#include <stdint.h>
enum irq_status : uint8_t {
@@ -45,4 +44,9 @@ void irq_line_attach(struct irq_line* self, struct irq_handler* handler);
void irq_lock();
void irq_unlock();
bool irq_set_interrupted(bool is_interrupted);
void irq_raise();
void irq_line_raise(struct irq_line* line);
// Hints to stop execution on this CPU until an interrupt happens.
void irq_wait();
bool irq_get_state();
void irq_set_state(bool state);
+26 -62
View File
@@ -1,71 +1,35 @@
#pragma once
#include <zinnia/types.h>
#include <stddef.h>
#include <stdint.h>
struct mmio_view {
volatile void* base;
size_t len;
};
static inline uint8_t mmio_read8(void* ptr) {
return *((volatile uint8_t*)ptr);
}
#define _MMIO_REG(x) \
typedef struct { \
size_t offset; \
bool swapped; \
} mmio_reg##x;
static inline uint16_t mmio_read16(void* ptr) {
return *((volatile uint16_t*)ptr);
}
_MMIO_REG(8)
_MMIO_REG(16)
_MMIO_REG(32)
_MMIO_REG(64)
static inline uint32_t mmio_read32(void* ptr) {
return *((volatile uint32_t*)ptr);
}
#define bswap_16(x) (uint16_t)x
#define bswap_32(x) (uint32_t)x
#define bswap_64(x) (uint64_t)x
static inline uint64_t mmio_read64(void* ptr) {
return *((volatile uint64_t*)ptr);
}
#define mmio_load(_view, _reg) \
({ \
auto _mmio_ptr = _Generic( \
(_reg), \
mmio_reg8: (volatile uint8_t*)((_view)->base + (_reg).offset), \
mmio_reg16: (volatile uint16_t*)((_view)->base + (_reg).offset), \
mmio_reg32: (volatile uint32_t*)((_view)->base + (_reg).offset), \
mmio_reg64: (volatile uint64_t*)((_view)->base + (_reg).offset) \
); \
auto _mmio_val = *_mmio_ptr; \
if ((_reg).swapped) \
_Generic( \
(_mmio_val), \
char: (void)(_mmio_val), \
uint8_t: (void)(_mmio_val), \
uint16_t: (_mmio_val = bswap_16(_mmio_val)), \
uint32_t: (_mmio_val = bswap_32(_mmio_val)), \
uint64_t: (_mmio_val = bswap_64(_mmio_val)) \
); \
_mmio_val; \
})
static inline void mmio_write8(void* ptr, uint8_t value) {
*((volatile uint8_t*)ptr) = value;
}
#define mmio_store(_view, _reg, _val) \
({ \
auto _mmio_val = _val; \
if ((_reg).swapped) \
_Generic( \
(_mmio_val), \
char: (void)(_mmio_val), \
uint8_t: (void)(_mmio_val), \
uint16_t: (_mmio_val = bswap_16(_mmio_val)), \
uint32_t: (_mmio_val = bswap_32(_mmio_val)), \
uint64_t: (_mmio_val = bswap_64(_mmio_val)) \
); \
auto _mmio_ptr = _Generic( \
(_reg), \
mmio_reg8: (volatile uint8_t*)((_view)->base + (_reg).offset), \
mmio_reg16: (volatile uint16_t*)((_view)->base + (_reg).offset), \
mmio_reg32: (volatile uint32_t*)((_view)->base + (_reg).offset), \
mmio_reg64: (volatile uint64_t*)((_view)->base + (_reg).offset) \
); \
*_mmio_ptr = _mmio_val; \
})
static inline void mmio_write16(void* ptr, uint16_t value) {
*((volatile uint16_t*)ptr) = value;
}
struct mmio_view mmio_new(phys_t addr, size_t length);
void mmio_free(struct mmio_view* view);
static inline void mmio_write32(void* ptr, uint32_t value) {
*((volatile uint32_t*)ptr) = value;
}
static inline void mmio_write64(void* ptr, uint64_t value) {
*((volatile uint64_t*)ptr) = value;
}
+6 -19
View File
@@ -7,7 +7,7 @@
#include <bits/percpu.h>
#include <stddef.h>
ASSERT_TYPE(struct arch_percpu);
ASSERT_TYPE(struct arch_percpu); // bits/percpu.h
// CPU-relative information.
struct percpu {
@@ -21,23 +21,10 @@ struct percpu {
struct sched_percpu sched; // Scheduler information.
};
struct percpu* percpu_new();
struct percpu* percpu_get();
void percpu_bsp_init();
void percpu_init();
// Per-CPU data for the bootstrap processor.
extern struct percpu percpu_bsp;
// Allocates a block of memory for a new CPU.
struct percpu* percpu_new();
// Gets the per-CPU data on the current CPU.
static inline struct percpu* percpu_get() {
return arch_percpu_get();
}
// Initializes the bootstrap processor.
static inline void percpu_bsp_init() {
arch_percpu_bsp_init();
}
// Initializes all processors.
static inline void percpu_init() {
arch_percpu_init();
}
+3 -3
View File
@@ -4,7 +4,7 @@
#include <zinnia/errno.h>
#include <zinnia/spin.h>
#include <zinnia/utils.h>
#include <bits/mmu.h>
#include <bits/pmap.h>
enum pte_flags : uint8_t {
PTE_READ = 1 << 0, // Can read from this page.
@@ -28,8 +28,8 @@ struct pmap {
bool is_user;
};
errno_t pmap_kernel(struct pmap* pt, enum alloc_flags flags);
errno_t pmap_user(struct pmap* pt, enum alloc_flags flags);
errno_t pmap_new_kernel(struct pmap* pt, enum alloc_flags flags);
errno_t pmap_new_user(struct pmap* pt, enum alloc_flags flags);
errno_t pmap_map(struct pmap* pt, uintptr_t vaddr, phys_t paddr, enum pte_flags flags, enum cache_mode cache);
errno_t pmap_protect(struct pmap* pt, uintptr_t vaddr, enum pte_flags flags);
errno_t pmap_unmap(struct pmap* pt, uintptr_t vaddr);
+9
View File
@@ -7,3 +7,12 @@
void kprintf(const char* message, ...);
void kvprintf(const char* message, va_list args);
#include <zinnia/clock.h>
#include <stdint.h>
#define log(category, message, ...) \
do { \
uint64_t _time = clock_get_elapsed_ns(); \
kprintf("[%5lu.%06lu] \e[1;34m" category ":\e[0m " message, _time / 1'000'000'000, _time % 1'000'000, ##__VA_ARGS__); \
} while (0)
+2 -10
View File
@@ -26,8 +26,7 @@ enum task_state {
struct task {
size_t id;
char name[TASK_NAME_MAX];
struct vas* space;
struct namespace* namespace;
struct vma* space;
enum task_state state;
struct arch_task_context context;
struct usercopy_region* usercopy_region;
@@ -59,14 +58,7 @@ void sched_wake_all(struct sched_percpu* sched, struct wait_queue* wq);
typedef void (*task_fn_t)(uintptr_t arg0);
errno_t task_create(
const char* name,
struct vas* space,
struct namespace* ns,
task_fn_t entry,
uintptr_t arg0,
struct task** out
);
errno_t task_create(const char* name, struct vma* space, task_fn_t entry, uintptr_t arg0, struct task** out);
[[noreturn]]
void task_entry(task_fn_t entry, uintptr_t arg0);
+7 -14
View File
@@ -2,32 +2,25 @@
#include <zinnia/sched.h>
enum syscall_kind : uint8_t {
SYSKIND_CALL = 0, // Regular call, returns error and/or value.
SYSKIND_CONTEXT, // Consumes the entire register image.
};
struct syscall_return {
struct syscall_ret {
uintptr_t value;
int errno;
};
struct syscall {
union {
struct syscall_return (*call)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
void (*context)(struct arch_context*);
};
enum syscall_kind kind;
void* func;
int num_args;
};
struct syscall_return syscall_dispatch_call(
size_t num,
[[gnu::no_caller_saved_registers]]
struct syscall_ret syscall_dispatch_fast(
uintptr_t a0,
uintptr_t a1,
uintptr_t a2,
uintptr_t a3,
uintptr_t a4,
uintptr_t a5
uintptr_t a5,
size_t num
);
void syscall_dispatch(struct arch_context* ctx);
+146 -150
View File
@@ -2,155 +2,151 @@
#include <zinnia/sched.h>
#include <zinnia/syscall.h>
#include <stdint.h>
#define __SYSCALL_CALL(name) \
struct syscall_return sys_##name(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t)
#define SYSCALL_DECLARE(name) extern void sys_##name()
#define __SYSCALL_CONTEXT(name) void sys_##name(struct arch_context*)
__SYSCALL_CALL(exit);
__SYSCALL_CALL(syslog);
__SYSCALL_CALL(getuname);
__SYSCALL_CALL(setuname);
__SYSCALL_CALL(archctl);
__SYSCALL_CALL(reboot);
__SYSCALL_CALL(mmap);
__SYSCALL_CALL(munmap);
__SYSCALL_CALL(mprotect);
__SYSCALL_CALL(madvise);
__SYSCALL_CALL(sigprocmask);
__SYSCALL_CALL(sigsuspend);
__SYSCALL_CALL(sigpending);
__SYSCALL_CALL(sigaction);
__SYSCALL_CALL(sigtimedwait);
__SYSCALL_CALL(sigaltstack);
__SYSCALL_CALL(sigreturn);
__SYSCALL_CALL(sigqueue);
__SYSCALL_CALL(execve);
__SYSCALL_CALL(fexecve);
__SYSCALL_CONTEXT(fork);
__SYSCALL_CALL(kill);
__SYSCALL_CALL(gettid);
__SYSCALL_CALL(getpid);
__SYSCALL_CALL(getppid);
__SYSCALL_CALL(waitid);
__SYSCALL_CALL(waitpid);
__SYSCALL_CALL(pread);
__SYSCALL_CALL(readv);
__SYSCALL_CALL(pwrite);
__SYSCALL_CALL(writev);
__SYSCALL_CALL(seek);
__SYSCALL_CALL(ioctl);
__SYSCALL_CALL(openat);
__SYSCALL_CALL(close);
__SYSCALL_CALL(fstat);
__SYSCALL_CALL(fstatat);
__SYSCALL_CALL(statvfs);
__SYSCALL_CALL(fstatvfs);
__SYSCALL_CALL(faccessat);
__SYSCALL_CALL(fcntl);
__SYSCALL_CALL(ftruncate);
__SYSCALL_CALL(truncate);
__SYSCALL_CALL(fallocate);
__SYSCALL_CALL(fadvise);
__SYSCALL_CALL(utimensat);
__SYSCALL_CALL(mknodat);
__SYSCALL_CALL(getcwd);
__SYSCALL_CALL(chdir);
__SYSCALL_CALL(fchdir);
__SYSCALL_CALL(mkdirat);
__SYSCALL_CALL(rmdirat);
__SYSCALL_CALL(getdents);
__SYSCALL_CALL(renameat);
__SYSCALL_CALL(fchmod);
__SYSCALL_CALL(fchmodat);
__SYSCALL_CALL(fchownat);
__SYSCALL_CALL(linkat);
__SYSCALL_CALL(symlinkat);
__SYSCALL_CALL(unlinkat);
__SYSCALL_CALL(readlinkat);
__SYSCALL_CALL(flock);
__SYSCALL_CALL(ppoll);
__SYSCALL_CALL(dup);
__SYSCALL_CALL(dup3);
__SYSCALL_CALL(sync);
__SYSCALL_CALL(fsync);
__SYSCALL_CALL(fdatasync);
__SYSCALL_CALL(getgroups);
__SYSCALL_CALL(setgroups);
__SYSCALL_CALL(getsid);
__SYSCALL_CALL(setsid);
__SYSCALL_CALL(setuid);
__SYSCALL_CALL(getuid);
__SYSCALL_CALL(setgid);
__SYSCALL_CALL(getgid);
__SYSCALL_CALL(geteuid);
__SYSCALL_CALL(seteuid);
__SYSCALL_CALL(getegid);
__SYSCALL_CALL(setegid);
__SYSCALL_CALL(getpgid);
__SYSCALL_CALL(setpgid);
__SYSCALL_CALL(getresuid);
__SYSCALL_CALL(setresuid);
__SYSCALL_CALL(getresgid);
__SYSCALL_CALL(setresgid);
__SYSCALL_CALL(setreuid);
__SYSCALL_CALL(setregid);
__SYSCALL_CALL(umask);
__SYSCALL_CALL(pipe);
__SYSCALL_CALL(futex_wait);
__SYSCALL_CALL(futex_wake);
__SYSCALL_CALL(thread_create);
__SYSCALL_CALL(thread_kill);
__SYSCALL_CALL(thread_exit);
__SYSCALL_CALL(thread_setname);
__SYSCALL_CALL(thread_getname);
__SYSCALL_CALL(timer_create);
__SYSCALL_CALL(timer_set);
__SYSCALL_CALL(timer_get);
__SYSCALL_CALL(timer_getoverrun);
__SYSCALL_CALL(timer_delete);
__SYSCALL_CALL(itimer_get);
__SYSCALL_CALL(itimer_set);
__SYSCALL_CALL(clock_get);
__SYSCALL_CALL(clock_getres);
__SYSCALL_CALL(clock_set);
__SYSCALL_CALL(sleep);
__SYSCALL_CALL(yield);
__SYSCALL_CALL(chroot);
__SYSCALL_CALL(mount);
__SYSCALL_CALL(umount);
__SYSCALL_CALL(socket);
__SYSCALL_CALL(socketpair);
__SYSCALL_CALL(shutdown);
__SYSCALL_CALL(bind);
__SYSCALL_CALL(connect);
__SYSCALL_CALL(accept);
__SYSCALL_CALL(listen);
__SYSCALL_CALL(getpeername);
__SYSCALL_CALL(getsockname);
__SYSCALL_CALL(getsockopt);
__SYSCALL_CALL(setsockopt);
__SYSCALL_CALL(sendmsg);
__SYSCALL_CALL(recvmsg);
__SYSCALL_CALL(getentropy);
__SYSCALL_CALL(getrusage);
__SYSCALL_CALL(getrlimit);
__SYSCALL_CALL(setrlimit);
__SYSCALL_CALL(getpriority);
__SYSCALL_CALL(setpriority);
__SYSCALL_CALL(sched_getparam);
__SYSCALL_CALL(sched_setparam);
__SYSCALL_CALL(module_insert);
__SYSCALL_CALL(module_remove);
__SYSCALL_CALL(epoll_create);
__SYSCALL_CALL(epoll_ctl);
__SYSCALL_CALL(epoll_pwait);
__SYSCALL_CALL(timerfd_create);
__SYSCALL_CALL(timerfd_gettime);
__SYSCALL_CALL(timerfd_settime);
__SYSCALL_CALL(signalfd_create);
__SYSCALL_CALL(eventfd_create);
__SYSCALL_CALL(msync);
__SYSCALL_CALL(sysconf);
SYSCALL_DECLARE(exit);
SYSCALL_DECLARE(syslog);
SYSCALL_DECLARE(getuname);
SYSCALL_DECLARE(setuname);
SYSCALL_DECLARE(archctl);
SYSCALL_DECLARE(reboot);
SYSCALL_DECLARE(mmap);
SYSCALL_DECLARE(munmap);
SYSCALL_DECLARE(mprotect);
SYSCALL_DECLARE(madvise);
SYSCALL_DECLARE(sigprocmask);
SYSCALL_DECLARE(sigsuspend);
SYSCALL_DECLARE(sigpending);
SYSCALL_DECLARE(sigaction);
SYSCALL_DECLARE(sigtimedwait);
SYSCALL_DECLARE(sigaltstack);
SYSCALL_DECLARE(sigreturn);
SYSCALL_DECLARE(sigqueue);
SYSCALL_DECLARE(execve);
SYSCALL_DECLARE(fexecve);
SYSCALL_DECLARE(fork);
SYSCALL_DECLARE(kill);
SYSCALL_DECLARE(gettid);
SYSCALL_DECLARE(getpid);
SYSCALL_DECLARE(getppid);
SYSCALL_DECLARE(waitid);
SYSCALL_DECLARE(waitpid);
SYSCALL_DECLARE(pread);
SYSCALL_DECLARE(readv);
SYSCALL_DECLARE(pwrite);
SYSCALL_DECLARE(writev);
SYSCALL_DECLARE(seek);
SYSCALL_DECLARE(ioctl);
SYSCALL_DECLARE(openat);
SYSCALL_DECLARE(close);
SYSCALL_DECLARE(fstat);
SYSCALL_DECLARE(fstatat);
SYSCALL_DECLARE(statvfs);
SYSCALL_DECLARE(fstatvfs);
SYSCALL_DECLARE(faccessat);
SYSCALL_DECLARE(fcntl);
SYSCALL_DECLARE(ftruncate);
SYSCALL_DECLARE(truncate);
SYSCALL_DECLARE(fallocate);
SYSCALL_DECLARE(fadvise);
SYSCALL_DECLARE(utimensat);
SYSCALL_DECLARE(mknodat);
SYSCALL_DECLARE(getcwd);
SYSCALL_DECLARE(chdir);
SYSCALL_DECLARE(fchdir);
SYSCALL_DECLARE(mkdirat);
SYSCALL_DECLARE(rmdirat);
SYSCALL_DECLARE(getdents);
SYSCALL_DECLARE(renameat);
SYSCALL_DECLARE(fchmod);
SYSCALL_DECLARE(fchmodat);
SYSCALL_DECLARE(fchownat);
SYSCALL_DECLARE(linkat);
SYSCALL_DECLARE(symlinkat);
SYSCALL_DECLARE(unlinkat);
SYSCALL_DECLARE(readlinkat);
SYSCALL_DECLARE(flock);
SYSCALL_DECLARE(ppoll);
SYSCALL_DECLARE(dup);
SYSCALL_DECLARE(dup3);
SYSCALL_DECLARE(sync);
SYSCALL_DECLARE(fsync);
SYSCALL_DECLARE(fdatasync);
SYSCALL_DECLARE(getgroups);
SYSCALL_DECLARE(setgroups);
SYSCALL_DECLARE(getsid);
SYSCALL_DECLARE(setsid);
SYSCALL_DECLARE(setuid);
SYSCALL_DECLARE(getuid);
SYSCALL_DECLARE(setgid);
SYSCALL_DECLARE(getgid);
SYSCALL_DECLARE(geteuid);
SYSCALL_DECLARE(seteuid);
SYSCALL_DECLARE(getegid);
SYSCALL_DECLARE(setegid);
SYSCALL_DECLARE(getpgid);
SYSCALL_DECLARE(setpgid);
SYSCALL_DECLARE(getresuid);
SYSCALL_DECLARE(setresuid);
SYSCALL_DECLARE(getresgid);
SYSCALL_DECLARE(setresgid);
SYSCALL_DECLARE(setreuid);
SYSCALL_DECLARE(setregid);
SYSCALL_DECLARE(umask);
SYSCALL_DECLARE(pipe);
SYSCALL_DECLARE(futex_wait);
SYSCALL_DECLARE(futex_wake);
SYSCALL_DECLARE(thread_create);
SYSCALL_DECLARE(thread_kill);
SYSCALL_DECLARE(thread_exit);
SYSCALL_DECLARE(thread_setname);
SYSCALL_DECLARE(thread_getname);
SYSCALL_DECLARE(timer_create);
SYSCALL_DECLARE(timer_set);
SYSCALL_DECLARE(timer_get);
SYSCALL_DECLARE(timer_getoverrun);
SYSCALL_DECLARE(timer_delete);
SYSCALL_DECLARE(itimer_get);
SYSCALL_DECLARE(itimer_set);
SYSCALL_DECLARE(clock_get);
SYSCALL_DECLARE(clock_getres);
SYSCALL_DECLARE(clock_set);
SYSCALL_DECLARE(sleep);
SYSCALL_DECLARE(yield);
SYSCALL_DECLARE(chroot);
SYSCALL_DECLARE(mount);
SYSCALL_DECLARE(umount);
SYSCALL_DECLARE(socket);
SYSCALL_DECLARE(socketpair);
SYSCALL_DECLARE(shutdown);
SYSCALL_DECLARE(bind);
SYSCALL_DECLARE(connect);
SYSCALL_DECLARE(accept);
SYSCALL_DECLARE(listen);
SYSCALL_DECLARE(getpeername);
SYSCALL_DECLARE(getsockname);
SYSCALL_DECLARE(getsockopt);
SYSCALL_DECLARE(setsockopt);
SYSCALL_DECLARE(sendmsg);
SYSCALL_DECLARE(recvmsg);
SYSCALL_DECLARE(getentropy);
SYSCALL_DECLARE(getrusage);
SYSCALL_DECLARE(getrlimit);
SYSCALL_DECLARE(setrlimit);
SYSCALL_DECLARE(getpriority);
SYSCALL_DECLARE(setpriority);
SYSCALL_DECLARE(sched_getparam);
SYSCALL_DECLARE(sched_setparam);
SYSCALL_DECLARE(module_insert);
SYSCALL_DECLARE(module_remove);
SYSCALL_DECLARE(epoll_create);
SYSCALL_DECLARE(epoll_ctl);
SYSCALL_DECLARE(epoll_pwait);
SYSCALL_DECLARE(timerfd_create);
SYSCALL_DECLARE(timerfd_gettime);
SYSCALL_DECLARE(timerfd_settime);
SYSCALL_DECLARE(signalfd_create);
SYSCALL_DECLARE(eventfd_create);
SYSCALL_DECLARE(msync);
SYSCALL_DECLARE(sysconf);
+2 -3
View File
@@ -1,8 +1,7 @@
#pragma once
#include <bits/types.h>
#include <zinnia/utils.h>
#include <bits/types.h>
ASSERT_TYPE(phys_t);
ASSERT_TYPE(uintptr_t);
ASSERT_TYPE(reg_t);
ASSERT_TYPE(virt_t);
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <stddef.h>
#include <zinnia/compiler.h>
#include <stddef.h>
struct usercopy_region {
void (*start_ip)();
-32
View File
@@ -1,32 +0,0 @@
#pragma once
#include <zinnia/alloc.h>
#include <zinnia/errno.h>
#include <zinnia/mutex.h>
#include <zinnia/object.h>
#include <zinnia/pmap.h>
// Virtual address space.
struct vas {
// Architecture-specific virtual memory map implementation.
struct pmap pmap;
};
// Try to create a new, empty virtual address space.
errno_t vma_new(struct vas** out);
// Delete a virtual address space.
void vma_delete(struct vas* vm);
errno_t vma_map_vmo(struct vas* vm, struct vmo* vmo, uintptr_t addr, size_t len, enum flags, uintptr_t vmo_offset);
// Remove any mappings in the given address range.
errno_t vma_unmap(struct vas* vm, uintptr_t vaddr, size_t size);
// Change the protection of an existing mapping.
errno_t vma_protect(struct vas* vm, uintptr_t vaddr, size_t size, enum zn_vm_flags flags);
// Try to handle a page fault.
bool vma_page_fault(struct vas* vm, uintptr_t vaddr, enum zn_vm_flags access_type);
extern struct vas kernel_vas;
+31 -29
View File
@@ -7,35 +7,6 @@
#include <stdint.h>
#include <uapi/fcntl.h>
struct vfs_mount {
struct refcount rc;
};
struct vfs_entry {
struct refcount rc;
};
struct vfs_path {
struct vfs_mount* mount;
struct vfs_entry* entry;
};
struct vfs_node;
struct vfs_regular_ops {
errno_t (*read)(struct vfs_node* file, struct iovec_iter* buffer, uint64_t offset, ssize_t* out_read);
errno_t (*write)(struct vfs_node* file, struct iovec_iter* buffer, uint64_t offset, ssize_t* out_written);
errno_t (*devctl)(struct vfs_node* file);
};
struct vfs_node {
struct refcount rc;
const struct vfs_regular_ops* ops;
struct vfs_vnode* vnode;
struct vfs_path path;
const char* abs_path;
bool has_path;
};
enum open_flags : uint32_t {
O_RDONLY = __O_RDONLY,
O_WRONLY = __O_WRONLY,
@@ -62,3 +33,34 @@ enum open_flags : uint32_t {
O_SEARCH = __O_SEARCH,
O_ACCMODE = __O_ACCMODE,
};
struct vfs_mount {
struct refcount rc;
// TODO
};
struct vfs_entry {
struct refcount rc;
// TODO
};
struct vfs_path {
struct vfs_mount* mount;
struct vfs_entry* entry;
};
struct vfs_node;
struct vfs_regular_ops {
errno_t (*read)(struct vfs_node* file, struct iovec_iter* buffer, uint64_t offset, ssize_t* out_read);
errno_t (*write)(struct vfs_node* file, struct iovec_iter* buffer, uint64_t offset, ssize_t* out_written);
errno_t (*devctl)(struct vfs_node* file);
};
struct vfs_node {
struct refcount rc;
const struct vfs_regular_ops* ops;
struct vfs_vnode* vnode;
struct vfs_path path;
const char* abs_path;
bool has_path;
};
@@ -1,5 +1,7 @@
#pragma once
#include <zinnia/hashmap.h>
#include <zinnia/types.h>
#include <stddef.h>
#include <stdint.h>
@@ -21,10 +23,18 @@ struct page {
static_assert(0x1000 % sizeof(struct page) == 0, "struct must fit cleanly inside a page!");
static_assert(sizeof(struct page) <= 64, "struct must be smaller than 64 bytes!");
void* vm_alloc(size_t length);
void vm_free(void* addr, size_t length);
// Base address of the `struct page` array.
extern struct page* vm_pfndb;
uintptr_t vm_page_addr(struct page* page);
// Allocator for virtual memory.
struct vm_alloc {
virt_t start_page;
virt_t end_page;
virt_t next_fit;
hashmap(int, void);
};
uintptr_t vm_alloc(size_t length);
void vm_free(uintptr_t addr, size_t length);
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <zinnia/errno.h>
#include <zinnia/mman.h>
#include <zinnia/mutex.h>
#include <zinnia/pmap.h>
#include <zinnia/vmo.h>
// Virtual address space.
struct vma {
// Architecture-specific virtual memory map implementation.
struct pmap pmap;
};
// Try to create a new, empty virtual address space.
errno_t vma_new(struct vma** out);
// Delete a virtual address space.
void vma_free(struct vma* v);
errno_t vma_map(
struct vma* vm,
struct vmo* vmo,
uintptr_t addr,
size_t len,
enum prot_flags flags,
uintptr_t vmo_offset
);
// Remove any mappings in the given address range.
errno_t vma_unmap(struct vma* v, uintptr_t vaddr, size_t size);
// Change the protection of an existing mapping.
errno_t vma_protect(struct vma* v, uintptr_t vaddr, size_t size, enum prot_flags flags);
struct vma_fault_info {
uintptr_t ip;
uintptr_t addr;
bool caused_by_user;
bool caused_by_write;
bool caused_by_fetch;
bool page_was_present;
};
// Try to handle a page fault.
bool vma_page_fault(struct vma* v, const struct vma_fault_info* info);
extern struct vma kernel_vma;
@@ -2,8 +2,8 @@
#include <zinnia/errno.h>
#include <zinnia/list.h>
#include <zinnia/page.h>
#include <zinnia/spin.h>
#include <zinnia/virt.h>
#include <stddef.h>
#include <stdint.h>