#ifndef FURIX_ARCH_X86_64_PERCPU_H #define FURIX_ARCH_X86_64_PERCPU_H #include /* * number of per-CPU slots. the array is indexed densely from 0, not by APIC * ID: an x2APIC MADT can report an ID far larger than the number of * processors, so the ID itself is not a usable index. 256 is also the largest * count the trampoline can carry, since it passes the slot in one byte. */ #define PERCPU_MAX_CPUS 256 /* per-AP stack; statically reserved until the buddy allocator exists */ #define PERCPU_STACK_SIZE 4096 /* bring up GS-based per-CPU data for the BSP */ void percpu_init(void); /* * point %gs at the per-CPU area for `slot`, recording `apic_id` as this CPU's * identity. used by the BSP once at boot and by each AP from its trampoline. * must not be called for APIC ID 0 before percpu_init(), since that is where the * BSP's swapgs lands. */ void percpu_attach(uint32_t apic_id, uint8_t slot); void percpu_set_id(uint32_t apic_id); /* this CPU's APIC ID, as recorded by percpu_attach() */ uint32_t percpu_apic_id(void); /* address of this CPU's per-CPU area */ uint64_t percpu_address(void); /* per-CPU area for a slot, for the AP trampolines */ uint64_t percpu_area(uint8_t slot); /* top of the stack for a slot, for the AP trampoline */ uint64_t percpu_stack_top(uint8_t slot); /* store a value through %gs:0 and read it back the same way */ uint64_t percpu_gs_selftest(uint64_t value); /* * same, but the read-back goes through the C variable, proving GS.base and the * compiler-generated access agree. */ uint64_t percpu_gs_selftest_via_c(uint64_t value); #endif /* FURIX_ARCH_X86_64_PERCPU_H */