Page 1 of 2

Multi Processor Floating Pointer Structure

Posted: Mon Jan 05, 2009 7:15 pm
by mobruan
Hi, im trying to find this structure on memory.
I do the following code:

Code: Select all

start:

mov ax, word 0x0000
mov ds, ax

mov ax, word [0x40e]        ;looking at the extended bios area segment
mov ds, ax
mov bx, word 0x0000
mov cx, word 1024

l:
mov ax, word [bx]
cmp ax, 0x4D5F                    ;floating pointer structure signature
je find
add bx, 16
loop l

mov ax, word 0xf000               ; looking at the bios rom
mov ds, ax
mov cx, word 1024
mov bx, 0x0000

l2:
mov ax, word [bx]
cmp ax, 0x4D5F
je find
add bx, 16
loop l2

mov ax, word 0x9fc0                       ;looking at the top of system memory
mov ds, ax
mov cx, word 1024
mov bx, 0x0000

l3:
mov ax, word [bx]
cmp ax, 0x4D5F
je find
add bx, 16
loop l3

mov ah, 0x0e
mov al, 0x60
int 0x10
spin1: jmp spin1

find:
mov ax, word [bx+2]
cmp ax, 0x5F50                        ;;floating pointer structure signature(second part)
je find2
mov ah, 0x0e
mov al, 0x61
int 0x10
spin2: jmp spin2


find2:
mov ah, 0x0e
mov al, 0x62
int 0x10
spin3: jmp spin3


but it didnt find...any ideias?
Thanks

Re: Multi Processor Floating Pointer Structure

Posted: Mon Jan 05, 2009 7:53 pm
by mobruan
im testing on bochs.

Re: Multi Processor Floating Pointer Structure

Posted: Mon Jan 05, 2009 8:28 pm
by 01000101
have you taken a look at the MP Specs?

