mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
kernel: rework init
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <arch/msr.h>
|
||||
#include <kernel/timer.h>
|
||||
#include <kernel/timekeeper.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#include <uacpi/tables.h>
|
||||
#include <uacpi/acpi.h>
|
||||
@@ -240,6 +241,8 @@ void arch_apic_timerinit() {
|
||||
__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) {
|
||||
writelapic(APIC_REG_ICR_HI, (uint32_t)cpu << 24);
|
||||
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
|
||||
|
||||
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);
|
||||
__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
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(arch_irq, INIT_ROUTINE_FLAGS_NONE, arch_apic_init, acpi_early);
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#include <logging.h>
|
||||
#include <arch/cpuid.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
|
||||
|
||||
@@ -145,9 +149,7 @@ static void get_topology(long *topology_ids, long *topology_types) {
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_initstate() {
|
||||
arch_apic_initap();
|
||||
|
||||
void arch_cpu_init() {
|
||||
// syscall instruction
|
||||
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
__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());
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <kernel/devfs.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/usercopy.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
void arch_e9_putc(char c) {
|
||||
#ifdef X86_64_ENABLE_E9
|
||||
@@ -9,6 +10,11 @@ void arch_e9_putc(char c) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void arch_early_log(char c) {
|
||||
arch_e9_putc(c);
|
||||
}
|
||||
|
||||
|
||||
void arch_e9_puts(char *c) {
|
||||
#ifdef X86_64_ENABLE_E9
|
||||
while (*c) {
|
||||
@@ -35,10 +41,10 @@ static int devwrite(int minor, iovec_iterator_t *iovec_iterator, size_t count, u
|
||||
static devops_t devops = {
|
||||
.write = devwrite
|
||||
};
|
||||
#endif
|
||||
|
||||
void arch_e9_initdev() {
|
||||
#ifdef X86_64_ENABLE_E9
|
||||
__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
|
||||
|
||||
@@ -32,6 +32,13 @@ SECTIONS
|
||||
*(.timekeeper_sources);
|
||||
timekeeper_sources_end = .;
|
||||
} :rodata
|
||||
|
||||
. = ALIGN(8);
|
||||
.init_routines : {
|
||||
init_routines = .;
|
||||
*(.init_routines);
|
||||
init_routines_end = .;
|
||||
} :rodata
|
||||
|
||||
. = ALIGN(4K);
|
||||
_rodata_end = .;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <kernel/vmm.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/smp.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define ADDRMASK (uint64_t)0x7ffffffffffff000
|
||||
#define PTMASK (uint64_t)0b111111111000000000000
|
||||
@@ -381,6 +382,8 @@ void arch_mmu_init() {
|
||||
arch_mmu_apswitch();
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(mmu, INIT_ROUTINE_FLAGS_NONE, arch_mmu_init, pmm);
|
||||
|
||||
void arch_mmu_apswitch() {
|
||||
arch_mmu_switch(FROM_HHDM(template));
|
||||
interrupt_register(13, gpfisr, NULL, IPL_IGNORE);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <logging.h>
|
||||
#include <arch/ps2kbd.h>
|
||||
#include <arch/ps2mouse.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static void ps2_disablescanning(int port) {
|
||||
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_data(control);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(ps2, INIT_ROUTINE_FLAGS_NONE, arch_ps2_init, acpi, keyboard);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <kernel/cmdline.h>
|
||||
#include <arch/smp.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static volatile struct limine_smp_request smprequest = {
|
||||
.id = LIMINE_SMP_REQUEST
|
||||
@@ -21,8 +22,6 @@ static void cpuwakeuphalt(struct limine_smp_info *info) {
|
||||
for (;;) CPU_HALT();
|
||||
}
|
||||
|
||||
static time_t us_offset;
|
||||
|
||||
static void cpuwakeup(struct limine_smp_info *info) {
|
||||
cpu_set((cpu_t *)info->extra_argument);
|
||||
|
||||
@@ -33,11 +32,13 @@ static void cpuwakeup(struct limine_smp_info *info) {
|
||||
arch_mmu_apswitch();
|
||||
vmm_apinit();
|
||||
|
||||
timekeeper_early_init(us_offset);
|
||||
arch_apic_initap();
|
||||
|
||||
cpu_initstate();
|
||||
timekeeper_early_init();
|
||||
|
||||
arch_cpu_init();
|
||||
arch_apic_timerinit();
|
||||
|
||||
|
||||
timekeeper_init();
|
||||
|
||||
__atomic_add_fetch(&arch_smp_cpusawake, 1, __ATOMIC_SEQ_CST);
|
||||
@@ -55,7 +56,6 @@ void arch_smp_haltallothers() {
|
||||
cpu_t **smp_cpus;
|
||||
|
||||
void arch_smp_wakeup() {
|
||||
interrupt_register(0xfd, (void *)cpuwakeuphalt, NULL, IPL_IGNORE);
|
||||
struct limine_smp_response *response = smprequest.response;
|
||||
if (response == NULL) {
|
||||
// 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;
|
||||
|
||||
us_offset = timespec_us(timekeeper_timefromboot());
|
||||
|
||||
// make the other processors jump to cpuwakeup()
|
||||
for (int i = 0; i < response->cpu_count; ++i) {
|
||||
// skip the bootstrap processor
|
||||
@@ -99,3 +97,5 @@ void arch_smp_wakeup() {
|
||||
|
||||
printf("smp: awoke other processors\n");
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(smp, INIT_ROUTINE_FLAGS_NONE, arch_smp_wakeup, scheduler);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <kernel/pmm.h>
|
||||
#include <kernel/vmmcache.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static devnode_t *devfsroot;
|
||||
|
||||
@@ -498,6 +499,8 @@ void devfs_init() {
|
||||
__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 error = vfs_lookup(ret, (vnode_t *)devfsroot, name, NULL, 0);
|
||||
if (error)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <kernel/vmmcache.h>
|
||||
#include <kernel/pipefs.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define INODE_ROOT 2
|
||||
|
||||
@@ -2010,3 +2011,5 @@ void ext2_init() {
|
||||
nodecache = slab_newcache(sizeof(ext2node_t), 0, NULL, NULL);
|
||||
__assert(nodecache);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(ext2, INIT_ROUTINE_FLAGS_NONE, ext2_init, vfs);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <errno.h>
|
||||
#include <kernel/abi.h>
|
||||
#include <kernel/poll.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define BUFFER_SIZE 16 * PAGE_SIZE
|
||||
#define PIPE_ATOMIC_SIZE 4096
|
||||
@@ -403,6 +404,8 @@ void pipefs_init() {
|
||||
__assert(nodecache);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(pipefs, INIT_ROUTINE_FLAGS_NONE, pipefs_init, bsp_early);
|
||||
|
||||
int pipefs_newpipe(vnode_t **nodep) {
|
||||
vnode_t *vnode = slab_allocate(nodecache);
|
||||
pipenode_t *node = (pipenode_t *)vnode;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <kernel/poll.h>
|
||||
#include <kernel/sock.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static scache_t *nodecache;
|
||||
static uintmax_t currentinode;
|
||||
@@ -267,6 +268,8 @@ void sockfs_init() {
|
||||
__assert(nodecache);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(sockfs, INIT_ROUTINE_FLAGS_NONE, sockfs_init, bsp_early);
|
||||
|
||||
int sockfs_newsocket(vnode_t **nodep, socket_t *socket) {
|
||||
vnode_t *vnode = slab_allocate(nodecache);
|
||||
socketnode_t *node = (socketnode_t *)vnode;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <kernel/vmmcache.h>
|
||||
#include <kernel/pipefs.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static scache_t *nodecache;
|
||||
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);
|
||||
__assert(nodecache);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(tmpfs, INIT_ROUTINE_FLAGS_NONE, tmpfs_init, vfs);
|
||||
|
||||
+7
-4
@@ -11,6 +11,7 @@
|
||||
#include <kernel/block.h>
|
||||
#include <kernel/pipefs.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define PATHNAME_MAX 512
|
||||
#define MAXLINKDEPTH 64
|
||||
@@ -18,7 +19,7 @@
|
||||
static hashtable_t fstable;
|
||||
vnode_t *vfsroot;
|
||||
|
||||
static spinlock_t listlock;
|
||||
static mutex_t listlock;
|
||||
static vfs_t *vfslist;
|
||||
|
||||
static cred_t *getcred() {
|
||||
@@ -53,12 +54,14 @@ void vfs_init() {
|
||||
__assert(hashtable_init(&fstable, 20) == 0);
|
||||
vfsroot = alloc(sizeof(vnode_t));
|
||||
__assert(vfsroot);
|
||||
SPINLOCK_INIT(listlock);
|
||||
MUTEX_INIT(&listlock);
|
||||
vfsroot->type = V_TYPE_DIR;
|
||||
vfsroot->refcount = 1;
|
||||
vfsroot->ops = &vnops;
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(vfs, INIT_ROUTINE_FLAGS_NONE, vfs_init, bsp_early);
|
||||
|
||||
int vfs_register(vfsops_t *ops, char *name) {
|
||||
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;
|
||||
}
|
||||
|
||||
spinlock_acquire(&listlock);
|
||||
MUTEX_ACQUIRE(&listlock);
|
||||
|
||||
vfs->next = vfslist;
|
||||
vfslist = vfs;
|
||||
|
||||
spinlock_release(&listlock);
|
||||
MUTEX_RELEASE(&listlock);
|
||||
|
||||
mounton->vfsmounted = vfs;
|
||||
vfs->nodecovered = mounton;
|
||||
|
||||
@@ -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
|
||||
@@ -21,7 +21,7 @@ typedef struct {
|
||||
} timekeeper_source_t;
|
||||
|
||||
// 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
|
||||
void timekeeper_init(void);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <arch/cpu.h>
|
||||
#include <util.h>
|
||||
|
||||
void arch_early_log(char c);
|
||||
void _putchar(char c);
|
||||
void logging_sethook(void (*fun)(char));
|
||||
void logging_init();
|
||||
|
||||
@@ -117,6 +117,6 @@ static inline void cpu_set(cpu_t *ptr) {
|
||||
wrmsr(MSR_GSBASE, (uint64_t)ptr);
|
||||
}
|
||||
|
||||
void cpu_initstate();
|
||||
void arch_cpu_init();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,12 +7,15 @@
|
||||
#include <uacpi/event.h>
|
||||
#include <kernel/acpi.h>
|
||||
#include <kernel/interrupt.h>
|
||||
#include <kernel/init.h>
|
||||
#include <logging.h>
|
||||
|
||||
void acpi_early_init(void) {
|
||||
__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)ctx;
|
||||
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);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(acpi, INIT_ROUTINE_FLAGS_NONE, acpi_init, pci, devfs, scheduler);
|
||||
|
||||
int acpi_poweroff(void) {
|
||||
uacpi_status ret = uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S5);
|
||||
if (uacpi_unlikely_error(ret)) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <arch/cpu.h>
|
||||
#include <errno.h>
|
||||
#include <kernel/block.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define CC_ENABLE(cc) cc = (cc) | 1
|
||||
#define CC_DISABLE(cc) cc = (cc) & ~1
|
||||
@@ -788,3 +789,5 @@ void nvme_init() {
|
||||
initcontroller(e);
|
||||
}
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(nvme, INIT_ROUTINE_FLAGS_NONE, nvme_init, acpi);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <termios.h>
|
||||
#include <kernel/poll.h>
|
||||
#include <kernel/tty.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static mutex_t writemutex;
|
||||
static thread_t *thread;
|
||||
@@ -124,3 +125,5 @@ void console_init() {
|
||||
tty->winsize.ws_xpixel = fbx;
|
||||
tty->winsize.ws_ypixel = fby;
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(console, INIT_ROUTINE_FLAGS_NONE, console_init, scheduler, keyboard);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <arch/cpu.h>
|
||||
#include <kernel/pmm.h>
|
||||
#include <kernel/usercopy.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
typedef struct bitfield_t {
|
||||
uint32_t offset;
|
||||
@@ -256,3 +257,5 @@ void fb_init() {
|
||||
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);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <hashtable.h>
|
||||
#include <kernel/poll.h>
|
||||
#include <kernel/usercopy.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define BUFFER_PACKET_CAPACITY 100
|
||||
#define BUFFER_SIZE (BUFFER_PACKET_CAPACITY * sizeof(kbpacket_t))
|
||||
@@ -252,3 +253,5 @@ void keyboard_init() {
|
||||
__assert(keyboard_console);
|
||||
__assert(hashtable_init(&kbtable, 20) == 0);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(keyboard, INIT_ROUTINE_FLAGS_NONE, keyboard_init, bsp_early);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <kernel/eth.h>
|
||||
#include <ringbuffer.h>
|
||||
#include <kernel/event.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define CACHE_TIMEOUT_SEC 300
|
||||
#define CACHE_TIMEOUT_MS (CACHE_TIMEOUT_SEC * 1000)
|
||||
@@ -315,3 +316,5 @@ void arp_init() {
|
||||
sched_queue(handlerthread);
|
||||
sched_queue(cleanupthread);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(arp, INIT_ROUTINE_FLAGS_NONE, arp_init, scheduler);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <mutex.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/abi.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
typedef struct {
|
||||
netdev_t *netdev;
|
||||
@@ -229,3 +230,5 @@ void ipv4_init() {
|
||||
__assert(routingtable);
|
||||
__assert(ipv4_addroute(loopback_device(), 0x7f000001, 0, 0xff000000, 10000) == 0);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(ipv4, INIT_ROUTINE_FLAGS_NONE, ipv4_init, devfs)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <kernel/net.h>
|
||||
#include <hashtable.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static netdev_t loopbacknetdev;
|
||||
|
||||
@@ -64,3 +65,5 @@ void loopback_init() {
|
||||
|
||||
__assert(netdev_register(&loopbacknetdev, "lo") == 0);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(loopback, INIT_ROUTINE_FLAGS_NONE, loopback_init, devfs);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <kernel/timekeeper.h>
|
||||
#include <kernel/interrupt.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define WORKER_COUNT 12
|
||||
#define WORKER_BUFFER_SIZE (64 * 1024)
|
||||
@@ -1879,3 +1880,5 @@ void tcp_init() {
|
||||
sched_queue(thread);
|
||||
}
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(tcp, INIT_ROUTINE_FLAGS_NONE, tcp_init, ipv4, scheduler);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <kernel/pci.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/vmm.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
uint8_t pci_read8(int bus, int device, int function, uint32_t offset) {
|
||||
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,6 +3,7 @@
|
||||
#include <string.h>
|
||||
#include <logging.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) {
|
||||
*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(&urandomops, "urandom", V_TYPE_CHDEV, DEV_MAJOR_URANDOM, 0, 0666, NULL) == 0);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(pseudo_devices, INIT_ROUTINE_FLAGS_NONE, pseudodevices_init, devfs);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <logging.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/usercopy.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define PTY_BUFFER 4096
|
||||
#define PTY_MAX 1024
|
||||
@@ -285,3 +286,5 @@ void pty_init() {
|
||||
__assert(devfs_createdir("pts") == 0);
|
||||
SPINLOCK_INIT(listlock);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(pty, INIT_ROUTINE_FLAGS_NONE, pty_init, tty);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
#include <kernel/pmm.h>
|
||||
#include <arch/mmu.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
extern volatile struct limine_framebuffer_request fb_liminereq;
|
||||
static size_t xs, ys, fbxs, fbys;
|
||||
@@ -66,3 +67,5 @@ void term_init() {
|
||||
|
||||
MUTEX_INIT(&term_mutex);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(term, INIT_ROUTINE_FLAGS_NONE, term_init, pmm);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/jobctl.h>
|
||||
#include <kernel/usercopy.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define TTY_MAX_COUNT 4096
|
||||
#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);
|
||||
MUTEX_INIT(&listmutex);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(tty, INIT_ROUTINE_FLAGS_NONE, tty_init, devfs);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <logging.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/pmm.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define VIRTIO_VENDOR 0x1af4
|
||||
#define VIRTIO_DEVICE_MIN 0x1000
|
||||
@@ -176,3 +177,5 @@ void virtio_init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(virtio, INIT_ROUTINE_FLAGS_NONE, virtio_init, acpi);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <kernel/slab.h>
|
||||
#include <logging.h>
|
||||
#include <string.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
// each allocation has the following structure:
|
||||
// ptr: data capacity (allocsizes size)
|
||||
@@ -96,3 +97,5 @@ void alloc_init() {
|
||||
for (int i = 0; i < 5; ++i)
|
||||
caches[i] = caches[5];
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(alloc, INIT_ROUTINE_FLAGS_NONE, alloc_init, vmm);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mutex.h>
|
||||
#include <util.h>
|
||||
#include <kernel/vmmcache.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
uintptr_t hhdmbase;
|
||||
static size_t memorysize;
|
||||
@@ -266,6 +267,11 @@ void pmm_init() {
|
||||
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
|
||||
|
||||
void *pmm_alloc(size_t size, int section) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string.h>
|
||||
#include <kernel/slab.h>
|
||||
#include <kernel/vmmcache.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size)
|
||||
|
||||
@@ -962,6 +963,8 @@ void vmm_init() {
|
||||
printspace(&kernelspace);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(vmm, INIT_ROUTINE_FLAGS_NONE, vmm_init, mmu);
|
||||
|
||||
void vmm_apinit() {
|
||||
vmm_switchcontext(&vmm_kernelctx);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <logging.h>
|
||||
#include <kernel/timekeeper.h>
|
||||
#include <kernel/event.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define TABLE_SIZE 4096
|
||||
#define WRITER_TICK_SECONDS 15
|
||||
@@ -475,3 +476,5 @@ void vmmcache_init() {
|
||||
EVENT_INITHEADER(&syncevent);
|
||||
EVENT_INITHEADER(&pagereadyevent);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(vmm_cache, INIT_ROUTINE_FLAGS_NONE, vmmcache_init, scheduler);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <kernel/auth.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
// default listeners for auth
|
||||
|
||||
@@ -285,3 +286,5 @@ void defaultauth_init() {
|
||||
auth_registerlistener(AUTH_SCOPE_PROCESS, process);
|
||||
auth_registerlistener(AUTH_SCOPE_NETWORK, network);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(default_auth, INIT_ROUTINE_FLAGS_NONE, defaultauth_init, bsp_early);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <kernel/cmdline.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <arch/smp.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
#define QUANTUM_US 100000
|
||||
#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);
|
||||
__assert(current_cpu()->reschedule_isr);
|
||||
|
||||
sched_target_cpu(current_cpu());
|
||||
|
||||
timer_insert(current_cpu()->timer, ¤t_cpu()->schedtimerentry, reschedule_timer_dpc, NULL, QUANTUM_US, true);
|
||||
// XXX move this resume to a more appropriate place
|
||||
timer_resume(current_cpu()->timer);
|
||||
}
|
||||
|
||||
INIT_ROUTINE_DEFINE(scheduler, INIT_ROUTINE_FLAGS_NONE, sched_init, arch_timer);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <mutex.h>
|
||||
#include <limine.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/init.h>
|
||||
|
||||
static volatile struct limine_boot_time_request timereq = {
|
||||
.id = LIMINE_BOOT_TIME_REQUEST,
|
||||
@@ -106,6 +107,8 @@ void timekeeper_sync(void) {
|
||||
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_end;
|
||||
|
||||
@@ -130,7 +133,7 @@ void timekeeper_wait_us(time_t us) {
|
||||
CPU_PAUSE();
|
||||
}
|
||||
|
||||
void timekeeper_early_init(time_t us_offset) {
|
||||
void timekeeper_early_init(void) {
|
||||
__assert(timereq.response);
|
||||
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 = 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",
|
||||
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
|
||||
// the initialization threads will not switch cpus so we dont have to worry about it here
|
||||
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",
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user