kernel: rework init

This commit is contained in:
Matheus
2025-08-14 20:25:43 -03:00
parent fb6cbe49d7
commit 607566531d
41 changed files with 268 additions and 164 deletions
+6 -1
View File
@@ -8,6 +8,7 @@
#include <arch/msr.h> #include <arch/msr.h>
#include <kernel/timer.h> #include <kernel/timer.h>
#include <kernel/timekeeper.h> #include <kernel/timekeeper.h>
#include <kernel/init.h>
#include <uacpi/tables.h> #include <uacpi/tables.h>
#include <uacpi/acpi.h> #include <uacpi/acpi.h>
@@ -240,6 +241,8 @@ void arch_apic_timerinit() {
__assert(current_cpu()->timer); __assert(current_cpu()->timer);
} }
INIT_ROUTINE_DEFINE(arch_timer, INIT_ROUTINE_FLAGS_NONE, arch_apic_timerinit, timekeeper_early);
void arch_apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uint8_t level) { void arch_apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uint8_t level) {
writelapic(APIC_REG_ICR_HI, (uint32_t)cpu << 24); writelapic(APIC_REG_ICR_HI, (uint32_t)cpu << 24);
writelapic(APIC_REG_ICR_LO, vec | (level << 8) | (mode << 11) | (dest << 18) | (1 << 14)); writelapic(APIC_REG_ICR_LO, vec | (level << 8) | (mode << 11) | (dest << 18) | (1 << 14));
@@ -263,7 +266,7 @@ void arch_apic_init() {
// map LAPIC to virtual memory // map LAPIC to virtual memory
void *paddr = (void *) rdmsr(MSR_IA32APICBASE); void *paddr = (void *) rdmsr(MSR_IA32APICBASE);
lapic_address = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr); lapic_address = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr);
__assert(lapic_address); __assert(lapic_address);
@@ -289,3 +292,5 @@ void arch_apic_init() {
// FIXME limine does this already but just in case the PIC should be masked // FIXME limine does this already but just in case the PIC should be masked
} }
INIT_ROUTINE_DEFINE(arch_irq, INIT_ROUTINE_FLAGS_NONE, arch_apic_init, acpi_early);
+22 -3
View File
@@ -4,6 +4,10 @@
#include <logging.h> #include <logging.h>
#include <arch/cpuid.h> #include <arch/cpuid.h>
#include <kernel/topology.h> #include <kernel/topology.h>
#include <kernel/init.h>
#include <arch/idt.h>
#include <arch/gdt.h>
#include <kernel/dpc.h>
#define EFER_SYSCALLENABLE 1 #define EFER_SYSCALLENABLE 1
@@ -145,9 +149,7 @@ static void get_topology(long *topology_ids, long *topology_types) {
} }
} }
void cpu_initstate() { void arch_cpu_init() {
arch_apic_initap();
// syscall instruction // syscall instruction
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
__get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx); __get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
@@ -224,3 +226,20 @@ void cpu_initstate() {
topology_insert(topology_nodes[i], i == 0 ? topology_get_root() : topology_nodes[i - 1], TOPOLOGY_MAKE_ID(topology_types[i], topology_ids[i]), current_cpu()); topology_insert(topology_nodes[i], i == 0 ? topology_get_root() : topology_nodes[i - 1], TOPOLOGY_MAKE_ID(topology_types[i], topology_ids[i]), current_cpu());
} }
} }
INIT_ROUTINE_DEFINE(cpu, INIT_ROUTINE_FLAGS_NONE, arch_cpu_init, acpi_early);
static void infinite_loop(void) {
asm volatile("cli");
for (;;) asm volatile("");
}
static void arch_early(void) {
arch_gdt_reload();
arch_idt_setup();
arch_idt_reload();
interrupt_register(0xfd, (void *)infinite_loop, NULL, IPL_IGNORE);
dpc_init();
}
INIT_ROUTINE_DEFINE(arch_early, INIT_ROUTINE_FLAGS_NONE, arch_early)
+9 -3
View File
@@ -2,6 +2,7 @@
#include <kernel/devfs.h> #include <kernel/devfs.h>
#include <logging.h> #include <logging.h>
#include <kernel/usercopy.h> #include <kernel/usercopy.h>
#include <kernel/init.h>
void arch_e9_putc(char c) { void arch_e9_putc(char c) {
#ifdef X86_64_ENABLE_E9 #ifdef X86_64_ENABLE_E9
@@ -9,6 +10,11 @@ void arch_e9_putc(char c) {
#endif #endif
} }
void arch_early_log(char c) {
arch_e9_putc(c);
}
void arch_e9_puts(char *c) { void arch_e9_puts(char *c) {
#ifdef X86_64_ENABLE_E9 #ifdef X86_64_ENABLE_E9
while (*c) { while (*c) {
@@ -35,10 +41,10 @@ static int devwrite(int minor, iovec_iterator_t *iovec_iterator, size_t count, u
static devops_t devops = { static devops_t devops = {
.write = devwrite .write = devwrite
}; };
#endif
void arch_e9_initdev() { void arch_e9_initdev() {
#ifdef X86_64_ENABLE_E9
__assert(devfs_register(&devops, "e9", V_TYPE_CHDEV, DEV_MAJOR_E9, 0, 0666, NULL) == 0); __assert(devfs_register(&devops, "e9", V_TYPE_CHDEV, DEV_MAJOR_E9, 0, 0666, NULL) == 0);
#endif
} }
INIT_ROUTINE_DEFINE(e9, INIT_ROUTINE_FLAGS_NONE, arch_e9_initdev, devfs);
#endif
+7
View File
@@ -32,6 +32,13 @@ SECTIONS
*(.timekeeper_sources); *(.timekeeper_sources);
timekeeper_sources_end = .; timekeeper_sources_end = .;
} :rodata } :rodata
. = ALIGN(8);
.init_routines : {
init_routines = .;
*(.init_routines);
init_routines_end = .;
} :rodata
. = ALIGN(4K); . = ALIGN(4K);
_rodata_end = .; _rodata_end = .;
-138
View File
@@ -1,138 +0,0 @@
#include <arch/e9.h>
#include <logging.h>
#include <arch/cpu.h>
#include <arch/gdt.h>
#include <arch/idt.h>
#include <kernel/acpi.h>
#include <kernel/term.h>
#include <kernel/pmm.h>
#include <arch/mmu.h>
#include <kernel/vmm.h>
#include <kernel/slab.h>
#include <kernel/alloc.h>
#include <arch/apic.h>
#include <arch/hpet.h>
#include <kernel/timekeeper.h>
#include <kernel/scheduler.h>
#include <kernel/vfs.h>
#include <kernel/tmpfs.h>
#include <kernel/initrd.h>
#include <kernel/devfs.h>
#include <kernel/pseudodevices.h>
#include <arch/ps2.h>
#include <kernel/keyboard.h>
#include <kernel/console.h>
#include <kernel/dpc.h>
#include <kernel/pipefs.h>
#include <kernel/fb.h>
#include <kernel/pci.h>
#include <kernel/nvme.h>
#include <kernel/block.h>
#include <kernel/ext2.h>
#include <kernel/cmdline.h>
#include <arch/smp.h>
#include <kernel/virtio.h>
#include <kernel/net.h>
#include <kernel/sock.h>
#include <kernel/mouse.h>
#include <kernel/tty.h>
#include <kernel/pty.h>
#include <kernel/vmmcache.h>
#include <kernel/defaultauth.h>
static cpu_t bsp_cpu;
void kernel_entry() {
cpu_set(&bsp_cpu);
logging_sethook(arch_e9_putc);
arch_gdt_reload();
arch_idt_setup();
arch_idt_reload();
dpc_init();
pmm_init();
term_init();
logging_sethook(term_putchar);
arch_mmu_init();
vmm_init();
alloc_init();
cmdline_parse();
acpi_early_init();
arch_apic_init();
timekeeper_early_init(0);
cpu_initstate();
arch_apic_timerinit();
sched_init();
timekeeper_init();
arch_smp_wakeup();
timekeeper_sync();
pci_init();
acpi_init();
vmmcache_init();
vfs_init();
tmpfs_init();
devfs_init();
pipefs_init();
sockfs_init();
ext2_init();
acpi_initdevice();
tty_init();
pty_init();
loopback_init();
arp_init();
ipv4_init();
tcp_init();
pseudodevices_init();
arch_e9_initdev();
keyboard_init();
arch_ps2_init();
fb_init();
nvme_init();
virtio_init();
console_init();
logging_sethook(console_putc);
char *root = cmdline_get("root");
char *rootfs = cmdline_get("rootfs");
printf("entry: mounting %s (%s) on /\n", root == NULL ? "none" : root, rootfs);
vnode_t *backing;
if (root) {
__assert(devfs_getbyname(root, &backing) == 0);
} else {
backing = NULL;
}
__assert(vfs_mount(backing, vfsroot, "/", rootfs, NULL) == 0);
if (backing) {
VOP_RELEASE(backing);
}
if (cmdline_get("initrd"))
initrd_unpack();
defaultauth_init();
proc_run_init();
sched_threadexit();
}
cpu_t *get_bsp(void) {
return &bsp_cpu;
}
+3
View File
@@ -7,6 +7,7 @@
#include <kernel/vmm.h> #include <kernel/vmm.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <arch/smp.h> #include <arch/smp.h>
#include <kernel/init.h>
#define ADDRMASK (uint64_t)0x7ffffffffffff000 #define ADDRMASK (uint64_t)0x7ffffffffffff000
#define PTMASK (uint64_t)0b111111111000000000000 #define PTMASK (uint64_t)0b111111111000000000000
@@ -381,6 +382,8 @@ void arch_mmu_init() {
arch_mmu_apswitch(); arch_mmu_apswitch();
} }
INIT_ROUTINE_DEFINE(mmu, INIT_ROUTINE_FLAGS_NONE, arch_mmu_init, pmm);
void arch_mmu_apswitch() { void arch_mmu_apswitch() {
arch_mmu_switch(FROM_HHDM(template)); arch_mmu_switch(FROM_HHDM(template));
interrupt_register(13, gpfisr, NULL, IPL_IGNORE); interrupt_register(13, gpfisr, NULL, IPL_IGNORE);
+3
View File
@@ -2,6 +2,7 @@
#include <logging.h> #include <logging.h>
#include <arch/ps2kbd.h> #include <arch/ps2kbd.h>
#include <arch/ps2mouse.h> #include <arch/ps2mouse.h>
#include <kernel/init.h>
static void ps2_disablescanning(int port) { static void ps2_disablescanning(int port) {
ps2_device_command(port, PS2_DEVICE_CMD_DISABLESCANNING); ps2_device_command(port, PS2_DEVICE_CMD_DISABLESCANNING);
@@ -275,3 +276,5 @@ void arch_ps2_init() {
ps2_write_command(PS2_CTLR_CMD_WRITECFG); ps2_write_command(PS2_CTLR_CMD_WRITECFG);
ps2_write_data(control); ps2_write_data(control);
} }
INIT_ROUTINE_DEFINE(ps2, INIT_ROUTINE_FLAGS_NONE, arch_ps2_init, acpi, keyboard);
+8 -8
View File
@@ -7,6 +7,7 @@
#include <kernel/cmdline.h> #include <kernel/cmdline.h>
#include <arch/smp.h> #include <arch/smp.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/init.h>
static volatile struct limine_smp_request smprequest = { static volatile struct limine_smp_request smprequest = {
.id = LIMINE_SMP_REQUEST .id = LIMINE_SMP_REQUEST
@@ -21,8 +22,6 @@ static void cpuwakeuphalt(struct limine_smp_info *info) {
for (;;) CPU_HALT(); for (;;) CPU_HALT();
} }
static time_t us_offset;
static void cpuwakeup(struct limine_smp_info *info) { static void cpuwakeup(struct limine_smp_info *info) {
cpu_set((cpu_t *)info->extra_argument); cpu_set((cpu_t *)info->extra_argument);
@@ -33,11 +32,13 @@ static void cpuwakeup(struct limine_smp_info *info) {
arch_mmu_apswitch(); arch_mmu_apswitch();
vmm_apinit(); vmm_apinit();
timekeeper_early_init(us_offset); arch_apic_initap();
cpu_initstate(); timekeeper_early_init();
arch_cpu_init();
arch_apic_timerinit(); arch_apic_timerinit();
timekeeper_init(); timekeeper_init();
__atomic_add_fetch(&arch_smp_cpusawake, 1, __ATOMIC_SEQ_CST); __atomic_add_fetch(&arch_smp_cpusawake, 1, __ATOMIC_SEQ_CST);
@@ -55,7 +56,6 @@ void arch_smp_haltallothers() {
cpu_t **smp_cpus; cpu_t **smp_cpus;
void arch_smp_wakeup() { void arch_smp_wakeup() {
interrupt_register(0xfd, (void *)cpuwakeuphalt, NULL, IPL_IGNORE);
struct limine_smp_response *response = smprequest.response; struct limine_smp_response *response = smprequest.response;
if (response == NULL) { if (response == NULL) {
// TODO try to detect the other processors manually // TODO try to detect the other processors manually
@@ -77,8 +77,6 @@ void arch_smp_wakeup() {
void (*wakeupfn)(struct limine_smp_info *) = cmdline_get("nosmp") ? cpuwakeuphalt : cpuwakeup; void (*wakeupfn)(struct limine_smp_info *) = cmdline_get("nosmp") ? cpuwakeuphalt : cpuwakeup;
us_offset = timespec_us(timekeeper_timefromboot());
// make the other processors jump to cpuwakeup() // make the other processors jump to cpuwakeup()
for (int i = 0; i < response->cpu_count; ++i) { for (int i = 0; i < response->cpu_count; ++i) {
// skip the bootstrap processor // skip the bootstrap processor
@@ -99,3 +97,5 @@ void arch_smp_wakeup() {
printf("smp: awoke other processors\n"); printf("smp: awoke other processors\n");
} }
INIT_ROUTINE_DEFINE(smp, INIT_ROUTINE_FLAGS_NONE, arch_smp_wakeup, scheduler);
+3
View File
@@ -9,6 +9,7 @@
#include <kernel/pmm.h> #include <kernel/pmm.h>
#include <kernel/vmmcache.h> #include <kernel/vmmcache.h>
#include <kernel/auth.h> #include <kernel/auth.h>
#include <kernel/init.h>
static devnode_t *devfsroot; static devnode_t *devfsroot;
@@ -498,6 +499,8 @@ void devfs_init() {
__assert(hashtable_set(&devfsroot->children, devfsroot, ".", 1, true) == 0); __assert(hashtable_set(&devfsroot->children, devfsroot, ".", 1, true) == 0);
} }
INIT_ROUTINE_DEFINE(devfs, INIT_ROUTINE_FLAGS_NONE, devfs_init, vfs);
int devfs_getbyname(char *name, vnode_t **ret) { int devfs_getbyname(char *name, vnode_t **ret) {
int error = vfs_lookup(ret, (vnode_t *)devfsroot, name, NULL, 0); int error = vfs_lookup(ret, (vnode_t *)devfsroot, name, NULL, 0);
if (error) if (error)
+3
View File
@@ -12,6 +12,7 @@
#include <kernel/vmmcache.h> #include <kernel/vmmcache.h>
#include <kernel/pipefs.h> #include <kernel/pipefs.h>
#include <kernel/auth.h> #include <kernel/auth.h>
#include <kernel/init.h>
#define INODE_ROOT 2 #define INODE_ROOT 2
@@ -2010,3 +2011,5 @@ void ext2_init() {
nodecache = slab_newcache(sizeof(ext2node_t), 0, NULL, NULL); nodecache = slab_newcache(sizeof(ext2node_t), 0, NULL, NULL);
__assert(nodecache); __assert(nodecache);
} }
INIT_ROUTINE_DEFINE(ext2, INIT_ROUTINE_FLAGS_NONE, ext2_init, vfs);
+3
View File
@@ -8,6 +8,7 @@
#include <errno.h> #include <errno.h>
#include <kernel/abi.h> #include <kernel/abi.h>
#include <kernel/poll.h> #include <kernel/poll.h>
#include <kernel/init.h>
#define BUFFER_SIZE 16 * PAGE_SIZE #define BUFFER_SIZE 16 * PAGE_SIZE
#define PIPE_ATOMIC_SIZE 4096 #define PIPE_ATOMIC_SIZE 4096
@@ -403,6 +404,8 @@ void pipefs_init() {
__assert(nodecache); __assert(nodecache);
} }
INIT_ROUTINE_DEFINE(pipefs, INIT_ROUTINE_FLAGS_NONE, pipefs_init, bsp_early);
int pipefs_newpipe(vnode_t **nodep) { int pipefs_newpipe(vnode_t **nodep) {
vnode_t *vnode = slab_allocate(nodecache); vnode_t *vnode = slab_allocate(nodecache);
pipenode_t *node = (pipenode_t *)vnode; pipenode_t *node = (pipenode_t *)vnode;
+3
View File
@@ -9,6 +9,7 @@
#include <kernel/poll.h> #include <kernel/poll.h>
#include <kernel/sock.h> #include <kernel/sock.h>
#include <kernel/auth.h> #include <kernel/auth.h>
#include <kernel/init.h>
static scache_t *nodecache; static scache_t *nodecache;
static uintmax_t currentinode; static uintmax_t currentinode;
@@ -267,6 +268,8 @@ void sockfs_init() {
__assert(nodecache); __assert(nodecache);
} }
INIT_ROUTINE_DEFINE(sockfs, INIT_ROUTINE_FLAGS_NONE, sockfs_init, bsp_early);
int sockfs_newsocket(vnode_t **nodep, socket_t *socket) { int sockfs_newsocket(vnode_t **nodep, socket_t *socket) {
vnode_t *vnode = slab_allocate(nodecache); vnode_t *vnode = slab_allocate(nodecache);
socketnode_t *node = (socketnode_t *)vnode; socketnode_t *node = (socketnode_t *)vnode;
+3
View File
@@ -15,6 +15,7 @@
#include <kernel/vmmcache.h> #include <kernel/vmmcache.h>
#include <kernel/pipefs.h> #include <kernel/pipefs.h>
#include <kernel/auth.h> #include <kernel/auth.h>
#include <kernel/init.h>
static scache_t *nodecache; static scache_t *nodecache;
static tmpfsnode_t *newnode(vfs_t *vfs, int type); static tmpfsnode_t *newnode(vfs_t *vfs, int type);
@@ -598,3 +599,5 @@ void tmpfs_init() {
nodecache = slab_newcache(sizeof(tmpfsnode_t), 0, NULL, NULL); nodecache = slab_newcache(sizeof(tmpfsnode_t), 0, NULL, NULL);
__assert(nodecache); __assert(nodecache);
} }
INIT_ROUTINE_DEFINE(tmpfs, INIT_ROUTINE_FLAGS_NONE, tmpfs_init, vfs);
+7 -4
View File
@@ -11,6 +11,7 @@
#include <kernel/block.h> #include <kernel/block.h>
#include <kernel/pipefs.h> #include <kernel/pipefs.h>
#include <kernel/auth.h> #include <kernel/auth.h>
#include <kernel/init.h>
#define PATHNAME_MAX 512 #define PATHNAME_MAX 512
#define MAXLINKDEPTH 64 #define MAXLINKDEPTH 64
@@ -18,7 +19,7 @@
static hashtable_t fstable; static hashtable_t fstable;
vnode_t *vfsroot; vnode_t *vfsroot;
static spinlock_t listlock; static mutex_t listlock;
static vfs_t *vfslist; static vfs_t *vfslist;
static cred_t *getcred() { static cred_t *getcred() {
@@ -53,12 +54,14 @@ void vfs_init() {
__assert(hashtable_init(&fstable, 20) == 0); __assert(hashtable_init(&fstable, 20) == 0);
vfsroot = alloc(sizeof(vnode_t)); vfsroot = alloc(sizeof(vnode_t));
__assert(vfsroot); __assert(vfsroot);
SPINLOCK_INIT(listlock); MUTEX_INIT(&listlock);
vfsroot->type = V_TYPE_DIR; vfsroot->type = V_TYPE_DIR;
vfsroot->refcount = 1; vfsroot->refcount = 1;
vfsroot->ops = &vnops; vfsroot->ops = &vnops;
} }
INIT_ROUTINE_DEFINE(vfs, INIT_ROUTINE_FLAGS_NONE, vfs_init, bsp_early);
int vfs_register(vfsops_t *ops, char *name) { int vfs_register(vfsops_t *ops, char *name) {
return hashtable_set(&fstable, ops, name, strlen(name), true); return hashtable_set(&fstable, ops, name, strlen(name), true);
} }
@@ -111,12 +114,12 @@ int vfs_mount(vnode_t *backing, vnode_t *pathref, char *path, char *name, void *
return err; return err;
} }
spinlock_acquire(&listlock); MUTEX_ACQUIRE(&listlock);
vfs->next = vfslist; vfs->next = vfslist;
vfslist = vfs; vfslist = vfs;
spinlock_release(&listlock); MUTEX_RELEASE(&listlock);
mounton->vfsmounted = vfs; mounton->vfsmounted = vfs;
vfs->nodecovered = mounton; vfs->nodecovered = mounton;
+80
View File
@@ -0,0 +1,80 @@
#ifndef _INIT_H
#define _INIT_H
#include <stddef.h>
#define INIT_ROUTINE_FLAGS_NONE 0
#define INIT_ROUTINE_FLAGS_ALREADY_DONE 1
#define INIT_ROUTINE_FLAGS_QUIET 2
#define INIT_ROUTINE_FLAGS_PHONY 4
typedef struct init_routine_t {
const char *name;
int flags;
void (*fn)(void);
struct init_routine_t ***dependencies;
size_t dependency_count;
} init_routine_t;
// tasty tasty macro soup!
// this will make it cleaner overall and keep the ugly here
// if any routine has more than 10 deps add more here
#define INIT_MACRO_ARG_COUNT_(n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n, ...) n
#define INIT_MACRO_ARG_COUNT(...) INIT_MACRO_ARG_COUNT_(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define INIT_CONCAT_(a, b) a##b
#define INIT_CONCAT(a, b) INIT_CONCAT_(a, b)
#define INIT_GET_DEP_NAME(x) init_routine_ ## x
#define INIT_DEFINE_EXTERN(x) extern init_routine_t * INIT_GET_DEP_NAME(x)
#define INIT_DEFINE_EXTERN_0(...)
#define INIT_DEFINE_EXTERN_1(x) INIT_DEFINE_EXTERN(x)
#define INIT_DEFINE_EXTERN_2(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_1(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_3(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_2(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_4(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_3(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_5(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_4(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_6(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_5(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_7(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_6(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_8(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_7(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_9(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_8(__VA_ARGS__)
#define INIT_DEFINE_EXTERN_10(x, ...) INIT_DEFINE_EXTERN(x); INIT_DEFINE_EXTERN_9(__VA_ARGS__)
#define INIT_GET_DEP_0(...)
#define INIT_GET_DEP_1(x) &INIT_GET_DEP_NAME(x)
#define INIT_GET_DEP_2(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_1(__VA_ARGS__)
#define INIT_GET_DEP_3(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_2(__VA_ARGS__)
#define INIT_GET_DEP_4(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_3(__VA_ARGS__)
#define INIT_GET_DEP_5(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_4(__VA_ARGS__)
#define INIT_GET_DEP_6(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_5(__VA_ARGS__)
#define INIT_GET_DEP_7(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_6(__VA_ARGS__)
#define INIT_GET_DEP_8(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_7(__VA_ARGS__)
#define INIT_GET_DEP_9(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_8(__VA_ARGS__)
#define INIT_GET_DEP_10(x, ...) &INIT_GET_DEP_NAME(x), INIT_GET_DEP_9(__VA_ARGS__)
#define INIT_GET_ROUTINE(name) init_routine_##name
// ... is deps
#define INIT_ROUTINE_DEFINE(name_, flags_, fn_, ...) \
/* first define all dependencies as extern. if none, then it will not define any
* but since it will not be used, then there is no harm done. */ \
INIT_CONCAT(INIT_DEFINE_EXTERN_, INIT_MACRO_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__); \
/* then, create the array of the dependencies for the use in the main struct.
* if none, then it will just be empty */ \
static init_routine_t **init_routine_deps_##name_ [] = { \
INIT_CONCAT(INIT_GET_DEP_, INIT_MACRO_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__) \
}; \
/* finally, define the init routine struct and keep a pointer to it in the special section */ \
static init_routine_t struct_init_routine_##name_ = { \
.name = #name_, \
.flags = flags_, \
.fn = fn_, \
.dependencies = init_routine_deps_##name_, \
.dependency_count = INIT_MACRO_ARG_COUNT(__VA_ARGS__) \
}; \
__attribute__((section(".init_routines"), used)) init_routine_t *init_routine_##name_ = &struct_init_routine_##name_;
void init_run_routine(init_routine_t *routine);
void init_run_all_routines(void);
#endif
+1 -1
View File
@@ -21,7 +21,7 @@ typedef struct {
} timekeeper_source_t; } timekeeper_source_t;
// initializes the highest priority source that can be used as an early timer and switches the cpu to use it // initializes the highest priority source that can be used as an early timer and switches the cpu to use it
void timekeeper_early_init(time_t us_offset); void timekeeper_early_init(void);
// initializes the highest priority source and switches the cpu to use it. uses the early timer for calibration if nescessary // initializes the highest priority source and switches the cpu to use it. uses the early timer for calibration if nescessary
void timekeeper_init(void); void timekeeper_init(void);
+1
View File
@@ -7,6 +7,7 @@
#include <arch/cpu.h> #include <arch/cpu.h>
#include <util.h> #include <util.h>
void arch_early_log(char c);
void _putchar(char c); void _putchar(char c);
void logging_sethook(void (*fun)(char)); void logging_sethook(void (*fun)(char));
void logging_init(); void logging_init();
+1 -1
View File
@@ -117,6 +117,6 @@ static inline void cpu_set(cpu_t *ptr) {
wrmsr(MSR_GSBASE, (uint64_t)ptr); wrmsr(MSR_GSBASE, (uint64_t)ptr);
} }
void cpu_initstate(); void arch_cpu_init();
#endif #endif
+5
View File
@@ -7,12 +7,15 @@
#include <uacpi/event.h> #include <uacpi/event.h>
#include <kernel/acpi.h> #include <kernel/acpi.h>
#include <kernel/interrupt.h> #include <kernel/interrupt.h>
#include <kernel/init.h>
#include <logging.h> #include <logging.h>
void acpi_early_init(void) { void acpi_early_init(void) {
__assert(uacpi_initialize(0) == UACPI_STATUS_OK); __assert(uacpi_initialize(0) == UACPI_STATUS_OK);
} }
INIT_ROUTINE_DEFINE(acpi_early, INIT_ROUTINE_FLAGS_NONE, acpi_early_init, alloc);
void acpi_dopoweroff(uacpi_handle ctx) { void acpi_dopoweroff(uacpi_handle ctx) {
(void)ctx; (void)ctx;
acpi_signaldevice('p'); acpi_signaldevice('p');
@@ -37,6 +40,8 @@ void acpi_init(void) {
uacpi_install_fixed_event_handler(UACPI_FIXED_EVENT_POWER_BUTTON, handle_pwrbtn, UACPI_NULL); uacpi_install_fixed_event_handler(UACPI_FIXED_EVENT_POWER_BUTTON, handle_pwrbtn, UACPI_NULL);
} }
INIT_ROUTINE_DEFINE(acpi, INIT_ROUTINE_FLAGS_NONE, acpi_init, pci, devfs, scheduler);
int acpi_poweroff(void) { int acpi_poweroff(void) {
uacpi_status ret = uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S5); uacpi_status ret = uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S5);
if (uacpi_unlikely_error(ret)) { if (uacpi_unlikely_error(ret)) {
+3
View File
@@ -10,6 +10,7 @@
#include <arch/cpu.h> #include <arch/cpu.h>
#include <errno.h> #include <errno.h>
#include <kernel/block.h> #include <kernel/block.h>
#include <kernel/init.h>
#define CC_ENABLE(cc) cc = (cc) | 1 #define CC_ENABLE(cc) cc = (cc) | 1
#define CC_DISABLE(cc) cc = (cc) & ~1 #define CC_DISABLE(cc) cc = (cc) & ~1
@@ -788,3 +789,5 @@ void nvme_init() {
initcontroller(e); initcontroller(e);
} }
} }
INIT_ROUTINE_DEFINE(nvme, INIT_ROUTINE_FLAGS_NONE, nvme_init, acpi);
+3
View File
@@ -9,6 +9,7 @@
#include <termios.h> #include <termios.h>
#include <kernel/poll.h> #include <kernel/poll.h>
#include <kernel/tty.h> #include <kernel/tty.h>
#include <kernel/init.h>
static mutex_t writemutex; static mutex_t writemutex;
static thread_t *thread; static thread_t *thread;
@@ -124,3 +125,5 @@ void console_init() {
tty->winsize.ws_xpixel = fbx; tty->winsize.ws_xpixel = fbx;
tty->winsize.ws_ypixel = fby; tty->winsize.ws_ypixel = fby;
} }
INIT_ROUTINE_DEFINE(console, INIT_ROUTINE_FLAGS_NONE, console_init, scheduler, keyboard);
+3
View File
@@ -7,6 +7,7 @@
#include <arch/cpu.h> #include <arch/cpu.h>
#include <kernel/pmm.h> #include <kernel/pmm.h>
#include <kernel/usercopy.h> #include <kernel/usercopy.h>
#include <kernel/init.h>
typedef struct bitfield_t { typedef struct bitfield_t {
uint32_t offset; uint32_t offset;
@@ -256,3 +257,5 @@ void fb_init() {
printf("%s: %dx%d %d bpp\n", name, fb->width, fb->height, fb->bpp); printf("%s: %dx%d %d bpp\n", name, fb->width, fb->height, fb->bpp);
} }
} }
INIT_ROUTINE_DEFINE(fb, INIT_ROUTINE_FLAGS_NONE, fb_init, devfs);
+3
View File
@@ -6,6 +6,7 @@
#include <hashtable.h> #include <hashtable.h>
#include <kernel/poll.h> #include <kernel/poll.h>
#include <kernel/usercopy.h> #include <kernel/usercopy.h>
#include <kernel/init.h>
#define BUFFER_PACKET_CAPACITY 100 #define BUFFER_PACKET_CAPACITY 100
#define BUFFER_SIZE (BUFFER_PACKET_CAPACITY * sizeof(kbpacket_t)) #define BUFFER_SIZE (BUFFER_PACKET_CAPACITY * sizeof(kbpacket_t))
@@ -252,3 +253,5 @@ void keyboard_init() {
__assert(keyboard_console); __assert(keyboard_console);
__assert(hashtable_init(&kbtable, 20) == 0); __assert(hashtable_init(&kbtable, 20) == 0);
} }
INIT_ROUTINE_DEFINE(keyboard, INIT_ROUTINE_FLAGS_NONE, keyboard_init, bsp_early);
+3
View File
@@ -7,6 +7,7 @@
#include <kernel/eth.h> #include <kernel/eth.h>
#include <ringbuffer.h> #include <ringbuffer.h>
#include <kernel/event.h> #include <kernel/event.h>
#include <kernel/init.h>
#define CACHE_TIMEOUT_SEC 300 #define CACHE_TIMEOUT_SEC 300
#define CACHE_TIMEOUT_MS (CACHE_TIMEOUT_SEC * 1000) #define CACHE_TIMEOUT_MS (CACHE_TIMEOUT_SEC * 1000)
@@ -315,3 +316,5 @@ void arp_init() {
sched_queue(handlerthread); sched_queue(handlerthread);
sched_queue(cleanupthread); sched_queue(cleanupthread);
} }
INIT_ROUTINE_DEFINE(arp, INIT_ROUTINE_FLAGS_NONE, arp_init, scheduler);
+3
View File
@@ -5,6 +5,7 @@
#include <mutex.h> #include <mutex.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/abi.h> #include <kernel/abi.h>
#include <kernel/init.h>
typedef struct { typedef struct {
netdev_t *netdev; netdev_t *netdev;
@@ -229,3 +230,5 @@ void ipv4_init() {
__assert(routingtable); __assert(routingtable);
__assert(ipv4_addroute(loopback_device(), 0x7f000001, 0, 0xff000000, 10000) == 0); __assert(ipv4_addroute(loopback_device(), 0x7f000001, 0, 0xff000000, 10000) == 0);
} }
INIT_ROUTINE_DEFINE(ipv4, INIT_ROUTINE_FLAGS_NONE, ipv4_init, devfs)
+3
View File
@@ -5,6 +5,7 @@
#include <kernel/net.h> #include <kernel/net.h>
#include <hashtable.h> #include <hashtable.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <kernel/init.h>
static netdev_t loopbacknetdev; static netdev_t loopbacknetdev;
@@ -64,3 +65,5 @@ void loopback_init() {
__assert(netdev_register(&loopbacknetdev, "lo") == 0); __assert(netdev_register(&loopbacknetdev, "lo") == 0);
} }
INIT_ROUTINE_DEFINE(loopback, INIT_ROUTINE_FLAGS_NONE, loopback_init, devfs);
+3
View File
@@ -5,6 +5,7 @@
#include <kernel/timekeeper.h> #include <kernel/timekeeper.h>
#include <kernel/interrupt.h> #include <kernel/interrupt.h>
#include <kernel/auth.h> #include <kernel/auth.h>
#include <kernel/init.h>
#define WORKER_COUNT 12 #define WORKER_COUNT 12
#define WORKER_BUFFER_SIZE (64 * 1024) #define WORKER_BUFFER_SIZE (64 * 1024)
@@ -1879,3 +1880,5 @@ void tcp_init() {
sched_queue(thread); sched_queue(thread);
} }
} }
INIT_ROUTINE_DEFINE(tcp, INIT_ROUTINE_FLAGS_NONE, tcp_init, ipv4, scheduler);
+3
View File
@@ -3,6 +3,7 @@
#include <kernel/pci.h> #include <kernel/pci.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/vmm.h> #include <kernel/vmm.h>
#include <kernel/init.h>
uint8_t pci_read8(int bus, int device, int function, uint32_t offset) { uint8_t pci_read8(int bus, int device, int function, uint32_t offset) {
return (pci_archread32(bus, device, function, offset) >> ((offset & 0b11) * 8)) & 0xff; return (pci_archread32(bus, device, function, offset) >> ((offset & 0b11) * 8)) & 0xff;
@@ -279,3 +280,5 @@ void pci_init() {
} }
} }
} }
INIT_ROUTINE_DEFINE(pci, INIT_ROUTINE_FLAGS_NONE, pci_init, scheduler);
+3
View File
@@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include <logging.h> #include <logging.h>
#include <kernel/timekeeper.h> #include <kernel/timekeeper.h>
#include <kernel/init.h>
static int null_write(int minor, iovec_iterator_t *iovec_iterator, size_t count, uintmax_t offset, int flags, size_t *wcount) { static int null_write(int minor, iovec_iterator_t *iovec_iterator, size_t count, uintmax_t offset, int flags, size_t *wcount) {
*wcount = count; *wcount = count;
@@ -77,3 +78,5 @@ void pseudodevices_init() {
__assert(devfs_register(&zeroops, "zero", V_TYPE_CHDEV, DEV_MAJOR_ZERO, 0, 0666, NULL) == 0); __assert(devfs_register(&zeroops, "zero", V_TYPE_CHDEV, DEV_MAJOR_ZERO, 0, 0666, NULL) == 0);
__assert(devfs_register(&urandomops, "urandom", V_TYPE_CHDEV, DEV_MAJOR_URANDOM, 0, 0666, NULL) == 0); __assert(devfs_register(&urandomops, "urandom", V_TYPE_CHDEV, DEV_MAJOR_URANDOM, 0, 0666, NULL) == 0);
} }
INIT_ROUTINE_DEFINE(pseudo_devices, INIT_ROUTINE_FLAGS_NONE, pseudodevices_init, devfs);
+3
View File
@@ -4,6 +4,7 @@
#include <logging.h> #include <logging.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/usercopy.h> #include <kernel/usercopy.h>
#include <kernel/init.h>
#define PTY_BUFFER 4096 #define PTY_BUFFER 4096
#define PTY_MAX 1024 #define PTY_MAX 1024
@@ -285,3 +286,5 @@ void pty_init() {
__assert(devfs_createdir("pts") == 0); __assert(devfs_createdir("pts") == 0);
SPINLOCK_INIT(listlock); SPINLOCK_INIT(listlock);
} }
INIT_ROUTINE_DEFINE(pty, INIT_ROUTINE_FLAGS_NONE, pty_init, tty);
+3
View File
@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <kernel/pmm.h> #include <kernel/pmm.h>
#include <arch/mmu.h> #include <arch/mmu.h>
#include <kernel/init.h>
extern volatile struct limine_framebuffer_request fb_liminereq; extern volatile struct limine_framebuffer_request fb_liminereq;
static size_t xs, ys, fbxs, fbys; static size_t xs, ys, fbxs, fbys;
@@ -66,3 +67,5 @@ void term_init() {
MUTEX_INIT(&term_mutex); MUTEX_INIT(&term_mutex);
} }
INIT_ROUTINE_DEFINE(term, INIT_ROUTINE_FLAGS_NONE, term_init, pmm);
+3
View File
@@ -4,6 +4,7 @@
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/jobctl.h> #include <kernel/jobctl.h>
#include <kernel/usercopy.h> #include <kernel/usercopy.h>
#include <kernel/init.h>
#define TTY_MAX_COUNT 4096 #define TTY_MAX_COUNT 4096
#define CONTROLLING_TTY_MINOR TTY_MAX_COUNT #define CONTROLLING_TTY_MINOR TTY_MAX_COUNT
@@ -552,3 +553,5 @@ void tty_init() {
__assert(devfs_register(&devops, "tty", V_TYPE_CHDEV, DEV_MAJOR_TTY, CONTROLLING_TTY_MINOR, 0666, NULL) == 0); __assert(devfs_register(&devops, "tty", V_TYPE_CHDEV, DEV_MAJOR_TTY, CONTROLLING_TTY_MINOR, 0666, NULL) == 0);
MUTEX_INIT(&listmutex); MUTEX_INIT(&listmutex);
} }
INIT_ROUTINE_DEFINE(tty, INIT_ROUTINE_FLAGS_NONE, tty_init, devfs);
+3
View File
@@ -3,6 +3,7 @@
#include <logging.h> #include <logging.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <kernel/pmm.h> #include <kernel/pmm.h>
#include <kernel/init.h>
#define VIRTIO_VENDOR 0x1af4 #define VIRTIO_VENDOR 0x1af4
#define VIRTIO_DEVICE_MIN 0x1000 #define VIRTIO_DEVICE_MIN 0x1000
@@ -176,3 +177,5 @@ void virtio_init() {
} }
} }
} }
INIT_ROUTINE_DEFINE(virtio, INIT_ROUTINE_FLAGS_NONE, virtio_init, acpi);
+3
View File
@@ -2,6 +2,7 @@
#include <kernel/slab.h> #include <kernel/slab.h>
#include <logging.h> #include <logging.h>
#include <string.h> #include <string.h>
#include <kernel/init.h>
// each allocation has the following structure: // each allocation has the following structure:
// ptr: data capacity (allocsizes size) // ptr: data capacity (allocsizes size)
@@ -96,3 +97,5 @@ void alloc_init() {
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
caches[i] = caches[5]; caches[i] = caches[5];
} }
INIT_ROUTINE_DEFINE(alloc, INIT_ROUTINE_FLAGS_NONE, alloc_init, vmm);
+6
View File
@@ -6,6 +6,7 @@
#include <mutex.h> #include <mutex.h>
#include <util.h> #include <util.h>
#include <kernel/vmmcache.h> #include <kernel/vmmcache.h>
#include <kernel/init.h>
uintptr_t hhdmbase; uintptr_t hhdmbase;
static size_t memorysize; static size_t memorysize;
@@ -266,6 +267,11 @@ void pmm_init() {
MUTEX_INIT(&freelistmutex); MUTEX_INIT(&freelistmutex);
} }
INIT_ROUTINE_DEFINE(pmm,
INIT_ROUTINE_FLAGS_NONE,
pmm_init,
arch_early);
// XXX pmm_alloc won't be able to take pages from the page cache when the allocation size is over 1 page // XXX pmm_alloc won't be able to take pages from the page cache when the allocation size is over 1 page
void *pmm_alloc(size_t size, int section) { void *pmm_alloc(size_t size, int section) {
+3
View File
@@ -7,6 +7,7 @@
#include <string.h> #include <string.h>
#include <kernel/slab.h> #include <kernel/slab.h>
#include <kernel/vmmcache.h> #include <kernel/vmmcache.h>
#include <kernel/init.h>
#define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size) #define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size)
@@ -962,6 +963,8 @@ void vmm_init() {
printspace(&kernelspace); printspace(&kernelspace);
} }
INIT_ROUTINE_DEFINE(vmm, INIT_ROUTINE_FLAGS_NONE, vmm_init, mmu);
void vmm_apinit() { void vmm_apinit() {
vmm_switchcontext(&vmm_kernelctx); vmm_switchcontext(&vmm_kernelctx);
} }
+3
View File
@@ -4,6 +4,7 @@
#include <logging.h> #include <logging.h>
#include <kernel/timekeeper.h> #include <kernel/timekeeper.h>
#include <kernel/event.h> #include <kernel/event.h>
#include <kernel/init.h>
#define TABLE_SIZE 4096 #define TABLE_SIZE 4096
#define WRITER_TICK_SECONDS 15 #define WRITER_TICK_SECONDS 15
@@ -475,3 +476,5 @@ void vmmcache_init() {
EVENT_INITHEADER(&syncevent); EVENT_INITHEADER(&syncevent);
EVENT_INITHEADER(&pagereadyevent); EVENT_INITHEADER(&pagereadyevent);
} }
INIT_ROUTINE_DEFINE(vmm_cache, INIT_ROUTINE_FLAGS_NONE, vmmcache_init, scheduler);
+3
View File
@@ -1,5 +1,6 @@
#include <kernel/auth.h> #include <kernel/auth.h>
#include <logging.h> #include <logging.h>
#include <kernel/init.h>
// default listeners for auth // default listeners for auth
@@ -285,3 +286,5 @@ void defaultauth_init() {
auth_registerlistener(AUTH_SCOPE_PROCESS, process); auth_registerlistener(AUTH_SCOPE_PROCESS, process);
auth_registerlistener(AUTH_SCOPE_NETWORK, network); auth_registerlistener(AUTH_SCOPE_NETWORK, network);
} }
INIT_ROUTINE_DEFINE(default_auth, INIT_ROUTINE_FLAGS_NONE, defaultauth_init, bsp_early);
+27
View File
@@ -0,0 +1,27 @@
#include <kernel/init.h>
#include <arch/cpu.h>
#include <logging.h>
void init_run_routine(init_routine_t *routine) {
if (routine->flags & INIT_ROUTINE_FLAGS_ALREADY_DONE)
return;
for (int i = 0; i < routine->dependency_count; ++i)
init_run_routine(*routine->dependencies[i]);
if ((routine->flags & INIT_ROUTINE_FLAGS_QUIET) == 0)
printf("kernel_init: running routine %s\n", routine->name);
if ((routine->flags & INIT_ROUTINE_FLAGS_PHONY) == 0)
routine->fn();
routine->flags |= INIT_ROUTINE_FLAGS_ALREADY_DONE;
}
extern init_routine_t *init_routines;
extern init_routine_t *init_routines_end;
void init_run_all_routines(void) {
for (init_routine_t **routine_ptr = &init_routines; routine_ptr < &init_routines_end; ++routine_ptr)
init_run_routine(*routine_ptr);
}
+5
View File
@@ -13,6 +13,7 @@
#include <kernel/cmdline.h> #include <kernel/cmdline.h>
#include <kernel/auth.h> #include <kernel/auth.h>
#include <arch/smp.h> #include <arch/smp.h>
#include <kernel/init.h>
#define QUANTUM_US 100000 #define QUANTUM_US 100000
#define SCHEDULER_STACK_SIZE PAGE_SIZE * 16 #define SCHEDULER_STACK_SIZE PAGE_SIZE * 16
@@ -458,7 +459,11 @@ void sched_init() {
current_cpu()->reschedule_isr = interrupt_allocate(reschedule_ipi, ARCH_EOI, IPL_MAX); current_cpu()->reschedule_isr = interrupt_allocate(reschedule_ipi, ARCH_EOI, IPL_MAX);
__assert(current_cpu()->reschedule_isr); __assert(current_cpu()->reschedule_isr);
sched_target_cpu(current_cpu());
timer_insert(current_cpu()->timer, &current_cpu()->schedtimerentry, reschedule_timer_dpc, NULL, QUANTUM_US, true); timer_insert(current_cpu()->timer, &current_cpu()->schedtimerentry, reschedule_timer_dpc, NULL, QUANTUM_US, true);
// XXX move this resume to a more appropriate place // XXX move this resume to a more appropriate place
timer_resume(current_cpu()->timer); timer_resume(current_cpu()->timer);
} }
INIT_ROUTINE_DEFINE(scheduler, INIT_ROUTINE_FLAGS_NONE, sched_init, arch_timer);
+8 -5
View File
@@ -4,6 +4,7 @@
#include <mutex.h> #include <mutex.h>
#include <limine.h> #include <limine.h>
#include <logging.h> #include <logging.h>
#include <kernel/init.h>
static volatile struct limine_boot_time_request timereq = { static volatile struct limine_boot_time_request timereq = {
.id = LIMINE_BOOT_TIME_REQUEST, .id = LIMINE_BOOT_TIME_REQUEST,
@@ -106,6 +107,8 @@ void timekeeper_sync(void) {
MUTEX_RELEASE(&sync_mutex); MUTEX_RELEASE(&sync_mutex);
} }
INIT_ROUTINE_DEFINE(sync_cpu_time, INIT_ROUTINE_FLAGS_NONE, timekeeper_sync, smp, timekeeper);
extern timekeeper_source_t *timekeeper_sources; extern timekeeper_source_t *timekeeper_sources;
extern timekeeper_source_t *timekeeper_sources_end; extern timekeeper_source_t *timekeeper_sources_end;
@@ -130,7 +133,7 @@ void timekeeper_wait_us(time_t us) {
CPU_PAUSE(); CPU_PAUSE();
} }
void timekeeper_early_init(time_t us_offset) { void timekeeper_early_init(void) {
__assert(timereq.response); __assert(timereq.response);
boot_unix = timereq.response->boot_time; boot_unix = timereq.response->boot_time;
@@ -151,14 +154,12 @@ void timekeeper_early_init(time_t us_offset) {
current_cpu()->timekeeper_source_info = early_source_info; current_cpu()->timekeeper_source_info = early_source_info;
current_cpu()->timekeeper_source = early_source; current_cpu()->timekeeper_source = early_source;
// this tick offset is to account for any possible time before early_init.
// for example, on SMP init the early init will have the time passed on the ap as an offset
current_cpu()->timekeeper_source_tick_offset = us_offset * early_source_info->hz / 1000000;
printf("cpu%d: timekeeper: \"%s\" selected as early source. %lu ticks at early init (%lu hz)\n", printf("cpu%d: timekeeper: \"%s\" selected as early source. %lu ticks at early init (%lu hz)\n",
current_cpu_id(), early_source->name, current_cpu()->timekeeper_source_base_ticks, early_source_info->hz); current_cpu_id(), early_source->name, current_cpu()->timekeeper_source_base_ticks, early_source_info->hz);
} }
INIT_ROUTINE_DEFINE(timekeeper_early, INIT_ROUTINE_FLAGS_NONE, timekeeper_early_init, arch_irq);
// this will do a re-init per cpu // this will do a re-init per cpu
// the initialization threads will not switch cpus so we dont have to worry about it here // the initialization threads will not switch cpus so we dont have to worry about it here
void timekeeper_init(void) { void timekeeper_init(void) {
@@ -197,3 +198,5 @@ void timekeeper_init(void) {
printf("cpu%d: timekeeper: \"%s\" selected as main source. %lu ticks at init (%lu hz)\n", printf("cpu%d: timekeeper: \"%s\" selected as main source. %lu ticks at init (%lu hz)\n",
current_cpu_id(), new_source->name, current_cpu()->timekeeper_source_base_ticks, new_source_info->hz); current_cpu_id(), new_source->name, current_cpu()->timekeeper_source_base_ticks, new_source_info->hz);
} }
INIT_ROUTINE_DEFINE(timekeeper, INIT_ROUTINE_FLAGS_NONE, timekeeper_init, scheduler);