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 12BOOT_CODE bool_t x2apic_is_enabled(void); 13 14#ifdef CONFIG_X2APIC 15typedef 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 42static inline uint32_t apic_read_reg(apic_reg_t reg) 43{ 44 return x86_rdmsr_low(reg); 45} 46 47static inline void apic_write_reg(apic_reg_t reg, uint32_t val) 48{ 49 x86_wrmsr(reg, val); 50} 51 52static inline logical_id_t apic_get_logical_id(void) 53{ 54 return apic_read_reg(APIC_LOGICAL_DEST); 55} 56 57static inline word_t apic_get_cluster(logical_id_t logical_id) 58{ 59 return logical_id >> X2APIC_LDR_CLUSTER_SHIFT; 60} 61 62static 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