I am getting inconsistent results acknowledging IPI by writing to EOI.
At startup, I clean the APIC as much as I can and check IRR and ISR are "empty".
run1: send 1000 IPI from one core to the other at 1 IPI per ms rate. All IPIs are logged properly on the other core.
run2: I send one IPI from one core to the other, the ISR write EOI and displays IRR and ISR: IRR is "empty" while ISR shows my vector still present.
I send a second IPI, it appears in IRR and of course nothing happens.
In a nut shell, EOI seem to be "accepted" randomly.
Additional info:
- runs on Nehalem 2 CPU, in 64 bits mode
- No other IRQs or IPIs are triggered (each vector has a specific count)
- LAPIC memory is Uncached (MTRR and page descriptor)
How can I investigate this case ?
EOI Seem To Be "Accepted" Randomly
Re: EOI Seem To Be "Accepted" Randomly
Hi,
Sounds like a bug (e.g. possibly a "forgot to put "volatile" in the right place/s" bug).
Could you post the code for the ISR, etc?
Cheers,
Brendan
Sounds like a bug (e.g. possibly a "forgot to put "volatile" in the right place/s" bug).
Could you post the code for the ISR, etc?
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: EOI Seem To Be "Accepted" Randomly
EDIT: If I add a 32000 pause instructions after writing to EOI register, it works well..
The ISR just "prints" on the serial port and account for the number of invocations.
code template for ISRs:
I have tried to move arround the call to write to EOI without succcess.
The ISR just "prints" on the serial port and account for the number of invocations.
code template for ISRs:
Code: Select all
void __##name##Gate(void) \
{ \
asm volatile("\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"cli\n\t" \
"movq %%r15, %%gs:8+128\n\t" \
"movq %%r14, %%gs:8+120\n\t" \
"movq %%r13, %%gs:8+112\n\t" \
"movq %%r12, %%gs:8+104\n\t" \
"movq %%r11, %%gs:8+96\n\t" \
"movq %%r10, %%gs:8+88\n\t" \
"movq %%r9, %%gs:8+80\n\t" \
"movq %%r8, %%gs:8+72\n\t" \
"movq %%rbp, %%gs:8+56\n\t" \
"movq %%rdi, %%gs:8+48\n\t" \
"movq %%rsi, %%gs:8+40\n\t" \
"movq %%rdx, %%gs:8+32\n\t" \
"movq %%rcx, %%gs:8+24\n\t" \
"movq %%rbx, %%gs:8+16\n\t" \
"movq %%rax, %%gs:8+8\n\t" \
"movq 0(%%rsp),%%rax\n\tmovq %%rax, %%gs:8+0\n\t" \
"movq 16(%%rsp),%%rax\n\tmovq %%rax, %%gs:8+136\n\t" \
"movq 24(%%rsp),%%rax\n\tmovq %%rax, %%gs:8+64\n\t" \
"movq %%rsp, %%rdi\n\t" \
"call %P1\n\t" \
"call %P0\n\t" \
"movq %%gs:8+64,%%rax\n\tmov %%rax, 24(%%rsp)\n\t" \
"movq %%gs:8+136,%%rax\n\tmov %%rax, 16(%%rsp)\n\t" \
"movq %%gs:8+0,%%rax\n\tmov %%rax, 0(%%rsp)\n\t" \
"movq %%gs:8+128, %%r15\n\t" \
"movq %%gs:8+120, %%r14\n\t" \
"movq %%gs:8+112, %%r13\n\t" \
"movq %%gs:8+104, %%r12\n\t" \
"movq %%gs:8+96, %%r11\n\t" \
"movq %%gs:8+88, %%r10\n\t" \
"movq %%gs:8+80, %%r9\n\t" \
"movq %%gs:8+72, %%r8\n\t" \
"movq %%gs:8+56, %%rbp\n\t" \
"movq %%gs:8+48, %%rdi\n\t" \
"movq %%gs:8+40, %%rsi\n\t" \
"movq %%gs:8+32, %%rdx\n\t" \
"movq %%gs:8+24, %%rcx\n\t" \
"movq %%gs:8+16, %%rbx\n\t" \
"movq %%gs:8+8, %%rax\n\t" \
"iretq\n\t" \
:\
: "i"(name), "i" (Lapic_signalEOI) \
); \
} \
Code: Select all
void Lapic_signalEOI(void)
{
int i;
Lapic_write(APIC_EOI, 0);
Processor_sfence();
for(i=0; i<32000; i++)
Processor_pause();
}
Re: EOI Seem To Be "Accepted" Randomly
You were right about the volatile: now it works with:
It's been a long time I did not bow.... but I have to do it now
Well done!!!
Code: Select all
inline void Lapic_write(u32 offset, u32 value)
{
u32* volatile apicReg;
apicReg= ((u32* volatile)(apicAddress+offset));
*apicReg=value;
}
Well done!!!