Page 1 of 1
EOI Seem To Be "Accepted" Randomly
Posted: Wed May 30, 2012 4:56 pm
by fifo
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 ?
Re: EOI Seem To Be "Accepted" Randomly
Posted: Wed May 30, 2012 8:11 pm
by Brendan
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
Re: EOI Seem To Be "Accepted" Randomly
Posted: Thu May 31, 2012 2:08 am
by fifo
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:
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();
}
I have tried to move arround the call to write to EOI without succcess.
Re: EOI Seem To Be "Accepted" Randomly
Posted: Thu May 31, 2012 2:21 am
by fifo
You were right about the volatile: now it works with:
Code: Select all
inline void Lapic_write(u32 offset, u32 value)
{
u32* volatile apicReg;
apicReg= ((u32* volatile)(apicAddress+offset));
*apicReg=value;
}
It's been a long time I did not bow.... but I have to do it now
Well done!!!