_cpuid() - full cpuid instruction wrapper
- the prototype changes to _cpuid(u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx) - this makes possible to use all the features of the cpuid instruction as described in the Intel specs
This commit is contained in:
		
							parent
							
								
									45eabea285
								
							
						
					
					
						commit
						80d671aea7
					
				@ -18,6 +18,9 @@
 | 
				
			|||||||
#define _CPUF_I386_SSE4_1	11
 | 
					#define _CPUF_I386_SSE4_1	11
 | 
				
			||||||
#define _CPUF_I386_SSE4_2	12
 | 
					#define _CPUF_I386_SSE4_2	12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _CPUF_I386_HTT		13	/* Supports HTT */
 | 
				
			||||||
 | 
					#define _CPUF_I386_HTT_MAX_NUM	14	/* Maximal num of threads */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_PROTOTYPE(int _cpufeature, (int featureno));
 | 
					_PROTOTYPE(int _cpufeature, (int featureno));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ _PROTOTYPE(void std_err, (char *_s));
 | 
				
			|||||||
_PROTOTYPE(void prints, (const char *_s, ...));
 | 
					_PROTOTYPE(void prints, (const char *_s, ...));
 | 
				
			||||||
_PROTOTYPE(int fsversion, (char *_dev, char *_prog));
 | 
					_PROTOTYPE(int fsversion, (char *_dev, char *_prog));
 | 
				
			||||||
_PROTOTYPE(int getprocessor, (void));
 | 
					_PROTOTYPE(int getprocessor, (void));
 | 
				
			||||||
_PROTOTYPE(void _cpuid, (u32_t eax_in, u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx));
 | 
					_PROTOTYPE(void _cpuid, (u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx));
 | 
				
			||||||
_PROTOTYPE(int load_mtab, (char *_prog_name));
 | 
					_PROTOTYPE(int load_mtab, (char *_prog_name));
 | 
				
			||||||
_PROTOTYPE(int rewrite_mtab, (char *_prog_name));
 | 
					_PROTOTYPE(int rewrite_mtab, (char *_prog_name));
 | 
				
			||||||
_PROTOTYPE(int get_mtab_entry, (char *_s1, char *_s2, char *_s3, char *_s4));
 | 
					_PROTOTYPE(int get_mtab_entry, (char *_s1, char *_s2, char *_s3, char *_s4));
 | 
				
			||||||
 | 
				
			|||||||
@ -75,6 +75,7 @@ sys/vm_i386.h
 | 
				
			|||||||
#define CPUID1_EDX_PGE 		(1L << 13)	/* Page Global (bit) Enable */
 | 
					#define CPUID1_EDX_PGE 		(1L << 13)	/* Page Global (bit) Enable */
 | 
				
			||||||
#define CPUID1_EDX_APIC_ON_CHIP (1L << 9)	/* APIC is present on the chip */
 | 
					#define CPUID1_EDX_APIC_ON_CHIP (1L << 9)	/* APIC is present on the chip */
 | 
				
			||||||
#define CPUID1_EDX_TSC		(1L << 4)	/* Timestamp counter present */
 | 
					#define CPUID1_EDX_TSC		(1L << 4)	/* Timestamp counter present */
 | 
				
			||||||
 | 
					#define CPUID1_EDX_HTT		(1L << 28)	/* Supports HTT */
 | 
				
			||||||
#define CPUID1_EDX_FXSR		(1L << 24)
 | 
					#define CPUID1_EDX_FXSR		(1L << 24)
 | 
				
			||||||
#define CPUID1_EDX_SSE		(1L << 25)
 | 
					#define CPUID1_EDX_SSE		(1L << 25)
 | 
				
			||||||
#define CPUID1_EDX_SSE2		(1L << 26)
 | 
					#define CPUID1_EDX_SSE2		(1L << 26)
 | 
				
			||||||
 | 
				
			|||||||
