Commit Graph

768 Commits

Author SHA1 Message Date
Justin C. Miller
48e3f9f9d2 [kernel] Fix freelist-clobber bug in heap allocator
The heap_allocator::get_free(order) function returns a reference to the
head pointer of the given freelist, so that it can be manipulated.
However, split_off was also taking a reference to a pointer for an out
param - passing the freelist pointer in here caused split_off to modify
the freelist.

I cleaned up a bunch of the places the freelist pointers were being
touched to make the usage more explicit.
2022-10-10 20:50:08 -07:00
Justin C. Miller
19791d1d7f [debug] Add gdb pretty-printers: vectors, handle sets, cap table
Adding pretty printers to aid in debugging:
* For the cap_table type so that `p g_cap_table` displays a neat table
* For node_sets of handles to easily see what handles a process owns
* For util::vector to include its contents in the output
2022-10-09 22:07:53 -07:00
Justin C. Miller
d04b2ae315 [tools] Allow struct types in definitions
Allow struct type names in definitions, which result in struct buffer
pointers in generated code.
2022-10-06 23:15:20 -07:00
Justin C. Miller
6b20f1fb19 [kernel] Make sure high bits are 0 writing SFMASK MSR
QEMU handles bits bring written in the (reserved) high bits of SFMASK
just fine, but KVM gives a #GP exception.
2022-10-04 20:10:41 -07:00
Justin C. Miller
e90647d498 [kernel] Change heap alloc for better alignment
Created a new util/node_map.h that implements a map that grows in-place.
Now this is used for tracking blocks' size orders, instead of a header
at the start of the memory block. This allows the whole buddy block to
be allocated, allowing for page-aligned (or greater) blocks to be
requested from the heap.
2022-10-02 17:32:26 -07:00
Justin C. Miller
11b61ab345 [kernel] Change kernel log levels
The kernel log levels are now numerically reversed so that more-verbose
levels can be added to the end. Replaced 'debug' with 'verbose', and
added new 'spam' level.
2022-09-25 17:25:43 -07:00
Justin C. Miller
7b8fd76af0 [libj6] Move caps.h to cap_flags.h
This file is just the generated cap flag constants. Move it to not
collide with more capability code to be added.
2022-09-25 17:23:14 -07:00
Justin C. Miller
a2b876825a [kernel] Move mispalced slab_allocated.h
slab_allocated.h had accidentally been placed in src/kernel/objects
2022-09-25 17:15:00 -07:00
Justin C. Miller
9f981ada41 [kernel] Save rsp0 to a process' TSS too
On task switch a process' rsp0 value in its TSS was not getting updated.
2022-09-16 19:39:32 -07:00
Justin C. Miller
b4f13d694f [kernel] Make lld output SysV ABI ELF binaries
lld started creating ELF files with OSABI set to GNU instead of SysV.
Make sure to pass the option to tell lld we want plain SysV binaries.

Also, some debug output in boot if verification fails in ELF loading.
2022-09-16 19:35:36 -07:00
Justin C. Miller
5c26308b23 [kernel] Fix inverted block flag in mailbox_receive
The `block` flag was operating the opposite of its intended behavior.
2022-09-11 14:14:39 -07:00
Justin C. Miller
7fd39e91c1 [kernel] Pull block_allocator out into separate class
The vm_area_guarded code to keep a list of used/free block addresses
will be useful elsewhere.
2022-09-11 14:12:18 -07:00
Justin C. Miller
1d4c66a9a0 [util] Make bitset more constexpr-friendly
In order to more easily express constants as bitsets, add more constexpr
to util::bitset. This allows expressing uint64_t constants as bitsets in
the code instead, without changing the generated assembly, to make code
more readable.
2022-09-11 14:07:21 -07:00
Justin C. Miller
e2f4dad288 [kernel] Interrupt vector priority rearrangement
Rearranging of the ISR vectors for eventual TPR priority. Also removed
excess IRQs - if we need to support more than 64 IRQ vectors, we can add
some more back in.

Also clean up the legacy PIC init/masking code.
2022-03-13 20:00:49 -07:00
Justin C. Miller
31c2053c1c [libc] Implement some math.h functions with builtins
This commit adds implementation of some of the basic math.h functions
with compiler builtins.
2022-03-13 18:11:45 -07:00
Justin C. Miller
d759aae318 [kernel] Add new threads to different CPUs
Previously, when adding a new thread, we only ever added it to the
current CPU and relied on work stealing to balance the CPUs. This commit
has the scheduler schedule new tasks round-robin across CPUs in hopes of
having to steal fewer tasks.

