#ifndef KARLOS_CPU_H #define KARLOS_CPU_H #include #include /// Initializes bsp and jumps to `main()`. Does not return. __attribute__((noreturn)) void cpu_init_bsp(void); /// Initializes ap and jumps to `main()`. Does not return. Blocks until bsp is initialized. __attribute__((noreturn)) void cpu_init_ap(void); unsigned int cpu_get_core_id(void); void write_gs_base(uint64_t base); struct cpu_info { // first member of struct is pointer to itself, for easier loading struct cpu_info* cpu_info; volatile bool started; uint32_t APIC_ID; uint8_t ID; bool panicked; }; static inline struct cpu_info *local_cpu_data(void) { struct cpu_info *ptr; __asm__ ("mov %%gs:0, %0" : "=r" (ptr)); return ptr; } void interrupt_handler_register(unsigned int vector, void (*handler)(void)); /** Choose one of the 223 interrupt numbers available for Hardware IRQs. * This function is useful for drivers that can control the IRQ numbers they are assigned * (e.g. hardware using MSI, MSI-X or the IOAPIC). * Interrupt numbers are chosen based on a hash of the arguments given to the function. * This ensures evenly spread interrupt numbers, that are stable across * multiple boots, kernel changes, and different computers. */ unsigned int choose_irq_vector(const char *system_name, uint64_t instance_idx, uint64_t subinstance_idx); #endif