139 lines
3.1 KiB
C
139 lines
3.1 KiB
C
#include "multiboot2.h"
|
|
#include "intr.h"
|
|
#include "print.h"
|
|
#include "clib.h"
|
|
#include "cpu.h"
|
|
#include "thread.h"
|
|
#include "proc.h"
|
|
#include "pmm.h"
|
|
#include "syscall.h"
|
|
#include "error.h"
|
|
#include "vmm.h"
|
|
#include "elf64.h"
|
|
|
|
void kthread1(void *arg);
|
|
|
|
void kthread2(void *arg);
|
|
|
|
void kproc(void *arg);
|
|
|
|
void *_module;
|
|
|
|
void kmain(mbentry *mb)
|
|
{
|
|
char *ld_name = 0x0;
|
|
mod_tag *module = 0x0;
|
|
uint64 mem_low;
|
|
uint64 mem_high;
|
|
int32 status;
|
|
print_init();
|
|
|
|
parse_mb2(mb, (void **) &module, &ld_name, &mem_low, &mem_high);
|
|
|
|
kprintf("Bootloader: %s\n", ld_name);
|
|
kprintf("User executable loaded at 0x%x size %d.\n", (uint64) R_PADDR(module->mod_start), (uint64) (module->mod_end - module->mod_start));
|
|
|
|
kprintf("Initializing interrupt...\n");
|
|
status = intr_init();
|
|
kprintf("Initializing system call...\n");
|
|
syscall_init();
|
|
KASSERT(status == ESUCCESS);
|
|
|
|
_module = R_PADDR(module->mod_start);
|
|
|
|
kprintf("Initializing PMM...\n");
|
|
pmm_init(mem_low, mem_high);
|
|
kprintf("Initializing VMM...\n");
|
|
init_vm();
|
|
|
|
kprintf("Initializing threads...\n");
|
|
thread_init();
|
|
kprintf("Initializing processes...\n");
|
|
status = proc_init((void *) kproc);
|
|
KASSERT(status == ESUCCESS);
|
|
|
|
// unmask all interrupts
|
|
WRITE_IRQ(0x0);
|
|
|
|
send_ipi(INTR_VEC_TIMER);
|
|
KASSERT(FALSE);
|
|
}
|
|
|
|
#define THREAD_DELAY (5000000*4)
|
|
|
|
static uint32 kt1id;
|
|
static uint32 kt2id;
|
|
|
|
void kthread1(void *arg)
|
|
{
|
|
UNREFERENCED(arg);
|
|
uint64 i = 0;
|
|
while (i != 0xFFFFFFFFFF)
|
|
{
|
|
poor_sleep(THREAD_DELAY);
|
|
kprintf("[KThread1] %d\n", i);
|
|
|
|
if (i == 10)
|
|
{
|
|
kprintf("[KThread1] Blocking KThread 2... \n", i);
|
|
thread_block(kt2id);
|
|
}
|
|
|
|
if (i == 20)
|
|
{
|
|
kprintf("[KThread1] Resuming KThread 2... \n", i);
|
|
thread_resume(kt2id);
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void kthread2(void *arg)
|
|
{
|
|
UNREFERENCED(arg);
|
|
bool thread1exited = FALSE;
|
|
uint64 i = 0;
|
|
int32 ex;
|
|
while (i != 0xFFFFFFFFFF)
|
|
{
|
|
poor_sleep(THREAD_DELAY);
|
|
|
|
kprintf("[KThread2] %d\n", i);
|
|
|
|
if (i == 40)
|
|
{
|
|
kprintf("[KThread2] Stopping KThread1 with exit code 0xdeadbeef\n", i);
|
|
thread_stop(kt1id, 0xDEADBEEF);
|
|
}
|
|
|
|
if (!thread1exited && thread_get_exit_code(kt1id, &ex) == ESUCCESS)
|
|
{
|
|
kprintf("[KThread2] KThread1 exited with 0x%x\n", (uint64) ex);
|
|
thread1exited = TRUE;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void kproc(void *arg)
|
|
{
|
|
// the idle thread
|
|
UNREFERENCED(arg);
|
|
int32 status;
|
|
status = thread_create(get_cur_thread()->proc, (void *) kthread1, NULL, &kt1id);
|
|
kprintf("[KIdle] Created KThread1... 0x%x\n", (uint64) status);
|
|
status = thread_create(get_cur_thread()->proc, (void *) kthread2, NULL, &kt2id);
|
|
kprintf("[KIdle] Created KThread2... 0x%x\n", (uint64) status);
|
|
uint32 id;
|
|
status = proc_create(_module, &id);
|
|
kprintf("[KIdle] Created process from module... 0x%x\n", (uint64) status);
|
|
while (1)
|
|
{
|
|
#ifdef KDBG
|
|
kprintf("[KIdle] Yielding...\n");
|
|
#endif
|
|
thread_yield();
|
|
}
|
|
}
|