Small fixes
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
#include <zinnia/types.h>
|
|
||||||
#include <arch/mem.h>
|
#include <arch/mem.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ kernel_sources += files(
|
|||||||
'mem.c',
|
'mem.c',
|
||||||
'percpu.c',
|
'percpu.c',
|
||||||
'pmap.c',
|
'pmap.c',
|
||||||
'pmap.c',
|
|
||||||
'random.c',
|
'random.c',
|
||||||
'sched.c',
|
'sched.c',
|
||||||
'serial.c',
|
'serial.c',
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <bits/sched.h>
|
#include <bits/sched.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
#include <x86_64/apic.h>
|
#include <x86_64/apic.h>
|
||||||
#include <x86_64/asm.h>
|
#include <x86_64/asm.h>
|
||||||
#include <x86_64/defs.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);
|
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.
|
// Calls task_entry with the correct parameters.
|
||||||
[[__naked]]
|
[[__naked]]
|
||||||
void task_entry_thunk() {
|
void task_entry_thunk() {
|
||||||
@@ -142,6 +148,11 @@ errno_t arch_task_init(
|
|||||||
context->fpu_region = (void*)fpu_base;
|
context->fpu_region = (void*)fpu_base;
|
||||||
context->fpu_phys = pages;
|
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->ds = asm_read_ds();
|
||||||
context->es = asm_read_es();
|
context->es = asm_read_es();
|
||||||
context->fs = asm_read_fs();
|
context->fs = asm_read_fs();
|
||||||
|
|||||||
+1
-1
@@ -148,7 +148,7 @@ static void smp_trampoline() {
|
|||||||
[kernel64_cs] "i"(offsetof(struct gdt, kernel_code64)),
|
[kernel64_cs] "i"(offsetof(struct gdt, kernel_code64)),
|
||||||
[kernel64_ds] "i"(offsetof(struct gdt, kernel_data64)),
|
[kernel64_ds] "i"(offsetof(struct gdt, kernel_data64)),
|
||||||
[cr0] "i"(CR0_PE | CR0_ET),
|
[cr0] "i"(CR0_PE | CR0_ET),
|
||||||
[cr0_pg] "i"(CR0_PG),
|
[cr0_pg] "i"((uint32_t)CR0_PG),
|
||||||
[cr4_pae] "i"(CR4_PAE),
|
[cr4_pae] "i"(CR4_PAE),
|
||||||
[msr_efer] "i"(MSR_EFER),
|
[msr_efer] "i"(MSR_EFER),
|
||||||
[efer_lme] "i"(MSR_EFER_LME),
|
[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) {
|
void spin_unlock(struct spinlock* spin) {
|
||||||
uint32_t val = atomic_load(&spin->owner, ATOMIC_RELAXED);
|
uint32_t val = atomic_load(&spin->owner, ATOMIC_RELAXED);
|
||||||
atomic_store(&spin->owner, val + 1, ATOMIC_RELEASE);
|
atomic_store(&spin->owner, val + 1, ATOMIC_RELEASE);
|
||||||
|
|||||||
@@ -5,3 +5,13 @@ static const struct ident kernel_identity = {0};
|
|||||||
const struct ident* ident_kernel() {
|
const struct ident* ident_kernel() {
|
||||||
return &kernel_identity;
|
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);
|
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; \
|
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_first(head) ((head)->_sl_head)
|
||||||
#define list_next(elm, field) ((elm)->field._sl_link)
|
#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);
|
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) {
|
static inline bool refcount_dec(struct refcount* rc) {
|
||||||
if (atomic_fetch_sub(&rc->count, 1, ATOMIC_RELEASE) != 1)
|
if (atomic_fetch_sub(&rc->count, 1, ATOMIC_RELEASE) != 1)
|
||||||
return false;
|
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.
|
// Attempts to lock a spinlock. If it's already locked, waits until it's freed.
|
||||||
void spin_lock(struct spinlock* spin);
|
void spin_lock(struct spinlock* spin);
|
||||||
|
|
||||||
|
bool spin_trylock(struct spinlock* spin);
|
||||||
|
|
||||||
// Unlocks a spinlock.
|
// Unlocks a spinlock.
|
||||||
void spin_unlock(struct spinlock* spin);
|
void spin_unlock(struct spinlock* spin);
|
||||||
|
|||||||
Reference in New Issue
Block a user