diff --git a/arch/x86/include/kernel_arch_func.h b/arch/x86/include/kernel_arch_func.h index ff38432f982..b64f9bfd9cc 100644 --- a/arch/x86/include/kernel_arch_func.h +++ b/arch/x86/include/kernel_arch_func.h @@ -69,6 +69,20 @@ extern void k_cpu_atomic_idle(unsigned int imask); extern void _MsrWrite(unsigned int msr, u64_t msrData); extern u64_t _MsrRead(unsigned int msr); +#ifdef CONFIG_JAILHOUSE_X2APIC +#define MSR_X2APIC_BASE 0x00000800 + +static inline u32_t read_x2apic(unsigned int reg) +{ + return _MsrRead(MSR_X2APIC_BASE + reg); +} + +static inline void write_x2apic(unsigned int reg, u32_t val) +{ + _MsrWrite(MSR_X2APIC_BASE + reg, val); +} +#endif + /* * _IntLibInit() is called from the non-arch specific function, * prepare_multithreading(). The IA-32 kernel does not require any special diff --git a/drivers/interrupt_controller/loapic_intr.c b/drivers/interrupt_controller/loapic_intr.c index c6902f20827..743eab2832f 100644 --- a/drivers/interrupt_controller/loapic_intr.c +++ b/drivers/interrupt_controller/loapic_intr.c @@ -78,6 +78,7 @@ */ #include +#include #include #include #include @@ -190,12 +191,20 @@ static u32_t loapic_device_power_state = DEVICE_PM_ACTIVE_STATE; static ALWAYS_INLINE u32_t LOAPIC_READ(mem_addr_t addr) { +#ifndef CONFIG_JAILHOUSE_X2APIC return sys_read32(CONFIG_LOAPIC_BASE_ADDRESS + addr); +#else + return read_x2apic(addr >> 4); +#endif } static ALWAYS_INLINE void LOAPIC_WRITE(mem_addr_t addr, u32_t data) { +#ifndef CONFIG_JAILHOUSE_X2APIC sys_write32(data, CONFIG_LOAPIC_BASE_ADDRESS + addr); +#else + write_x2apic(addr >> 4, data); +#endif } /** @@ -219,7 +228,10 @@ static int _loapic_init(struct device *unused) /* reset the DFR, TPR, TIMER_CONFIG, and TIMER_ICR */ + /* Jailhouse does not allow writes to DFR in x2APIC mode */ +#ifndef CONFIG_JAILHOUSE_X2APIC LOAPIC_WRITE(LOAPIC_DFR, 0xffffffff); +#endif LOAPIC_WRITE(LOAPIC_TPR, 0x0); LOAPIC_WRITE(LOAPIC_TIMER_CONFIG, 0x0); diff --git a/drivers/timer/loapic_timer.c b/drivers/timer/loapic_timer.c index ecf2978dd66..ad66487b743 100644 --- a/drivers/timer/loapic_timer.c +++ b/drivers/timer/loapic_timer.c @@ -150,6 +150,13 @@ static u32_t reg_timer_cfg_save; #endif #endif +#ifdef CONFIG_JAILHOUSE_X2APIC +void _jailhouse_eoi(void) +{ + write_x2apic(LOAPIC_EOI >> 4, 0); +} +#endif + /** * * @brief Set the timer for periodic mode @@ -160,7 +167,12 @@ static u32_t reg_timer_cfg_save; */ static inline void periodic_mode_set(void) { +#ifndef CONFIG_JAILHOUSE_X2APIC *_REG_TIMER |= LOAPIC_TIMER_PERIODIC; +#else + write_x2apic(LOAPIC_TIMER >> 4, + read_x2apic(LOAPIC_TIMER >> 4) | LOAPIC_TIMER_PERIODIC); +#endif } @@ -176,7 +188,11 @@ static inline void periodic_mode_set(void) */ static inline void initial_count_register_set(u32_t count) { +#ifndef CONFIG_JAILHOUSE_X2APIC *_REG_TIMER_ICR = count; +#else + write_x2apic(LOAPIC_TIMER_ICR >> 4, count); +#endif } #if defined(CONFIG_TICKLESS_IDLE) @@ -207,7 +223,13 @@ static inline void one_shot_mode_set(void) #ifndef CONFIG_MVIC static inline void divide_configuration_register_set(void) { +#ifndef CONFIG_JAILHOUSE_X2APIC *_REG_TIMER_CFG = (*_REG_TIMER_CFG & ~0xf) | LOAPIC_TIMER_DIVBY_1; +#else + write_x2apic(LOAPIC_TIMER_CONFIG >> 4, + (read_x2apic(LOAPIC_TIMER_CONFIG >> 4) & ~0xf) + | LOAPIC_TIMER_DIVBY_1); +#endif } #endif @@ -223,7 +245,11 @@ static inline void divide_configuration_register_set(void) */ static inline u32_t current_count_register_get(void) { +#ifndef CONFIG_JAILHOUSE_X2APIC return *_REG_TIMER_CCR; +#else + return read_x2apic(LOAPIC_TIMER_CCR >> 4); +#endif } #if defined(CONFIG_TICKLESS_IDLE) diff --git a/include/drivers/sysapic.h b/include/drivers/sysapic.h index e6cf6425b8b..6264d740565 100644 --- a/include/drivers/sysapic.h +++ b/include/drivers/sysapic.h @@ -27,6 +27,10 @@ void __irq_controller_irq_config(unsigned int vector, unsigned int irq, int __irq_controller_isr_vector_get(void); +#ifdef CONFIG_JAILHOUSE_X2APIC +void _jailhouse_eoi(void); +#endif + static inline void __irq_controller_eoi(void) { #if CONFIG_EOI_FORWARDING_BUG @@ -44,9 +48,13 @@ static inline void __irq_controller_eoi(void) .endm #else .macro __irq_controller_eoi_macro +#ifdef CONFIG_JAILHOUSE_X2APIC + call _jailhouse_eoi +#else xorl %eax, %eax /* zeroes eax */ loapic_eoi_reg = (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) movl %eax, loapic_eoi_reg /* tell LOAPIC the IRQ is handled */ +#endif .endm #endif /* CONFIG_EOI_FORWARDING_BUG */