Hi,
Code:
ORG 0x8000
BITS 16
mov eax,[0xFEE000F0]
For 16-bit code the assembler probably generates "mov eax,[0x00F0]" here. You should also get a "warning: word data exceeds bounds" error (if it's enabled). You'd need to use "mov eax,[dword 0xFEE000F0]" so that the assembler knows you want 32-bit addressing (instead of the default 16-bit addressing).
However, I assume you are in real mode (and not 16-bit protected mode with 4 GiB data segment limits), which means that "mov eax,[dword 0xFEE000F0]" will cause a general protection fault (due to exceeding the 64 KiB segment limit). If that's the case then you need to switch to protected mode (and I'd recommend switching to 32-bit protected mode, and not using 16-bit code).
Code:
or eax, 0000000100000000b
mov [0xFEE000F0],eax
When enabling the local APIC you have to set the "spurious vector" part too (and have a interrupt handler for it).
Note: I'd recommend using a "spurious vector" where the lowest 4 bits are set, for compatibility with older CPUs where these bits are hard-wired to 1s.Also the reserved bits should be cleared and not left as random/unknown. Essentially these 3 instructions should be "mov dword [dword 0xFEE000F0], 0x0000001?F" (where the ? is up to you).
Code:
mov eax, 0x000C4500
mov [0xFEE00300], eax
0x000C4500 translates into "INIT, physical destination, assert, all excluding self".
Do not use "all excluding self" - it sends the IPI to CPUs that were disabled (either because they were faulty or because hyper-threading was disabled) and causes problems on some machines. It also makes it impossible to detect when one of the CPUs fails to respond.
Code:
delay_EAX_microseconds:
pushall
mov ecx,eax
mov eax,100000
xor edx, edx
div ecx
mov ecx,eax
mov eax,1193182
xor edx, edx
div ecx
out 0x42,al
xchg al, ah
out 0x42,al
.T0: in al,0x61
test al,0x20
jz .T0
popall
ret
I have no idea what "pushall" and "popall" are. Maybe you meant "pusha" and "popa" and the assembler thought it was a label without a colon.
You're assuming the firmware left the PIT configured somehow. Some BIOSs use mode 2 ("square wave") and some use mode 2 ("rate generator"). If the BIOS was using mode 2 then channel 2 output may be high immediately. Also, I wouldn't be too surprised if the BIOS IRQ handlers are still running here; so when timer channel 2 output changes the BIOS timer IRQ handler starts and the bit you're testing (in IO port 0x61) may be clear again before you get a chance to test it (which can result in waiting forever).
Code:
ORG 0x9000
BITS 16
At this point, the AP CPU/s just started. They don't have a valid stack (and all APs are using the same default SS:SP because you broadcast the IPIs to all CPUs), now...
Code:
mov ah,0x0
mov al,0x3
int 0x10
..here we probably have 3 or more CPUs, all with the same (invalid) stack, all calling a BIOS function at the exact same time; even though the BIOS was not designed for multi-CPU and none of its functions are re-entrant(!).
Cheers,
Brendan