Identify this!

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.
Post Reply
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Identify this!

Post by Zacariaz »

I have finaly figured out what i wan't to do, and thats about it.

First step involves identifying the cpu (in real mode/boot time) but i haven't been able to find much on google.

Basicly i just wanted to ask if anyone knows of any good recourses.

Thanks

edit: You are probably thinking, what an idiot, just use the CPUID, but when reading the manual, allthough it doesn't state that it can't be used in real mode, it refers only to 32bit registers, so this is a bit confusing.
This was supposed to be a cool signature...
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:

Post by Combuster »

you can use 32-bit registers in real mode, thanks.
"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 ]
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post by Zacariaz »

If thats the fact that probably the reason i've had such a hard time with this. It's embaresing enough as it is but it doesn't really make sence, 16 bit real mode and 32 bit registers? There must be some limitations.
This was supposed to be a cool signature...
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Just the default size of the registers, and some details of the instruction set -- like the way SIB bytes are handled in opcodes.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
Zacariaz wrote:It's embaresing enough as it is but it doesn't really make sence, 16 bit real mode and 32 bit registers? There must be some limitations.
You can use 32-bit registers and 32-bit addressing in real mode, just like you can use 16-bit registers and 16-bit addressing in 32-bit protected mode. The limitations are that you need a CPU capable of operating on 32-bits (it won't work for 80286 or older CPUs) and (for 32-bit addressing in real mode) the segment limits are still 64 KB.

This means that (for e.g.) in real mode you can use an instruction like "lea eax,[ecx*4+edx]", even though the 16-bit version of the instruction (e.g. "lea ax,[cx*4+dx]") won't work (it's not a valid addressing mode for 16-bit code).

You may want code to determine if the CPU supports 32-bit registers, etc. Here's some:

Code: Select all

;The first step is to find out if the CPU is an original 8086. This is necessary
;because the other tests will crash an 8086. This test simply determines
;if bit 15 of the flags register is set, as this bit is hardwired to 1
;on an 8086 and hardwired to 0 on everything after it.

	cli
	pushf
	pop ax				;ax = original flags
	test ah,0x80			;Is bit 15 set?
	jne .CPUold			; yes, old 8086!

;The next step is to find out if the CPU is 32 bit (80386 or later). This
;test just checks to see if the IOPL bits (bits 12 and 13) can be changed.
;On CPUs that don't support 32 bit protected mode these bits aren't
;implemented in the CPU.

	xor ah,0x30			;ax = flags with modified IOPL bits
	push ax				;Save flags
	popf				;Load flags
	pushf				;Save modified flags
	pop bx				;bx = modified flags
	xor ax,bx			;ax = flags with changed bits set
	test ah,0x30			;Did IOPL bits change?
	jne .CPUold			; no, not a 32 bit CPU

	CPU 386

;Make sure ESP is the same as SP.

	movzx esp,sp

;Now we know that the CPU is at least an 80386, so we can use
;eflags (the 32 bit version of the flags register) to see if it's
;an 80486 or later. Here we see if the bit that enables/disables
;the alignment check feature can be modified. Alignment check
;didn't exist before 80486, so this bit can't be changed on
;older CPUs.

	pushfd
	mov eax,[esp]			;eax = original eflags
	xor eax,0x00040000		;Invert AC flag
	push eax			;Store new eflags on stack
	popfd				;Read new eflags
	pushfd				;Store modified eflags
	pop ebx				;ebx = flags after changing
	xor eax,ebx			;If bits changed set them, else clear them
	popfd				;Restore original eflags
	test eax,0x40000		;Is alignment check supported?
	jne .CPUold			; no, must be older than an 80486

;After all that we know BCOS will be able to run on the CPU. We restore
;eflags to a known state and return.

	push dword 0x00000202		;Push default eflags (interrupts & reserved bit)
	popfd
	ret


;Error Handler
;_______________________________________________________________________________

;This little bit of code is responsible for displaying the "Your
;CPU is too old" error message and halting.

.CPUold:
	sti
	mov si,badCPUstring
	jmp abortBoot
The next step would be to determine if the CPUID instruction is supported or not. For this I setup an invalid opcode exception and execute CPUID to see if I get an invalid opcode exception or not. The normal method recommended by Intel (checking if the ID bit in EFLAGS can be modified) doesn't work on some CPUs (some CPUs, e.g. NexGen, support CPUID but don't support the ID bit in EFLAGS).

Also, for some CPUs (e.g. Cyrix) the CPUID instruction needs to be enabled before it's used, so if CPUID isn't supported you'd check if the CPU might be a Cyrix (using the "5/2" method) and then determine if it's an IBM "Blue Lightning" or a Cyrix (the IBM "Blue Lightning" chip supports MSRs while Cyrix chips don't).

If it is a Cyrix there's I/O ports to mess with. These I/O ports can return the "Cyrix CPU identification" information and (for later Cyrix CPUs) the I/O ports can also enable the CPUID instruction (and do other things).

In general, how much hassle CPU identification is will depend on which CPUs you support (e.g. it's easier if you don't support Pentium or older CPUs) and if you want high quality code or "average" code... ;)

IMHO at a minimum you need a reliable set of feature flags to determine if the CPU/s support a certain feature or not. This means getting the dodgy feature flags from CPUID and correcting them.


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.
Post Reply