This is the first of two rather big changes to clean up includes throughout the project. In this commit, the implicit semi-dependency on libc that bonnibel adds to every module is removed. Previously, I was sloppy with includes of libc headers and include directory order. Now, the freestanding headers from libc are split out into libc_free, and an implicit real dependency is added onto this module, unless `no_libc` is set to `True`. The full libc needs to be explicitly specified as a dependency to be used. Several things needed to change in order to do this: - Many places use `memset` or `memcpy` that cannot depend on libc. The kernel has basic implementations of them itself for this reason. Now those functions are moved into the lower-level `j6/memutils.h`, and libc merely references them. Other modules are now free to reference those functions from libj6 instead. - The kernel's `assert.h` was renamed kassert.h (matching its `kassert` function) so that the new `util/assert.h` can use `__has_include` to detect it and make sure the `assert` macro is usable in libutil code. - Several implementation header files under `__libj6/` also moved under the new libc_free. - A new `include_phase` property has been added to modules for Bonnibel, which can be "normal" (default) or "late" which uses `-idirafter` instead of `-I` for includes. - Since `<utility>` and `<new>` are not freestanding, implementations of `remove_reference`, `forward`, `move`, and `swap` were added to the `util` namespace to replace those from `std`, and `util/new.h` was added to declare `operator new` and `operator delete`.
69 lines
1.7 KiB
C++
69 lines
1.7 KiB
C++
#include <j6/memutils.h>
|
|
#include <util/no_construct.h>
|
|
|
|
#include "kassert.h"
|
|
#include "cpu.h"
|
|
#include "logger.h"
|
|
#include "memory.h"
|
|
#include "objects/vm_area.h"
|
|
#include "tss.h"
|
|
|
|
// The BSP's TSS is initialized _before_ global constructors are called,
|
|
// so we don't want it to have a global constructor, lest it overwrite
|
|
// the previous initialization.
|
|
static util::no_construct<TSS> __g_bsp_tss_storage;
|
|
TSS &g_bsp_tss = __g_bsp_tss_storage.value;
|
|
|
|
|
|
TSS::TSS()
|
|
{
|
|
memset(this, 0, sizeof(TSS));
|
|
m_iomap_offset = sizeof(TSS);
|
|
}
|
|
|
|
TSS &
|
|
TSS::current()
|
|
{
|
|
return *current_cpu().tss;
|
|
}
|
|
|
|
uintptr_t &
|
|
TSS::ring_stack(unsigned ring)
|
|
{
|
|
kassert(ring < 3, "Bad ring passed to TSS::ring_stack.");
|
|
return m_rsp[ring];
|
|
}
|
|
|
|
uintptr_t &
|
|
TSS::ist_stack(unsigned ist)
|
|
{
|
|
kassert(ist > 0 && ist < 7, "Bad ist passed to TSS::ist_stack.");
|
|
return m_ist[ist];
|
|
}
|
|
|
|
void
|
|
TSS::create_ist_stacks(uint8_t ist_entries)
|
|
{
|
|
extern obj::vm_area_guarded &g_kernel_stacks;
|
|
using mem::frame_size;
|
|
using mem::kernel_stack_pages;
|
|
constexpr size_t stack_bytes = kernel_stack_pages * frame_size;
|
|
|
|
for (unsigned ist = 1; ist < 8; ++ist) {
|
|
if (!(ist_entries & (1 << ist))) continue;
|
|
|
|
// Two zero entries at the top for the null frame
|
|
uintptr_t stack_bottom = g_kernel_stacks.get_section();
|
|
uintptr_t stack_top = stack_bottom + stack_bytes - 2 * sizeof(uintptr_t);
|
|
|
|
log::verbose(logs::memory, "Created IST stack at %016lx size 0x%lx",
|
|
stack_bottom, stack_bytes);
|
|
|
|
// Pre-realize these stacks, they're no good if they page fault
|
|
for (unsigned i = 0; i < kernel_stack_pages; ++i)
|
|
*reinterpret_cast<uint64_t*>(stack_bottom + i * frame_size) = 0;
|
|
|
|
ist_stack(ist) = stack_top;
|
|
}
|
|
}
|