compiles
This commit is contained in:
@@ -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();
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
#pragma once
|
||||
+13
-13
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <zinnia/compiler.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct usercopy_region {
|
||||
void (*start_ip)();
|
||||
|
||||
@@ -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
@@ -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);
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user