Problem with booting AP in SMP

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

Re: Problem with booting AP in SMP

Post by limp »

frank wrote:I don't see where you setup the temporary GDT. I would use the already booted processor to build a GDT and GDT_LOC at fixed addresses in memory, then just do a lgdt fixed_address. The way the code is setup now, you would have complications if you started more than 1 processor at a time. Also it might be a good idea to 16 byte align structures in memory that the CPU has to access.
Actually that is what I am doing

The GDT limit is at address 0x901C and the base at 0x901E
The GDT table is from 0x9004 to 0x901B

The code that I am using now is this:

Code: Select all

.globl  AP_startup_start
.globl  AP_startup_end
.globl  AP_flush
.equ    GDT_ADDRESS 0x901C

.text
.code16
AP_startup_start:
   cli

   xor %ax, %ax
   mov %ax, %ds
   mov %ax, %ss
   mov 0x100, %sp

   movb $0xFF,%al
   movb %al,(0x1000)

   /* Load temporary GDT */
   lgdt GDT_ADDRESS

   /* Switch to Protected Mode */
   mov %cr0,%eax
   inc %eax
   mov %eax,%cr0

   /* Jmp to AP_flush */
   ljmp $0x8, $(0x7000 + AP_flush - AP_startup_start)

/* If we get here just halt */
loop:
   hlt
   jmp     loop

.code32
AP_flush:
   mov $0x10, %eax
   mov %eax, %ds
   mov %eax, %es
   mov %eax, %fs
   mov %eax, %gs
   mov %eax, %ss

   /*For debugging*/
   movb $0x55,%al
   movb %al,(0x1000)
AP_startup_end:
When I run it as it is, the system restarts. If I remove the ljmp it doesn't restart. Any suggestions? I think I am doing the ljmp the right way.
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

Re: Problem with booting AP in SMP

Post by limp »

I am still trying to figure what's wrong but without any results so far.

When I am performing this long jump

Code: Select all

ljmp $0x8, $(0x7000 + AP_flush - AP_startup_start)
Bochs gives me that:

Code: Select all

(2).[193654005] [0x02103e20] 0008:0000000002103e20 (unk. ctxt): iretd
          ; cf
Next at t=193654010
(0) [0x00100f4f] 0008:100f4f (unk. ctxt): push ebp                  ; 55
(1) [0x0009f02c] 9f00:002c (unk. ctxt): jmp .+0xfffd (0xffff002b) ; ebfd
(2) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b         ; ea5be000f0
(3) [0x0009f02c] 9f00:002c (unk. ctxt): jmp .+0xfffd (0xffff002b) ; ebfd
So it seems that it jump to 0008:0000000002103e20. Hovewer, the AP_flush is at 0x7027 and the AP_startup_start at 0x7000 so it should jump at 0008:0000000000007027. Can anyone explain to me why it jumps there?


The output that I am getting from Bochs is the following:

Code: Select all

00160981520i[APIC2] Deliver INIT IPI
00160981520i[CPU2 ] cpu software reset
00160981520i[APIC2] allocate APIC id=2 (MMIO enabled) to 0xfee00000
00160981520i[CPU2 ] CPU[2] is an application processor. Halting until IPI.
00193121750i[APIC2] Deliver Start Up IPI
00193121750i[CPU2 ] CPU 2 started up at 0700:00000000 by APIC
00193654005e[CPU2 ] iret: return CS selector null
00193654005e[CPU2 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00193654005e[CPU2 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00193654005i[CPU2 ] CPU is in protected mode (active)
00193654005i[CPU2 ] CS.d_b = 32 bit
00193654005i[CPU2 ] SS.d_b = 32 bit
00193654005i[CPU2 ] EFER   = 0x00000000
00193654005i[CPU2 ] | RAX=0000000002000000  RBX=0000000000000000
00193654005i[CPU2 ] | RCX=0000000000000000  RDX=0000000000000f20
00193654005i[CPU2 ] | RSP=000000000000ec59  RBP=0000000000000000
00193654005i[CPU2 ] | RSI=0000000000000000  RDI=0000000000000000
00193654005i[CPU2 ] |  R8=0000000000000000   R9=0000000000000000
00193654005i[CPU2 ] | R10=0000000000000000  R11=0000000000000000
00193654005i[CPU2 ] | R12=0000000000000000  R13=0000000000000000
00193654005i[CPU2 ] | R14=0000000000000000  R15=0000000000000000
00193654005i[CPU2 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af pf cf
00193654005i[CPU2 ] | SEG selector     base    limit G D
00193654005i[CPU2 ] | SEG sltr(index|ti|rpl)     base    limit G D
00193654005i[CPU2 ] |  CS:0008( 0001| 0|  0) 00000000 ffffffff 1 1
00193654005i[CPU2 ] |  DS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00193654005i[CPU2 ] |  SS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00193654005i[CPU2 ] |  ES:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00193654005i[CPU2 ] |  FS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00193654005i[CPU2 ] |  GS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00193654005i[CPU2 ] |  MSR_FS_BASE:0000000000000000
00193654005i[CPU2 ] |  MSR_GS_BASE:0000000000000000
00193654005i[CPU2 ] | RIP=0000000002103e20 (0000000002103e20)
00193654005i[CPU2 ] | CR0=0x60000011 CR2=0x0000000000000000
00193654005i[CPU2 ] | CR3=0x00000000 CR4=0x00000000
00193654005e[CPU2 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00193654005i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00193654005i[CPU0 ] cpu hardware reset
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Re: Problem with booting AP in SMP

Post by frank »

Well as you can see in the bochs output the AP_flush function is running just fine, ie cs is set to 0x8 and ds, es, fs, gs are set to 0x10. I don't see a loop after the AP_Flush function so its possible its just running off into random memory and then finding a jump 0x200000 whatever some where. Put a loop after AP_Flush.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Problem with booting AP in SMP

Post by Combuster »

iret: return CS selector null
(...)
RSP=000000000000ec59
Did you forget to set up a stack somewhere?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply