Commit Graph

568 Commits

Author SHA1 Message Date
Justin C. Miller
e3ecd73cd8 [util] Add constexpr log2/is_pow2 helpers
I didn't end up using these, but constexpr log2 and is_pow2 functions
might be helpful.
2022-01-30 21:02:32 -08:00
Justin C. Miller
5dfc6ae62e [kernel] Add event syscalls
The event object was missing any syscalls. Furthermore, kobject had an
old object_signal implementation (the syscall itself no longer exists),
which was removed. User code should only be able to set signals on
events.
2022-01-30 21:00:46 -08:00
Justin C. Miller
343622d4e5 [kernel] Fix up formatting
Two minor issues: scheduler::prune wasn't formatted correctly, and
j6/caps.h was not using the ull prefix when shifting 64 bit numbers.
(It's doubtful an object would get more than 32 caps any time soon, but
better to be correct.)
2022-01-30 20:52:43 -08:00
Justin C. Miller
9945ebab34 [kernel] Get rid of obsolete thread loading state
The thread::state::loading flag was left over from a time when the
kernel did elf loading for all processes.
2022-01-30 20:50:48 -08:00
Justin C. Miller
42774d94c0 [kernel] Fix SMP not starting
The cpu.cpp/smp.cpp cleanup out of kernel_main missed an important call:
kernel_main never called smp::ready() to unblock the APs waiting for the
scheduler to be ready.
2022-01-30 20:48:50 -08:00
Justin C. Miller
dd535158f2 [kernel] Re-add slab_allocated mixin
The return of slab_allocated! Now after the kutil/util/kernel giant
cleanup, this belongs squarely in the kernel, and works much better
there. Slabs are allocated via a bump pointer into a new kernel VMA,
instead of using kalloc() or allocating pages directly.
2022-01-30 20:46:19 -08:00
Justin C. Miller
a7245116b6 [util] Add util::deque container
Adding the util::deque container, implemented with the util::linked_list
of arrays of items.

Also, use the deque for a kobject's blocked thread list to maintain
order instead of a vector using remove_swap().
2022-01-30 20:42:49 -08:00
Justin C. Miller
2aef7176ab [kernel] Add missing zero_ok changes
This change adds some changes I missed as part of the previous (see
da5c1e9) zero_ok change.
2022-01-30 20:40:51 -08:00
Justin C. Miller
da5c1e9833 [kernel] Add new zero_ok flag to syscall params
The new zero_ok flag is similar to optional for reference parameters,
but only in cases where there is a length parameter. If that parameter
is a reference parameter itself and is null, or it is non-null and
contains a non-zero length, or there is no length parameter, then the
main parameter may not be null.
2022-01-30 14:26:36 -08:00
Justin C. Miller
b6218a1121 [kernel] Allow 7+ argument syscalls
The syscall interface is designed to closely follow the System V amd64
calling convention, so that as much as possible, the call into the
assembly trampoline for the syscall sets up the call correctly. Before
this change, the only exception was using r10 (a caller-saved register
already) to stash the contents of rcx, which gets clobbered by the
syscall instruction. However, this only preserves registers for the
function call, as the stack is switched upon kernel entry, and
additional call frames have been added by the time the syscall gets back
into C++ land.

This change adds a new parameter to the syscall in rbx. Since rbx is
callee-saved, the syscall trampoline pushes it to the stack, and then
puts the address of the stack-passed arguments into rbx. Now that the
syscall implementations are wrapped in the _syscall_verify_* functions,
we can piggy-back on those to also set up the extra arguments from the
user stack.

Now, for any syscall with 7 or more arguments, the verify wrapper takes
the first six arguments normally, then gets a stack pointer (the rbx
value) as its 7th and final argument. It's then the job of the verify
wrapper to get the remaining arguments from that stack pointer and pass
them to the implementation function as normal arguments.
2022-01-30 12:25:11 -08:00
Justin C. Miller
cd037aca15 [kernel] Let objects inherit caps from superclasses
The main point of this change is to allow "global" capabilities defined
on the base object type. The example here is the clone capability on all
objects, which governs the ability to clone a handle.

Related changes in this commit:
- Renamed `kobject` to `object` as far as the syscall interface is
  concerned. `kobject` is the cname, but j6_cap_kobject_clone feels
  clunky.
- The above change made me realize that the "object <type>" syntax for
  specifying object references was also clunky, so now it's "ref <type>"
- Having to add `.object` on everywhere to access objects in
  interface.exposes or object.super was cumbersome, so those properties
  now return object types directly, instead of ObjectRef.
- syscall_verify.cpp.cog now generates code to check capabilities on
  handles if they're specified in the definition, even when not passing
  an object to the implementation function.
2022-01-29 15:56:33 -08:00
Justin C. Miller
bdae812274 [kernel] Add handle_clone syscall
Added the handle_clone syscall which allows for cloning a handle with
a subset of the original handle's capabilities.

Related changes:

- srv.init now calls handle_clone on its system handle, and load_program
  was changed to allow this second system handle to be passed to loaded
  programs instead. However, as drv.uart is still a driver AND a log
  reader, this new handle is not actually passed yet.
- The definition parser was using a set for the cap list, which meant
  the order (and thus values) of caps was not static.
- Some code in objects/handle.h was made more explicit about what bits
  meant what.
2022-01-28 23:40:21 -08:00
Justin C. Miller
f1246f84e0 [kernel] Add capabilities to handles
This change finally adds capabilities to handles. Included changes:

- j6_handle_t is now again 64 bits, with the highest 8 bits being a type
  code, and the next highest 24 bits being the capability mask, so that
  programs can check type/caps without calling the kernel.
- The definitions grammar now includes a `capabilities [ ]` section on
  objects, to list what capabilities are relevant.
- j6/caps.h is auto-generated from object capability lists
- init_libj6 again sets __handle_self and __handle_sys, this is a bit
  of a hack.
- A new syscall, j6_handle_list, will return the list of existing
  handles owned by the calling process.
- syscall_verify.cpp.cog now actually checks that the needed
  capabilities exist on handles before allowing the call.
2022-01-28 01:54:45 -08:00
Justin C. Miller
9b75acf0b5 [kernel] Re-add channel syscalls
Channels were unused, and while they were listed in syscalls.def, they
had no syscalls listed in their interface. This change adds them back,
and updates them to the curren syscall style.
2022-01-27 22:37:04 -08:00
Justin C. Miller
42d7f4245d [kernel] Remove placement-new declaration from memory.h.cog
Finishing the trend of using `#include <new>` to define new, get rid of
the last bits of custom-declared operator new.
2022-01-27 22:04:06 -08:00
Justin C. Miller
fd25d3babc [kernel] Clean up main.cpp and others
The kernel/main.cpp and kernel/memory_bootstrap.cpp files had become
something of a junk drawer. This change cleans them up in the following
ways:

- Most CPU initialization has moved to cpu.cpp, allowing several
  functions to be made static and removed from cpu.h
- Multi-core startup code has moved to the new smp.h and smp.cpp, and
  ap_startup.s has been renamed smp.s to match.
- run_constructors() has moved to memory_bootstrap.cpp, and all the
  functionality of that file has been hidden behind a new public
  interface mem::initialize().
- load_init_server() has moved from memory_bootstrap.cpp to main.cpp
2022-01-27 19:28:35 -08:00
Justin C. Miller
3f8dfbd5b2 [kernel] Add locking to endpoint
Endpoints could previously crash if two senders were concurrently
writing to them, so this change adds a spinlock and protects functions
that touch the signals and blocked list.
2022-01-23 19:42:37 -08:00
Justin C. Miller
0394f29f70 [util] Add release() and reaquire() to scoped_lock
Added methods for releasing the lock held in a scoped_lock early, as
well as reacquiring it after. Useful when, eg a thread is about to block
and should not be holding the lock while blocked.
2022-01-23 19:40:00 -08:00
Justin C. Miller
2750ec8ef9 [util] Fix bip_buffer concurrency bug
If a bip_buffer's A buffer is in the middle of being appended to, but
that append has not yet been committed, and all committed A data has
been read, the buffer would get into a bad state where m_start_r pointed
to the end of the previous A buffer, but that data is no longer
connected to either A or B. So now we make sure to check m_size_r before
considering A "done".
2022-01-23 17:43:30 -08:00
Justin C. Miller
75e7fe941b [kernel] Fix thread-wait scoped lock scoping bug
A spinlock was recenly added to thread wait states, so that they
couldn't get stuck if their wake event happened while setting the wake
state, and cause the thread to deadlock. But the scoped_lock objects
locking that spinlock were being instantiated as temporaries and
immediately being thrown away because I forgot to name them.
2022-01-23 00:32:06 -08:00
Justin C. Miller
cbd2d9d625 [kernel] Fix scheduler promotion bug
The scheduler was accidentally checking the state of the _currently
running_ thread when seeing if it should promote a thread in the ready
queue. So, ie, constant-priority threads would get promoted as long as
some non-constant-priority thread was the currently-running thread.
2022-01-23 00:29:51 -08:00
Justin C. Miller
1d30322820 [kernel] Pass objects not handles to syscall impls
This commit contains a couple large, interdependent changes:

- In preparation for capability checking, the _syscall_verify_*
  functions now load most handles passed in, and verify that they exist
  and are of the correct type. Lists and out-handles are not converted
  to objects.
- Also in preparation for capability checking, the internal
  representation of handles has changed. j6_handle_t is now 32 bits, and
  a new j6_cap_t (also 32 bits) is added. Handles of a process are now a
  util::map<j6_handle_t, handle> where handle is a new struct containing
  the id, capabilities, and object pointer.
- The kernel object definition DSL gained a few changes to support auto
  generating the handle -> object conversion in the _syscall_verify_*
  functions, mostly knowing the object type, and an optional "cname"
  attribute on objects where their names differ from C++ code.
  (Specifically vma/vm_area)
- Kernel object code and other code under kernel/objects is now in a new
  obj:: namespace, because fuck you <cstdlib> for putting "system" in
  the global namespace. Why even have that header then?
- Kernel object types constructed with the construct_handle helper now
  have a creation_caps static member to declare what capabilities a
  newly created object's handle should have.
2022-01-17 23:23:04 -08:00
Justin C. Miller
e0246df26b [kernel] Add automatic verification to syscalls
Since we have a DSL for specifying syscalls, we can create a verificaton
method for each syscall that can cover most argument (and eventually
capability) verification instead of doing it piecemeal in each syscall
implementation, which can be more error-prone.

Now a new _syscall_verify_* function exists for every syscall, which
calls the real implementation. The syscall table for the syscall handler
now maps to these verify functions.

Other changes:

- Updated the definition grammar to allow options to have a "key:value"
  style, to eventually support capabilities.
- Added an "optional" option for parameters that says a syscall will
  accept a null value.
- Some bonnibel fixes, as definition file changes weren't always
  properly causing updates in the build dep graph.
- The syscall implementation function signatures are no longer exposed
  in syscall.h. Also, the unused syscall enum has been removed.
2022-01-16 15:11:58 -08:00
Justin C. Miller
e845379b1e [kernel] Use the hpet clock source in scheduler
There has been a global clock object for a while now, but scheduler was
never using it, instead still using its simple increment clock. Now it
uses the hpet clock.
2022-01-15 22:31:00 -08:00
Justin C. Miller
c631ec5ef5 [uart] Add first pass UART driver and logger
First attempt at a UART driver. I'm not sure it's the most stable. Now
that userspace is handling displaying logs, also removed serial and log
output support from the kernel.
2022-01-15 18:20:37 -08:00
Justin C. Miller
44d3918e4f [util] Add try_aquire to spinlock
Also added a scoped_trylock class that mirrors scoped_lock, but uses
try_aquire and has a scoped_lock::locked() accessor.
2022-01-15 17:51:55 -08:00
Justin C. Miller
19f9496889 [kernel] Add a timeout to endpoint recieve syscalls
This also required adding support for multiple wait conditions on a
thread, so wait_type is an enum_bitfield now.

I really need a real clock.
2022-01-15 17:48:19 -08:00
Justin C. Miller
2dd78beb92 [tools] Add j6threads gdb command
The j6threads command shows the current thread, ready threads, and
blocked threads for a given CPU.

To support this, TCB structs gained a pointer to their thread (instead
of trying to do offset magic) and threads gained a pointer to their
creator. Also removed thread::from_tcb() now that the TCB has a pointer.
2022-01-15 17:45:12 -08:00
Justin C. Miller
7bb6b21c65 [kernel] Simplify kernel logger
The logger had a lot of code that was due to it being in kutil instead
of the kernel. Simplifying it a bit here in order to make the uart
logger easier and eventual paring down of the logger easier.

- Log areas are no longer hashes of their names, just an enum
- Log level settings are no longer saved in 4 bits, just a byte
- System signal updating is done in the logger now
2022-01-15 10:00:13 -08:00
Justin C. Miller
11eef8d892 [kernel] Add process_give_handle syscall
This syscall allows a process to give another process access to an
object it has a handle to. The value of the handle as seen in the
receiver process is returned to the caller, so that the caller may
notify the recipient which handle was given.
2022-01-15 09:37:55 -08:00
Justin C. Miller
4d9b33ecd4 [panic] Allow assert/panic to take optional user cpu_state
In places where the "user" state is available, like interrupt handlers,
panic() and kassert() can now take an optional pointer to that user
cpu_state structure, and the panic handler will print that out as well.
2022-01-15 09:33:38 -08:00
Justin C. Miller
421fe33dc0 [boot] Scroll serial output before exit_boot_services
The last line of the boot output was always getting cut off by anything
else getting printed to the serial port. Adding two newlines to clear
the cursor of the previous output.
2022-01-15 09:08:46 -08:00
Justin C. Miller
b3aaddadc8 [kernel] Expose a sysconf page to userspace
A structure, system_config, which is dynamically defined by the
definitions/sysconf.yaml config, is now mapped into every user address
space. The kernel fills this with information about itself and the
running machine.

User programs access this through the new j6_sysconf fake syscall in
libj6.

See: Github bug #242
See: [frobozz blog post](https://jsix.dev/posts/frobozz/)

Tags:
2022-01-13 22:08:35 -08:00
Justin C. Miller
939022bb5e [build] Change memory_layout from csv to yaml
I realized we don't need yet another format for configuration. As a
bonus, yaml also allows for a more descriptive file.
2022-01-13 20:23:14 -08:00
Justin C. Miller
950360fddc [libj6] Move remaining j6 headers out of src/include
This means the kernel now depends on libj6. I've added the macro
definition __j6kernel when building for the kernel target, so I can
remove parts with #ifdefs.
2022-01-12 16:04:16 -08:00
Justin C. Miller
2ff7a0864b [build] Fix handling of cog header deps
The last commit was a bandaid, but this needed a real fix. Now we create
a .parse_deps.phony file in every module build dir that implicitly
depends on that module's dependencies' .parse_deps.phony files, as well
as order-only depends on any cog-parsed output for that module. This
causes the cog files to get generated first if they never have been, but
still leaves real header dependency tracking to clang's depfile
generation.
2022-01-08 15:34:47 -08:00
Justin C. Miller
488f2df869 [boot] Add explicit dependency on bootproto/memory.h
bootproto/memory.h is generated from a cog file. Some builds could fail
because the dependency on this file was not explicit.
2022-01-08 14:38:54 -08:00
Justin C. Miller
6877944d17 [kernel] Make unknown IRQs a warning, not a panic
There's not a good reason for them to panic the kernel, not even the
traceback in the panic will be useful.
2022-01-08 01:13:55 -08:00
Justin C. Miller
eeef23c2b7 [panic] Have panics stop all cores
Kernel panics previously only stopped the calling core. This commit
re-implements the panic system to allow us to stop all cores on a panic.

Changes include:

- panic now sends an NMI to all cores. This means we can't control the
  contents of their registers, so panic information has been moved to a
  global struct, and the panicking cpu sets the pointer to that data in
  its cpu_data.
- the panic_handler is now set up with mutexes to print appropriately
  and only initialize objects once.
- copying _current_gsbase into the panic handler, and #including the
  cpprt.cpp file (so that we can define NDEBUG and not have it try to
  link the assert code back in)
- making the symbol data pointer in kargs an actual pointer again, not
  an address - and carrying that through to the panic handler
- the number of cpus is now saved globally in the kernel as g_num_cpus
2022-01-08 01:00:43 -08:00
Justin C. Miller
a3fff889d1 [boot] Create bootconfig to tell boot what to load
While bonnibel already had the concept of a manifest, which controls
what goes into the built disk image, the bootloader still had filenames
hard-coded. Now bonnibel creates a 'jsix_boot.dat' file that tells the
bootloader what it should load.

Changes include:

- Modules have two new fields: location and description. location is
  their intended directory on the EFI boot volume. description is
  self-explanatory, and is used in log messages.
- New class, boot::bootconfig, implements reading of jsix_boot.dat
- New header, bootproto/bootconfig.h, specifies flags used in the
  manifest and jsix_boot.dat
- New python module, bonnibel/manifest.py, encapsulates reading of the
  manifest and writing jsix_boot.dat
- Syntax of the manifest changed slightly, including adding flags
- Boot and Kernel target ccflags unified a bit (this was partly due to
  trying to get enum_bitfields to work in boot)
- util::counted gained operator+= and new free function util::read<T>
2022-01-07 22:43:44 -08:00
Justin C. Miller
9f3e682b89 [util] Handle const better in enum_bitfields
I just can't get enum_bitfields to work in boot. The same code works in
other targets. None of the compiler options should change that. I gave
up, but I'm leaving these changes in because they do actually handle
const better.
2022-01-07 00:46:45 -08:00
Justin C. Miller
411c8c4cb3 [util] Move enum_bitfields into util
Continuing on the cleaning up of the src/include 'junk drawer', the
enum_bitfields.h and its dependency basic_types.h are now in util.
2022-01-03 21:42:20 -08:00
Justin C. Miller
c1d9b35e7c [bootproto] Create new bootproto lib
This is a rather large commit that is widely focused on cleaning things
out of the 'junk drawer' that is src/include. Most notably, several
things that were put in there because they needed somewhere where both
the kernel, boot, and init could read them have been moved to a new lib,
'bootproto'.

- Moved kernel_args.h and init_args.h to bootproto as kernel.h and
  init.h, respectively.

- Moved counted.h and pointer_manipulation.h into util, renaming the
  latter to util/pointers.h.

- Created a new src/include/arch for very arch-dependent definitions,
  and moved some kernel_memory.h constants like frame size, page table
  entry count, etc to arch/amd64/memory.h. Also created arch/memory.h
  which detects platform and includes the former.

- Got rid of kernel_memory.h entirely in favor of a new, cog-based
  approach. The new definitions/memory_layout.csv lists memory regions
  in descending order from the top of memory, their sizes, and whether
  they are shared outside the kernel (ie, boot needs to know them). The
  new header bootproto/memory.h exposes the addresses of the shared
  regions, while the kernel's memory.h gains the start and size of all
  the regions. Also renamed the badly-named page-offset area the linear
  area.

- The python build scripts got a few new features: the ability to parse
  the csv mentioned above in a new memory.py module; the ability to add
  dependencies to existing source files (The list of files that I had to
  pull out of the main list just to add them with the dependency on
  memory.h was getting too large. So I put them back into the sources
  list, and added the dependency post-hoc.); and the ability to
  reference 'source_root', 'build_root', and 'module_root' variables in
  .module files.

- Some utility functions that were in the kernel's memory.h got moved to
  util/pointers.h and util/misc.h, and misc.h's byteswap was renamed
  byteswap32 to be more specific.
2022-01-03 17:44:13 -08:00
Justin C. Miller
cd9b85b555 [util] Replace kutil with util
Now that kutil has no kernel-specific code in it anymore, it can
actually be linked to by anything, so I'm renaming it 'util'.

Also, I've tried to unify the way that the system libraries from
src/libraries are #included using <> instead of "".

Other small change: util::bip_buffer got a spinlock to guard against
state corruption.
2022-01-03 00:03:29 -08:00
Justin C. Miller
5f88f5ed02 [kernel] Move kassert out of kutil
Continuing moving things out of kutil. The assert as implemented could
only ever work in the kernel, so remaining kutil uses of kassert have
been moved to including standard C assert instead.

Along the way, kassert was broken out into panic::panic and kassert,
and the panic.serial namespace was renamed panicking.
2022-01-02 01:38:04 -08:00
Justin C. Miller
a6ec294f63 [kernel] Move more from kutil to kernel
The moving of kernel-only code out of kutil continues. (See 042f061)
This commit moves the following:

- The heap allocator code
- memory.cpp/h which means:
  - letting string.h be the right header for memset and memcpy, still
    including an implementation of it for the kernel though, since
    we're not linking libc to the kernel
  - Changing calls to kalloc/kfree to new/delete in kutil containers
    that aren't going to be merged into the kernel
- Fixing a problem with stdalign.h from libc, which was causing issues
  for type_traits.
2022-01-01 23:23:51 -08:00
Justin C. Miller
4d5ed8157c [kutil] Remove unused kutil headers
Part two of rearranging kutil code. (See 042f061) Removing unused kutil
headers:

I can imagine that avl_tree or slab_allocated may want to be returned to
at some point, but for now they're just clutter.
2022-01-01 19:06:24 -08:00
Justin C. Miller
042f061d86 [kernel] Move the logger from kutil into kernel
Part one of a series of code moves. The kutil library is not very
useful, as most of its code is kernel-specific. This was originally for
testing purposes, but that can be achieved in other ways with the
current build system. I find this mostly creates a strange division in
the kernel code.

Instead, I'm going to move everything kernel-specific to actually be in
the kernel, and replace kutil with just 'util' for generic utility code
I want to share.

This commit:

- Moves the logger into the kernel.
- Updates the 'printf' library used from mpaland/printf to
  eyalroz/printf and moved it into the kernel, as it's only used by the
  logger in kutil.
- Removes some other unused kutil headers from some files, to help
  future code rearrangement.

Note that the (now redundant-seeming) log.cpp/h in kernel is currently
still there - these files are more about log output than the logging
system, and will get replaced once I add user-space log output.
2022-01-01 18:02:11 -08:00
Justin C. Miller
99de8454cd [kernel] Fix some page allocation bugs
Fixing two page allocation issues I came across while debugging:

- Added a spinlock to the page_table static page cache, to avoid
  multiple CPUs grabbing the same page. This cache should probably
  just be made into per-CPU caches.
- Fixed a bitwise math issue ("1" instead of "1ull" when working with
  64-bit numbers) that made it so that pages were never marked as
  allocated when allocating 32 or more.
2021-12-31 20:35:11 -08:00
Justin C. Miller
3c44bf55eb [kernel] Remove 'fb hack' include from scheduler
scheduler.cpp was still including kernel_args.h because of the old hack
of passing around the framebuffer. Get that shit outta here.
2021-12-30 20:34:39 -08:00