arch/x86: drivers/loapic_intr.c: move local APIC initialization
In the general case, the local APIC can't be treated as a normal device with a single boot-time initialization - on SMP systems, each CPU must initialize its own. Hence the initialization proper is separated from the device-driver initialization, and said initialization is called from the early startup-assembly code when appropriate. Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
parent
418e5c1b38
commit
a981f51fe6
4 changed files with 24 additions and 8 deletions
|
@ -235,6 +235,10 @@ __csSet:
|
||||||
#endif
|
#endif
|
||||||
lidt z_x86_idt /* load 32-bit operand size IDT */
|
lidt z_x86_idt /* load 32-bit operand size IDT */
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOAPIC
|
||||||
|
call z_loapic_enable
|
||||||
|
#endif
|
||||||
|
|
||||||
pushl %ebx /* pointer to multiboot info, or NULL */
|
pushl %ebx /* pointer to multiboot info, or NULL */
|
||||||
call z_x86_prep_c /* enter kernel; never returns */
|
call z_x86_prep_c /* enter kernel; never returns */
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,10 @@ __start:
|
||||||
xorl %edi, %edi
|
xorl %edi, %edi
|
||||||
call x86_sse_init
|
call x86_sse_init
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOAPIC
|
||||||
|
call z_loapic_enable
|
||||||
|
#endif
|
||||||
|
|
||||||
/* don't replace CALL with JMP; honor the ABI stack alignment! */
|
/* don't replace CALL with JMP; honor the ABI stack alignment! */
|
||||||
|
|
||||||
movl %ebx, %edi /* multiboot pointer (or NULL) */
|
movl %ebx, %edi /* multiboot pointer (or NULL) */
|
||||||
|
|
|
@ -66,18 +66,13 @@ static u32_t loapic_device_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief Enable and initialize the local APIC.
|
||||||
*
|
*
|
||||||
* @brief Initialize the Local APIC or xAPIC
|
* Called from early assembly layer (e.g., crt0.S).
|
||||||
*
|
|
||||||
* This routine initializes Local APIC or xAPIC.
|
|
||||||
*
|
|
||||||
* @return N/A
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int loapic_init(struct device *unused)
|
void z_loapic_enable(void)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(unused);
|
|
||||||
s32_t loApicMaxLvt; /* local APIC Max LVT */
|
s32_t loApicMaxLvt; /* local APIC Max LVT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -150,7 +145,19 @@ static int loapic_init(struct device *unused)
|
||||||
|
|
||||||
/* discard a pending interrupt if any */
|
/* discard a pending interrupt if any */
|
||||||
x86_write_loapic(LOAPIC_EOI, 0);
|
x86_write_loapic(LOAPIC_EOI, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Dummy initialization function.
|
||||||
|
*
|
||||||
|
* The local APIC is initialized via z_loapic_enable() long before the
|
||||||
|
* kernel runs through its device initializations, so this is unneeded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int loapic_init(struct device *unused)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(unused);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void z_loapic_enable(void);
|
||||||
extern void z_loapic_int_vec_set(unsigned int irq, unsigned int vector);
|
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_enable(unsigned int irq);
|
||||||
extern void z_loapic_irq_disable(unsigned int irq);
|
extern void z_loapic_irq_disable(unsigned int irq);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue