David Lang wrote:
> 
> Jeff, the problem is not detecting the CPU type at runtime, the problem is
> trying to re-compile the code to take advantage of that CPU at runtime.
> 
> depending on what CPU you have the kernel (and compiler) can use different
> commands/opmizations/etc, if you want to do this on boot you have two
> options.
> 
> 1. re-compile the kernel
> 
> 2. change all the CPU specific places from inline code to function calls
> into a table that get changed at boot to point at the correct calls.

The macros would be a problem.  Some of the options, like MTRR, should
be auto-detected.

Jeff

> 
> doing #2 will cost you so much performance that you would be better off
> just compiling for a 386 and not going through the autodetect hassle in
> the first place.
> 
> David Lang
> 
>  On Tue, 7 Nov 2000, Jeff V. Merkey wrote:
> 
> > Date: Tue, 07 Nov 2000 16:10:58 -0700
> > From: Jeff V. Merkey <[EMAIL PROTECTED]>
> > To: [EMAIL PROTECTED]
> > Cc: Martin Josefsson <[EMAIL PROTECTED]>,
> >      Tigran Aivazian <[EMAIL PROTECTED]>, Anil kumar <[EMAIL PROTECTED]>,
> >      [EMAIL PROTECTED]
> > Subject: Re: Installing kernel 2.4
> >
> >
> > There are tests for all this in the feature flags for intel and
> > non-intel CPUs like AMD -- including MTRR settings.  All of this could
> > be dynamic.  Here's some code that does this, and it's similiar to
> > NetWare.  It detexts CPU type, feature flags, special instructions,
> > etc.  All of this on x86 could be dynamically detected.
> >
> > :-)
> >
> > ;*************************************************************************
> > ;
> > ;  check current processor type and state
> > ;
> > ;*************************************************************************
> >
> > public DetectProcessorInformation
> > DetectProcessorInformation proc near
> >
> >     mov   ax, cs
> >     mov   ds, ax
> >     mov   es, ax
> >
> >     pushf
> >     call  get_cpuid
> >     call  get_fpuid
> >     call  print
> >     popf
> >     ret
> >
> > DetectProcessorInformation endp
> >
> > get_cpuid proc near
> >
> > check_8086:
> >
> >     pushf
> >     pop   ax
> >     mov   cx, ax
> >     and   ax, 0fffh
> >     push  ax
> >     popf
> >     pushf
> >     pop   ax
> >     and   ax, 0f000h
> >     cmp   ax, 0f000h    ; flag bits 12-15 are always set on an 8086
> >     mov   CPU_TYPE, 0   ; 8086 detected
> >     je    end_get_cpuid
> >
> > check_80286:
> >     or    cx, 0f000h
> >     push  cx
> >     popf
> >     pushf
> >     pop   ax
> >     and   ax, 0f000h   ; flag bits 12-15 are always clear on 80286 in
> > real mode
> >     mov   CPU_TYPE, 2  ; 80286 processor
> >     jz    end_get_cpuid
> >
> > check_80386:
> >     mov     bx, sp
> >     and     sp, not 3
> >     OPND32
> >     pushf
> >     OPND32
> >     pop ax
> >     OPND32
> >     mov      cx, ax
> >     OPND32   35h, 40000h
> >     OPND32
> >     push     ax
> >     OPND32
> >     popf
> >     OPND32
> >     pushf
> >     OPND32
> >     pop      ax
> >     OPND32
> >     xor      ax, cx       ; AC bit won't toggle, 80386 detected
> >     mov      sp, bx
> >     mov      CPU_TYPE, 3  ; 80386 detected
> >     jz       end_get_cpuid
> >
> >     and      sp, not 3
> >     OPND32
> >     push     cx
> >     OPND32
> >     popf
> >     mov      sp, bx     ; restore stack
> >
> >
> > check_80486:
> >     mov      CPU_TYPE, 4     ; default to 80486
> >
> >     OPND32
> >     mov      ax, cx
> >     OPND32   35h, 200000h      ; xor ID bit
> >     OPND32
> >     push ax
> >     OPND32
> >     popf
> >     OPND32
> >     pushf
> >     OPND32
> >     pop      ax
> >     OPND32
> >     xor      ax, cx           ; cant toggle ID bit
> >     je       end_get_cpuid
> >
> >
> > check_vendor:
> >     mov     ID_FLAG, 1
> >     OPND32
> >     xor     ax, ax
> >     CPUID
> >     OPND32
> >     mov     word ptr VENDOR_ID, bx
> >     OPND32
> >     mov     word ptr VENDOR_ID[+4], dx
> >     OPND32
> >     mov     word ptr VENDOR_ID[+8], cx
> >     mov     si, offset VENDOR_ID
> >     mov     di, offset intel_id
> >     mov     cx, length intel_id
> >
> > compare:
> >     repe    cmpsb
> >     or      cx, cx
> >     jnz     end_get_cpuid
> >
> > intel_processor:
> >     mov     INTEL_PROC, 1
> >
> > cpuid_data:
> >     OPND32
> >     cmp     ax, 1
> >
> >     jl      end_get_cpuid
> >     OPND32
> >     xor     ax, ax
> >     OPND32
> >     inc     ax
> >     CPUID
> >     mov     byte ptr ds:STEPPING, al
> >     and     STEPPING, STEPPING_MASK
> >
> >     and     al, MODEL_MASK
> >     shr     al, MODEL_SHIFT
> >     mov     byte ptr ds:CPU_MODEL, al
> >
> >     and     ax, FAMILY_MASK
> >     shr     ax, FAMILY_SHIFT
> >     mov     byte ptr ds:CPU_TYPE, al
> >
> >     mov     dword ptr FEATURE_FLAGS, edx
> >
> > end_get_cpuid:
> >     ret
> >
> > get_cpuid  endp
> >
> >
> > get_fpuid proc near
> >
> >     fninit
> >     mov      word ptr ds:FP_STATUS, 5a5ah
> >
> >     fnstsw   word ptr ds:FP_STATUS
> >     mov      ax, word ptr ds:FP_STATUS
> >     cmp      al, 0
> >
> >     mov      FPU_TYPE, 0
> >     jne      end_get_fpuid
> >
> > check_control_word:
> >     fnstcw   word ptr ds:FP_STATUS
> >     mov      ax, word ptr ds:FP_STATUS
> >     and      ax, 103fh
> >     cmp      ax, 3fh
> >
> >     mov      FPU_TYPE, 0
> >     jne      end_get_fpuid
> >     mov      FPU_TYPE, 1
> >
> >
> > check_infinity:
> >     cmp      CPU_TYPE, 3
> >     jne      end_get_fpuid
> >     fld1
> >     fldz
> >     fdiv
> >     fld      st
> >     fchs
> >     fcompp
> >     fstsw    word ptr ds:FP_STATUS
> >     mov      ax, word ptr ds:FP_STATUS
> >     mov      FPU_TYPE, 2
> >
> >     sahf
> >     jz       end_get_fpuid
> >     mov      FPU_TYPE, 3
> > end_get_fpuid:
> >     ret
> > get_fpuid endp
> >
> >
> >
> > print proc near
> >     cmp      ID_FLAG, 1
> >     je       print_cpuid_data
> >
> > if (VERBOSE)
> >     mov      dx, offset id_msg
> >     call     OutputMessage
> > endif
> >
> > print_86:
> >     cmp      CPU_TYPE, 0
> >     jne      print_286
> >
> > if (VERBOSE)
> >     mov      dx, offset c8086
> >     call     OutputMessage
> > endif
> >     cmp      FPU_TYPE, 0
> >     je       end_print
> >
> > if (VERBOSE)
> >     mov      dx, offset fp_8087
> >     call     OutputMessage
> > endif
> >     jmp      end_print
> >
> > print_286:
> >     cmp      CPU_TYPE, 2
> >     jne      print_386
> > if (VERBOSE)
> >     mov      dx, offset c286
> >     call     OutputMessage
> > endif
> >     cmp      FPU_TYPE, 0
> >     je       end_print
> > if (VERBOSE)
> >     mov      dx, offset fp_80287
> >     call     OutputMessage
> > endif
> >     jmp      end_print
> >
> > print_386:
> >     cmp      CPU_TYPE, 3
> >     jne      print_486
> > if (VERBOSE)
> >     mov      dx, offset c386
> >     call     OutputMessage
> > endif
> >     cmp      FPU_TYPE, 0
> >     je       end_print
> >     cmp      FPU_TYPE, 2
> >     jne      print_387
> > if (VERBOSE)
> >     mov      dx, offset fp_80287
> >     call     OutputMessage
> > endif
> >     jmp      end_print
> >
> > print_387:
> > if (VERBOSE)
> >     mov      dx, offset fp_80387
> >     call     OutputMessage
> > endif
> >     jmp      end_print
> >
> > print_486:
> >     cmp      FPU_TYPE, 0
> >     je       print_Intel486sx
> > if (VERBOSE)
> >     mov      dx, offset c486
> >     call     OutputMessage
> > endif
> >     jmp      end_print
> >
> > print_Intel486sx:
> > if (VERBOSE)
> >     mov      dx, offset c486nfp
> >     call     OutputMessage
> > endif
> >     jmp      end_print
> >
> > print_cpuid_data:
> >
> > cmp_vendor:
> >     cmp      INTEL_PROC, 1
> >     jne      not_GenuineIntel
> >
> >     cmp      CPU_TYPE, 4
> >     jne      check_Pentium
> > if (VERBOSE)
> >     mov      dx, offset Intel486_msg
> >     call     OutputMessage
> > endif
> >     jmp      print_family
> >
> > check_Pentium:
> >     cmp      CPU_TYPE, 5
> >     jne      check_PentiumPro
> > if (VERBOSE)
> >     mov      dx, offset Pentium_msg
> >     call     OutputMessage
> > endif
> >     jmp      print_family
> >
> > check_PentiumPro:
> >     cmp      CPU_TYPE, 6
> >     jne      print_features
> > if (VERBOSE)
> >     mov      dx, offset PentiumPro_msg
> >     call     OutputMessage
> > endif
> >
> > print_family:
> >
> > IF VERBOSE
> >     mov      dx, offset family_msg
> >     call     OutputMessage
> > ENDIF
> >
> >     mov      al, byte ptr ds:CPU_TYPE
> >     mov      byte ptr dataCR, al
> >     add      byte ptr dataCR, 30h
> >
> > IF VERBOSE
> >     mov      dx, offset dataCR
> >     call     OutputMessage
> > ENDIF
> >
> > print_model:
> >
> > IF VERBOSE
> >     mov      dx, offset model_msg
> >     call     OutputMessage
> > ENDIF
> >
> >     mov      al, byte ptr ds:CPU_MODEL
> >     mov      byte ptr dataCR, al
> >     add      byte ptr dataCR, 30h
> >
> > IF VERBOSE
> >     mov      dx, offset dataCR
> >     call     OutputMessage
> > ENDIF
> >
> > print_features:
> >     mov      ax, word ptr ds:FEATURE_FLAGS
> >     and      ax, FPU_FLAG
> >     jz       check_mce
> >
> > if (VERBOSE)
> >     mov      dx, offset fpu_msg
> >     call     OutputMessage
> > ENDIF
> >
> > check_mce:
> >     mov      ax, word ptr ds:FEATURE_FLAGS
> >     and      ax, MCE_FLAG
> >     jz       check_wc
> >
> > IF VERBOSE
> >     mov      dx, offset mce_msg
> >     call     OutputMessage
> > ENDIF
> >
> > check_CMPXCHG8B:
> >     mov      ax, word ptr ds:FEATURE_FLAGS
> >     and      ax, CMPXCHG8B_FLAG
> >     jz       check_4MB_paging
> >
> > IF VERBOSE
> >     mov      dx, offset cmp_msg
> >     call     OutputMessage
> > ENDIF
> >
> > chekc_io_break:
> >     mov      ax, word ptr ds:FEATURE_FLAGS
> >     test     ax, 4
> >     jz       check_4MB_paging
> >
> > IF VERBOSE
> >     mov      dx, offset io_break_msg
> >     call     OutputMessage
> > ENDIF
> >
> >     ; Enable Debugging Extensions bit in CR4
> >     CR4_TO_ECX
> >     or        ecx, 08h
> >     ECX_TO_CR4
> >
> > if (VERBOSE)
> >     mov      dx, offset io_break_enable
> >     call     OutputMessage
> > endif
> >
> > check_4MB_paging:
> >     mov      ax, word ptr ds:FEATURE_FLAGS
> >     test     ax, 08h
> >     jz       check_PageExtend
> >
> > IF VERBOSE
> >     mov      dx, offset page_4MB_msg
> >     call     OutputMessage
> > ENDIF
> >
> >     ; Enable page size extension bit in CR4
> >     CR4_TO_ECX
> >     or             ecx, 10h
> >     ECX_TO_CR4
> >
> > if (VERBOSE)
> >     mov      dx, offset p4mb_enable
> >     call     OutputMessage
> > endif
> >
> > check_PageExtend:
> >     mov      ax, word ptr ds:FEATURE_FLAGS
> >     test     ax, 40h
> >     jz       check_wc
> >
> > ;; DEBUG DEBUG DEBUG !!!
> >     ; Enable page address extension bit in CR4
> >
> >     ;; CR4_TO_ECX
> >     ;; or          ecx, 20h
> >     ;; ECX_TO_CR4
> >
> > check_wc:
> >     mov      dx, word ptr ds:FEATURE_FLAGS
> >     test     dx, 1000h ; MTRR support flag
> >     jz       end_print
> >
> > if (VERBOSE)
> >     mov      dx, offset wc_enable
> >     call     OutputMessage
> > endif
> >     jmp      end_print
> >
> > not_GenuineIntel:
> > if (VERBOSE)
> >     mov      dx, offset not_Intel
> >     call     OutputMessage
> > endif
> >
> > end_print:
> >     ret
> > print endp
> >
> >
> > [EMAIL PROTECTED] wrote:
> > >
> > > On Tue, 7 Nov 2000, Jeff V. Merkey wrote:
> > >
> > > > So how come NetWare and NT can detect this at run time, and we have to
> > > > use a .config option to specifiy it?  Come on guys.....
> > >
> > > Then run a kernel compiled for i386 and suffer the poorer code quality
> > > that comes with not using newer instructions and including the
> > > workarounds for ancient hardware.
> > >
> > >                 -ben
> > >
> > > -
> > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > > the body of a message to [EMAIL PROTECTED]
> > > Please read the FAQ at http://www.tux.org/lkml/
> > -
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to [EMAIL PROTECTED]
> > Please read the FAQ at http://www.tux.org/lkml/
> >
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to