Compare commits
8 Commits
80492f6ad3
...
c376477080
Author | SHA1 | Date | |
---|---|---|---|
c376477080 | |||
c51b119eb4 | |||
abdd460525 | |||
293be2c75a | |||
e30eec4213 | |||
ca85a69442 | |||
7d045e45c1 | |||
eaed109fe9 |
@ -23,6 +23,18 @@ extern void pic_eoi(unsigned char irq);
|
|||||||
extern void pic_eoi(Registers* regs);
|
extern void pic_eoi(Registers* regs);
|
||||||
extern void setup_idt();
|
extern void setup_idt();
|
||||||
|
|
||||||
|
void FPData::save()
|
||||||
|
{
|
||||||
|
asm volatile("fxsave (%0)" : : "r"(m_data));
|
||||||
|
m_already_saved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FPData::restore()
|
||||||
|
{
|
||||||
|
if (!m_already_saved) return;
|
||||||
|
asm volatile("fxrstor (%0)" : : "r"(m_data));
|
||||||
|
}
|
||||||
|
|
||||||
// Interrupt handling
|
// Interrupt handling
|
||||||
|
|
||||||
#define FIXME_UNHANDLED_INTERRUPT(name) \
|
#define FIXME_UNHANDLED_INTERRUPT(name) \
|
||||||
@ -52,6 +64,13 @@ void decode_page_fault_error_code(u64 code)
|
|||||||
|
|
||||||
decode_page_fault_error_code(regs->error);
|
decode_page_fault_error_code(regs->error);
|
||||||
|
|
||||||
|
if (!is_in_kernel(regs))
|
||||||
|
{
|
||||||
|
// FIXME: Kill this process with SIGSEGV once we have signals and all that.
|
||||||
|
kerrorln("Current task %zu was terminated because of a page fault", Scheduler::current()->id);
|
||||||
|
kernel_exit();
|
||||||
|
}
|
||||||
|
|
||||||
CPU::print_stack_trace_at(regs);
|
CPU::print_stack_trace_at(regs);
|
||||||
|
|
||||||
CPU::efficient_halt();
|
CPU::efficient_halt();
|
||||||
|
@ -9,6 +9,16 @@ struct Registers // Saved CPU registers for x86-64
|
|||||||
u64 rip, cs, rflags, rsp, ss;
|
u64 rip, cs, rflags, rsp, ss;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FPData
|
||||||
|
{
|
||||||
|
void save();
|
||||||
|
void restore();
|
||||||
|
|
||||||
|
private:
|
||||||
|
char m_data[512] alignas(16);
|
||||||
|
bool m_already_saved;
|
||||||
|
};
|
||||||
|
|
||||||
struct [[gnu::packed]] TSS
|
struct [[gnu::packed]] TSS
|
||||||
{
|
{
|
||||||
u32 reserved0;
|
u32 reserved0;
|
||||||
|
@ -7,7 +7,7 @@ namespace TmpFS
|
|||||||
{
|
{
|
||||||
Result<SharedPtr<VFS::FileSystem>> FileSystem::create()
|
Result<SharedPtr<VFS::FileSystem>> FileSystem::create()
|
||||||
{
|
{
|
||||||
SharedPtr<FileSystem> fs = TRY(adopt_shared(new (std::nothrow) FileSystem()));
|
SharedPtr<FileSystem> fs = TRY(adopt_shared_if_nonnull(new (std::nothrow) FileSystem()));
|
||||||
SharedPtr<VFS::Inode> root = TRY(fs->create_dir_inode({}));
|
SharedPtr<VFS::Inode> root = TRY(fs->create_dir_inode({}));
|
||||||
fs->set_root(root);
|
fs->set_root(root);
|
||||||
return (SharedPtr<VFS::FileSystem>)fs;
|
return (SharedPtr<VFS::FileSystem>)fs;
|
||||||
|
@ -219,10 +219,12 @@ namespace Scheduler
|
|||||||
if (old_thread != new_thread)
|
if (old_thread != new_thread)
|
||||||
{
|
{
|
||||||
switch_context(old_thread, new_thread, regs);
|
switch_context(old_thread, new_thread, regs);
|
||||||
|
if (!old_thread->is_kernel) old_thread->fp_data.save();
|
||||||
if (!new_thread->is_kernel)
|
if (!new_thread->is_kernel)
|
||||||
{
|
{
|
||||||
MMU::switch_page_directory(new_thread->directory);
|
MMU::switch_page_directory(new_thread->directory);
|
||||||
CPU::switch_kernel_stack(new_thread->kernel_stack.top());
|
CPU::switch_kernel_stack(new_thread->kernel_stack.top());
|
||||||
|
new_thread->fp_data.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,6 @@ enum class ThreadState
|
|||||||
Dying
|
Dying
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Save floating point state. (SSE registers on x86_64 using FXSAVE and FXRSTOR)
|
|
||||||
|
|
||||||
struct Thread : public LinkedListNode<Thread>
|
struct Thread : public LinkedListNode<Thread>
|
||||||
{
|
{
|
||||||
Registers regs;
|
Registers regs;
|
||||||
@ -41,6 +39,8 @@ struct Thread : public LinkedListNode<Thread>
|
|||||||
|
|
||||||
OwnedPtr<UserVM> vm_allocator;
|
OwnedPtr<UserVM> vm_allocator;
|
||||||
|
|
||||||
|
FPData fp_data;
|
||||||
|
|
||||||
ThreadState state = ThreadState::Runnable;
|
ThreadState state = ThreadState::Runnable;
|
||||||
|
|
||||||
bool is_kernel { true };
|
bool is_kernel { true };
|
||||||
|
@ -2,10 +2,8 @@
|
|||||||
#include <luna/TypeTraits.h>
|
#include <luna/TypeTraits.h>
|
||||||
#include <luna/Types.h>
|
#include <luna/Types.h>
|
||||||
|
|
||||||
// Must ALWAYS be called with a power of two as alignment.
|
template <usize alignment, typename T> constexpr inline T is_aligned(T value)
|
||||||
template <usize alignment, typename T> constexpr T is_aligned(T value)
|
|
||||||
{
|
{
|
||||||
static_assert(IsPowerOfTwo<usize, alignment>);
|
|
||||||
return (value % alignment == 0);
|
return (value % alignment == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,10 +11,8 @@ static_assert(is_aligned<512>(1024u));
|
|||||||
static_assert(!is_aligned<32>(235u));
|
static_assert(!is_aligned<32>(235u));
|
||||||
static_assert(is_aligned<4096>(40960u));
|
static_assert(is_aligned<4096>(40960u));
|
||||||
|
|
||||||
// Must ALWAYS be called with a power of two as alignment.
|
template <usize alignment, typename T> constexpr inline T align_down(T value)
|
||||||
template <usize alignment, typename T> constexpr T align_down(T value)
|
|
||||||
{
|
{
|
||||||
static_assert(IsPowerOfTwo<usize, alignment>);
|
|
||||||
return value - value % alignment;
|
return value - value % alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,8 +20,7 @@ static_assert(align_down<512>(598ul) == 512ul);
|
|||||||
static_assert(align_down<64>(194ul) == 192ul);
|
static_assert(align_down<64>(194ul) == 192ul);
|
||||||
static_assert(align_down<32>(64ul) == 64ul);
|
static_assert(align_down<32>(64ul) == 64ul);
|
||||||
|
|
||||||
// Must ALWAYS be called with a power of two as alignment.
|
template <usize alignment, typename T> constexpr inline T align_up(T value)
|
||||||
template <usize alignment, typename T> constexpr T align_up(T value)
|
|
||||||
{
|
{
|
||||||
if (is_aligned<alignment>(value)) return value;
|
if (is_aligned<alignment>(value)) return value;
|
||||||
return align_down<alignment>(value) + alignment;
|
return align_down<alignment>(value) + alignment;
|
||||||
@ -47,7 +42,7 @@ static_assert(get_blocks_from_size(0, 256) == 0);
|
|||||||
|
|
||||||
// Offset a pointer by exactly <offset> bytes, no matter the type. Useful to avoid the quirks that come from C pointer
|
// Offset a pointer by exactly <offset> bytes, no matter the type. Useful to avoid the quirks that come from C pointer
|
||||||
// arithmetic.
|
// arithmetic.
|
||||||
template <typename T, typename Offset> constexpr T* offset_ptr(T* ptr, Offset offset)
|
template <typename T, typename Offset> constexpr inline T* offset_ptr(T* ptr, Offset offset)
|
||||||
{
|
{
|
||||||
return (T*)((u8*)ptr + offset);
|
return (T*)((u8*)ptr + offset);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,11 @@ template <usize Size> class StaticString
|
|||||||
adopt(string);
|
adopt(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<usize OtherSize> StaticString(const StaticString<OtherSize>& other)
|
||||||
|
{
|
||||||
|
adopt(other.chars());
|
||||||
|
}
|
||||||
|
|
||||||
void adopt(const char* string)
|
void adopt(const char* string)
|
||||||
{
|
{
|
||||||
usize length = strlcpy(m_buffer, string, sizeof(m_buffer));
|
usize length = strlcpy(m_buffer, string, sizeof(m_buffer));
|
||||||
@ -25,9 +30,9 @@ template <usize Size> class StaticString
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <usize OSize> StaticString<Size>& operator=(const StaticString<OSize>& string)
|
template <usize OtherSize> StaticString<Size>& operator=(const StaticString<OtherSize>& string)
|
||||||
{
|
{
|
||||||
if constexpr (OSize == Size)
|
if constexpr (OtherSize == Size)
|
||||||
{
|
{
|
||||||
if (this == &string) return *this;
|
if (this == &string) return *this;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,9 @@ static Option<HeapBlock*> split(HeapBlock* block, usize size)
|
|||||||
const usize offset = get_fair_offset_to_split_at(block, size + sizeof(HeapBlock));
|
const usize offset = get_fair_offset_to_split_at(block, size + sizeof(HeapBlock));
|
||||||
block->full_size = offset; // shrink the old block to fit this offset
|
block->full_size = offset; // shrink the old block to fit this offset
|
||||||
|
|
||||||
HeapBlock* new_block = offset_ptr(block, offset + sizeof(HeapBlock));
|
HeapBlock* const new_block = offset_ptr(block, offset + sizeof(HeapBlock));
|
||||||
|
|
||||||
|
memset(new_block, 0, sizeof(*new_block));
|
||||||
|
|
||||||
new_block->magic = BLOCK_MAGIC;
|
new_block->magic = BLOCK_MAGIC;
|
||||||
new_block->status = (block->status & BLOCK_END_MEM) ? BLOCK_END_MEM : 0;
|
new_block->status = (block->status & BLOCK_END_MEM) ? BLOCK_END_MEM : 0;
|
||||||
@ -212,6 +214,8 @@ Result<void*> malloc_impl(usize size, bool should_scrub)
|
|||||||
usize pages = get_pages_for_allocation(size + sizeof(HeapBlock));
|
usize pages = get_pages_for_allocation(size + sizeof(HeapBlock));
|
||||||
HeapBlock* const current = (HeapBlock*)TRY(allocate_pages_impl(pages));
|
HeapBlock* const current = (HeapBlock*)TRY(allocate_pages_impl(pages));
|
||||||
|
|
||||||
|
memset(current, 0, sizeof(*current));
|
||||||
|
|
||||||
current->full_size = (pages * PAGE_SIZE) - sizeof(HeapBlock);
|
current->full_size = (pages * PAGE_SIZE) - sizeof(HeapBlock);
|
||||||
current->magic = BLOCK_MAGIC;
|
current->magic = BLOCK_MAGIC;
|
||||||
current->status = BLOCK_START_MEM | BLOCK_END_MEM;
|
current->status = BLOCK_START_MEM | BLOCK_END_MEM;
|
||||||
|
@ -6,8 +6,8 @@ source $(dirname $0)/env.sh
|
|||||||
cd $LUNA_ROOT
|
cd $LUNA_ROOT
|
||||||
|
|
||||||
SOURCES=($(find kernel/src -type f | grep -v "\.asm"))
|
SOURCES=($(find kernel/src -type f | grep -v "\.asm"))
|
||||||
SOURCES+=($(find luna/src -type f))
|
SOURCES+=($(find libluna/src -type f))
|
||||||
SOURCES+=($(find luna/include/luna -type f))
|
SOURCES+=($(find libluna/include/luna -type f))
|
||||||
|
|
||||||
for f in ${SOURCES[@]}
|
for f in ${SOURCES[@]}
|
||||||
do
|
do
|
||||||
|
Loading…
Reference in New Issue
Block a user