CPU Identification For OS Developers...
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Re:CPU Identification For OS Developers...
Wow, Thanks smiddy..
Also I'm releasing another patch, It includes some additional features for Intel CPU detection.
Brand Number and Information..
I had started this before but never finished it. :-*
Also I'm releasing another patch, It includes some additional features for Intel CPU detection.
Brand Number and Information..
I had started this before but never finished it. :-*
Re:CPU Identification For OS Developers...
No sweat! A cursory look at CPUID from http://www.sandple.org/ seems to have quite a few 64-bit CPUs there, along with a few obscure CPUs from other vendors than Intel and AMD.
Oh, it is also good to look at the manufactures website for hidden features associated with CPUID that only their processor does, if I recall right. It has been over a year since I last worked on my own CPUID routine.
;D
Oh, it is also good to look at the manufactures website for hidden features associated with CPUID that only their processor does, if I recall right. It has been over a year since I last worked on my own CPUID routine.
;D
- Combuster
- 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:CPU Identification For OS Developers...
Cyrixes are rare nowadays, and even i dont have one. so having it is pretty much a feature for nerds or scrooges. But then againg cyrix has had his share and there are probably still people trying to run someone's os on that platform.Brynet-Inc wrote: And is anyone at all interested in classic Cyrix CPU detection support?
The biggest problem with cyrix is that only the 6x86 series and later (which is only the MediaGX afaik) have cpuid support enabled by default. On other systems, you have to enable that via a set of MSRs, which would further limit the cpuid only detection to these two series. Basically you can only detect a third of the cyrix chips without additional asm-level code.
But then again, we are all crazy enough to be osdeving in the first place so why not
Re:CPU Identification For OS Developers...
Hi,
For other CPU manufacturers, VIA and Transmeta are still making/selling 80x86 compatible CPUs. Even though these products are more often used in embedded systems, they can be found in normal desktop/laptop systems too.
In general (IMHO), an OS designer has 4 choices:
Cheers,
Brendan
For "pentium compatible" CPUs, I've got about 3 Cyrix and 2 AMD...Combuster wrote:Cyrixes are rare nowadays, and even i dont have one. so having it is pretty much a feature for nerds or scrooges. But then againg cyrix has had his share and there are probably still people trying to run someone's os on that platform.Brynet-Inc wrote:And is anyone at all interested in classic Cyrix CPU detection support?
For other CPU manufacturers, VIA and Transmeta are still making/selling 80x86 compatible CPUs. Even though these products are more often used in embedded systems, they can be found in normal desktop/laptop systems too.
If you don't have special detection code for Cyrix chips, then some other software may have enabled CPUID on these chips (e.g. BIOS). In any case, your OS may crash because of un-detected bugs in these CPUs. For example, any attempt to access CR4 in a "pentium compatible" Cyrix chip causes an exception (can't remember if it's a general protection fault or an undefined opcde). If CPUID was enabled then some Cyrix chips return ECX = 'tead' when CPUID is used with eax = 1, which can cause the OS to think it supports all sorts of much more recent features - it corresponds to the following features: SSE3, Intel's hardware virtualisation (VMX), cache context ID, the CMPXCHG16B instruction and task priority disabling, and will also make a mess features added in the future.Combuster wrote:The biggest problem with cyrix is that only the 6x86 series and later (which is only the MediaGX afaik) have cpuid support enabled by default. On other systems, you have to enable that via a set of MSRs, which would further limit the cpuid only detection to these two series. Basically you can only detect a third of the cyrix chips without additional asm-level code.
But then again, we are all crazy enough to be osdeving in the first place so why not
In general (IMHO), an OS designer has 4 choices:
- - write unreliable software.
- never support any features that are detected via. CPUID
- never allow any code to use CPUID directly, except for your detection code, and try to fix all of the bugs within your detection code.
- create a list of exactly which CPUs your OS should work on, and make sure end-users check this list.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:CPU Identification For OS Developers...
Hi again,
While I'm at it, I thought it'd be a good idea to show how to detect these Cyrix chips...
The general steps would be to try CPUID first, and if it's not supported check if the CPU is a Cyrix, if it is a Cyrix try to enable the CPUID instruction and then try CPUID again.
Hopefully everyone knows how to detect if CPUID is supported (see if the "ID" flag in the eflags register can be modified), so I'll skip that.
I wrote this based on the what little documentation I could find (mostly an original IBM application note) and some information from Ralph Brown's Interrupt list concerning I/O ports 0x22 and 0x23. I've tested it on my machines (both Cyrix and non-Cyrix), and it *seems* to work perfectly...
Cheers,
Brendan
While I'm at it, I thought it'd be a good idea to show how to detect these Cyrix chips...
The general steps would be to try CPUID first, and if it's not supported check if the CPU is a Cyrix, if it is a Cyrix try to enable the CPUID instruction and then try CPUID again.
Hopefully everyone knows how to detect if CPUID is supported (see if the "ID" flag in the eflags register can be modified), so I'll skip that.
Code: Select all
;Check if CPU is a Cyrix with CPUID disabled.
;_______________________________________________________________________________
clr ax
sahf
mov ax,5
mov bx,2
div bl
lahf
cmp ah,2 ;Is it Cyrix?
jne .is486 ; no, must be 80486
;Cyrix Detected - Try To Enable CPUID
;_______________________________________________________________________________
;Preset CPU vendor string to 'CyrixInstead' in case CPUID not supported
mov dword [gs:edi+CPUdataStruct.vendorString],'Cyri'
mov dword [gs:edi+CPUdataStruct.vendorString+4],'xIns'
mov dword [gs:edi+CPUdataStruct.vendorString+8],'tead'
;Get processor ID
pushfd ;Save eflags
cli ;Disable interrupts
mov al,0xFE
out 0x22,al ;Address = device ID register 0
clr ebx
in al,0x23 ;al = device ID register 0
mov bh,al ;bh = device ID register 0
mov al,0xFF
out 0x22,al ;Address = device ID register 1
in al,0x23 ;al = device ID register 1
popfd ;Restore original eflags (and interrupts)
mov bl,al ;bh = device ID register 1
cmp bh,0x20 ;Is it a 486?
jb .oldCyrix ; yes, no CPUID anyway
;Try to enable CPUID
pushfd ;Save eflags
cli ;Disable interrupts
mov al,0xC3
out 0x22,al ;Address = config register 3
in al,0x23 ;al = config register 3
mov ch,0x0F ;ch = config register 3 mask
mov cl,al ;cl = original config register 3 contents
and ch,al
or ch,0x10
mov al,0xC3
out 0x22,al ;Address = config register 3
mov al,ch
out 0x23,al ;Set new config register 3 (enable config access)
mov al,0xE8
out 0x22,al ;Address = config register 4
mov ch,0x80 ;ch = CPUID enable bit
in al,0x23 ;al = current config register 4 contents
or ch,al ;ch = config register 4 with CPUID enable bit
mov al,0xE8
out 0x22,al ;Address = config register 4
mov al,ch ;al = config register 4 with CPUID enable bit
out 0x23,al ;Set CPUID enabled bit
mov al,bh ;al = device ID register 0
and al,0xF0
cmp al,0x30 ;Is it an early 6x86?
jne .not6x86 ; no
mov al,0xE9
out 0x22,al ;Address = config register 5
mov ch,0xFD ;ch = mask
in al,0x23 ;al = config register 5
and ch,al ;ch = fixed config register 5
mov al,0xE9
out 0x22,al ;Address = config register 5
mov al,ch ;al = fixed config register 5
out 0x23,al ;Set new config register 5 (attempt to fix CPU bug)
.not6x86:
mov al,0xC3
out 0x22,al ;Address = config register 3
mov al,cl
out 0x23,al ;Restore old config register 3 (disable config access)
;Recheck CPUID presence
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Re:CPU Identification For OS Developers...
Wow, I went through it this morning and noticed a few unused variables in the code, Cleaned up..
Thanks Smiddy/Brendan...
Those interested in Cyrix support for models MediaGX, 6x86, 6x86/MX or BXm..
A friend of mine sent me patches to support Cyrix chips, I don't have any so I can't verify this works so I'm not including it in the main file..
Declare int do_cyrix(void); at the top of the file..
In the detect_cpu() function add:
Then add the do_cyrix() function..
Thanks Smiddy/Brendan...
Those interested in Cyrix support for models MediaGX, 6x86, 6x86/MX or BXm..
A friend of mine sent me patches to support Cyrix chips, I don't have any so I can't verify this works so I'm not including it in the main file..
Declare int do_cyrix(void); at the top of the file..
In the detect_cpu() function add:
Code: Select all
case 0x69727943: /* Cyrix Magic Code */
do_cyrix();
break;
Code: Select all
int do_cyrix(void)
{
printf("Cyrix-specific functions:\n");
unsigned long eax, unused;
int model, family, stepping, reserved;
cpuid(1, eax, unused, unused, unused);
model = (eax >> 4) & 0xf;
family = (eax >> 8) & 0xf;
stepping = eax & 0xf;
reserved = eax >> 12;
printf("Family: %d Model: %d [", family, model);
switch(family)
{
case 4:
switch(model)
{
case 4:
printf("MediaGX");
break;
}
break;
case 5:
switch(model)
{
case 2:
printf("6x86");
break;
case 4:
printf("BXm");
break;
}
break;
case 6:
switch(model)
{
case 0:
printf("6x86/MX");
break;
}
break;
}
printf("Stepping %d\n", stepping);
printf("Reserved %d\n", reserved);
}
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
- chase
- Site Admin
- Posts: 710
- Joined: Wed Oct 20, 2004 10:46 pm
- Libera.chat IRC: chase_osdev
- Location: Texas
- Discord: chase/matt.heimer
- Contact:
How would you feel about moving this into the OSDev Wiki?
I just modified the wiki to support uploading of files.
I read though all of this thread and at some point everyone will need to agree on coding style/compilers/etc but thats a separate discussion that we'll start once a couple of more MT people have a chance to move over.
Little bit more on topic, I have a Transmeta system that I still use and I think I have some Cyrix 5x86 cpus and motherboards in a closet somewhere.
I just modified the wiki to support uploading of files.
I read though all of this thread and at some point everyone will need to agree on coding style/compilers/etc but thats a separate discussion that we'll start once a couple of more MT people have a chance to move over.
Little bit more on topic, I have a Transmeta system that I still use and I think I have some Cyrix 5x86 cpus and motherboards in a closet somewhere.
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Well if you wish to list this on the Wiki your welcome, I've never really done any Wiki stuff so I wouldn't know where to startchase wrote:How would you feel about moving this into the OSDev Wiki?
I just modified the wiki to support uploading of files.
I read though all of this thread and at some point everyone will need to agree on coding style/compilers/etc but thats a separate discussion that we'll start once a couple of more MT people have a chance to move over.
Little bit more on topic, I have a Transmeta system that I still use and I think I have some Cyrix 5x86 cpus and motherboards in a closet somewhere.
If your willing to check out Transmeta systems your more then welcome
Compile and run this on the Transmeta to find the Magic Code for dealing with that specific CPU manufacture.
Code: Select all
#include <stdio.h>
#define cpuid(in, a, b, c, d) asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
int main(void)
{
unsigned int ebx, unused;
cpuid(0, unused, ebx, unused, unused);
printf("0x%x\n", ebx);
return 0;
}
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Hey, I've updated CPUID, Including a few variables renames with more detailed names and also support for detecting the temperature sensing diode on a few AMD CPU's
I wrote this is for detecting the Maximum Physical and Linear Address Size on AMD CPU's..
I wrote this is for detecting the Maximum Physical and Linear Address Size on AMD CPU's..
Code: Select all
#include <stdio.h>
#define cpuid(in,a,b,c,d) asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
int main(void)
{
unsigned long unused, eax;
cpuid(0x80000008, eax, unused, unused, unused);
printf("Maximum Linear Address: %ld\n", (eax >> 8) & 0xff);
printf("Maximum Physical Address: %ld\n", eax & 0xff);
}
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Here's the patch I gave to Brynet for the Intel brand detection update. If anyone wants to just download this and apply it, it applies pretty easily with the command (after unzipping of course):
Code: Select all
patch -p0 -i cpudet-better_intel_brand_detection.patch cpudet-clean.c
- Attachments
-
- cpudet-better_intel_brand_detection.zip
- (1.51 KiB) Downloaded 275 times
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact: