Skip to content
Permalink
Browse files

arch/x86: add x2APIC-aware accessors for local APIC access

MSRs related to x2APIC will never be accessed directly by name, but
rather via an offset from a base MSR, so the definitions are removed
from msr.h.

New local APIC accessor functions, which are sensitive to xAPIC vs
x2APIC mode (CONFIG_X2APIC), are added to include/drivers/loapic.h.
These accessors use the MSR definitions as modified above.

Signed-off-by: Charles E. Youse <charles.youse@intel.com>
  • Loading branch information...
Charles E. Youse authored and nashif committed Jun 6, 2019
1 parent f3611fd commit 53b370a7c618fd5e610201d128ddcecd95885462
Showing with 96 additions and 44 deletions.
  1. +10 −44 include/arch/x86/msr.h
  2. +86 −0 include/drivers/loapic.h
@@ -233,50 +233,16 @@
#define X86_VMX_TRUE_EXIT_CTLS_MSR 0x048f
#define X86_VMX_TRUE_ENTRY_CTLS_MSR 0x0490
#define X86_DS_AREA_MSR 0x0600
#define X86_EXT_XAPICID_MSR 0x0802
#define X86_EXT_XAPIC_VERSION_MSR 0x0803
#define X86_EXT_XAPIC_TPR_MSR 0x0808
#define X86_EXT_XAPIC_PPR_MSR 0x080a
#define X86_EXT_XAPIC_EOI_MSR 0x080d
#define X86_EXT_XAPIC_LDR_MSR 0x080c
#define X86_EXT_XAPIC_SIVR_MSR 0x080f
#define X86_EXT_XAPIC_ISR0_MSR 0x0810
#define X86_EXT_XAPIC_ISR1_MSR 0x0811
#define X86_EXT_XAPIC_ISR2_MSR 0x0812
#define X86_EXT_XAPIC_ISR3_MSR 0x0813
#define X86_EXT_XAPIC_ISR4_MSR 0x0814
#define X86_EXT_XAPIC_ISR5_MSR 0x0815
#define X86_EXT_XAPIC_ISR6_MSR 0x0816
#define X86_EXT_XAPIC_ISR7_MSR 0x0817
#define X86_EXT_XAPIC_TMR0_MSR 0x0818
#define X86_EXT_XAPIC_TMR1_MSR 0x0819
#define X86_EXT_XAPIC_TMR2_MSR 0x081a
#define X86_EXT_XAPIC_TMR3_MSR 0x081b
#define X86_EXT_XAPIC_TMR4_MSR 0x081c
#define X86_EXT_XAPIC_TMR5_MSR 0x081d
#define X86_EXT_XAPIC_TMR6_MSR 0x081e
#define X86_EXT_XAPIC_TMR7_MSR 0x081f
#define X86_EXT_XAPIC_IRR0_MSR 0x0820
#define X86_EXT_XAPIC_IRR1_MSR 0x0821
#define X86_EXT_XAPIC_IRR2_MSR 0x0822
#define X86_EXT_XAPIC_IRR3_MSR 0x0823
#define X86_EXT_XAPIC_IRR4_MSR 0x0824
#define X86_EXT_XAPIC_IRR5_MSR 0x0825
#define X86_EXT_XAPIC_IRR6_MSR 0x0826
#define X86_EXT_XAPIC_IRR7_MSR 0x0827
#define X86_EXT_XAPIC_ESR_MSR 0x0828
#define X86_EXT_XAPIC_LVT_CMCI_MSR 0x082f
#define X86_EXT_XAPIC_ICR_MSR 0x0830
#define X86_EXT_XAPIC_LVT_TIMER_MSR 0x0832
#define X86_EXT_XAPIC_LVT_THERMAL_MSR 0x0833
#define X86_EXT_XAPIC_LVT_PMI_MSR 0x0834
#define X86_EXT_XAPIC_LVT_LINT0_MSR 0x0835
#define X86_EXT_XAPIC_LVT_LINT1_MSR 0x0836
#define X86_EXT_XAPIC_LVT_ERROR_MSR 0x0837
#define X86_EXT_XAPIC_INIT_COUNT_MSR 0x0838
#define X86_EXT_XAPIC_CUR_COUNT_MSR 0x0839
#define X86_EXT_XAPIC_DIV_CONF_MSR 0x083e
#define X86_EXT_XAPIC_SELF_IPI_MSR 0x083f

/*
* MSRs 0x0800 to 0x0BFF are reserved for x2APIC access.
*
* We only record the base address here, as the local APIC code
* knows how to find the registers, see include/drivers/loapic.h.
*/

#define X86_X2APIC_BASE_MSR 0x0800

#define X86_EFER_MSR 0xc0000080
#define X86_STAR_MSR 0xc0000081
#define X86_LSTAR_MSR 0xc0000082
@@ -9,6 +9,9 @@
#ifndef ZEPHYR_INCLUDE_DRIVERS_LOAPIC_H_
#define ZEPHYR_INCLUDE_DRIVERS_LOAPIC_H_

#include <arch/x86/sys_io.h>
#include <arch/x86/msr.h>

#ifdef __cplusplus
extern "C" {
#endif
@@ -50,6 +53,89 @@ extern void z_loapic_int_vec_set(unsigned int irq, unsigned int vector);
extern void z_loapic_irq_enable(unsigned int irq);
extern void z_loapic_irq_disable(unsigned int irq);

/**
* @brief Read 64-bit value from the local APIC in x2APIC mode.
*
* @param reg the LOAPIC register number to read (LOAPIC_*)
*/
static inline u64_t x86_read_x2apic(unsigned int reg)
{
reg >>= 4;
return z_x86_msr_read(X86_X2APIC_BASE_MSR + reg);
}

/**
* @brief Read 32-bit value from the local APIC in xAPIC (MMIO) mode.
*
* @param reg the LOAPIC register number to read (LOAPIC_*)
*/
static inline u32_t x86_read_xapic(unsigned int reg)
{
return sys_read32(CONFIG_LOAPIC_BASE_ADDRESS + reg);
}

/**
* @brief Read value from the local APIC using the default mode.
*
* Returns a 32-bit value read from the local APIC, using the access
* method determined by CONFIG_X2APIC (either xAPIC or x2APIC). Note
* that 64-bit reads are only allowed in x2APIC mode and can only be
* done by calling x86_read_x2apic() directly. (This is intentional.)
*
* @param reg the LOAPIC register number to read (LOAPIC_*)
*/
static inline u32_t x86_read_loapic(unsigned int reg)
{
#ifdef CONFIG_X2APIC
return x86_read_x2apic(reg);
#else
return x86_read_xapic(reg);
#endif
}

/**
* @brief Write 64-bit value to the local APIC in x2APIC mode.
*
* @param reg the LOAPIC register number to write (one of LOAPIC_*)
* @param val 64-bit value to write
*/
static inline void x86_write_x2apic(unsigned int reg, u64_t val)
{
reg >>= 4;
z_x86_msr_write(X86_X2APIC_BASE_MSR + reg, val);
}

/**
* @brief Write 32-bit value to the local APIC in xAPIC (MMIO) mode.
*
* @param reg the LOAPIC register number to write (one of LOAPIC_*)
* @param val 32-bit value to write
*/
static inline void x86_write_xapic(unsigned int reg, u32_t val)
{
sys_write32(val, CONFIG_LOAPIC_BASE_ADDRESS + reg);
}

/**
* @brief Write 32-bit value to the local APIC using the default mode.
*
* Write a 32-bit value to the local APIC, using the access method
* determined by CONFIG_X2APIC (either xAPIC or x2APIC). Note that
* 64-bit writes are only available in x2APIC mode and can only be
* done by calling x86_write_x2apic() directly. (This is intentional.)
*
* @param reg the LOAPIC register number to write (one of LOAPIC_*)
* @param val 32-bit value to write
*/
static inline void x86_write_loapic(unsigned int reg, u32_t val)
{
#ifdef CONFIG_X2APIC
x86_write_x2apic(reg, val);
#else
x86_write_xapic(reg, val);
#endif
}

#if CONFIG_EOI_FORWARDING_BUG
extern void z_lakemont_eoi(void);
#endif

0 comments on commit 53b370a

Please sign in to comment.
You can’t perform that action at this time.