bzt wrote:1. is your code at 0x8000 compiled for 16 bits?
The given code is a hlt and a short jmp, those are mode independent.
bzt wrote:2. what happens if an AP receives an interrupt? Do you have a proper stack for the CPU? What about the IDT? Is the PIC masked properly?
PIC in multi-core mode? That's a recipe for disaster. But you might be on to something here. After an INIT IPI, the core should be in reset state, which means - if my manual is not mistaken - that the IDTR is set to a base address of 0 and a length limit of 64k. Given that the CPU is in real mode at that point, if an interrupt did occur, it would be vectored according to the IVT assumed present at 0. However, the very same manual also says that the flags register is initialized to a value of 2, so no interrupt flag is set. That leaves NMIs, tho. Is there a valid IVT present at address 0?
Try the following code. It should either work or tripple fault:
Code: Select all
ap_start_:
mov ax,cs
mov ss,ax
xor sp,sp
push word 0
push word 0
push word 0
lidt [sp]
popf
.loop:
hlt
jmp .loop
bzt wrote:3. I believe you should set bits 18-19 of ICR to 1. According to the docs, this means send interrupt to all cores except the current one, and this works for me.
I would strongly counsel against that. Sending a startup IPI to all nodes will send it to deactivated nodes as well. Sometimes they are deactivated for a reason. Sometimes cores are broken (remember tripple-core CPUs? Those were quad-core CPUs with one broken core), or maybe the user really wanted to disable cores for whatever reason (e.g. power, heat), or maybe in a hyperthreading system, the hyperthreading is broken and only one thread per core works (AMD's first foray into hyperthreading had a bit of a bumpy start).
Yeah, it'll work most of the time, but I work in the software industry, I know exactly how bad code can become before it will stop working most of the time.