@ -40,7 +40,12 @@
@@ -40,7 +40,12 @@
# define LOAPIC_TIMER_CCR 0x390 /* Timer Current Count Reg */
# define LOAPIC_TIMER_CONFIG 0x3e0 /* Timer Divide Config Reg */
/* Local APIC Vector Table Bits */
# define LOAPIC_ICR_BUSY 0x00001000 /* delivery status: 1 = busy */
# define LOAPIC_ICR_IPI_OTHERS 0x000C4000U /* normal IPI to other CPUs */
# define LOAPIC_ICR_IPI_INIT 0x00004500U
# define LOAPIC_ICR_IPI_STARTUP 0x00004600U
# define LOAPIC_LVT_MASKED 0x00010000 /* mask */
# ifndef _ASMLANGUAGE
@ -137,6 +142,36 @@ static inline void x86_write_loapic(unsigned int reg, u32_t val)
@@ -137,6 +142,36 @@ static inline void x86_write_loapic(unsigned int reg, u32_t val)
# endif
}
/**
* @ brief Send an IPI .
*
* @ param apic_id If applicable , the target CPU APIC ID ( 0 otherwise ) .
* @ param ipi Type of IPI : one of the LOAPIC_ICR_IPI_ * constants .
* @ param vector If applicable , the target vector ( 0 otherwise ) .
*/
static inline void z_loapic_ipi ( u8_t apic_id , u32_t ipi , u8_t vector )
{
ipi | = vector ;
# ifndef CONFIG_X2APIC
/*
* Legacy xAPIC mode : first wait for any previous IPI to be delivered .
*/
while ( x86_read_xapic ( LOAPIC_ICRLO ) & LOAPIC_ICR_BUSY ) {
}
x86_write_xapic ( LOAPIC_ICRHI , apic_id < < 24 ) ;
x86_write_xapic ( LOAPIC_ICRLO , ipi ) ;
# else
/*
* x2APIC mode is greatly simplified : one write , no delivery status .
*/
x86_write_x2apic ( LOAPIC_ICRLO , ( ( ( u64_t ) apic_id ) < < 32 ) | ipi ) ;
# endif
}
# ifdef __cplusplus
}
# endif