@ -6,57 +6,61 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int _cpufeature(int cpufeature)
 | 
					int _cpufeature(int cpufeature)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32_t cpuid_feature_edx = 0;
 | 
						u32_t eax, ebx, ecx, edx;
 | 
				
			||||||
	u32_t cpuid_feature_ecx = 0;
 | 
					 | 
				
			||||||
	int proc;
 | 
						int proc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						eax = ebx = ecx = edx = 0;
 | 
				
			||||||
	proc = getprocessor();
 | 
						proc = getprocessor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If processor supports CPUID and its CPUID supports enough
 | 
						/* If processor supports CPUID and its CPUID supports enough
 | 
				
			||||||
	 * parameters, retrieve EDX feature flags to test against.
 | 
						 * parameters, retrieve EDX feature flags to test against.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if(proc >= 586) {
 | 
						if(proc >= 586) {
 | 
				
			||||||
		u32_t params, a, b, c, d;
 | 
							eax = 0;
 | 
				
			||||||
		_cpuid(0, ¶ms, &b, &c, &d);
 | 
							_cpuid(&eax, &ebx, &ecx, &edx);
 | 
				
			||||||
		if(params > 0) {
 | 
							if(eax > 0) {
 | 
				
			||||||
			_cpuid(1, &a, &b, &cpuid_feature_ecx,
 | 
								eax = 1;
 | 
				
			||||||
					  &cpuid_feature_edx);
 | 
								_cpuid(&eax, &ebx, &ecx, &edx);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch(cpufeature) {
 | 
						switch(cpufeature) {
 | 
				
			||||||
		case _CPUF_I386_PSE:
 | 
							case _CPUF_I386_PSE:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_PSE;
 | 
								return edx & CPUID1_EDX_PSE;
 | 
				
			||||||
		case _CPUF_I386_PGE:
 | 
							case _CPUF_I386_PGE:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_PGE;
 | 
								return edx & CPUID1_EDX_PGE;
 | 
				
			||||||
		case _CPUF_I386_APIC_ON_CHIP:
 | 
							case _CPUF_I386_APIC_ON_CHIP:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_APIC_ON_CHIP;
 | 
								return edx & CPUID1_EDX_APIC_ON_CHIP;
 | 
				
			||||||
		case _CPUF_I386_TSC:
 | 
							case _CPUF_I386_TSC:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_TSC;
 | 
								return edx & CPUID1_EDX_TSC;
 | 
				
			||||||
		case _CPUF_I386_FPU:
 | 
							case _CPUF_I386_FPU:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_FPU;
 | 
								return edx & CPUID1_EDX_FPU;
 | 
				
			||||||
		case _CPUF_I386_SSEx:
 | 
							case _CPUF_I386_SSEx:
 | 
				
			||||||
			return (cpuid_feature_edx & (CPUID1_EDX_FXSR |
 | 
								return (edx & (CPUID1_EDX_FXSR |
 | 
				
			||||||
						     CPUID1_EDX_SSE |
 | 
										CPUID1_EDX_SSE |
 | 
				
			||||||
						     CPUID1_EDX_SSE2)) &&
 | 
										CPUID1_EDX_SSE2)) &&
 | 
				
			||||||
			       (cpuid_feature_ecx & (CPUID1_ECX_SSE3 |
 | 
										(ecx & (CPUID1_ECX_SSE3 |
 | 
				
			||||||
						     CPUID1_ECX_SSSE3 |
 | 
										CPUID1_ECX_SSSE3 |
 | 
				
			||||||
						     CPUID1_ECX_SSE4_1 |
 | 
										CPUID1_ECX_SSE4_1 |
 | 
				
			||||||
						     CPUID1_ECX_SSE4_2));
 | 
										CPUID1_ECX_SSE4_2));
 | 
				
			||||||
		case _CPUF_I386_FXSR:
 | 
							case _CPUF_I386_FXSR:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_FXSR;
 | 
								return edx & CPUID1_EDX_FXSR;
 | 
				
			||||||
		case _CPUF_I386_SSE:
 | 
							case _CPUF_I386_SSE:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_SSE;
 | 
								return edx & CPUID1_EDX_SSE;
 | 
				
			||||||
		case _CPUF_I386_SSE2:
 | 
							case _CPUF_I386_SSE2:
 | 
				
			||||||
			return cpuid_feature_edx & CPUID1_EDX_SSE2;
 | 
								return edx & CPUID1_EDX_SSE2;
 | 
				
			||||||
		case _CPUF_I386_SSE3:
 | 
							case _CPUF_I386_SSE3:
 | 
				
			||||||
			return cpuid_feature_ecx & CPUID1_ECX_SSE3;
 | 
								return ecx & CPUID1_ECX_SSE3;
 | 
				
			||||||
		case _CPUF_I386_SSSE3:
 | 
							case _CPUF_I386_SSSE3:
 | 
				
			||||||
			return cpuid_feature_ecx & CPUID1_ECX_SSSE3;
 | 
								return ecx & CPUID1_ECX_SSSE3;
 | 
				
			||||||
		case _CPUF_I386_SSE4_1:
 | 
							case _CPUF_I386_SSE4_1:
 | 
				
			||||||
			return cpuid_feature_ecx & CPUID1_ECX_SSE4_1;
 | 
								return ecx & CPUID1_ECX_SSE4_1;
 | 
				
			||||||
		case _CPUF_I386_SSE4_2:
 | 
							case _CPUF_I386_SSE4_2:
 | 
				
			||||||
			return cpuid_feature_ecx & CPUID1_ECX_SSE4_2;
 | 
								return ecx & CPUID1_ECX_SSE4_2;
 | 
				
			||||||
 | 
							case _CPUF_I386_HTT:
 | 
				
			||||||
 | 
								return edx & CPUID1_EDX_HTT;
 | 
				
			||||||
 | 
							case _CPUF_I386_HTT_MAX_NUM:
 | 
				
			||||||
 | 
								return (ebx >> 16) & 0xff;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -3,41 +3,38 @@
 | 
				
			|||||||
.sect .text; .sect .rom; .sect .data; .sect .bss
 | 
					.sect .text; .sect .rom; .sect .data; .sect .bss
 | 
				
			||||||
.sect .text
 | 
					.sect .text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! void _cpuid(u32_t eax, u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx);
 | 
					! void _cpuid(u32_t *eax, u32_t *ebx, u32_t *ecx, u32_t *edx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.define	__cpuid
 | 
					.define	__cpuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__cpuid:
 | 
					__cpuid:
 | 
				
			||||||
 | 
						! save registers
 | 
				
			||||||
	push	ebp
 | 
						push	ebp
 | 
				
			||||||
 | 
					 | 
				
			||||||
	mov	ebp, esp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	! save work registers
 | 
					 | 
				
			||||||
	push	eax
 | 
					 | 
				
			||||||
	push	ebx
 | 
						push	ebx
 | 
				
			||||||
	push	ecx
 | 
					 | 
				
			||||||
	push	edx
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	! set eax parameter to cpuid and execute cpuid
 | 
						! set parameters to cpuid and execute cpuid
 | 
				
			||||||
	mov	eax,  24(esp)
 | 
						mov	ebp,  12(esp)
 | 
				
			||||||
 | 
						mov	eax, (ebp)
 | 
				
			||||||
 | 
						mov	ebp,  16(esp)
 | 
				
			||||||
 | 
						mov	ebx, (ebp)
 | 
				
			||||||
 | 
						mov	ebp,  20(esp)
 | 
				
			||||||
 | 
						mov	ecx, (ebp)
 | 
				
			||||||
 | 
						mov	ebp,  24(esp)
 | 
				
			||||||
 | 
						mov	edx, (ebp)
 | 
				
			||||||
	.data1	0x0F, 0xA2	! CPUID
 | 
						.data1	0x0F, 0xA2	! CPUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	! store results in pointer arguments
 | 
						! store results in pointer arguments
 | 
				
			||||||
	mov	ebp, 28(esp)
 | 
						mov	ebp, 12(esp)
 | 
				
			||||||
	mov	(ebp), eax
 | 
						mov	(ebp), eax
 | 
				
			||||||
	mov	ebp, 32(esp)
 | 
						mov	ebp, 16(esp)
 | 
				
			||||||
	mov	(ebp), ebx
 | 
						mov	(ebp), ebx
 | 
				
			||||||
	mov	ebp, 36(esp)
 | 
						mov	ebp, 20(esp)
 | 
				
			||||||
	mov	(ebp), ecx
 | 
						mov	(ebp), ecx
 | 
				
			||||||
	mov	ebp, 40(esp)
 | 
						mov	ebp, 24(esp)
 | 
				
			||||||
	mov	(ebp), edx
 | 
						mov	(ebp), edx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	! restore registers
 | 
						! restore registers
 | 
				
			||||||
	pop	edx
 | 
					 | 
				
			||||||
	pop	ecx
 | 
					 | 
				
			||||||
	pop	ebx
 | 
						pop	ebx
 | 
				
			||||||
	pop	eax
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pop	ebp
 | 
						pop	ebp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret
 | 
						ret
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user