you need to scan 0xE0000-0xFFFFF and (unless I'm going further into blindness) don't see it in your code.
on almost all the systems I've ever ran MP detection on, the FPS was always in that range.

Re: Multi Processor Floating Pointer Structure

Posted: Mon Jan 05, 2009 8:35 pm
by mobruan
You are right...sorry!
thanks

Re: Multi Processor Floating Pointer Structure

Posted: Mon Jan 05, 2009 10:35 pm
by 01000101
also, just a quick last piece of advice (ignore if you already do this as I haven't really looked into your code).

make sure the resulting address is 16-byte aligned (bits 0-3 are 0) as I've heard of people finding phantom structures on non-aligned addresses and they will return incorrect information.

Re: Multi Processor Floating Pointer Structure

Posted: Wed Jan 07, 2009 8:12 am
by mobruan
Hi, apparently i find the structure.
Now, i want to know if exists a mp table. For this im looking at mp feature information byte 1. The spec says if the value = 0 the table exists. If the different from zero the number in this field represents the number of the default configuration. This number in the spec is from 1 to 7. The problem is that i didnt find a value in this range...here is the code.

Code: Select all

org 0x07c00

mp1 dw 0
mp2 dw 0
mp3 db 0
mp4 db 0


start:
bits 16

mov ax, word 0x0000
mov ds, ax

mov ax, word [0x40e]
mov ds, ax
mov bx, word 0x0000              ;looking at the ebda
mov cx, word 1024

l:
mov ax, word [bx]
cmp ax, 0x4D5F
je find
add bx, 16                      ;16 byte align
loop l

mov ah, 0x0e
mov al, 0x31                    ;breakpoint
int 0x10

mov ax, word 0x9fc0             ;looking at tthe top of system memory area 
mov ds, ax
mov cx, word 1024
mov bx, 0x0000

l2:
mov ax, word [bx]
cmp ax, 0x4D5F
je find
add bx, 16
loop l2

mov ah, 0x0e
mov al, 0x32                   ;breakpoint
int 0x10

mov ax, word 0xf000
mov ds, ax                     ;looking at bios rom
mov cx, word 65535
mov bx, 0x0000

l3:
mov ax, word [bx]
cmp ax, 0x4D5F
je find
add bx, 16
loop l3

mov ah, 0x0e
mov al, 0x33                   ;breakpoint
int 0x10

spin4: jmp spin4

find:
mov ax, word [bx+2]            ;check the second part of the structure signature
cmp ax, 0x5F50
je find2
mov ah, 0x0e
mov al, 0x61                   
int 0x10                       ;breakpoint
spin2: jmp spin2


find2:
mov ax, word [bx+4]                            ;pointer to the mp configuration table
mov [mp1], word ax
mov ax, word [bx+6]                            ;pointer to the table, second word 
mov [mp2], word ax
mov al, byte [bx+11]                            ;mp feature information byte 1
mov [mp3], al
mov al, byte [bx+12]                            ;mp feature byte 2
mov [mp4], al

mov cx, word 7
mov bl, byte 0
mov al, byte [mp3]
mov dl, byte 0x30

teste:
cmp al, byte bl                ;transform the mp config number in ascii
je numero
inc dl
inc bl
loop teste

numero:
mov ah, 0x0e
mov al, byte dl                ;print mp default configuration number on screen
int 0x10

mov ah, 0x0e
mov al, 0x63                   ;breakpoint
int 0x10


;******************hereafter is just to set the protected mode
mov ax, word 0x0000
mov ds, ax

cli

lgdt [gdt_addr]
mov eax, cr0
or eax, 0x01
mov cr0, eax
jmp 0x08:codigo



bits 32
codigo:

mov ax, word 0x10    
mov ds, word ax

lea eax, [isr]
mov [off1], ax
;mov [of1], ax
shr eax, 16
mov [off2], ax
;mov [of2], ax

lidt [idt_addr]

mov eax, [mp2]
shl eax, 16
mov ax, [mp1]




;sti

spin: jmp spin

isr:

mov [0xb8000], byte 0x61
mov [0xb8001], byte 0x0f

spin1: jmp spin1


bits 16

gdt_addr:
lim dw 31
base dd gdt

idt_addr:
limite dw end_idt - idt - 1
bas dd idt

gdt:

null dd 0
null2 dd 0

c_limite dw 0xffff
c_base dw 0x0000
c_base2 db 0x00
c_type db 0x98
c_limite2 db 0xcf
c_base3 db 0x00

d_limite dw 0xffff
d_base dw 0x0000
d_base2 db 0x00
d_type db 0x92
d_limite2 db 0xcf
d_base3 db 0x00

end_gdt:

idt:
times 66 dd 0

;of1 dw 0 
;sel dw 0x08 
;res db 0x00 
;mis db 0x8e 
;of2 dw 0

off1 dw 0 
seletor dw 0x08 
reserv db 0x00 
misc db 0x8e 
off2 dw 0
end_idt:

Re: Multi Processor Floating Pointer Structure

Posted: Wed Jan 07, 2009 9:11 am
by Brendan
Hi,
mobruan wrote:Hi, apparently i find the structure.
You probably do find the MP Floating Pointer Structure, but without checking the checksum you can't be entirely sure... ;)
mobruan wrote:Now, i want to know if exists a mp table. For this im looking at mp feature information byte 1. The spec says if the value = 0 the table exists. If the different from zero the number in this field represents the number of the default configuration. This number in the spec is from 1 to 7. The problem is that i didnt find a value in this range...here is the code.
For all modern computers there won't be a default configuration and MP Feature Information Byte 1 will be zero (and there will be an MP Configuration Table at the address given by the "Physical Address Pointer" field in the MP Floating Pointer Structure, which will be non-zero).

The reason for this is that the default configurations are obsolete and very restrictive - the IRQ usage must match, there must be 2 CPUs with APIC ID's 0 and 1, the buses must match (one ISA, one EISA, one MCA, one ISA and one PCI, one EISA and one PCI, or one MCA and one PCI), etc. Modern computers have several PCI buses (e.g. a tree of PCI sub-buses connected by "PCI to PCI bridges"), and AFAIK anything that supports ACPI needs to support the SCI IRQ; so both the IRQ usage and the buses won't/can't match any default configuration (for any desktop/server made in the last 10 years).

Basically, unless you want to support extremely rare multi-CPU 80486 and Pentium systems you can skip support for default configurations (e.g. refuse to boot if the MP Feature Information Byte 1 is non-zero). If you do want to add support for default configurations (now or later on), it's simple to add the data for seven MP Configuration Tables to your code, so that instead of using the "Physical Address Pointer" field in the MP Floating Pointer Structure to find the MP Configuration Table you'd use the default configuration number to get the address of the corresponding MP Configuration Table that was built into your code. Apart from that, everything else in your code remains unchanged (the rest of your code would just use the address of the MP Configuration Table without caring where this structure originally came from).


Cheers,

Brendan

Re: Multi Processor Floating Pointer Structure

Posted: Thu Jan 08, 2009 5:41 am
by worldsapart
Hi, guys...

I'm helping an OS developer to add SMP to his OS. I thought it would be a gud follow up to my Computer architecture background. So have been going through the MP specs and ACPI specs to learn abt Processor identification... I know many of you have worked in this area... I jus wanted to know, at which stage do u'll usually do the processor identification and AP bootup... bootloader stages or in the actual kernel... and is it possible to parse the memory to find the MP FP struct and MP config tables using C and inline assembly?? I dont have much of OS programming experience and could do with some insight... Sorry if I sound stupid... thanks...

David.

Re: Multi Processor Floating Pointer Structure

Posted: Thu Jan 08, 2009 6:33 am
by AJ
worldsapart wrote:I jus wanted to know, at which stage do u'll usually do the processor identification and AP bootup... bootloader stages or in the actual kernel...
Entirely up to you. As long as you have some way of telling the kernel what state the AP's are in, you could do this in the boot loader (which is what I'm doing, purely because it keeps most of my "run once" code in once place).

and is it possible to parse the memory to find the MP FP struct and MP config tables using C and inline assembly??
Absolutely - in fact, I just use C++ for this - no inline assembly. As long as you are parsing the correct memory areas aligned on the correct boundaries, you can do this. One thing to be careful of - if you are looking (for example) for a string such as "_MP_" and decide to do this by comparing with a 32 bit integer for speed, make sure you have the correct endianness.

Cheers,
Adam

Re: Multi Processor Floating Pointer Structure

Posted: Thu Jan 08, 2009 9:26 am
by mobruan
Hi, im re-writing the code, something was strange...the feature byte 1 was non-zero, but the mp table pointer was non-zero too.
I think i cant located the structure.
I try check it with the checksum, but im not sure if i done write. I did the following way:
add the values stored in all structure.
compare this value with the field checksum.
thanks

Re: Multi Processor Floating Pointer Structure

Posted: Thu Jan 08, 2009 10:18 am
by Brendan
Hi,
mobruan wrote:I try check it with the checksum, but im not sure if i done write. I did the following way:
add the values stored in all structure.
compare this value with the field checksum.
I think you're meant to add all bytes in the structure together (including the checksum byte) and see if the 8-bit result (ignoring overflow) is zero.


Cheers,

Brendan

Re: Multi Processor Floating Pointer Structure

Posted: Thu Jan 08, 2009 6:23 pm
by 01000101
Brendan is correct.

You need to do something like this:

Code: Select all

uint8_t checksum = 0;
for(i = 0; i < length_of_fps; i++)
{
    checksum += *(uint8_t*)(start_of_fps + i);
}
return checksum;
I'd suggest making that a seperate function instead of just adding that to your fps parsing. The next table will require you to checksum *every* structure, so it's handy to just have a function to do the checksumming.

You need to add all the bytes of the structure, including the checksum field, and if it == 0, it's good, else, it's an invalid checksum.

Re: Multi Processor Floating Pointer Structure

Posted: Fri Jan 09, 2009 6:25 am
by mobruan
Hi, i write this code before see the tip about the checksum function.
Im really with problems with it, i cant find the mp table.
I find the mp structure with its signature and checksum alright but when i try to read the mp table i cant find it, the signature doesnt match...please help.

Code: Select all

org 0x07c00

ba dw 0
t  dw 0

start:
bits 16

;mov ax, word 0x0000
;mov ds, ax

cli

lgdt [gdt_addr]
mov eax, cr0
or eax, 0x01
mov cr0, eax                          ;jump to pm mode
jmp 0x08:codigo



bits 32
codigo:

mov ax, word 0x10    
mov ds, word ax

;lea eax, [isr]
;mov [off1], ax
;mov [of1], ax
;shr eax, 16
;mov [off2], ax
;mov [of2], ax

;lidt [idt_addr]

mov bx, word [0x40e]        ;looking for mp structure at the ebda memory area
mov cx, word 1024

l:
mov eax, [bx]
cmp eax, 0x5F504D5F
je find
add bx, 16                      ;16 byte align
loop l

mov ebx, dword 0x0009FC00       ; looking the structure at system memory
mov cx, 1024

l2:
mov eax, dword [ebx]
cmp eax, 0x5F504D5F
je find
add bx, 16                      ;16 byte align
loop l2

mov ebx, dword 0x000F0000       ; looking at rom bios
mov cx, word 65535

l3:
mov eax, dword [ebx]
cmp eax, 0x5F504D5F
je find
add bx, 16                      ;16 byte align
loop l3

spin: jmp spin

find:

lea ax, [bx]                    ;stores the base address of the structure
mov [ba], ax

mov eax, dword 0
mov cx, 15
checksum:                       ;checksum
add al, byte [bx]
inc bx
loop checksum
cmp al, byte 0
jne spin2 

mov [0xb8000], byte 0x30        ;breakpoint for the checksum - its correct
mov [0xb8001], byte 0x0f        ;it prints a 0 on the screen

mov bx, word [ba]
mov eax, dword [bx+4]           ;checking the mp table signature
mov ecx, dword [eax]
cmp ecx, 0x504D4350
jne spin2


mov [0xb8000], byte 0x31        ;breakpoint for the signature - its incorrect
mov [0xb8001], byte 0x0f        ;it was to print a 1 on the screen if it fnds the signature


spin2: jmp spin2 

;***************************************hereafter is not important********************
mov al, byte [bx+11]
cmp al, byte 0
jne find

bits 16

gdt_addr:
lim dw end_gdt - gdt - 1
base dd gdt

gdt:

null dd 0
null2 dd 0

c_limite dw 0xffff
c_base dw 0x0000
c_base2 db 0x00
c_type db 0x98
c_limite2 db 0xcf
c_base3 db 0x00

d_limite dw 0xffff
d_base dw 0x0000
d_base2 db 0x00
d_type db 0x92
d_limite2 db 0xcf
d_base3 db 0x00

end_gdt:

thanks

Re: Multi Processor Floating Pointer Structure

Posted: Fri Jan 09, 2009 7:15 am
by Brendan
Hi,
mobruan wrote:Hi, i write this code before see the tip about the checksum function.
Im really with problems with it, i cant find the mp table.
I find the mp structure with its signature and checksum alright but when i try to read the mp table i cant find it, the signature doesnt match...please help.
There's plenty of bugs in the code you posted - I added comments in the code itself...

Code: Select all

org 0x07c00

;*** BIOS starts executing here, so the first instruction/s for your boot loader is "0x00, 0x00, 0x00, 0x00".
;    Try putting a "jmp 0x0000:start" before these (badly named) variables. ***

ba dw 0
t  dw 0

start:
bits 16

;mov ax, word 0x0000
;mov ds, ax

;*** Should uncomment the above 2 lines, otherwise the "lgdt" instruction below
;    could attempt to load a GDT from anywhere. An alternative may be to use
;    "lgdt [cs:gdt_addr]" so that the default segment register (DS) isn't used, but
;    that only works if you know that CS = 0x0000 (and isn't 0x07C0, for example) ***

cli

;*** First thing it does is switch to protected mode, just to make loading the
;    rest of the boot loader, or the second stage, or the kernel harder ***

lgdt [gdt_addr]
mov eax, cr0
or eax, 0x01
mov cr0, eax                          ;jump to pm mode
jmp 0x08:codigo



bits 32
codigo:

mov ax, word 0x10    
mov ds, word ax

;lea eax, [isr]
;mov [off1], ax
;mov [of1], ax
;shr eax, 16
;mov [off2], ax
;mov [of2], ax

;lidt [idt_addr]

mov bx, word [0x40e]        ;looking for mp structure at the ebda memory area
mov cx, word 1024

;*** Here, BX contains the real mode segment of the EBDA not the address of the EBDA ***

;*** Should only do this on systems that do have an EBDA ***

l:
mov eax, [bx]
cmp eax, 0x5F504D5F
je find
add bx, 16                      ;16 byte align
loop l

;*** This loop searches "16 * 1024" bytes at the wrong address for the MP signature. It
;    should only check 1024 bytes, and should use the address "EBDAsegment << 4". ***


mov ebx, dword 0x0009FC00       ; looking the structure at system memory
mov cx, 1024

;*** Should only do this on systems that don't have an EBDA ***

l2:
mov eax, dword [ebx]
cmp eax, 0x5F504D5F
je find
add bx, 16                      ;16 byte align
loop l2

;*** This loop searches "16 * 1024" bytes for the MP signature. It should only check 1024 bytes. ***


mov ebx, dword 0x000F0000       ; looking at rom bios
mov cx, word 65535

l3:
mov eax, dword [ebx]
cmp eax, 0x5F504D5F
je find
add bx, 16                      ;16 byte align
loop l3

;*** This loop searches "16 * 65535" bytes for the MP signature. It should only check 65536 bytes. ***

spin: jmp spin

find:

lea ax, [bx]                    ;stores the base address of the structure
mov [ba], ax

;*** "lea ax,[bx]" is the same as "mov ax,bx" and it's wrong, because the address
;    could easily be 0x000F1234 and you'd need a 32-bit register for that. ***

;*** If the checksum is wrong you should continue looking for the signature, not
;    just give up ***

mov eax, dword 0
mov cx, 15
checksum:                       ;checksum
add al, byte [bx]
inc bx
loop checksum
cmp al, byte 0
jne spin2 

;*** Same bug here - need to use a 32-bit address not a 16-bit address (e.g. "add al, [ebx]"). ***


mov [0xb8000], byte 0x30        ;breakpoint for the checksum - its correct
mov [0xb8001], byte 0x0f        ;it prints a 0 on the screen

;*** Assumes that the BIOS (or boot manager or whatever else may have been used to boot the
;    boot loader) has left the video in text mode. This isn't always the case - you should
;    make sure. ***


mov bx, word [ba]
mov eax, dword [bx+4]           ;checking the mp table signature
mov ecx, dword [eax]
cmp ecx, 0x504D4350
jne spin2

;*** Same bug here - need to use a 32-bit address not a 16-bit address (e.g. "mov ebx, dword [ba]"). ***

mov [0xb8000], byte 0x31        ;breakpoint for the signature - its incorrect
mov [0xb8001], byte 0x0f        ;it was to print a 1 on the screen if it fnds the signature


spin2: jmp spin2 

;***************************************hereafter is not important********************

Cheers,

Brendan

Re: Multi Processor Floating Pointer Structure

Posted: Fri Jan 09, 2009 9:22 am
by mobruan
Thanks...damned loop! :D