summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1998-01-25 12:01:38 +0000
committerkato <kato@FreeBSD.org>1998-01-25 12:01:38 +0000
commit4f6278680f887d118dbbfeda3ce773999dedb091 (patch)
treec2cd531bc9173954e039bc50a7d46486b74a8cdb /sys/i386
parent014c10f64903e490153e51b38f0869d1dd7b72cb (diff)
downloadFreeBSD-src-4f6278680f887d118dbbfeda3ce773999dedb091.zip
FreeBSD-src-4f6278680f887d118dbbfeda3ce773999dedb091.tar.gz
Even though BIOS writer's guide recommends cpuid instruction of Cyrix
6x86MX CPU is enabled (BIOS should not disable it), some BIOS disables it via CCR4. In this case, cpu variable becomes CPU_486 and identblue() is called. Because Cyrix 6x86MX has MSR and doesn't have MSR1002, wrmsr instruction generates general protection fault. Tested by: Simon Coggins <chaos@ultra.net.au>
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/identcpu.c70
-rw-r--r--sys/i386/i386/machdep.c3
2 files changed, 56 insertions, 17 deletions
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index 110b0b4..cbb9b8a 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
- * $Id: identcpu.c,v 1.37 1998/01/03 05:36:40 obrien Exp $
+ * $Id: identcpu.c,v 1.38 1998/01/03 05:43:37 obrien Exp $
*/
#include "opt_cpu.h"
@@ -55,10 +55,14 @@
#include <i386/isa/intr_machdep.h>
+#define IDENTBLUE_CYRIX486 0
+#define IDENTBLUE_IBMCPU 1
+#define IDENTBLUE_CYRIXM2 2
+
/* XXX - should be in header file */
void i486_bzero __P((void *buf, size_t len));
-void printcpuinfo(void); /* XXX should be in different header file */
+void printcpuinfo(void); /* XXX should be in different header file */
void finishidentcpu(void);
void earlysetcpuclass(void);
void panicifcpuunsupported(void);
@@ -534,21 +538,38 @@ panicifcpuunsupported(void)
static volatile u_int trap_by_wrmsr;
/*
- * Special exception 16 handler.
+ * Special exception 6 handler.
* The wrmsr instruction generates invalid opcodes fault on 486-class
* Cyrix CPU. Stacked eip register points the wrmsr instruction in the
* function identblue() when this handler is called. Stacked eip should
* be advanced.
*/
-inthand_t bluetrap;
+inthand_t bluetrap6;
asm
("
.text
.p2align 2,0x90
-" __XSTRING(CNAME(bluetrap)) ":
+" __XSTRING(CNAME(bluetrap6)) ":
ss
- movl $0xa8c1d," __XSTRING(CNAME(trap_by_wrmsr)) " # Don't ask meaning of the number :-).
- addl $2, (%esp) # I know wrmsr is a 2-bytes instruction.
+ movl $0xa8c1d," __XSTRING(CNAME(trap_by_wrmsr)) "
+ addl $2, (%esp) # I know wrmsr is a 2-bytes instruction.
+ iret
+");
+
+/*
+ * Special exception 13 handler.
+ * Accessing non-existent MSR generates general protection fault.
+ */
+inthand_t bluetrap13;
+asm
+("
+ .text
+ .p2align 2,0x90
+" __XSTRING(CNAME(bluetrap13)) ":
+ ss
+ movl $0xa89c4," __XSTRING(CNAME(trap_by_wrmsr)) "
+ popl %eax # discard errorcode.
+ addl $2, (%esp) # I know wrmsr is a 2-bytes instruction.
iret
");
@@ -565,19 +586,29 @@ identblue(void)
{
trap_by_wrmsr = 0;
+
/*
* Cyrix 486-class CPU does not support wrmsr instruction.
- * The wrmsr instruction causes invalid opcode fault, and exception
- * will be trapped by bluetrap() on Cyrix 486-class CPU. The bluetrap()
- * set the magic number to trap_by_wrmsr.
+ * The wrmsr instruction generates invalid opcode fault, and exception
+ * will be trapped by bluetrap6() on Cyrix 486-class CPU. The
+ * bluetrap6() set the magic number to trap_by_wrmsr.
*/
- setidt(6, bluetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
- wrmsr(0x1002, 0x03000000LL); /* Fault on Cyrix 486-class CPU. */
+ setidt(6, bluetrap6, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
- if (trap_by_wrmsr == 0xa8c1d)
- return 0; /* Cyrix CPU sets the magic number. */
+ /*
+ * Certain BIOS disables cpuid instructnion of Cyrix 6x86MX CPU.
+ * In this case, wrmsr generates general protection fault, and
+ * exception will be trapped by bluetrap13().
+ */
+ setidt(13, bluetrap13, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
- return 1; /* IBM Blue Lightnig CPU */
+ wrmsr(0x1002, 0x03000000LL); /* Cyrix CPU generates fault. */
+
+ if (trap_by_wrmsr == 0xa8c1d)
+ return IDENTBLUE_CYRIX486;
+ else if (trap_by_wrmsr == 0xa89c4)
+ return IDENTBLUE_CYRIXM2;
+ return IDENTBLUE_IBMCPU;
}
@@ -632,6 +663,7 @@ identifycyrix(void)
void
finishidentcpu(void)
{
+ int isblue = 0;
if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
if (cpu == CPU_486) {
@@ -640,7 +672,8 @@ finishidentcpu(void)
* - CPU does not support cpuid instruction.
* - Cyrix/IBM CPU is detected.
*/
- if (identblue()) {
+ isblue = identblue();
+ if (isblue == IDENTBLUE_IBMCPU) {
strcpy(cpu_vendor, "IBM");
cpu = CPU_BLUE;
return;
@@ -686,6 +719,11 @@ finishidentcpu(void)
default:
/* M2 and later CPUs are treated as M2. */
cpu = CPU_M2;
+ /*
+ * XXX
+ * Execute cpuid instrunction here and fix cpu_id and
+ * cpu_feature variables.
+ */
break;
}
}
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index fa544df..9139c63 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.282 1998/01/22 17:29:26 dyson Exp $
+ * $Id: machdep.c,v 1.283 1998/01/24 02:00:47 dyson Exp $
*/
#include "apm.h"
@@ -1225,6 +1225,7 @@ init386(first)
finishidentcpu(); /* Final stage of CPU initialization */
setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
initializecpu(); /* Initialize CPU registers */
/* Use BIOS values stored in RTC CMOS RAM, since probing
OpenPOWER on IntegriCloud