#ifndef _KERNEL_AMD64_SMP_H
#define _KERNEL_AMD64_SMP_H

#include <amd64/gdt.h>
#include <amd64/tss.h>
#include <aux/compiler.h>
#include <libk/rbtree.h>
#include <libk/std.h>
#include <proc/proc.h>

#define CPUS_MAX 32

struct cpu {
  /* for syscall instruction */
  uintptr_t syscall_user_stack;
  uintptr_t syscall_kernel_stack;
  struct cpu* self;
  volatile uint8_t kernel_stack[KSTACK_SIZE] ALIGNED (16);
  volatile uint8_t except_stack[KSTACK_SIZE] ALIGNED (16);
  volatile uint8_t irq_stack[KSTACK_SIZE] ALIGNED (16);
  volatile struct gdt_extended gdt ALIGNED (16);
  volatile struct tss tss;

  uint64_t lapic_ticks;
  uint32_t id;

  struct {
    uint64_t rflags;
    atomic_int nesting;
  } irq_ctx;

  spin_lock_t lock;

  struct rb_node_link* proc_run_q;
  struct proc* proc_current;
};

struct cpu* cpu_make (void);
struct cpu* cpu_get (void);
void cpu_request_sched (struct cpu* cpu);

#define thiscpu (cpu_get ())

#endif // _KERNEL_AMD64_SMP_H
