Small fixes
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
#include <zinnia/types.h>
|
||||
#include <arch/mem.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -14,7 +14,6 @@ kernel_sources += files(
|
||||
'mem.c',
|
||||
'percpu.c',
|
||||
'pmap.c',
|
||||
'pmap.c',
|
||||
'random.c',
|
||||
'sched.c',
|
||||
'serial.c',
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <bits/sched.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <x86_64/apic.h>
|
||||
#include <x86_64/asm.h>
|
||||
#include <x86_64/defs.h>
|
||||
@@ -93,6 +94,11 @@ struct task* arch_sched_switch(struct task* from, struct task* to) {
|
||||
return perform_switch(&from_ctx->rsp, to_ctx->rsp, from);
|
||||
}
|
||||
|
||||
constexpr size_t FPU_FCW_OFFSET = 0;
|
||||
constexpr size_t FPU_MXCSR_OFFSET = 24;
|
||||
constexpr uint16_t FPU_DEFAULT_FCW = 0x37F;
|
||||
constexpr uint32_t FPU_DEFAULT_MXCSR = 0x1F80;
|
||||
|
||||
// Calls task_entry with the correct parameters.
|
||||
[[__naked]]
|
||||
void task_entry_thunk() {
|
||||
@@ -142,6 +148,11 @@ errno_t arch_task_init(
|
||||
context->fpu_region = (void*)fpu_base;
|
||||
context->fpu_phys = pages;
|
||||
|
||||
const uint16_t fcw = FPU_DEFAULT_FCW;
|
||||
const uint32_t mxcsr = FPU_DEFAULT_MXCSR;
|
||||
memcpy((uint8_t*)fpu_base + FPU_FCW_OFFSET, &fcw, sizeof(fcw));
|
||||
memcpy((uint8_t*)fpu_base + FPU_MXCSR_OFFSET, &mxcsr, sizeof(mxcsr));
|
||||
|
||||
context->ds = asm_read_ds();
|
||||
context->es = asm_read_es();
|
||||
context->fs = asm_read_fs();
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ static void smp_trampoline() {
|
||||
[kernel64_cs] "i"(offsetof(struct gdt, kernel_code64)),
|
||||
[kernel64_ds] "i"(offsetof(struct gdt, kernel_data64)),
|
||||
[cr0] "i"(CR0_PE | CR0_ET),
|
||||
[cr0_pg] "i"(CR0_PG),
|
||||
[cr0_pg] "i"((uint32_t)CR0_PG),
|
||||
[cr4_pae] "i"(CR4_PAE),
|
||||
[msr_efer] "i"(MSR_EFER),
|
||||
[efer_lme] "i"(MSR_EFER_LME),
|
||||
|
||||
+10
@@ -17,6 +17,16 @@ void spin_lock(struct spinlock* spin) {
|
||||
}
|
||||
}
|
||||
|
||||
bool spin_trylock(struct spinlock* spin) {
|
||||
irq_lock();
|
||||
uint32_t owner = atomic_load(&spin->owner, ATOMIC_RELAXED);
|
||||
uint32_t expected = owner;
|
||||
if (atomic_compare_exchange(&spin->next, &expected, owner + 1, ATOMIC_ACQUIRE, ATOMIC_RELAXED))
|
||||
return true;
|
||||
irq_unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
void spin_unlock(struct spinlock* spin) {
|
||||
uint32_t val = atomic_load(&spin->owner, ATOMIC_RELAXED);
|
||||
atomic_store(&spin->owner, val + 1, ATOMIC_RELEASE);
|
||||
|
||||
@@ -5,3 +5,13 @@ static const struct ident kernel_identity = {0};
|
||||
const struct ident* ident_kernel() {
|
||||
return &kernel_identity;
|
||||
}
|
||||
|
||||
bool ident_in_group(const struct ident* identity, gid_t gid, bool use_real) {
|
||||
if (gid == (use_real ? identity->gid : identity->egid))
|
||||
return true;
|
||||
vec_foreach(&identity->groups, i) {
|
||||
if (vec_elem_get(&identity->groups, i) == gid)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11,3 +11,5 @@ struct ident {
|
||||
};
|
||||
|
||||
const struct ident* ident_kernel(void);
|
||||
|
||||
bool ident_in_group(const struct ident* identity, gid_t gid, bool use_real);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
type _sl_link; \
|
||||
}
|
||||
|
||||
#define list_is_empty(head) ((head)->_sl_head == NULL)
|
||||
#define list_is_empty(head) ((head)->_sl_head == nullptr)
|
||||
#define list_first(head) ((head)->_sl_head)
|
||||
#define list_next(elm, field) ((elm)->field._sl_link)
|
||||
|
||||
|
||||
@@ -16,6 +16,15 @@ static inline void refcount_inc(struct refcount* rc) {
|
||||
atomic_fetch_add(&rc->count, 1, ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
static inline bool refcount_inc_not_zero(struct refcount* rc) {
|
||||
size_t count = atomic_load(&rc->count, ATOMIC_RELAXED);
|
||||
do {
|
||||
if (count == 0)
|
||||
return false;
|
||||
} while (!atomic_compare_exchange_weak(&rc->count, &count, count + 1, ATOMIC_ACQUIRE, ATOMIC_RELAXED));
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool refcount_dec(struct refcount* rc) {
|
||||
if (atomic_fetch_sub(&rc->count, 1, ATOMIC_RELEASE) != 1)
|
||||
return false;
|
||||
|
||||
@@ -14,5 +14,7 @@ void spin_init(struct spinlock* spin);
|
||||
// Attempts to lock a spinlock. If it's already locked, waits until it's freed.
|
||||
void spin_lock(struct spinlock* spin);
|
||||
|
||||
bool spin_trylock(struct spinlock* spin);
|
||||
|
||||
// Unlocks a spinlock.
|
||||
void spin_unlock(struct spinlock* spin);
|
||||
|
||||
Reference in New Issue
Block a user