Files
jsix_import/src/kernel/tss.cpp
Justin C. Miller f5208d1641 [all] Remove dependencies on non-freestanding libc
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`.
2023-07-12 19:38:31 -07:00

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;
}
}