The code to send IPI is like this:
Code: Select all
mov ecx, IA32_X2APIC_ICR (I'm sure the MSR address is right.)
mov edx, 0
mov eax, 0xC4500
wrmsr
nop
nop
nop
mov eax, 0xC4690
wrmsr
nop
nop
wrmsr
Code: Select all
mov ecx, IA32_X2APIC_ICR (I'm sure the MSR address is right.)
mov edx, 0
mov eax, 0xC4500
wrmsr
nop
nop
nop
mov eax, 0xC4690
wrmsr
nop
nop
wrmsr
How do you know if the CPUs started or not? For example, what if the CPUs did start but crashed soon after starting?Js2xxx wrote:I had let my OS loader enter long mode and I had also enabled X2APIC in a right way. I used VMware to run my OS loader, and I had set the number of CPU to 2. Now I sent INIT-SIPI-SIPI to the other processor. However, it wasn't effective - the screen kept quiet.
Real mode 9000h:0100h is not (32-bit physical) address 0x00090000, it's 0x00090100.Js2xxx wrote:Now I've corrected it already. Then I inserted 'EA 00 01 00 90' that means 'jmp 9000h:0100h' to address 0x90000, which is APs' start-up address. The address 9000h:0100h contains the code to initialize APs. But the CPU reset - APs received SIPI, but failed to execute the initial code. Is there something wrong? Or should I load another module for APs to execute?
Thanks for any help.
Code: Select all
mov byte [cs:0x0800],1 ;Set flag to tell BSP that the CPU did start
.wait:
cmp byte [cs:0x0800],2 ;Has BSP acknowledged that the CPU has started?
jne .wait ; no, wait until it does
mov eax,0x80000001 ;eax = value for CR0
mov bx,0x0010 ;bx = value for data segments
xor cx,cx ;cx = zero
mov edx,[cs:0x0804] ;edx = value to load into CR3
mov esp,[cs:0x0808] ;Set ESP to whatever address BSP allocated for this CPU's stack
lgdt [cs:0x0120] ;Load GDT
mov cr3,edx ;Load page directory
mov cr0,eax ;Enable protected mode and paging
mov ss,bx ;Set SS to "big flat data"
mov ds,bx ;Set DS to "big flat data"
mov es,bx ;Set ES to "big flat data"
mov fs,cx ;Set FS to "NULL"
mov gs,cx ;Set GS to "NULL"
jmp far [dword cs:0x0810] ;Jump to kernel's entry point