Also adds the run_queue.prev pointer for debugging what task was just
running on the given CPU.
2022-03-13 18:07:08 -07:00
Justin C. Miller
bb0d30610e [util] Add util::format replacement for snprintf
The printf library I have been using, while useful, has way more than I
need in it, and had comparably huge stack space requirements. This
change adds a new util::format() which is a replacement for snprintf,
but with only the features used by kernel logging.

The logger has been changed to use it, as well as the few instances of
snprintf in the interrupt handling code before calling kassert.

Also part of this change: the logger's (now vestigial) immediate output
handling code is removed, as well as the "sequence" field on log
message headers.
2022-03-13 17:59:56 -07:00
Justin C. Miller
24f324552a [kernel] Get rid of fake stack frame in isr_prelude
The isr_prelude (and its IRQ equivalent) had been pushing RIP and RBP in
order to create a fake stack frame. This was in an effor to make GDB
display tracebacks more reliably, but GDB has other reasons for being
finnicky about stack frames, so this was just wasted. This commit gets
rid of it to make looking at the stack clearer.
2022-03-13 17:54:27 -07:00
Justin C. Miller
5c3943bf38 [kernel] Make grabbing an IST stack atomic
In the beginning of the interrupt handler, we had previously checked if
the current handler had grabbed an IST stack from the IDT/TSS. If it
was, it saved this value and set it to 0 in the IDT, then restored it at
the end.

Now this is an atomic action. This is unlikely to make a difference
unless the interrupt handler is itself interrupted by an exception
before being able to swap the IDT value, but such a situation is now
impossible.
2022-03-13 17:49:29 -07:00
Justin C. Miller
90663a674a [kernel] Unify CPUs' control register settings
Previously, the CPU control registers were being set in a number of
different ways. Now, since the APs' need this to be set in the CPU
initialization code, always do it there. This removes some of the
settings from the bootloader, and some unused ones from smp.s.
Additionally, the control registers' flags are now enums in cpu.h and
manipulated via util::bitset.
2022-03-13 17:45:16 -07:00
Justin C. Miller
cca07d97b5 [test_runner] Fix static ctor ordering bug
The test_runner was potentially initializing the array of tests after
tests had been added. Now, allocate the vector dynamically on the first
test addition.
2022-03-13 17:41:50 -07:00
Justin C. Miller
1cc22e78e2 [kernel] Save all cpu_data pointers in global array
For the sake of introspection and debugging, I created a new g_cpu_data
pointer, which points to an array of cpu_data pointers.
2022-03-13 17:40:19 -07:00
Justin C. Miller
95252e793c [kernel] Fix incorrect BSP idle rsp0
In bsp_early_init(), the BSP cpu_data's rsp0 was getting initialized to
the _value_ at the idle_stack_end symbol, instead of its address. I
don't believe this was causing any actual harm, but it was a red herring
when debugging.
2022-03-13 17:36:33 -07:00
Justin C. Miller
54aef00913 [cpu] Reimplement CPUID features as util::bitset
The cpu::cpu_id class no longer looks up all known features in the
constructor, but instead provides access to the map of supported
features as a bitset from the verify() method. It also exposes the
brand_name() method instead of loading the brand name string in the
constructor and storing it as part of the object.
2022-03-13 17:33:16 -07:00
Justin C. Miller
e2eaf43b4a [util] Add templated bitset class
Add a new bitset class which allows for arbitrarily-large bit sets, with
specializations for 32 and 64 bit sets.

Eventually the enum_bitfields code should probably be reconsidered and
moved to bitsets, since it doesn't work everywhere.
2022-03-13 17:26:29 -07:00
Justin C. Miller
e7ccccad7f [tools] Improve j6threads display
Add cpu-specific data like TSS stacks and IST stacks.
2022-03-13 17:15:42 -07:00
Justin C. Miller
d08e5dabe4 [kernel] Fix AP idle stack overflow
This bug has been making me tear my hair out for weeks. When creating
the idle thread for each CPU, we were previously sharing stack areas
with other CPUs' idle threads in an effort to save memory. However, this
caused stack corruption that was very hard to track down. The kernel
stacks are in a vm_area_guarded to better detect this exact kind of
issue, but splitting stacks like this skirts that protection. It's not
worth saving a few KiB per CPU.
2022-03-13 16:58:57 -07:00
Justin C. Miller
df8eb43074 [project] README updates v0.6.0 2022-02-28 21:48:18 -08:00
Justin C. Miller
8b5aedd463 [libc] Stub out math.h
Stub out math.h in order to include c++ headers that include it but
don't actually call any math functions.
2022-02-28 20:34:32 -08:00
Justin C. Miller
b0c0dc53b1 [srv.logger] Create new logger service
Split the functionality of outputting kernel logs out of the UART
driver, and into a new service. The UART driver now registers a console
out channel with the service locator, which the logger service
retrieves, and then enters a loop getting logs from the kernel and
printing them out to the console.
2022-02-28 20:31:50 -08:00
Justin C. Miller
17dcb961ec [srv.init] Serve a service locator protocol from init
The init process now serves as a service locator for its children,
passing all children a mailbox handle on which it is serving the service
locator protocol.
2022-02-28 20:23:18 -08:00
Justin C. Miller
ef307e8ec6 [kernel] Fix mailbox bugs
This commit contains a number of related mailbox issues:

