Change CPU recognition code to know more types, and make it changeable
easier when new types arrive. Locore: make profiling work for some functions; use <machine/asm.h> (from Jonathan Stone)
This commit is contained in:
parent
2775763610
commit
1f758a1a78
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore.s,v 1.157 1996/11/18 01:06:10 fvdl Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.158 1996/12/03 23:59:25 fvdl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
|
||||
|
@ -62,18 +62,24 @@
|
|||
#include <machine/specialreg.h>
|
||||
#include <machine/trap.h>
|
||||
|
||||
/*
|
||||
* override user-land alignment before including asm.h
|
||||
*/
|
||||
#define ALIGN_DATA .align 2
|
||||
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
||||
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
||||
#define _ALIGN_TEXT ALIGN_TEXT
|
||||
#include <machine/asm.h>
|
||||
|
||||
#include <i386/isa/debug.h>
|
||||
|
||||
|
||||
/* XXX temporary kluge; these should not be here */
|
||||
#define IOM_BEGIN 0x0a0000 /* start of I/O memory "hole" */
|
||||
#define IOM_END 0x100000 /* end of I/O memory "hole" */
|
||||
#define IOM_SIZE (IOM_END - IOM_BEGIN)
|
||||
|
||||
|
||||
#define ALIGN_DATA .align 2
|
||||
#define ALIGN_TEXT .align 2,0x90 /* 4-byte boundaries, NOP-filled */
|
||||
#define SUPERALIGN_TEXT .align 4,0x90 /* 16-byte boundaries better for 486 */
|
||||
|
||||
/* NB: NOP now preserves registers so NOPs can be inserted anywhere */
|
||||
/* XXX: NOP and FASTER_NOP are misleadingly named */
|
||||
#ifdef DUMMY_NOPS /* this will break some older machines */
|
||||
|
@ -138,7 +144,13 @@
|
|||
.set _APTD,(_APTmap + APTDPTDI * NBPG)
|
||||
.set _APTDpde,(_PTD + APTDPTDI * 4) # XXX 4 == sizeof pde
|
||||
|
||||
#define ENTRY(name) .globl _/**/name; ALIGN_TEXT; _/**/name:
|
||||
|
||||
/*
|
||||
* Non-profiled, profiled, and alternate entry points.
|
||||
*
|
||||
* XXX most entry points should be profilable. Due to ignorance of which
|
||||
* are safe, only a few (bcopy, copyin, copyout) are profiled.
|
||||
*/
|
||||
#define ALTENTRY(name) .globl _/**/name; _/**/name:
|
||||
|
||||
/*
|
||||
|
@ -146,10 +158,14 @@
|
|||
*/
|
||||
.data
|
||||
|
||||
.globl _cpu,_cpu_vendor,_cold,_esym,_boothowto,_bootdev,_atdevbase
|
||||
.globl _cpu,_cpu_id,_cpu_vendor,_cpuid_level,_cpu_feature
|
||||
.globl _cold,_esym,_boothowto,_bootdev,_atdevbase
|
||||
.globl _cyloffset,_proc0paddr,_curpcb,_PTDpaddr,_biosbasemem
|
||||
.globl _biosextmem,_dynamic_gdt
|
||||
_cpu: .long 0 # are we 386, 386sx, or 486
|
||||
_cpu: .long 0 # are we 386, 386sx, or 486, or Pentium, or..
|
||||
_cpu_id: .long 0 # saved from `cpuid' instruction
|
||||
_cpu_feature: .long 0 # feature flags from 'cpuid' instruction
|
||||
_cpuid_level: .long -1 # max. level accepted by 'cpuid' instruction
|
||||
_cpu_vendor: .space 16 # vendor string returned by `cpuid' instruction
|
||||
_cold: .long 1 # cold till we are not
|
||||
_esym: .long 0 # ptr to end of syms
|
||||
|
@ -230,6 +246,26 @@ try386: /* Try to toggle alignment check flag; does not exist on 386. */
|
|||
|
||||
testl %eax,%eax
|
||||
jnz try486
|
||||
|
||||
/*
|
||||
* Try the test of a NexGen CPU -- ZF will not change on a DIV
|
||||
* instruction on a NexGen, it will on an i386. Documented in
|
||||
* Nx586 Processor Recognition Application Note, NexGen, Inc.
|
||||
*/
|
||||
movl $0x5555,%eax
|
||||
xorl %edx,%edx
|
||||
movl $2,%ecx
|
||||
jnz is386
|
||||
|
||||
isnx586:
|
||||
/*
|
||||
* Don't try cpuid, as Nx586s reportedly don't support the
|
||||
* PSL_ID bit.
|
||||
*/
|
||||
movl $CPU_NX586,RELOC(_cpu)
|
||||
jmp 2f
|
||||
|
||||
is386:
|
||||
movl $CPU_386,RELOC(_cpu)
|
||||
jmp 2f
|
||||
|
||||
|
@ -269,8 +305,6 @@ is486: movl $CPU_486,RELOC(_cpu)
|
|||
jne 2f # yes; must not be Cyrix CPU
|
||||
|
||||
movl $CPU_486DLC,RELOC(_cpu) # set CPU type
|
||||
movl $0x69727943,RELOC(_cpu_vendor) # store vendor string
|
||||
movb $0x78,RELOC(_cpu_vendor)+4
|
||||
|
||||
#ifndef CYRIX_CACHE_WORKS
|
||||
/* Disable caching of the ISA hole only. */
|
||||
|
@ -334,17 +368,16 @@ is486: movl $CPU_486,RELOC(_cpu)
|
|||
try586: /* Use the `cpuid' instruction. */
|
||||
xorl %eax,%eax
|
||||
cpuid
|
||||
movl %eax,RELOC(_cpuid_level)
|
||||
movl %ebx,RELOC(_cpu_vendor) # store vendor string
|
||||
movl %edx,RELOC(_cpu_vendor)+4
|
||||
movl %ecx,RELOC(_cpu_vendor)+8
|
||||
movl $0, RELOC(_cpu_vendor)+12
|
||||
|
||||
movl $1,%eax
|
||||
cpuid
|
||||
rorl $8,%eax # extract family type
|
||||
andl $15,%eax
|
||||
cmpl $5,%eax
|
||||
jb is486 # less than a Pentium
|
||||
movl $CPU_586,RELOC(_cpu)
|
||||
movl %eax,RELOC(_cpu_id) # store cpu_id and features
|
||||
movl %edx,RELOC(_cpu_feature)
|
||||
|
||||
2:
|
||||
/*
|
||||
|
@ -561,7 +594,7 @@ begin:
|
|||
|
||||
call _main
|
||||
|
||||
ENTRY(proc_trampoline)
|
||||
NENTRY(proc_trampoline)
|
||||
pushl %ebx
|
||||
call %esi
|
||||
addl $4,%esp
|
||||
|
@ -573,7 +606,7 @@ ENTRY(proc_trampoline)
|
|||
/*
|
||||
* Signal trampoline; copied to top of user stack.
|
||||
*/
|
||||
ENTRY(sigcode)
|
||||
NENTRY(sigcode)
|
||||
call SIGF_HANDLER(%esp)
|
||||
leal SIGF_SC(%esp),%eax # scp (the call may have clobbered the
|
||||
# copy at SIGF_SCP(%esp))
|
||||
|
@ -597,7 +630,7 @@ _esigcode:
|
|||
/*****************************************************************************/
|
||||
|
||||
#ifdef COMPAT_SVR4
|
||||
ENTRY(svr4_sigcode)
|
||||
NENTRY(svr4_sigcode)
|
||||
call SVR4_SIGF_HANDLER(%esp)
|
||||
leal SVR4_SIGF_UC(%esp),%eax # ucp (the call may have clobbered the
|
||||
# copy at SIGF_UCP(%esp))
|
||||
|
@ -626,7 +659,7 @@ _svr4_esigcode:
|
|||
/*
|
||||
* Signal trampoline; copied to top of user stack.
|
||||
*/
|
||||
ENTRY(linux_sigcode)
|
||||
NENTRY(linux_sigcode)
|
||||
call LINUX_SIGF_HANDLER(%esp)
|
||||
leal LINUX_SIGF_SC(%esp),%ebx # scp (the call may have clobbered the
|
||||
# copy at SIGF_SCP(%esp))
|
||||
|
@ -653,7 +686,7 @@ _linux_esigcode:
|
|||
/*
|
||||
* Signal trampoline; copied to top of user stack.
|
||||
*/
|
||||
ENTRY(freebsd_sigcode)
|
||||
NENTRY(freebsd_sigcode)
|
||||
call FREEBSD_SIGF_HANDLER(%esp)
|
||||
leal FREEBSD_SIGF_SC(%esp),%eax # scp (the call may have clobbered
|
||||
# the copy at SIGF_SCP(%esp))
|
||||
|
@ -775,8 +808,8 @@ ENTRY(bcopyw)
|
|||
* bcopy(caddr_t from, caddr_t to, size_t len);
|
||||
* Copy len bytes.
|
||||
*/
|
||||
ENTRY(bcopy)
|
||||
ALTENTRY(ovbcopy)
|
||||
ENTRY(bcopy)
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
movl 12(%esp),%esi
|
||||
|
@ -853,10 +886,10 @@ ENTRY(copyout)
|
|||
ja _copy_fault
|
||||
|
||||
#if defined(I386_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_386,_cpu_class
|
||||
jne 3f
|
||||
#endif /* I486_CPU || I586_CPU */
|
||||
#endif /* I486_CPU || I586_CPU || I686_CPU */
|
||||
|
||||
testl %eax,%eax # anything to do?
|
||||
jz 3f
|
||||
|
@ -989,10 +1022,10 @@ ENTRY(copyoutstr)
|
|||
movl 20(%esp),%edx # edx = maxlen
|
||||
|
||||
#if defined(I386_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_386,_cpu_class
|
||||
jne 5f
|
||||
#endif /* I486_CPU || I586_CPU */
|
||||
#endif /* I486_CPU || I586_CPU || I686_CPU */
|
||||
|
||||
/* Compute number of bytes in first page. */
|
||||
movl %edi,%eax
|
||||
|
@ -1054,7 +1087,7 @@ ENTRY(copyoutstr)
|
|||
jmp copystr_return
|
||||
#endif /* I386_CPU */
|
||||
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
5: /*
|
||||
* Get min(%edx, VM_MAXUSER_ADDRESS-%edi).
|
||||
*/
|
||||
|
@ -1085,7 +1118,7 @@ ENTRY(copyoutstr)
|
|||
jae _copystr_fault
|
||||
movl $ENAMETOOLONG,%eax
|
||||
jmp copystr_return
|
||||
#endif /* I486_CPU || I586_CPU */
|
||||
#endif /* I486_CPU || I586_CPU || I686_CPU */
|
||||
|
||||
/*
|
||||
* copyinstr(caddr_t from, caddr_t to, size_t maxlen, size_t *lencopied);
|
||||
|
@ -1290,10 +1323,10 @@ ENTRY(suword)
|
|||
movl $_fusufault,PCB_ONFAULT(%ecx)
|
||||
|
||||
#if defined(I386_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_386,_cpu_class
|
||||
jne 2f
|
||||
#endif /* I486_CPU || I586_CPU */
|
||||
#endif /* I486_CPU || I586_CPU || I686_CPU */
|
||||
|
||||
movl %edx,%eax
|
||||
shrl $PGSHIFT,%eax # calculate pte address
|
||||
|
@ -1331,10 +1364,10 @@ ENTRY(susword)
|
|||
movl $_fusufault,PCB_ONFAULT(%ecx)
|
||||
|
||||
#if defined(I386_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_386,_cpu_class
|
||||
jne 2f
|
||||
#endif /* I486_CPU || I586_CPU */
|
||||
#endif /* I486_CPU || I586_CPU || I686_CPU */
|
||||
|
||||
movl %edx,%eax
|
||||
shrl $PGSHIFT,%eax # calculate pte address
|
||||
|
@ -1373,10 +1406,10 @@ ENTRY(suswintr)
|
|||
movl $_fusubail,PCB_ONFAULT(%ecx)
|
||||
|
||||
#if defined(I386_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_386,_cpu_class
|
||||
jne 2f
|
||||
#endif /* I486_CPU || I586_CPU */
|
||||
#endif /* I486_CPU || I586_CPU || I686_CPU */
|
||||
|
||||
movl %edx,%eax
|
||||
shrl $PGSHIFT,%eax # calculate pte address
|
||||
|
@ -1407,10 +1440,10 @@ ENTRY(subyte)
|
|||
movl $_fusufault,PCB_ONFAULT(%ecx)
|
||||
|
||||
#if defined(I386_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_386,_cpu_class
|
||||
jne 2f
|
||||
#endif /* I486_CPU || I586_CPU */
|
||||
#endif /* I486_CPU || I586_CPU || I686_CPU */
|
||||
|
||||
movl %edx,%eax
|
||||
shrl $PGSHIFT,%eax # calculate pte address
|
||||
|
@ -1446,7 +1479,7 @@ ENTRY(subyte)
|
|||
* void lgdt(struct region_descriptor *rdp);
|
||||
* Change the global descriptor table.
|
||||
*/
|
||||
ENTRY(lgdt)
|
||||
NENTRY(lgdt)
|
||||
/* Reload the descriptor table. */
|
||||
movl 4(%esp),%eax
|
||||
lgdt (%eax)
|
||||
|
@ -1506,7 +1539,7 @@ ENTRY(longjmp)
|
|||
* setrunqueue(struct proc *p);
|
||||
* Insert a process on the appropriate queue. Should be called at splclock().
|
||||
*/
|
||||
ENTRY(setrunqueue)
|
||||
NENTRY(setrunqueue)
|
||||
movl 4(%esp),%eax
|
||||
#ifdef DIAGNOSTIC
|
||||
cmpl $0,P_BACK(%eax) # should not be on q already
|
||||
|
@ -1537,7 +1570,7 @@ ENTRY(setrunqueue)
|
|||
* remrunqueue(struct proc *p);
|
||||
* Remove a process from its queue. Should be called at splclock().
|
||||
*/
|
||||
ENTRY(remrunqueue)
|
||||
NENTRY(remrunqueue)
|
||||
movl 4(%esp),%ecx
|
||||
movzbl P_PRIORITY(%ecx),%eax
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -1587,7 +1620,7 @@ ENTRY(idle)
|
|||
jmp _idle
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
ENTRY(switch_error)
|
||||
NENTRY(switch_error)
|
||||
pushl $1f
|
||||
call _panic
|
||||
/* NOTREACHED */
|
||||
|
@ -1978,16 +2011,16 @@ IDTVEC(align)
|
|||
* necessary, and resume as if we were handling a general protection fault.
|
||||
* This will cause the process to get a SIGBUS.
|
||||
*/
|
||||
ENTRY(resume_iret)
|
||||
NENTRY(resume_iret)
|
||||
ZTRAP(T_PROTFLT)
|
||||
ENTRY(resume_pop_ds)
|
||||
NENTRY(resume_pop_ds)
|
||||
movl $GSEL(GDATA_SEL, SEL_KPL),%eax
|
||||
movl %ax,%es
|
||||
ENTRY(resume_pop_es)
|
||||
NENTRY(resume_pop_es)
|
||||
movl $T_PROTFLT,TF_TRAPNO(%esp)
|
||||
jmp calltrap
|
||||
|
||||
ENTRY(alltraps)
|
||||
NENTRY(alltraps)
|
||||
INTRENTRY
|
||||
calltrap:
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -2032,7 +2065,7 @@ calltrap:
|
|||
* This code checks for a kgdb trap, then falls through
|
||||
* to the regular trap code.
|
||||
*/
|
||||
ENTRY(bpttraps)
|
||||
NENTRY(bpttraps)
|
||||
INTRENTRY
|
||||
testb $SEL_RPL,TF_CS(%esp)
|
||||
jne calltrap
|
||||
|
@ -2126,7 +2159,7 @@ ENTRY(bzero)
|
|||
stosb
|
||||
|
||||
#if defined(I486_CPU)
|
||||
#if defined(I386_CPU) || defined(I586_CPU)
|
||||
#if defined(I386_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_486,_cpu_class
|
||||
jne 8f
|
||||
#endif
|
||||
|
@ -2181,7 +2214,7 @@ ENTRY(bzero)
|
|||
.data
|
||||
apmstatus: .long 0
|
||||
.text
|
||||
ENTRY(apmcall)
|
||||
NENTRY(apmcall)
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %esi
|
||||
|
@ -2255,7 +2288,7 @@ _biostramp_image_size:
|
|||
*
|
||||
* Fills in *regs with registers as returned by BIOS.
|
||||
*/
|
||||
ENTRY(bioscall)
|
||||
NENTRY(bioscall)
|
||||
pushl %ebp
|
||||
movl %esp,%ebp /* set up frame ptr */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.215 1996/11/18 01:06:12 fvdl Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.216 1996/12/03 23:59:27 fvdl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994, 1995, 1996 Charles M. Hannum. All rights reserved.
|
||||
|
@ -418,57 +418,231 @@ allocsys(v)
|
|||
char cpu_model[120];
|
||||
extern char version[];
|
||||
|
||||
struct cpu_nameclass i386_cpus[] = {
|
||||
{ "i386SX", CPUCLASS_386 }, /* CPU_386SX */
|
||||
{ "i386DX", CPUCLASS_386 }, /* CPU_386 */
|
||||
{ "i486SX", CPUCLASS_486 }, /* CPU_486SX */
|
||||
{ "i486DX", CPUCLASS_486 }, /* CPU_486 */
|
||||
{ "Pentium", CPUCLASS_586 }, /* CPU_586 */
|
||||
{ "Cx486DLC", CPUCLASS_486 }, /* CPU_486DLC (Cyrix) */
|
||||
/*
|
||||
* Note: these are just the ones that may not have a cpuid instruction.
|
||||
* We deal with the rest in a different way.
|
||||
*/
|
||||
struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = {
|
||||
{ CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386 }, /* CPU_386SX */
|
||||
{ CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386 }, /* CPU_386 */
|
||||
{ CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486 }, /* CPU_486SX */
|
||||
{ CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486 }, /* CPU_486 */
|
||||
{ CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486 }, /* CPU_486DLC */
|
||||
{ CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_586 }, /* CPU_NX586 */
|
||||
};
|
||||
|
||||
const char *classnames[] = {
|
||||
"386",
|
||||
"486",
|
||||
"586",
|
||||
"686"
|
||||
};
|
||||
|
||||
const char *modifiers[] = {
|
||||
"",
|
||||
"OverDrive ",
|
||||
"Dual ",
|
||||
""
|
||||
};
|
||||
|
||||
struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
|
||||
{
|
||||
"GenuineIntel",
|
||||
CPUVENDOR_INTEL,
|
||||
"Intel",
|
||||
/* Family 4 */
|
||||
{ {
|
||||
CPUCLASS_486,
|
||||
{
|
||||
"486DX", "486DX", "486DX", "486DX2", "486SL",
|
||||
"486SX2", 0, "486DX2 W/B Enhanced",
|
||||
"486DX4", 0, 0, 0, 0, 0, 0, 0,
|
||||
"486" /* Default */
|
||||
}
|
||||
},
|
||||
/* Family 5 */
|
||||
{
|
||||
CPUCLASS_586,
|
||||
{
|
||||
0, "Pentium", "Pentium (P54C)",
|
||||
"Pentium (P24T)", "Pentium", "Pentium", 0,
|
||||
"Pentium (P54C)", 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
"Pentium" /* Default */
|
||||
}
|
||||
},
|
||||
/* Family 6 */
|
||||
{
|
||||
CPUCLASS_686,
|
||||
{
|
||||
0, "Pentium Pro", 0, 0, "Pentium Pro", 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
"Pentium Pro" /* Default */
|
||||
}
|
||||
} }
|
||||
},
|
||||
{
|
||||
"AuthenticAMD",
|
||||
CPUVENDOR_AMD,
|
||||
"AMD",
|
||||
/* Family 4 */
|
||||
{ {
|
||||
CPUCLASS_486,
|
||||
{
|
||||
0, 0, 0, "Am486DX2 W/T",
|
||||
0, 0, 0, "Am486DX2 W/B",
|
||||
"Am486DX4 W/T or Am5x86 W/T 150",
|
||||
"Am486DX4 W/B or Am5x86 W/B 150", 0, 0,
|
||||
0, 0, "Am5x86 W/T 133/160",
|
||||
"Am5x86 W/B 133/160",
|
||||
"Am486 or Am5x86" /* Default */
|
||||
},
|
||||
},
|
||||
/* Family 5 */
|
||||
{
|
||||
CPUCLASS_586,
|
||||
{
|
||||
"K5", "K5", 0, 0, 0, 0, "K6",
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
"K5 or K6", /* Default */
|
||||
},
|
||||
},
|
||||
/* Family 6, not yet available from AMD */
|
||||
{
|
||||
CPUCLASS_686,
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
"Pentium Pro compatible" /* Default */
|
||||
},
|
||||
} }
|
||||
},
|
||||
{
|
||||
"CyrixInstead",
|
||||
CPUVENDOR_CYRIX,
|
||||
"Cyrix",
|
||||
/* Family 4 */
|
||||
{ {
|
||||
CPUCLASS_486,
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
"486" /* Default */
|
||||
},
|
||||
},
|
||||
/* Family 5 */
|
||||
{
|
||||
CPUCLASS_586,
|
||||
{
|
||||
0, 0, "6x86", 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
"6x86" /* Default */
|
||||
}
|
||||
},
|
||||
/* Family 6, not yet available from Cyrix */
|
||||
{
|
||||
CPUCLASS_686,
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
"Pentium Pro compatible" /* Default */
|
||||
}
|
||||
} }
|
||||
}
|
||||
};
|
||||
|
||||
#define CPUDEBUG
|
||||
|
||||
void
|
||||
identifycpu()
|
||||
{
|
||||
extern char cpu_vendor[];
|
||||
extern int cpu_id;
|
||||
const char *name, *modifier, *vendorname;
|
||||
int class = CPUCLASS_386, vendor, i, max;
|
||||
int family, model, step, modif;
|
||||
struct cpu_cpuid_nameclass *cpup = NULL;
|
||||
|
||||
printf("CPU: ");
|
||||
if (cpuid_level == -1) {
|
||||
#ifdef DIAGNOSTIC
|
||||
if (cpu < 0 || cpu >= (sizeof i386_cpus/sizeof(struct cpu_nameclass)))
|
||||
panic("unknown cpu type %d\n", cpu);
|
||||
if (cpu < 0 || cpu >=
|
||||
(sizeof i386_nocpuid_cpus/sizeof(struct cpu_nocpuid_nameclass)))
|
||||
panic("unknown cpu type %d\n", cpu);
|
||||
#endif
|
||||
sprintf(cpu_model, "%s (", i386_cpus[cpu].cpu_name);
|
||||
if (cpu_vendor[0] != '\0') {
|
||||
strcat(cpu_model, cpu_vendor);
|
||||
strcat(cpu_model, " ");
|
||||
name = i386_nocpuid_cpus[cpu].cpu_name;
|
||||
vendor = i386_nocpuid_cpus[cpu].cpu_vendor;
|
||||
vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname;
|
||||
class = i386_nocpuid_cpus[cpu].cpu_class;
|
||||
modifier = "";
|
||||
} else {
|
||||
max = sizeof (i386_cpuid_cpus) / sizeof (i386_cpuid_cpus[0]);
|
||||
modif = (cpu_id >> 12) & 3;
|
||||
family = (cpu_id >> 8) & 15;
|
||||
if (family < CPU_MINFAMILY)
|
||||
panic("identifycpu: strange family value");
|
||||
model = (cpu_id >> 4) & 15;
|
||||
step = cpu_id & 15;
|
||||
#ifdef CPUDEBUG
|
||||
printf("cpu0: family %x model %x step %x\n", family, model,
|
||||
step);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
if (!strncmp(cpu_vendor,
|
||||
i386_cpuid_cpus[i].cpu_id, 12)) {
|
||||
cpup = &i386_cpuid_cpus[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cpup == NULL) {
|
||||
vendor = CPUVENDOR_UNKNOWN;
|
||||
if (cpu_vendor[0] != '\0')
|
||||
vendorname = &cpu_vendor[0];
|
||||
else
|
||||
vendorname = "Unknown";
|
||||
if (family > CPU_MAXFAMILY)
|
||||
family = CPU_MAXFAMILY;
|
||||
class = family - 3;
|
||||
modifier = "";
|
||||
name = "";
|
||||
} else {
|
||||
vendor = cpup->cpu_vendor;
|
||||
vendorname = cpup->cpu_vendorname;
|
||||
modifier = modifiers[modif];
|
||||
if (family > CPU_MAXFAMILY) {
|
||||
family = CPU_MAXFAMILY;
|
||||
model = CPU_DEFMODEL;
|
||||
} else if (model > CPU_MAXMODEL)
|
||||
model = CPU_DEFMODEL;
|
||||
i = family - CPU_MINFAMILY;
|
||||
name = cpup->cpu_family[i].cpu_models[model];
|
||||
if (name == NULL)
|
||||
name = cpup->cpu_family[i].cpu_models[CPU_DEFMODEL];
|
||||
class = cpup->cpu_family[i].cpu_class;
|
||||
}
|
||||
}
|
||||
|
||||
cpu_class = i386_cpus[cpu].cpu_class;
|
||||
switch(cpu_class) {
|
||||
case CPUCLASS_386:
|
||||
strcat(cpu_model, "386");
|
||||
break;
|
||||
case CPUCLASS_486:
|
||||
strcat(cpu_model, "486");
|
||||
break;
|
||||
case CPUCLASS_586:
|
||||
strcat(cpu_model, "586");
|
||||
break;
|
||||
default:
|
||||
strcat(cpu_model, "unknown"); /* will panic below... */
|
||||
break;
|
||||
}
|
||||
strcat(cpu_model, "-class CPU)");
|
||||
printf("%s\n", cpu_model); /* cpu speed would be nice, but how? */
|
||||
sprintf(cpu_model, "%s %s%s (%s-class)", vendorname, modifier, name,
|
||||
classnames[class]);
|
||||
printf("cpu0: %s\n", cpu_model);
|
||||
|
||||
cpu_class = class;
|
||||
|
||||
/*
|
||||
* Now that we have told the user what they have,
|
||||
* let them know if that machine type isn't configured.
|
||||
*/
|
||||
switch (cpu_class) {
|
||||
#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU)
|
||||
#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
|
||||
#error No CPU classes configured.
|
||||
#endif
|
||||
#ifndef I686_CPU
|
||||
case CPUCLASS_686:
|
||||
printf("NOTICE: this kernel does not support Pentium Pro CPU class\n");
|
||||
#ifdef I586_CPU
|
||||
printf("NOTICE: lowering CPU class to i586\n");
|
||||
cpu_class = CPUCLASS_586;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifndef I586_CPU
|
||||
case CPUCLASS_586:
|
||||
printf("NOTICE: this kernel does not support Pentium CPU class\n");
|
||||
|
@ -508,7 +682,7 @@ identifycpu()
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(I486_CPU) || defined(I586_CPU)
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
/*
|
||||
* On a 486 or above, enable ring 0 write protection.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue