[project] Generate syscalls from new interface DSL

This change adds a new interface DSL for specifying objects (with
methods) and interfaces (that expose objects, and optionally have their
own methods).

Significant changes:

- Add the new scripts/definitions Python module to parse the DSL
- Add the new definitions directory containing DSL definition files
- Use cog to generate syscall-related code in kernel and libj6
- Unify ordering of pointer + length pairs in interfaces
This commit is contained in:
Justin C. Miller
2021-08-30 01:05:32 -07:00
parent 80f815c020
commit 186724e751
52 changed files with 4025 additions and 206 deletions

View File

@@ -14,7 +14,6 @@ kernel = module("kernel",
"clock.cpp",
"console.cpp",
"cpprt.cpp",
"cpu.cpp",
"debug.cpp",
"debug.s",
"device_manager.cpp",
@@ -27,7 +26,6 @@ kernel = module("kernel",
"interrupts.s",
"io.cpp",
"log.cpp",
"main.cpp",
"memory_bootstrap.cpp",
"msr.cpp",
"objects/channel.cpp",
@@ -42,8 +40,6 @@ kernel = module("kernel",
"pci.cpp",
"scheduler.cpp",
"serial.cpp",
"syscall.cpp",
"syscall.s",
"syscalls/channel.cpp",
"syscalls/endpoint.cpp",
"syscalls/object.cpp",
@@ -56,4 +52,15 @@ kernel = module("kernel",
"vm_space.cpp",
])
from glob import glob
definitions = glob('definitions/**/*.def', recursive=True)
sysinc = kernel.add_input("syscalls.inc.cog", deps=definitions)
kernel.add_input("syscall.s", deps=[sysinc])
sysh = kernel.add_input("syscall.h.cog", deps=definitions)
sysc = kernel.add_input("syscall.cpp.cog", deps=definitions + [sysh])
kernel.add_input("main.cpp", deps=[sysh])
kernel.add_input("cpu.cpp", deps=[sysh])
kernel.variables['ldflags'] = ["${ldflags}", "-T", "${source_root}/src/kernel/kernel.ld"]

View File

@@ -28,10 +28,10 @@ endpoint::close()
}
j6_status_t
endpoint::send(j6_tag_t tag, size_t len, void *data)
endpoint::send(j6_tag_t tag, const void *data, size_t data_len)
{
thread_data sender = { &thread::current(), data };
sender.len = len;
sender.len = data_len;
sender.tag = tag;
if (!check_signal(j6_signal_endpoint_can_send)) {
@@ -55,11 +55,11 @@ endpoint::send(j6_tag_t tag, size_t len, void *data)
}
j6_status_t
endpoint::receive(j6_tag_t *tag, size_t *len, void *data)
endpoint::receive(j6_tag_t *tag, void *data, size_t *data_len)
{
thread_data receiver = { &thread::current(), data };
receiver.tag_p = tag;
receiver.len_p = len;
receiver.len_p = data_len;
if (!check_signal(j6_signal_endpoint_can_recv)) {
assert_signal(j6_signal_endpoint_can_send);
@@ -120,7 +120,7 @@ endpoint::do_message_copy(const endpoint::thread_data &sender, endpoint::thread_
if (sender.len) {
vm_space &source = sender.th->parent().space();
vm_space &dest = receiver.th->parent().space();
vm_space::copy(source, dest, sender.data, receiver.data, sender.len);
vm_space::copy(source, dest, sender.data, receiver.buffer, sender.len);
}
*receiver.len_p = sender.len;

View File

@@ -27,10 +27,10 @@ public:
/// Send a message to a thread waiting to receive on this endpoint. If no threads
/// are currently trying to receive, block the current thread.
/// \arg tag The application-specified message tag
/// \arg len The size in bytes of the message
/// \arg data The message data
/// \arg len The size in bytes of the message
/// \returns j6_status_ok on success
j6_status_t send(j6_tag_t tag, size_t len, void *data);
j6_status_t send(j6_tag_t tag, const void *data, size_t data_len);
/// Receive a message from a thread waiting to send on this endpoint. If no threads
/// are currently trying to send, block the current thread.
@@ -38,7 +38,7 @@ public:
/// \arg len [in] The size in bytes of the buffer [out] Number of bytes in the message
/// \arg data Buffer for copying message data into
/// \returns j6_status_ok on success
j6_status_t receive(j6_tag_t *tag, size_t *len, void *data);
j6_status_t receive(j6_tag_t *tag, void *data, size_t *data_len);
/// Give the listener on the endpoint a message that a bound IRQ has been signalled
/// \arg irq The IRQ that caused this signal
@@ -48,7 +48,10 @@ private:
struct thread_data
{
thread *th;
void *data;
union {
const void *data;
void *buffer;
};
union {
j6_tag_t *tag_p;
j6_tag_t tag;

View File

@@ -1,52 +0,0 @@
#include <stddef.h>
#include "kutil/memory.h"
#include "console.h"
#include "debug.h"
#include "log.h"
#include "syscall.h"
extern "C" {
void syscall_invalid(uint64_t call);
}
uintptr_t syscall_registry[256] __attribute__((section(".syscall_registry")));
const char * syscall_names[256] __attribute__((section(".syscall_registry")));
static constexpr size_t num_syscalls = sizeof(syscall_registry) / sizeof(syscall_registry[0]);
void
syscall_invalid(uint64_t call)
{
console *cons = console::get();
cons->set_color(9);
cons->printf("\nReceived unknown syscall: %02x\n", call);
cons->printf(" Known syscalls:\n");
cons->printf(" invalid %016lx\n", syscall_invalid);
for (unsigned i = 0; i < num_syscalls; ++i) {
const char *name = syscall_names[i];
uintptr_t handler = syscall_registry[i];
if (name)
cons->printf(" %02x %10s %016lx\n", i, name, handler);
}
cons->set_color();
_halt();
}
void
syscall_initialize()
{
kutil::memset(&syscall_registry, 0, sizeof(syscall_registry));
kutil::memset(&syscall_names, 0, sizeof(syscall_names));
#define SYSCALL(id, name, result, ...) \
syscall_registry[id] = reinterpret_cast<uintptr_t>(syscalls::name); \
syscall_names[id] = #name; \
log::debug(logs::syscall, "Enabling syscall 0x%02x as " #name , id);
#include "j6/tables/syscalls.inc"
#undef SYSCALL
}

View File

@@ -0,0 +1,56 @@
// vim: ft=cpp
#include <stddef.h>
#include "kutil/memory.h"
#include "console.h"
#include "debug.h"
#include "log.h"
#include "syscall.h"
extern "C" {
void syscall_invalid(uint64_t call);
}
/*[[[cog code generation
from definitions.context import Context
ctx = Context(definitions_path)
ctx.parse("syscalls.def")
syscalls = ctx.interfaces['syscalls']
cog.outl(f"constexpr size_t num_syscalls = {len(syscalls.methods)};")
]]]*/
/// [[[end]]]
uintptr_t syscall_registry[num_syscalls] __attribute__((section(".syscall_registry")));
void
syscall_invalid(uint64_t call)
{
console *cons = console::get();
cons->set_color(9);
cons->printf("\nReceived unknown syscall: %02x\n", call);
cons->set_color();
_halt();
}
void
syscall_initialize()
{
kutil::memset(&syscall_registry, 0, sizeof(syscall_registry));
/*[[[cog code generation
for id, scope, method in syscalls.methods:
if scope:
name = f"{scope.name}_{method.name}"
else:
name = method.name
cog.outl(f"syscall_registry[{id}] = reinterpret_cast<uintptr_t>(syscalls::{name});")
cog.outl(f"""log::debug(logs::syscall, "Enabling syscall {id:x} as {name}");""")
cog.outl("")
]]]*/
//[[[end]]]
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include <stdint.h>
#include "j6/types.h"
struct cpu_state;
enum class syscall : uint64_t
{
#define SYSCALL(id, name, ...) name = id,
#include "j6/tables/syscalls.inc"
#undef SYSCALL
};
void syscall_initialize();
extern "C" void syscall_enable();
namespace syscalls
{
#define SYSCALL(id, name, ...) j6_status_t name (__VA_ARGS__);
#include "j6/tables/syscalls.inc"
#undef SYSCALL
}

60
src/kernel/syscall.h.cog Normal file
View File

@@ -0,0 +1,60 @@
#pragma once
// vim: ft=cpp
#include <stdint.h>
#include "j6/types.h"
struct cpu_state;
/*[[[cog code generation
from definitions.context import Context
ctx = Context(definitions_path)
ctx.parse("syscalls.def")
syscalls = ctx.interfaces["syscalls"]
]]]*/
/// [[[end]]]
enum class syscall : uint64_t
{
/*[[[cog code generation
for id, scope, method in syscalls.methods:
if scope:
name = f"{scope.name}_{method.name}"
else:
name = method.name
cog.outl(f"{name:20} = {id},")
]]]*/
//[[[end]]]
};
void syscall_initialize();
extern "C" void syscall_enable();
namespace syscalls
{
/*[[[cog code generation
for id, scope, method in syscalls.methods:
if scope:
name = f"{scope.name}_{method.name}"
else:
name = method.name
args = []
if method.constructor:
args.append("j6_handle_t *handle")
elif not method.static:
args.append("j6_handle_t handle")
for param in method.params:
for type, suffix in param.type.c_names(param.options):
args.append(f"{type} {param.name}{suffix}")
cog.outl(f"""j6_status_t {name} ({", ".join(args)});""")
]]]*/
//[[[end]]]
}

View File

@@ -1,4 +1,5 @@
%include "tasking.inc"
%include "syscalls.inc"
; SYSCALL/SYSRET control MSRs
MSR_STAR equ 0xc0000081
@@ -51,7 +52,9 @@ syscall_handler_prelude:
inc qword [rel __counter_syscall_enter]
and rax, 0xff ; Only 256 possible syscall values
cmp rax, NUM_SYSCALLS
jge .bad_syscall
lea r11, [rel syscall_registry]
mov r11, [r11 + rax * 8]
cmp r11, 0

View File

@@ -0,0 +1,11 @@
; vim: ft=asm
; [[[cog code generation
; from definitions.context import Context
;
; ctx = Context(definitions_path)
; ctx.parse("syscalls.def")
; syscalls = ctx.interfaces['syscalls']
; cog.outl(f"NUM_SYSCALLS equ {len(syscalls.methods)}")
; ]]]
; [[[end]]]

View File

@@ -15,7 +15,7 @@ endpoint_create(j6_handle_t *handle)
}
j6_status_t
endpoint_send(j6_handle_t handle, j6_tag_t tag, size_t len, void *data)
endpoint_send(j6_handle_t handle, uint64_t tag, const void * data, size_t data_len)
{
if (tag & j6_tag_system_flag)
return j6_err_invalid_arg;
@@ -23,28 +23,28 @@ endpoint_send(j6_handle_t handle, j6_tag_t tag, size_t len, void *data)
endpoint *e = get_handle<endpoint>(handle);
if (!e) return j6_err_invalid_arg;
return e->send(tag, len, data);
return e->send(tag, data, data_len);
}
j6_status_t
endpoint_receive(j6_handle_t handle, j6_tag_t *tag, size_t *len, void *data)
endpoint_receive(j6_handle_t handle, uint64_t * tag, void * data, size_t * data_len)
{
if (!tag || !len || (*len && !data))
if (!tag || !data_len || !data)
return j6_err_invalid_arg;
endpoint *e = get_handle<endpoint>(handle);
if (!e) return j6_err_invalid_arg;
j6_tag_t out_tag = j6_tag_invalid;
size_t out_len = *len;
j6_status_t s = e->receive(&out_tag, &out_len, data);
size_t out_len = *data_len;
j6_status_t s = e->receive(&out_tag, data, &out_len);
*tag = out_tag;
*len = out_len;
*data_len = out_len;
return s;
}
j6_status_t
endpoint_sendrecv(j6_handle_t handle, j6_tag_t *tag, size_t *len, void *data)
endpoint_sendrecv(j6_handle_t handle, uint64_t * tag, void * data, size_t * data_len)
{
if (!tag || (*tag & j6_tag_system_flag))
return j6_err_invalid_arg;
@@ -52,15 +52,15 @@ endpoint_sendrecv(j6_handle_t handle, j6_tag_t *tag, size_t *len, void *data)
endpoint *e = get_handle<endpoint>(handle);
if (!e) return j6_err_invalid_arg;
j6_status_t status = e->send(*tag, *len, data);
j6_status_t status = e->send(*tag, data, *data_len);
if (status != j6_status_ok)
return status;
j6_tag_t out_tag = j6_tag_invalid;
size_t out_len = *len;
j6_status_t s = e->receive(&out_tag, &out_len, data);
size_t out_len = *data_len;
j6_status_t s = e->receive(&out_tag, data, &out_len);
*tag = out_tag;
*len = out_len;
*data_len = out_len;
return s;
}

View File

@@ -9,7 +9,7 @@
namespace syscalls {
j6_status_t
object_koid(j6_handle_t handle, j6_koid_t *koid)
kobject_koid(j6_handle_t handle, j6_koid_t *koid)
{
if (koid == nullptr)
return j6_err_invalid_arg;
@@ -23,7 +23,7 @@ object_koid(j6_handle_t handle, j6_koid_t *koid)
}
j6_status_t
object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs)
kobject_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs)
{
kobject *obj = get_handle<kobject>(handle);
if (!obj)
@@ -47,11 +47,11 @@ object_wait(j6_handle_t handle, j6_signal_t mask, j6_signal_t *sigs)
}
j6_status_t
object_wait_many(j6_handle_t *handles, uint32_t count, j6_signal_t mask, j6_handle_t *handle, j6_signal_t *sigs)
kobject_wait_many(j6_handle_t * handles, size_t handles_count, uint64_t mask, j6_handle_t * handle, uint64_t * signals)
{
kutil::vector<kobject*> objects {count};
kutil::vector<kobject*> objects {uint32_t(handles_count)};
for (unsigned i = 0; i < count; ++i) {
for (unsigned i = 0; i < handles_count; ++i) {
j6_handle_t h = handles[i];
if (h == j6_handle_invalid)
continue;
@@ -62,7 +62,7 @@ object_wait_many(j6_handle_t *handles, uint32_t count, j6_signal_t mask, j6_hand
j6_signal_t current = obj->signals();
if ((current & mask) != 0) {
*sigs = current;
*signals = current;
*handle = h;
return j6_status_ok;
}
@@ -81,9 +81,9 @@ object_wait_many(j6_handle_t *handles, uint32_t count, j6_signal_t mask, j6_hand
return result;
*handle = j6_handle_invalid;
*sigs = th.get_wait_data();
*signals = th.get_wait_data();
j6_koid_t koid = th.get_wait_object();
for (unsigned i = 0; i < count; ++i) {
for (unsigned i = 0; i < handles_count; ++i) {
if (koid == objects[i]->koid())
*handle = handles[i];
else
@@ -96,7 +96,7 @@ object_wait_many(j6_handle_t *handles, uint32_t count, j6_signal_t mask, j6_hand
}
j6_status_t
object_signal(j6_handle_t handle, j6_signal_t signals)
kobject_signal(j6_handle_t handle, j6_signal_t signals)
{
if ((signals & j6_signal_user_mask) != signals)
return j6_err_invalid_arg;
@@ -110,7 +110,7 @@ object_signal(j6_handle_t handle, j6_signal_t signals)
}
j6_status_t
object_close(j6_handle_t handle)
kobject_close(j6_handle_t handle)
{
kobject *obj = get_handle<kobject>(handle);
if (!obj)

View File

@@ -16,14 +16,14 @@ process_create(j6_handle_t *handle)
}
j6_status_t
process_start(j6_handle_t handle, uintptr_t entrypoint, j6_handle_t *handles, size_t handle_count)
process_start(j6_handle_t handle, uintptr_t entrypoint, j6_handle_t * handles, size_t handles_count)
{
process &p = process::current();
process *c = get_handle<process>(handle);
if (handle_count && !handles)
if (handles_count && !handles)
return j6_err_invalid_arg;
for (size_t i = 0; i < handle_count; ++i) {
for (size_t i = 0; i < handles_count; ++i) {
kobject *o = p.lookup_handle(handles[i]);
if (o) c->add_handle(o);
}

View File

@@ -15,7 +15,7 @@ extern log::logger &g_logger;
namespace syscalls {
j6_status_t
system_log(const char *message)
log(const char *message)
{
if (message == nullptr)
return j6_err_invalid_arg;
@@ -26,7 +26,7 @@ system_log(const char *message)
}
j6_status_t
system_noop()
noop()
{
thread &th = thread::current();
log::debug(logs::syscall, "Thread %llx called noop syscall.", th.koid());
@@ -61,18 +61,18 @@ system_bind_irq(j6_handle_t sys, j6_handle_t endp, unsigned irq)
}
j6_status_t
system_map_phys(j6_handle_t sys, j6_handle_t *vma_handle, uintptr_t phys_addr, size_t size, uint32_t flags)
system_map_phys(j6_handle_t handle, j6_handle_t * area, uintptr_t phys, size_t size, uint32_t flags)
{
// TODO: check capabilities on sys handle
if (!vma_handle) return j6_err_invalid_arg;
if (!area) return j6_err_invalid_arg;
// TODO: check to see if frames are already used? How would that collide with
// the bootloader's allocated pages already being marked used?
if (!(flags & vm_flags::mmio))
frame_allocator::get().used(phys_addr, memory::page_count(size));
frame_allocator::get().used(phys, memory::page_count(size));
vm_flags vmf = (static_cast<vm_flags>(flags) & vm_flags::driver_mask);
construct_handle<vm_area_fixed>(vma_handle, phys_addr, size, vmf);
construct_handle<vm_area_fixed>(area, phys, size, vmf);
return j6_status_ok;
}

View File

@@ -4,17 +4,18 @@
#include "log.h"
#include "objects/process.h"
#include "objects/thread.h"
#include "syscalls/helpers.h"
namespace syscalls {
j6_status_t
thread_create(void *rip, j6_handle_t *handle)
thread_create(j6_handle_t *handle, uintptr_t entrypoint)
{
thread &parent = thread::current();
process &p = parent.parent();
thread *child = p.create_thread();
child->add_thunk_user(reinterpret_cast<uintptr_t>(rip));
child->add_thunk_user(entrypoint);
*handle = child->self_handle();
child->clear_state(thread::state::loading);
child->set_state(thread::state::ready);
@@ -36,6 +37,18 @@ thread_exit(int32_t status)
return j6_err_unexpected;
}
j6_status_t
thread_kill(j6_handle_t handle)
{
thread *th = get_handle<thread>(handle);
if (!th)
return j6_err_invalid_arg;
log::debug(logs::task, "Killing thread %llx", th->koid());
th->exit(-1);
return j6_status_ok;
}
j6_status_t
thread_pause()
{

View File

@@ -286,7 +286,7 @@ vm_space::handle_fault(uintptr_t addr, fault_type fault)
}
size_t
vm_space::copy(vm_space &source, vm_space &dest, void *from, void *to, size_t length)
vm_space::copy(vm_space &source, vm_space &dest, const void *from, void *to, size_t length)
{
uintptr_t ifrom = reinterpret_cast<uintptr_t>(from);
uintptr_t ito = reinterpret_cast<uintptr_t>(to);

View File

@@ -103,7 +103,7 @@ public:
/// \arg to Pointer to the destination in the dest address space
/// \arg length Amount of data to copy, in bytes
/// \returnd The number of bytes copied
static size_t copy(vm_space &source, vm_space &dest, void *from, void *to, size_t length);
static size_t copy(vm_space &source, vm_space &dest, const void *from, void *to, size_t length);
private:
friend class vm_area;

View File

@@ -1,15 +0,0 @@
#pragma once
#include <j6/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SYSCALL(n, name, ...) j6_status_t j6_ ## name (__VA_ARGS__);
#include "j6/tables/syscalls.inc"
#undef SYSCALL
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,39 @@
#pragma once
// vim: ft=cpp
#include <j6/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/*[[[cog code generation
from definitions.context import Context
ctx = Context(definitions_path)
ctx.parse("syscalls.def")
syscalls = ctx.interfaces["syscalls"]
for id, scope, method in syscalls.methods:
if scope:
name = f"{scope.name}_{method.name}"
else:
name = method.name
args = []
if method.constructor:
args.append("j6_handle_t *handle")
elif not method.static:
args.append("j6_handle_t handle")
for param in method.params:
for type, suffix in param.type.c_names(param.options):
args.append(f"{type} {param.name}{suffix}")
cog.outl(f"""j6_status_t j6_{name} ({", ".join(args)});""")
]]]*/
/// [[[end]]]
#ifdef __cplusplus
}
#endif

View File

@@ -1,9 +1,14 @@
# vim: ft=python
module("j6",
j6 = module("j6",
kind = "lib",
includes = [ "include" ],
sources = [
"init.cpp",
"syscalls.s",
])
from glob import glob
definitions = glob('definitions/**/*.def', recursive=True)
j6.add_input("include/j6/syscalls.h.cog", deps=definitions)
j6.add_input("syscalls.s.cog", deps=definitions)

View File

@@ -1,28 +0,0 @@
%macro SYSCALL 2
global j6_%1
j6_%1:
push rbp
mov rbp, rsp
; args should already be in rdi, etc, but rcx will
; get stomped, so stash it in r10, which isn't a
; callee-saved register, but also isn't used in the
; function call ABI.
mov r10, rcx
mov rax, %2
syscall
; result is now already in rax, so just return
pop rbp
ret
%endmacro
%define SYSCALL(n, name) SYSCALL name, n
%define SYSCALL(n, name, a) SYSCALL name, n
%define SYSCALL(n, name, a, b) SYSCALL name, n
%define SYSCALL(n, name, a, b, c) SYSCALL name, n
%define SYSCALL(n, name, a, b, c, d) SYSCALL name, n
%define SYSCALL(n, name, a, b, c, d, e) SYSCALL name, n
%include "j6/tables/syscalls.inc"

View File

@@ -0,0 +1,37 @@
; vim: ft=asm
%macro define_syscall 2
global j6_%1
j6_%1:
push rbp
mov rbp, rsp
; args should already be in rdi, etc, but rcx will
; get stomped, so stash it in r10, which isn't a
; callee-saved register, but also isn't used in the
; function call ABI.
mov r10, rcx
mov rax, %2
syscall
; result is now already in rax, so just return
pop rbp
ret
%endmacro
; [[[cog code generation
; from definitions.context import Context
;
; ctx = Context(definitions_path)
; ctx.parse("syscalls.def")
; syscalls = ctx.interfaces['syscalls']
;
; for id, scope, method in syscalls.methods:
; if scope:
; name = f"{scope.name}_{method.name}"
; else:
; name = method.name
; cog.outl(f"define_syscall {name:20}, {id}")
; ]]]
; [[[end]]]

View File

@@ -33,7 +33,7 @@ struct entry
int
main(int argc, const char **argv)
{
j6_system_log("fb driver starting");
j6_log("fb driver starting");
size_t initc = 0;
j6_init_value *initv = nullptr;
@@ -48,7 +48,7 @@ main(int argc, const char **argv)
}
if (!fb || fb->addr == 0) {
j6_system_log("fb driver didn't find a framebuffer, exiting");
j6_log("fb driver didn't find a framebuffer, exiting");
return 1;
}
@@ -109,7 +109,7 @@ main(int argc, const char **argv)
buffer_size = size;
continue;
} else if (s != j6_status_ok) {
j6_system_log("fb driver got error from get_log, quitting");
j6_log("fb driver got error from get_log, quitting");
return s;
}
@@ -134,7 +134,7 @@ main(int argc, const char **argv)
}
}
j6_system_log("fb driver done, exiting");
j6_log("fb driver done, exiting");
return 0;
}

View File

@@ -20,7 +20,7 @@ j6_handle_t handle_system = 2; // boot protocol is that init gets the system as
int
main(int argc, const char **argv)
{
j6_system_log("srv.init starting");
j6_log("srv.init starting");
modules mods = modules::load_modules(_arg_modules_phys, handle_system, handle_self);
@@ -28,7 +28,7 @@ main(int argc, const char **argv)
for (auto &mod : mods.of_type(module_type::program)) {
auto &prog = static_cast<const module_program&>(mod);
sprintf(message, " program module '%s' at %lx", prog.filename, prog.base_address);
j6_system_log(message);
j6_log(message);
}
return 0;

View File

@@ -70,7 +70,7 @@ modules::load_modules(uintptr_t address, j6_handle_t system, j6_handle_t self)
char message[100];
sprintf(message, "srv.init found %d modules from page at 0x%lx", page->count, address);
j6_system_log(message);
j6_log(message);
if (!first)
first = page->modules;

View File

@@ -20,32 +20,32 @@ extern "C" {
void
thread_proc()
{
j6_system_log("sub thread starting");
j6_log("sub thread starting");
char buffer[512];
size_t len = sizeof(buffer);
j6_tag_t tag = 0;
j6_status_t result = j6_endpoint_receive(endp, &tag, &len, (void*)buffer);
j6_status_t result = j6_endpoint_receive(endp, &tag, (void*)buffer, &len);
if (result != j6_status_ok)
j6_thread_exit(result);
j6_system_log("sub thread received message");
j6_log("sub thread received message");
for (int i = 0; i < len; ++i)
if (buffer[i] >= 'A' && buffer[i] <= 'Z')
buffer[i] += 0x20;
tag++;
result = j6_endpoint_send(endp, tag, len, (void*)buffer);
result = j6_endpoint_send(endp, tag, (void*)buffer, len);
if (result != j6_status_ok)
j6_thread_exit(result);
j6_system_log("sub thread sent message");
j6_log("sub thread sent message");
for (int i = 1; i < 5; ++i)
j6_thread_sleep(i*10);
j6_system_log("sub thread exiting");
j6_log("sub thread exiting");
j6_thread_exit(0);
}
@@ -55,10 +55,10 @@ main(int argc, const char **argv)
j6_handle_t children[2] = {j6_handle_invalid, j6_handle_invalid};
j6_signal_t out = 0;
j6_system_log("main thread starting");
j6_log("main thread starting");
for (int i = 0; i < argc; ++i)
j6_system_log(argv[i]);
j6_log(argv[i]);
void *base = malloc(0x1000);
if (!base)
@@ -68,57 +68,57 @@ main(int argc, const char **argv)
for (int i = 0; i < 3; ++i)
vma_ptr[i*100] = uint64_t(i);
j6_system_log("main thread wrote to memory area");
j6_log("main thread wrote to memory area");
j6_status_t result = j6_endpoint_create(&endp);
if (result != j6_status_ok)
return result;
j6_system_log("main thread created endpoint");
j6_log("main thread created endpoint");
result = j6_thread_create(reinterpret_cast<void*>(&thread_proc), &children[1]);
result = j6_thread_create(&children[1], reinterpret_cast<uintptr_t>(&thread_proc));
if (result != j6_status_ok)
return result;
j6_system_log("main thread created sub thread");
j6_log("main thread created sub thread");
char message[] = "MAIN THREAD SUCCESSFULLY CALLED SENDRECV IF THIS IS LOWERCASE";
size_t size = sizeof(message);
j6_tag_t tag = 16;
result = j6_endpoint_sendrecv(endp, &tag, &size, (void*)message);
result = j6_endpoint_sendrecv(endp, &tag, (void*)message, &size);
if (result != j6_status_ok)
return result;
if (tag != 17)
j6_system_log("GOT WRONG TAG FROM SENDRECV");
j6_log("GOT WRONG TAG FROM SENDRECV");
result = j6_system_bind_irq(__handle_sys, endp, 3);
if (result != j6_status_ok)
return result;
j6_system_log(message);
j6_log(message);
j6_system_log("main thread creating a new process");
j6_log("main thread creating a new process");
result = j6_process_create(&children[0]);
if (result != j6_status_ok)
return result;
j6_system_log("main thread waiting on children");
j6_log("main thread waiting on children");
j6_handle_t outhandle;
result = j6_object_wait_many(children, 2, -1ull, &outhandle, &out);
result = j6_kobject_wait_many(children, 2, -1ull, &outhandle, &out);
if (result != j6_status_ok)
return result;
if (outhandle == children[1]) {
j6_system_log(" ok from child thread");
j6_log(" ok from child thread");
} else if (outhandle == children[0]) {
j6_system_log(" ok from child process");
j6_log(" ok from child process");
} else {
j6_system_log(" ... got unknown handle");
j6_log(" ... got unknown handle");
}
j6_system_log("main testing irqs");
j6_log("main testing irqs");
serial_port com2(COM2);
@@ -137,16 +137,10 @@ main(int argc, const char **argv)
return result;
if (j6_tag_is_irq(tag))
j6_system_log("main thread got irq!");
j6_log("main thread got irq!");
}
j6_system_log("main thread closing endpoint");
result = j6_object_close(endp);
if (result != j6_status_ok)
return result;
j6_system_log("main thread done, exiting");
j6_log("main thread done, exiting");
return 0;
}