- Add extra parameters to mailbox_respond_receive to allow both the
  number of bytes/handles passed in, and the size of the byte/handle
  buffers to be passed in.
- Don't delete mailbox messages on receipt if the caller is waiting on
  reply
- Correctly pass status messages along with a mailbox::replyer object
- Actually wake the calling thread in the mailbox::replyer dtor
- Make sure to release locks _before_ calling thread::wake() on blocked
  threads, as that may cause them to be scheduled ahead of the current
  thread.
2022-02-28 20:16:42 -08:00
Justin C. Miller
b8684777e0 [kernel] Allow blocking on empty channels
This commit adds a new flag, j6_channel_block, and a new flags param to
the channel_receive syscall. When the block flag is specified, the
caller will block waiting for data on the channel if the channel is
empty.
2022-02-28 20:10:56 -08:00
Justin C. Miller
446025fb65 [kernel] Add clear() method to wait_queue
Allow objects to clear out the wait_queue earlier than waiting for the
destructor by moving that functionality into wait_queue::clear().
2022-02-28 20:06:49 -08:00
Justin C. Miller
19105542e5 [libc] Change memcpy back to rep movsb
Influenced by other libc implementations, I had tried to make memcpy
smarter for differently-sized ranges, but my benchmarks showed no real
change. So change memcpy back to the simple rep movsb implementation.
2022-02-28 18:56:38 -08:00
Justin C. Miller
467c2408c4 [util] Specialize util::hash() for more integer types
There was a specialization of util::hash() for uint64_t (which just
returns the integer value), but other integer sizes did not previously
have similar specializations.

