furix
cute os
include/arch/x86_64/lapic.h
2054 bytes raw
1#ifndef FURIX_ARCH_X86_64_LAPIC_H
2#define FURIX_ARCH_X86_64_LAPIC_H
3
4#include <types.h>
5
6/* delivery modes in ICR bits 8..10 */
7#define LAPIC_IPI_FIXED 0x0
8#define LAPIC_IPI_INIT 0x5
9#define LAPIC_IPI_STARTUP 0x6
10
11/* ICR shorthand in bits 18..19 */
12#define LAPIC_DEST 0x0
13#define LAPIC_SHORTHAND_SELF 0x1
14#define LAPIC_SHORTHAND_ALL_EXCL 0x2
15#define LAPIC_SHORTHAND_ALL 0x3
16
17void lapic_enable(void);
18uint32_t lapic_base(void);
19uint32_t lapic_id(void);
20void lapic_eoi(void);
21
22/* wait until the last ICR write has been delivered (bounded) */
23bool lapic_ipi_wait(void);
24
25/*
26 * send an IPI and block until the LAPIC reports it delivered. synchronous by
27 * design, for INIT/SIPI and the self-IPI test; a message-passing API belongs
28 * on top of this rather than replacing it.
29 */
30uint32_t lapic_ipi_send(uint32_t delivery, uint32_t shorthand, uint32_t vector, uint32_t apic_id);
31
32/*
33 * as lapic_ipi_send but with explicit ICR bits 13..15 (`flags`), used for the
34 * INIT trigger bit that asserts and deasserts the reset level.
35 *
36 * every IPI entry point returns 0 on success and non-zero when the destination
37 * ID is beyond what the xAPIC ICR can address. callers MUST check it: the
38 * alternative is an INIT sent to processor 0, which resets the BSP.
39 */
40uint32_t lapic_ipi_send_flags(uint32_t delivery, uint32_t shorthand, uint32_t vector,
41 uint32_t apic_id, uint32_t flags);
42
43/*
44 * assert and deassert INIT for one processor. both halves are required: INIT is
45 * level-triggered, so the assert (ICR bit 14) holds the target in reset and
46 * only the deassert releases it to real mode at the reset vector, where it
47 * waits for a SIPI. a deassert alone leaves the processor running wherever it
48 * already was, so the SIPI has no held state to redirect.
49 */
50uint32_t lapic_ipi_init_assert(uint32_t apic_id);
51uint32_t lapic_ipi_init_deassert(uint32_t apic_id);
52
53/* startup-IPI, which releases a held processor at `vector << 12` */
54uint32_t lapic_ipi_sipi(uint32_t apic_id, uint8_t vector);
55
56#endif /* FURIX_ARCH_X86_64_LAPIC_H */