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 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
|
||||
|
||||
#define FIXME_UNHANDLED_INTERRUPT(name) \
|
||||
@ -52,6 +64,13 @@ void decode_page_fault_error_code(u64 code)
|
||||
|
||||
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::efficient_halt();
|
||||
|
@ -9,6 +9,16 @@ struct Registers // Saved CPU registers for x86-64
|
||||
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
|
||||
{
|
||||
u32 reserved0;
|
||||
|
@ -7,7 +7,7 @@ namespace TmpFS
|
||||
{
|
||||
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({}));
|
||||
fs->set_root(root);
|
||||
return (SharedPtr<VFS::FileSystem>)fs;
|
||||
|
@ -219,10 +219,12 @@ namespace Scheduler
|
||||
if (old_thread != new_thread)
|
||||
{
|
||||
switch_context(old_thread, new_thread, regs);
|
||||
if (!old_thread->is_kernel) old_thread->fp_data.save();
|
||||
if (!new_thread->is_kernel)
|
||||
{
|
||||
MMU::switch_page_directory(new_thread->directory);
|
||||
CPU::switch_kernel_stack(new_thread->kernel_stack.top());
|
||||
new_thread->fp_data.restore();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,6 @@ enum class ThreadState
|
||||
Dying
|
||||
};
|
||||
|
||||
// FIXME: Save floating point state. (SSE registers on x86_64 using FXSAVE and FXRSTOR)
|
||||
|
||||
struct Thread : public LinkedListNode<Thread>
|
||||
{
|
||||
Registers regs;
|
||||
@ -41,6 +39,8 @@ struct Thread : public LinkedListNode<Thread>
|
||||
|
||||
OwnedPtr<UserVM> vm_allocator;
|
||||
|
||||
FPData fp_data;
|
||||
|
||||
ThreadState state = ThreadState::Runnable;
|
||||
|
||||
bool is_kernel { true };
|
||||
|
@ -2,10 +2,8 @@
|
||||
#include <luna/TypeTraits.h>
|
||||
#include <luna/Types.h>
|
||||
|
||||
// Must ALWAYS be called with a power of two as alignment.
|
||||
template <usize alignment, typename T> constexpr T is_aligned(T value)
|
||||
template <usize alignment, typename T> constexpr inline T is_aligned(T value)
|
||||
{
|
||||
static_assert(IsPowerOfTwo<usize, alignment>);
|
||||
return (value % alignment == 0);
|
||||
}
|
||||
|
||||
@ -13,10 +11,8 @@ static_assert(is_aligned<512>(1024u));
|
||||
static_assert(!is_aligned<32>(235u));
|
||||
static_assert(is_aligned<4096>(40960u));
|
||||
|
||||
// Must ALWAYS be called with a power of two as alignment.
|
||||
template <usize alignment, typename T> constexpr T align_down(T value)
|
||||
template <usize alignment, typename T> constexpr inline T align_down(T value)
|
||||
{
|
||||
static_assert(IsPowerOfTwo<usize, 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<32>(64ul) == 64ul);
|
||||
|
||||
// Must ALWAYS be called with a power of two as alignment.
|
||||
template <usize alignment, typename T> constexpr T align_up(T value)
|
||||
template <usize alignment, typename T> constexpr inline T align_up(T value)
|
||||
{
|
||||
if (is_aligned<alignment>(value)) return value;
|
||||
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
|
||||
// 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);
|
||||
}
|
||||
|
@ -11,6 +11,11 @@ template <usize Size> class StaticString
|
||||
adopt(string);
|
||||
}
|
||||
|
||||
template<usize OtherSize> StaticString(const StaticString<OtherSize>& other)
|
||||
{
|
||||
adopt(other.chars());
|
||||
}
|
||||
|
||||
void adopt(const char* string)
|
||||
{
|
||||
usize length = strlcpy(m_buffer, string, sizeof(m_buffer));
|
||||
@ -25,9 +30,9 @@ template <usize Size> class StaticString
|
||||
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;
|
||||
}
|
||||
|
@ -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));
|
||||
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->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));
|
||||
HeapBlock* const current = (HeapBlock*)TRY(allocate_pages_impl(pages));
|
||||
|
||||
memset(current, 0, sizeof(*current));
|
||||
|
||||
current->full_size = (pages * PAGE_SIZE) - sizeof(HeapBlock);
|
||||
current->magic = BLOCK_MAGIC;
|
||||
current->status = BLOCK_START_MEM | BLOCK_END_MEM;
|
||||
|
@ -6,8 +6,8 @@ source $(dirname $0)/env.sh
|
||||
cd $LUNA_ROOT
|
||||
|
||||
SOURCES=($(find kernel/src -type f | grep -v "\.asm"))
|
||||
SOURCES+=($(find luna/src -type f))
|
||||
SOURCES+=($(find luna/include/luna -type f))
|
||||
SOURCES+=($(find libluna/src -type f))
|
||||
SOURCES+=($(find libluna/include/luna -type f))
|
||||
|
||||
for f in ${SOURCES[@]}
|
||||
do
|
||||
|
Loading…
Reference in New Issue
Block a user