1 /*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7 #pragma once
8
9 #include <config.h>
10 #include <arch/machine.h>
11
12 BOOT_CODE bool_t x2apic_is_enabled(void);
13
14 #ifdef CONFIG_X2APIC
15 typedef enum _apic_reg_t {
16 APIC_ID = 0x802,
17 APIC_VERSION = 0x803,
18 APIC_TASK_PRIO = 0x808,
19 APIC_PROC_PRIO = 0x80A,
20 APIC_EOI = 0x80B,
21 APIC_LOGICAL_DEST = 0x80D,
22 APIC_SVR = 0x80F,
23 APIC_ISR_BASE = 0x810,
24 APIC_TMR_BASE = 0x818,
25 APIC_IRR_BASE = 0x820,
26 APIC_ERR_STATUS = 0x828,
27 APIC_ICR = 0x830,
28 APIC_LVT_TIMER = 0x832,
29 APIC_LVT_THERMAL = 0x833,
30 APIC_LVT_PERF_CNTR = 0x834,
31 APIC_LVT_LINT0 = 0x835,
32 APIC_LVT_LINT1 = 0x836,
33 APIC_LVT_ERROR = 0x837,
34 APIC_TIMER_COUNT = 0x838,
35 APIC_TIMER_CURRENT = 0x839,
36 APIC_TIMER_DIVIDE = 0x83E
37 } apic_reg_t;
38
39 #define X2APIC_LDR_CLUSTER_SHIFT 16
40 #define X2APIC_LDR_ID_MASK 16
41
apic_read_reg(apic_reg_t reg)42 static inline uint32_t apic_read_reg(apic_reg_t reg)
43 {
44 return x86_rdmsr_low(reg);
45 }
46
apic_write_reg(apic_reg_t reg,uint32_t val)47 static inline void apic_write_reg(apic_reg_t reg, uint32_t val)
48 {
49 x86_wrmsr(reg, val);
50 }
51
apic_get_logical_id(void)52 static inline logical_id_t apic_get_logical_id(void)
53 {
54 return apic_read_reg(APIC_LOGICAL_DEST);
55 }
56
apic_get_cluster(logical_id_t logical_id)57 static inline word_t apic_get_cluster(logical_id_t logical_id)
58 {
59 return logical_id >> X2APIC_LDR_CLUSTER_SHIFT;
60 }
61
apic_write_icr(word_t high,word_t low)62 static inline void apic_write_icr(word_t high, word_t low)
63 {
64 uint64_t icr = ((uint64_t)high << 32) | low;
65 x86_wrmsr(APIC_ICR, icr);
66 }
67
68 #define IPI_ICR_BARRIER asm volatile("mfence" ::: "memory")
69 #define IPI_MEM_BARRIER IPI_ICR_BARRIER
70 #endif /* CONFIG_X2APIC */
71