furix
cute os
include/arch/x86_64/percpu.h
1642 bytes raw
1#ifndef FURIX_ARCH_X86_64_PERCPU_H
2#define FURIX_ARCH_X86_64_PERCPU_H
3
4#include <types.h>
5
6/*
7 * number of per-CPU slots. the array is indexed densely from 0, not by APIC
8 * ID: an x2APIC MADT can report an ID far larger than the number of
9 * processors, so the ID itself is not a usable index. 256 is also the largest
10 * count the trampoline can carry, since it passes the slot in one byte.
11 */
12#define PERCPU_MAX_CPUS 256
13
14/* per-AP stack; statically reserved until the buddy allocator exists */
15#define PERCPU_STACK_SIZE 4096
16
17/* bring up GS-based per-CPU data for the BSP */
18void percpu_init(void);
19
20/*
21 * point %gs at the per-CPU area for `slot`, recording `apic_id` as this CPU's
22 * identity. used by the BSP once at boot and by each AP from its trampoline.
23 * must not be called for APIC ID 0 before percpu_init(), since that is where the
24 * BSP's swapgs lands.
25 */
26void percpu_attach(uint32_t apic_id, uint8_t slot);
27
28void percpu_set_id(uint32_t apic_id);
29
30/* this CPU's APIC ID, as recorded by percpu_attach() */
31uint32_t percpu_apic_id(void);
32
33/* address of this CPU's per-CPU area */
34uint64_t percpu_address(void);
35
36/* per-CPU area for a slot, for the AP trampolines */
37uint64_t percpu_area(uint8_t slot);
38
39/* top of the stack for a slot, for the AP trampoline */
40uint64_t percpu_stack_top(uint8_t slot);
41
42/* store a value through %gs:0 and read it back the same way */
43uint64_t percpu_gs_selftest(uint64_t value);
44
45/*
46 * same, but the read-back goes through the C variable, proving GS.base and the
47 * compiler-generated access agree.
48 */
49uint64_t percpu_gs_selftest_via_c(uint64_t value);
50
51#endif /* FURIX_ARCH_X86_64_PERCPU_H */