Page 1 of 1

386+ CPU detection routine

Posted: Thu Oct 18, 2001 9:24 am
by Ogotay
First of all, I would like to say "Hello" to all of you, since I am new to this board and this is my first post :).

Now, on to the reason of my post: detecting at the boot time if we run on a machine with an intel 386 (or compatible) CPU or higher.

I found the following code in Till Gerken's Protected Mode Tutorial V0.02 (is there any newer out there? ;), which he uses for this purpose:

Code: Select all

<--- cut --->
proc      check_processor
      pushf                        ; save flags
      xor      ah,ah                  ; clear high byte
      push      ax                  ; push AX onto the stack
      popf                        ; pop this value into the flag register
      pushf                        ; push flags onto the stack
      pop      ax                  ; ...and get flags into AX
      and      ah,0f0h                  ; try to set the high nibble
      cmp      ah,0f0h                  ; the high nibble is never 0f0h on a
      je      no386                  ; 80386!
      mov      ah,70h                  ; now try to set NT and IOPL
      push      ax
      popf
      pushf
      pop      ax
      and      ah,70h                  ; if they couldn't be modified, there
      jz      no386                  ; is no 80386 installed
      popf                        ; restore the flags
      ret                        ; ...and return
no386:                              ; if there isn't a 80386, put a msg
      mov      dx,offset no386e      ; and exit
      jmp      err16exit
endp      check_processor
<--- cut --->
Now, studying the above code and overlooking one of the intel manuals I came up with the following code:

Code: Select all

    pushf
    
    mov ah, 0f0h
    push ax
    popf
    pushf
    pop ax

    popf

    cmp ah, 070h
    jz .386detected

    ; we land here if we do not detect a 386

.386detected:
    ; we land here if we detect a 386
It's shorter and should be aquivalent to Till's code.
It is to be placed in the boot sector on a diskette (or MBR if booting from a hard drive). Now, my problem is: is this code correct? It seems logical to me that it is correct, the problem is that all computers I can test this code on have at least a 386 CPU or higher, so no warranty that one would not get unexpected results on older CPUs...

Is there anybody who can confirm the correctness of my code, or is there something I am missing and why my code should not work properly? Thanks in advance.

Re: 386+ CPU detection routine

Posted: Thu Oct 18, 2001 9:50 am
by Ogotay
Just a small change to my previous code...

Code: Select all

   pushf
   
   mov ah, 0d0h              ;0f0h before
   push ax
   popf
   pushf
   pop ax

   popf

   cmp ah, 50h              ; 70h before
   jz .386detected

   ; we land here if we do not detect a 386

.386detected:
   ; we land here if we detect a 386
I think this one is slightly better (safer).
Explanation:

When we are booting, we are in Real Mode.

Now, if we would try to set the bits 12-15 of the EFLAGS register on a 8086 to the following bit pattern: 1101 ( = 0dh) the machine would set them back to 1111 ( = 0fh ). So a comparision with 0101 ( = 5h ) would fail.

A 286 CPU would clear the bits 12-15 in the EFLAGS register, so a comparision with 5h would fail, too.

Only in case of a 386 CPU the comparision would NOT fail, since in Real Mode the bit 15 in the EFLAGS register is always clear and the bits 12-14 keep the value last loaded into them (101).

I am pretty sure now, my modified method should work perfectly =)
Any comments? ;)

Re: 386+ CPU detection routine

Posted: Thu Oct 18, 2001 9:38 pm
by df
there is heaps of cpu detect routines, pretty much standardised.

i dont see the need for it in the bootsector, since it gets too crowded to go pmode + load a kernel from the BS (it can be done, i had one that did just that + read dos fat for kernel)..

better to move it all out to a 16bit 1st stage loader or something, then you can add stuff for cpuid, etc and better error handling, so on.

Re: 386+ CPU detection routine

Posted: Fri Oct 19, 2001 1:34 am
by Ogotay
Well, personally I do see a benefit of having a routine detecting if we run on a 32-bit machine, preferably at the beginning of the boot sector:

1. It's only few lines of code, and if we can detect early that the CPU does not meet the requirements of our OS, we do not need to proceed with loading the rest of our routines (1st stage loader, kernel...), since it is not necessary any more. The user knows earlier what's going on, and so we do (see 2).

2. We can start using 32-bit code with the extended instruction set already in the boot sector, and if we are smart we can directly load the 32-bit kernel without the need of a (16-bit) 1st stage loader, so we just removed a layer between the boot sector and the kernel.

What we gain at the end is speed.

The only drawback in my opinion is that we use few bytes more in the boot sector to detect the CPU type we are running on (and maybe few more if we want to display an error message if the CPU is not 32-bit). But there is always a trade off...

Re: 386+ CPU detection routine

Posted: Fri Oct 19, 2001 1:04 pm
by df
but thats just it. there is not enough room in the boot sector for all that and have meaningfull error messages, good error handling, etc, and as soon as you start using the 'extended' opcode set, you really blow out space in the bootsector.

Re: 386+ CPU detection routine

Posted: Sun Oct 21, 2001 3:36 am
by Ogotay
Yes, I know... but all I actually need to do in my boot sector is to check for a 32-bit CPU, switching to pmode and loading the kernel. There is enough space for it (I do not need to program a whole file and memory managament system at that point ;)).

Re: 386+ CPU detection routine

Posted: Fri Nov 02, 2001 9:05 am
by Peter_Vigren
There is plenty of room in the bootsector for that detection routine. The question IS (and have always been) wether or not the code works. So can you stop arguing about the plus' and the minuses about having the code in the bootsector and instead check if the code works???

(For the record, I agree with Ogotay.)

Re: 386+ CPU detection routine

Posted: Fri Nov 02, 2001 9:08 am
by Peter_Vigren
By the way... Both me and my brother thinks that the code SHOULD work but we haven't been able to test it... sorry!

Re:386+ CPU detection routine

Posted: Sat Jun 15, 2002 12:59 pm
by beyondsociety
Hi,

When I ran this code:

mov ah,0d0h
push ax
popf
pushf
pop ax
popf
cmp ah,070h
jz .386detected:

.386detected:

This made my computer lock up. I looked at the code and
I came up with this and it works:

xor ah,ah
push ax
popf
pushf
pop ax
cmp ah,0d0h
jz found

found:

mov si,found386


found386 db "386 CPU detected",13,10,0

I suggest you use this instead as it works on my machine but I don't know if it will work on yours. Test it out and email me back to tell me if it works.

email: [email protected]

Re:386+ CPU detection routine

Posted: Sat Jun 15, 2002 3:10 pm
by beyondsociety
Just one more thing about the cpu code. When I ran it as a .com file in nasm it made my computer go crazy, but if I use it in a bootsector, it works fine. It might just be my cpu or os, I don't really know. Tell me if you get the same problem.

Re:386+ CPU detection routine

Posted: Sun Jun 16, 2002 3:27 pm
by pete.piper
Ogotay: I believe the first part of Till's code (up until the first "je no386") is used to detect an 8086/8088; the second half detects a 286. Therefore, looking at your condensed code, it would appear that it would only produce the desired result on a 286 and report .386detected on an 8086/8088.

Please note that I haven't tested this myself (I don't have access to anything less than a 386) so take my advice with a grain of salt.

Pete