Also, two minor semi-related changes to util::map - skip copying empty
nodes when growing the map, and assert that the hash is non-zero when
inserting a new node.
2022-02-28 18:52:18 -08:00
Justin C. Miller
f87a4fcd4e [kernel] Don't delete system object on no handles
The system object should never be deleted, so override on_no_handles()
to do nothing.
2022-02-28 18:50:59 -08:00
Justin C. Miller
9120318594 [kernel] Change thread_sleep arg from time to duration
It seems more common to want to sleep for a duration than to sleep to a
specific time. Change the implementation to not make the process look up
the current time first. (Plus, there's no current syscall to do so)
2022-02-28 18:43:20 -08:00
Justin C. Miller
982442eb00 [kernel] Add an IPI to tell a CPU to run the scheduler
When waking another thread, if that thread has a more urgent priority
than the current thread on the same CPU, send that CPU an IPI to tell it
to run its scheduler.

Related changes in this commit:

- Addition of the ipiSchedule isr (vector 0xe4) and its handler in
  isr_handler().
- Change the APIC's send_ipi* functions to take an isr enum and not an
  int for their vector parameter
- Thread TCBs now contain a pointer to their current CPU's cpu_data
  structure
- Add the maybe_schedule() call to the scheduler, which sends the
  schedule IPI to the given thread's CPU only when that CPU is running a
  less-urgent thread.
- Move the locking of a run queue lock earlier in schedule() instead of
  taking the lock in steal_work() and again in schedule().
2022-02-26 14:04:14 -08:00
Justin C. Miller
40274f5fac [kernel] Fix logger::get_entry() blocking bug
The new logger event object for making get_entry() block when no logs
are available was consuming the event's notification even if the thread
did not need to block. This was causing excessive blocking - if multiple
logs had been added since the last call to get_entry(), only one would
be returned, and the next call would block until yet another log was
added.

Now only call event::wait() to block the calling thread if there are no
logs available.
2022-02-26 13:46:11 -08:00
Justin C. Miller
a03804b09d [kernel] Add RAII profiler object
Added profiler.h which defines classes and macros for defining profiler
objects. Also added gdb command j6prof for printing profile data. Added
the syscall_profiles profiler class and auto wrapping of syscalls with
profile objects.

Other changes in this commit:

- Made the gdb command `j6threads` argument for specifying a CPU
  optional. Without an argument, it loops through all CPUs.
- Switched to -mcmodel=kernel for kernel code, which makes `call`
  instructions easier to follow when debugging / looking at disassembly.
2022-02-26 13:19:21 -08:00
Justin C. Miller
a9f40cf608 [panic] Improve panic register display
A few changes to the panic handler's display:

- Change rdi and rsi to match other general-purpose registers. (They
  were previously blue, matching the stack/base pointer registers.)
- Change the ordering of r8-r15 to be column-major instead of row-major.
  I find myself wanting to read down the columns to find the register
  I'm looking for, and rax-rdx are already this way.
- Make the flags register yellow, matching the ss and cs registers
- Comment out the call to print_rip() call, as it's only occasionally
  helpful and can cause the panic handler to page fault.
2022-02-26 13:14:16 -08:00
Justin C. Miller
82025bacad [kernel] Make bsp_idle a separate symbol
When debugging, or in panic callstacks, the BSP idle thread used to be
reported as `_kernel_start`, because it was just the loop at the end of
that assembly function. Now, wrap that loop in a separate symbol called
`bsp_idle` to make it clearer that the cpu is in the idle thread.
2022-02-26 13:04:21 -08:00
Justin C. Miller
2640cea175 [util] Update constexpr hash to be FNV-1a
The constexpr_hash.h header has fallen out of use. As constexpr hashing
will be used for IDs with the service locator protocol, update these
hashes to be 32 and 64 bit FNV-1a, and replace the _h user-defined
literal with _id (a 64-bit hash), and _id8 (a 32-bit hash folded down to
8 bits). These are now in the util/hash.h header along with the runtime
hash functions.
2022-02-22 00:20:00 -08:00
Justin C. Miller
63265728d4 [kernel] Fix build breakage
Three issues that caused build breaks when regenerating the build
directory after the previous commits:

- system.def was including endpoint.def
- syscalls/vm_area.cpp was including j6/signals.h
- util/util.h was missing an include of stddef.h
2022-02-22 00:12:07 -08:00
Justin C. Miller
69a3b6dad7 [test_runner] Add handle test suite
For now this just tests handle cloning and basic capability checking.
2022-02-22 00:11:38 -08:00
Justin C. Miller
30aed15090 [kernel] Replace endpoint with new mailbox API
The new mailbox kernel object API offers asynchronous message-based IPC
for sending data and handles between threads, as opposed to endpoint's
synchronous model.
2022-02-22 00:06:14 -08:00
Justin C. Miller
f7ae2e2220 [kernel] Re-design thread blocking
In preparation for the new mailbox IPC model, blocking threads needed an
overhaul. The `wait_on_*` and `wake_on_*` methods are gone, and the
`block()` and `wake()` calls on threads now pass a value between the
waker and the blocked thread.

As part of this change, the concept of signals on the base kobject class
was removed, along with the queue of blocked threads waiting on any
given object. Signals are now exclusively the domain of the event object
type, and the new wait_queue utility class helps manage waiting threads
when an object does actually need this functionality. In some cases (eg,
logger) an event object is used instead of the lower-level wait_queue.

Since this change has a lot of ramifications, this large commit includes
the following additional changes:

- The j6_object_wait, j6_object_wait_many, and j6_thread_pause syscalls
  have been removed.
- The j6_event_clear syscall has been removed - events are "cleared" by
  reading them now. A new j6_event_wait syscall has been added to read
  events.
- The generic close() method on kobject has been removed.
- The on_no_handles() method on kobject now deletes the object by
  default, and needs to be overridden by classes that should not be.
- The j6_system_bind_irq syscall now takes an event handle, as well as a
  signal that the IRQ should set on the event. IRQs will cause a waiting
  thread to be woken with the appropriate bit set.
- Threads waking due to timeout is simplified to just having a
  wake_timeout() accessor that returns a timestamp.
- The new wait_queue uses util::deque, which caused the disovery of two
  bugs in the deque implementation: empty deques could still have a
  single array allocated and thus return true for empty(), and new
  arrays getting allocated were not being zeroed first.
- Exposed a new erase() method on util::map that takes a node pointer
  instead of a key, skipping lookup.
2022-02-22 00:00:15 -08:00
Justin C. Miller
f93d80b8d2 [project] Update Readme and remove toolchain scripts
After hitting 700 commits last week, I thought it'd be a good time to
update the project status in the Readme. This change also pulls out the
toolchain scripts that moved to jsix-os/toolchain, and updates the
Readme about that as well.
2022-02-14 19:52:45 -08:00
Justin C. Miller
a6632625f4 [srv.init] Fix VMA size for non-aligned segments
Another issue related to the bug fix in 3be4b10 - if the segment is
non-aligned, the size of the VMA needs to be seg.mem_size + the prologue
size.

Also renamed the variables from prelude/prologue to prologue/epilogue;
it must have been late at night that I wrote that...
2022-02-14 00:18:29 -08:00