#pragma once

#include <stdint.h>

typedef struct kernel_info {
    char *cmdline; // kernel commandline options (maybe split into char**'s?)
    uint64_t hhdmoffset; // HHDM offset
    uint64_t cpu_count; // number of cpus
    uint64_t usable_memory; // amount of usable memory the system has
    uint64_t bsp_id; // id of the bsp cpu
    int64_t boot_timestamp; // timestamp at boot
} kernel_info;

typedef char link_symbol_ptr[];

#define ALIGN_UP_MASK(x, mask)   (((x) + (mask)) & ~(mask))
#define ALIGN_UP(x, val)         ALIGN_UP_MASK(x, (typeof(x))(val) - 1)

#define ALIGN_DOWN_MASK(x, mask) ((x) & ~(mask))
#define ALIGN_DOWN(x, val)       ALIGN_DOWN_MASK(x, (typeof(x))(val) - 1)

#define IS_ALIGNED_MASK(x, mask) (((x) & (mask)) == 0)
#define IS_ALIGNED(x, val)       IS_ALIGNED_MASK(x, (typeof(x))(val) - 1)

#define PAGE_ROUND_UP(size)   ALIGN_UP(size, PAGE_SIZE)
#define PAGE_ROUND_DOWN(size) ALIGN_DOWN(size, PAGE_SIZE)

#define SIZE_IN_PAGES(size) size/PAGE_SIZE

struct kernel_info *get_kinfo();
void initialize_kinfo();
void kkill(void); // phase this out in favor of assert