summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1997-03-22 18:54:54 +0000
committerkato <kato@FreeBSD.org>1997-03-22 18:54:54 +0000
commit51253b5e709366e0d1ada8027f65389abde0210e (patch)
tree9fe3ec455a22a2a04a2938a4198bbda8ab91a71f
parentee6bebb346b99ff43e0558c742e43ebe1e902662 (diff)
downloadFreeBSD-src-51253b5e709366e0d1ada8027f65389abde0210e.zip
FreeBSD-src-51253b5e709366e0d1ada8027f65389abde0210e.tar.gz
Improved CPU identification and initialization routines. This
supports All Cyrix CPUs, IBM Blue Lightning CPU and NexGen (now AMD) Nx586 CPU, and initialize special registers of Cyrix CPU and msr of IBM Blue Lightning CPU. If revision of Cyrix 6x86 CPU < 2.7, CPU cache is enabled in write-through mode. This can be disabled by kernel configuration options. Reviewed by: Bruce Evans <bde@freebsd.org> and Jordan K. Hubbard <jkh@freebsd.org>
-rw-r--r--sys/amd64/amd64/identcpu.c297
-rw-r--r--sys/amd64/amd64/locore.S175
-rw-r--r--sys/amd64/amd64/locore.s175
-rw-r--r--sys/amd64/amd64/machdep.c14
-rw-r--r--sys/amd64/include/cpufunc.h16
-rw-r--r--sys/amd64/include/cputypes.h8
-rw-r--r--sys/amd64/include/md_var.h8
-rw-r--r--sys/amd64/include/specialreg.h216
-rw-r--r--sys/conf/Makefile.pc988
-rw-r--r--sys/conf/files.i3863
-rw-r--r--sys/conf/files.pc983
-rw-r--r--sys/conf/options.i38623
-rw-r--r--sys/conf/options.pc9821
-rw-r--r--sys/i386/conf/files.i3863
-rw-r--r--sys/i386/conf/options.i38623
-rw-r--r--sys/i386/i386/identcpu.c297
-rw-r--r--sys/i386/i386/locore.s175
-rw-r--r--sys/i386/i386/machdep.c14
-rw-r--r--sys/i386/include/cpufunc.h16
-rw-r--r--sys/i386/include/cputypes.h8
-rw-r--r--sys/i386/include/md_var.h8
-rw-r--r--sys/i386/include/specialreg.h216
-rw-r--r--sys/i386/isa/bs/bshw_dma.c10
-rw-r--r--sys/i386/isa/bs/bsif.h1
-rw-r--r--sys/pc98/conf/Makefile.pc988
-rw-r--r--sys/pc98/conf/files.pc983
-rw-r--r--sys/pc98/conf/options.pc9821
-rw-r--r--sys/pc98/i386/locore.s1084
-rw-r--r--sys/pc98/i386/machdep.c20
-rw-r--r--sys/pc98/i386/trap.c22
-rw-r--r--sys/pc98/pc98/machdep.c20
-rw-r--r--sys/pc98/pc98/pc98.c14
32 files changed, 1420 insertions, 1510 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index b4b8af8..e78382b 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -1,6 +1,7 @@
-/*-
+/*
* Copyright (c) 1992 Terrence R. Lambert.
* Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
+ * Copyright (c) 1997 KATO Takenori.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -35,7 +36,7 @@
* SUCH DAMAGE.
*
* from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
- * $Id$
+ * $Id: identcpu.c,v 1.13 1997/02/22 09:32:19 peter Exp $
*/
#include "opt_cpu.h"
@@ -54,12 +55,18 @@
#include <machine/sysarch.h>
#include <machine/md_var.h>
+#include <i386/isa/isa_device.h>
+
/* XXX - should be in header file */
void i486_bzero __P((void *buf, size_t len));
-void identifycpu(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);
+static void identifycyrix(void);
+u_long cyrix_did; /* Device ID of Cyirx CPU */
int cpu_class = CPUCLASS_386; /* least common denominator */
char machine[] = "i386";
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
@@ -74,13 +81,19 @@ static struct cpu_nameclass i386_cpus[] = {
{ "i486SX", CPUCLASS_486 }, /* CPU_486SX */
{ "i486DX", CPUCLASS_486 }, /* CPU_486 */
{ "Pentium", CPUCLASS_586 }, /* CPU_586 */
- { "Cy486DLC", CPUCLASS_486 }, /* CPU_486DLC */
+ { "Cyrix 486", CPUCLASS_486 }, /* CPU_486DLC */
{ "Pentium Pro", CPUCLASS_686 }, /* CPU_686 */
+ { "Cyrix 5x86", CPUCLASS_486 }, /* CPU_M1SC */
+ { "Cyrix 6x86", CPUCLASS_486 }, /* CPU_M1 */
+ { "Blue Lightning", CPUCLASS_486 }, /* CPU_BLUE */
+ { "Cyrix 6x86 MMX", CPUCLASS_586 }, /* CPU_M2 (XXX) */
+ { "NexGen 586", CPUCLASS_386 }, /* CPU_NX586 (XXX) */
};
void
-identifycpu(void)
+printcpuinfo(void)
{
+
cpu_class = i386_cpus[cpu].cpu_class;
printf("CPU: ");
strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model);
@@ -140,7 +153,6 @@ identifycpu(void)
* Values taken from AMD Processor Recognition
* http://www.amd.com/html/products/pcd/techdocs/appnotes/20734c.pdf
*/
- cpu_model[0] = '\0';
strcpy(cpu_model, "AMD ");
switch (cpu_id & 0xFF0) {
case 0x4E0:
@@ -162,8 +174,119 @@ identifycpu(void)
strcat(cpu_model, "Unknown");
break;
}
- }
+ } else if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
+ strcpy(cpu_model, "Cyrix ");
+ switch (cyrix_did & 0xf0) {
+ case 0x00:
+ switch (cyrix_did & 0x0f) {
+ case 0x00:
+ strcat(cpu_model, "486SLC");
+ break;
+ case 0x01:
+ strcat(cpu_model, "486DLC");
+ break;
+ case 0x02:
+ strcat(cpu_model, "486SLC2");
+ break;
+ case 0x03:
+ strcat(cpu_model, "486DLC2");
+ break;
+ case 0x04:
+ strcat(cpu_model, "486SRx");
+ break;
+ case 0x05:
+ strcat(cpu_model, "486DRx");
+ break;
+ case 0x06:
+ strcat(cpu_model, "486SRx2");
+ break;
+ case 0x07:
+ strcat(cpu_model, "486DRx2");
+ break;
+ case 0x08:
+ strcat(cpu_model, "486SRu");
+ break;
+ case 0x09:
+ strcat(cpu_model, "486DRu");
+ break;
+ case 0x0a:
+ strcat(cpu_model, "486SRu2");
+ break;
+ case 0x0b:
+ strcat(cpu_model, "486DRu2");
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ break;
+ case 0x10:
+ switch (cyrix_did & 0x0f) {
+ case 0x00:
+ strcat(cpu_model, "486S");
+ break;
+ case 0x01:
+ strcat(cpu_model, "486S2");
+ break;
+ case 0x02:
+ strcat(cpu_model, "486Se");
+ break;
+ case 0x03:
+ strcat(cpu_model, "486S2e");
+ break;
+ case 0x0a:
+ strcat(cpu_model, "486DX");
+ break;
+ case 0x0b:
+ strcat(cpu_model, "486DX2");
+ break;
+ case 0x0f:
+ strcat(cpu_model, "486DX4");
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ break;
+ case 0x20:
+ if ((cyrix_did & 0x0f) < 8)
+ strcat(cpu_model, "6x86"); /* Where did you get it? */
+ else
+ strcat(cpu_model, "5x86");
+ break;
+ case 0x30:
+ strcat(cpu_model, "6x86");
+ break;
+ case 0x40:
+ /* XXX */
+ strcat(cpu_model, "Gx86");
+ break;
+ case 0x50:
+ strcat(cpu_model, "Enhanced 6x86 with MMX");
+ break;
+ case 0xf0:
+ switch (cyrix_did & 0x0f) {
+ case 0x0d:
+ strcat(cpu_model, "Overdrive CPU");
+ case 0x0e:
+ strcpy(cpu_model, "Texas Instruments 486SXL");
+ break;
+ case 0x0f:
+ strcat(cpu_model, "486SLC/DLC");
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ } else if (strcmp(cpu_vendor,"IBM") == 0)
+ strcpy(cpu_model, "Blue Lightning CPU");
#endif
+
printf("%s (", cpu_model);
switch(cpu_class) {
case CPUCLASS_286:
@@ -238,6 +361,14 @@ identifycpu(void)
"\020CMOV"
);
}
+ } else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
+ printf(" Device ID = 0x%lx", cyrix_did);
+ printf(" Stepping=%ld", (cyrix_did & 0xf000) >> 12);
+ printf(" Revision=%ld", (cyrix_did & 0x0fff) >> 8);
+#ifndef CYRIX_CACHE_REALLY_WORKS
+ if (cpu == CPU_M1 && (cyrix_did & 0xff00) < 0x1700)
+ printf("\n CPU cache: write-through mode");
+#endif
}
/* Avoid ugly blank lines: only print newline when we have to. */
if (*cpu_vendor || cpu_id)
@@ -248,6 +379,11 @@ identifycpu(void)
* XXX - Do PPro CPUID level=2 stuff here?
*/
#endif
+}
+
+void
+panicifcpuunsupported(void)
+{
/*
* Now that we have told the user what they have,
@@ -276,6 +412,152 @@ identifycpu(void)
}
}
+
+static volatile u_int trap_by_wrmsr;
+
+/*
+ * Special exception 16 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;
+asm
+("
+ .text
+_bluetrap:
+ ss
+ movl $0xa8c1d, _trap_by_wrmsr # Don't ask meaning of the number :-).
+ addl $2, (%esp) # I know wrmsr is a 2-bytes instruction.
+ iret
+");
+
+/*
+ * Distinguish IBM Blue Lightning CPU from Cyrix CPUs that does not
+ * support cpuid instruction. This function should be called after
+ * loading interrupt descriptor table register.
+ *
+ * I don't like this method that handles fault, but I couldn't get
+ * information for any other methods. Does blue giant know?
+ */
+static int
+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 tra_by_wrmsr.
+ */
+ setidt(6, bluetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ wrmsr(0x1002, 0x03000000LL); /* Fault on Cyrix 486-class CPU. */
+
+ if (trap_by_wrmsr == 0xa8c1d)
+ return 0; /* Cyrix CPU sets the magic number. */
+
+ return 1; /* IBM Blue Lightnig CPU */
+}
+
+
+/*
+ * identifycyrix() set lower 16 bits of cyrix_did as follows:
+ *
+ * F E D C B A 9 8 7 6 5 4 3 2 1 0
+ * +-------+-------+---------------+
+ * | SID | RID | Device ID |
+ * | (DIR 1) | (DIR 0) |
+ * +-------+-------+---------------+
+ */
+static void
+identifycyrix(void)
+{
+ u_long eflags;
+ int ccr2_test = 0, dir_test = 0;
+ u_char ccr2, ccr3;
+
+ eflags = read_eflags();
+ disable_intr();
+
+ ccr2 = read_cyrix_reg(CCR2);
+ write_cyrix_reg(CCR2, ccr2 ^ CCR2_LOCK_NW);
+ read_cyrix_reg(CCR2);
+ if (read_cyrix_reg(CCR2) != ccr2)
+ ccr2_test = 1;
+ write_cyrix_reg(CCR2, ccr2);
+
+ ccr3 = read_cyrix_reg(CCR3);
+ write_cyrix_reg(CCR3, ccr3 ^ CCR3_MAPEN3);
+ read_cyrix_reg(CCR3);
+ if (read_cyrix_reg(CCR3) != ccr3)
+ dir_test = 1; /* CPU supports DIRs. */
+ write_cyrix_reg(CCR3, ccr3);
+
+ if (dir_test) {
+ /* Device ID registers are available. */
+ cyrix_did = read_cyrix_reg(DIR1) << 8;
+ cyrix_did += read_cyrix_reg(DIR0);
+ } else if (ccr2_test)
+ cyrix_did = 0x0010; /* 486S A-step */
+ else
+ cyrix_did = 0x00ff; /* Old 486SLC/DLC and TI486SXLC/SXL */
+
+ write_eflags(eflags);
+}
+
+/*
+ * Final stage of CPU identification. -- Should I check TI?
+ */
+void
+finishidentcpu(void)
+{
+
+ if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
+ if (cpu == CPU_486) {
+ /*
+ * These conditions are equivalent to:
+ * - CPU does not support cpuid instruction.
+ * - Cyrix/IBM CPU is detected.
+ */
+ if (identblue()) {
+ strcpy(cpu_vendor, "IBM");
+ cpu = CPU_BLUE;
+ return;
+ }
+ }
+ identifycyrix();
+ /*
+ * This routine contains a trick.
+ * Don't check (cpu_id & 0x00f0) == 0x50 to detect M2, now.
+ */
+ switch (cyrix_did & 0x00f0) {
+ case 0x00:
+ case 0x10:
+ case 0xf0:
+ cpu = CPU_486DLC;
+ break;
+ case 0x20:
+ if ((cyrix_did & 0x00f0) < 8)
+ cpu = CPU_M1;
+ else
+ cpu = CPU_M1SC;
+ break;
+ case 0x30:
+ cpu = CPU_M1;
+ break;
+ case 0x40:
+ cpu = CPU_M1SC;
+ break;
+ default:
+ /* M2 and later CPUs are treated as M2. */
+ cpu = CPU_M2;
+ break;
+ }
+ }
+}
+
/*
* This routine is called specifically to set up cpu_class before
* startrtclock() uses it. Probably this should be rearranged so that
@@ -287,5 +569,6 @@ identifycpu(void)
void
earlysetcpuclass(void)
{
+
cpu_class = i386_cpus[cpu].cpu_class;
}
diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S
index 95930fe..5efddc5 100644
--- a/sys/amd64/amd64/locore.S
+++ b/sys/amd64/amd64/locore.S
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id$
+ * $Id: locore.s,v 1.81 1997/02/22 09:32:22 peter Exp $
*
* originally from: locore.s, by William F. Jolitz
*
@@ -192,6 +192,21 @@ _bdb_exists: .long 0
*/
NON_GPROF_ENTRY(btext)
+#ifdef PC98
+ jmp 1f
+ .globl _pc98_system_parameter
+ .org 0x400
+_pc98_system_parameter:
+ .space 0x240 /* BIOS parameter block */
+1:
+ /* save SYSTEM PARAMETER for resume (NS/T or other) */
+ movl $0xa1000,%esi
+ movl $0x100000,%edi
+ movl $0x0630,%ecx
+ cld
+ rep
+ movsb
+#else /* IBM-PC */
#ifdef BDE_DEBUGGER
#ifdef BIOS_STEALS_3K
cmpl $0x0375c339,0x95504
@@ -205,6 +220,7 @@ NON_GPROF_ENTRY(btext)
/* Tell the bios to warmboot next time */
movw $0x1234,0x472
+#endif /* PC98 */
/* Set up a real frame in case the double return in newboot is executed. */
pushl %ebp
@@ -232,6 +248,28 @@ NON_GPROF_ENTRY(btext)
*/
movl $R(tmpstk),%esp
+#ifdef PC98
+ testb $0x02,0x100620 /* pc98_machine_type & M_EPSON_PC98 */
+ jz 3f
+ cmpb $0x0b,0x100624 /* epson_machine_id <= 0x0b */
+ ja 3f
+
+ /* count up memory */
+ movl $0x100000,%eax /* next, talley remaining memory */
+ movl $0xFFF-0x100,%ecx
+1: movl 0(%eax),%ebx /* save location to check */
+ movl $0xa55a5aa5,0(%eax) /* write test pattern */
+ cmpl $0xa55a5aa5,0(%eax) /* does not check yet for rollover */
+ jne 2f
+ movl %ebx,0(%eax) /* restore memory */
+ addl $PAGE_SIZE,%eax
+ loop 1b
+2: subl $0x100000,%eax
+ shrl $17,%eax
+ movb %al,0x100401
+3:
+#endif
+
call identify_cpu
/* clear bss */
@@ -326,7 +364,7 @@ begin:
addl $(13*4),%esp /* back to a frame we can return with */
/*
- * now we've run main() and determined what cpu-type we are, we can
+ * Now we've run main() and determined what cpu-type we are, we can
* enable write protection and alignment checking on i486 cpus and
* above.
*/
@@ -524,7 +562,11 @@ olddiskboot:
movl %eax,R(_bootdev)
#if defined(USERCONFIG_BOOT) && defined(USERCONFIG)
+#ifdef PC98
+ movl $0x90200, %esi
+#else
movl $0x10200, %esi
+#endif
movl $R(_userconfig_from_boot),%edi
movl $512,%ecx
cld
@@ -557,11 +599,29 @@ identify_cpu:
popfl
testl %eax,%eax
- jnz 1f
+ jnz try486
+
+ /* NexGen CPU does not have aligment check flag. */
+ pushfl
+ movl $0x5555, %eax
+ xorl %edx, %edx
+ movl $2, %ecx
+ clc
+ divl %ecx
+ jz trynexgen
+ popfl
movl $CPU_386,R(_cpu)
jmp 3f
-1: /* Try to toggle identification flag; does not exist on early 486s. */
+trynexgen:
+ movl $CPU_NX586,R(_cpu)
+ movl $0x4778654e,R(_cpu_vendor) # store vendor string
+ movl $0x72446e65,R(_cpu_vendor+4)
+ movl $0x6e657669,R(_cpu_vendor+8)
+ movl $0,R(_cpu_vendor+12)
+ jmp 3f
+
+try486: /* Try to toggle identification flag; does not exist on early 486s. */
pushfl
popl %eax
movl %eax,%ecx
@@ -576,89 +636,40 @@ identify_cpu:
popfl
testl %eax,%eax
- jnz 1f
+ jnz trycpuid
movl $CPU_486,R(_cpu)
- /* check for Cyrix 486DLC -- based on check routine */
- /* documented in "Cx486SLC/e SMM Programmer's Guide" */
- xorw %dx,%dx
- cmpw %dx,%dx # set flags to known state
- pushfw
- popw %cx # store flags in ecx
- movw $0xffff,%ax
- movw $0x0004,%bx
- divw %bx
- pushfw
- popw %ax
- andw $0x08d5,%ax # mask off important bits
- andw $0x08d5,%cx
- cmpw %ax,%cx
-
- jnz 3f # if flags changed, Intel chip
-
- movl $CPU_486DLC,R(_cpu) # set CPU value for Cyrix
+ /*
+ * Check Cyrix CPU
+ * Cyrix CPUs do not change the undefined flags following
+ * execution of the divide instruction which divides 5 by 2.
+ *
+ * Note: CPUID is enabled on M2, so it passes another way.
+ */
+ pushfl
+ movl $0x5555, %eax
+ xorl %edx, %edx
+ movl $2, %ecx
+ clc
+ divl %ecx
+ jnc trycyrix
+ popfl
+ jmp 3f /* You may use Intel CPU. */
+
+trycyrix:
+ popfl
+ /*
+ * IBM Bluelighting CPU also doesn't change the undefined flags.
+ * Because IBM doesn't disclose the information for Bluelighting
+ * CPU, we couldn't distinguish it from Cyrix's (including IBM
+ * brand of Cyrix CPUs).
+ */
movl $0x69727943,R(_cpu_vendor) # store vendor string
- movw $0x0078,R(_cpu_vendor+4)
-
-#ifndef CYRIX_CACHE_WORKS
- /* Disable caching of the ISA hole only. */
- invd
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- orb $(CCR0_NC1|CCR0_BARB),%al
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- invd
-#else /* CYRIX_CACHE_WORKS */
- /* Set cache parameters */
- invd # Start with guaranteed clean cache
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- andb $~CCR0_NC0,%al
-#ifndef CYRIX_CACHE_REALLY_WORKS
- orb $(CCR0_NC1|CCR0_BARB),%al
-#else /* CYRIX_CACHE_REALLY_WORKS */
- orb $CCR0_NC1,%al
-#endif /* !CYRIX_CACHE_REALLY_WORKS */
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- /* clear non-cacheable region 1 */
- movb $(NCR1+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 2 */
- movb $(NCR2+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 3 */
- movb $(NCR3+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 4 */
- movb $(NCR4+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* enable caching in CR0 */
- movl %cr0,%eax
- andl $~(CR0_CD|CR0_NW),%eax
- movl %eax,%cr0
- invd
-#endif /* !CYRIX_CACHE_WORKS */
+ movl $0x736e4978,R(_cpu_vendor+4)
+ movl $0x64616574,R(_cpu_vendor+8)
jmp 3f
-1: /* Use the `cpuid' instruction. */
+trycpuid: /* Use the `cpuid' instruction. */
xorl %eax,%eax
.byte 0x0f,0xa2 # cpuid 0
movl %eax,R(_cpu_high) # highest capability
diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s
index 95930fe..5efddc5 100644
--- a/sys/amd64/amd64/locore.s
+++ b/sys/amd64/amd64/locore.s
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id$
+ * $Id: locore.s,v 1.81 1997/02/22 09:32:22 peter Exp $
*
* originally from: locore.s, by William F. Jolitz
*
@@ -192,6 +192,21 @@ _bdb_exists: .long 0
*/
NON_GPROF_ENTRY(btext)
+#ifdef PC98
+ jmp 1f
+ .globl _pc98_system_parameter
+ .org 0x400
+_pc98_system_parameter:
+ .space 0x240 /* BIOS parameter block */
+1:
+ /* save SYSTEM PARAMETER for resume (NS/T or other) */
+ movl $0xa1000,%esi
+ movl $0x100000,%edi
+ movl $0x0630,%ecx
+ cld
+ rep
+ movsb
+#else /* IBM-PC */
#ifdef BDE_DEBUGGER
#ifdef BIOS_STEALS_3K
cmpl $0x0375c339,0x95504
@@ -205,6 +220,7 @@ NON_GPROF_ENTRY(btext)
/* Tell the bios to warmboot next time */
movw $0x1234,0x472
+#endif /* PC98 */
/* Set up a real frame in case the double return in newboot is executed. */
pushl %ebp
@@ -232,6 +248,28 @@ NON_GPROF_ENTRY(btext)
*/
movl $R(tmpstk),%esp
+#ifdef PC98
+ testb $0x02,0x100620 /* pc98_machine_type & M_EPSON_PC98 */
+ jz 3f
+ cmpb $0x0b,0x100624 /* epson_machine_id <= 0x0b */
+ ja 3f
+
+ /* count up memory */
+ movl $0x100000,%eax /* next, talley remaining memory */
+ movl $0xFFF-0x100,%ecx
+1: movl 0(%eax),%ebx /* save location to check */
+ movl $0xa55a5aa5,0(%eax) /* write test pattern */
+ cmpl $0xa55a5aa5,0(%eax) /* does not check yet for rollover */
+ jne 2f
+ movl %ebx,0(%eax) /* restore memory */
+ addl $PAGE_SIZE,%eax
+ loop 1b
+2: subl $0x100000,%eax
+ shrl $17,%eax
+ movb %al,0x100401
+3:
+#endif
+
call identify_cpu
/* clear bss */
@@ -326,7 +364,7 @@ begin:
addl $(13*4),%esp /* back to a frame we can return with */
/*
- * now we've run main() and determined what cpu-type we are, we can
+ * Now we've run main() and determined what cpu-type we are, we can
* enable write protection and alignment checking on i486 cpus and
* above.
*/
@@ -524,7 +562,11 @@ olddiskboot:
movl %eax,R(_bootdev)
#if defined(USERCONFIG_BOOT) && defined(USERCONFIG)
+#ifdef PC98
+ movl $0x90200, %esi
+#else
movl $0x10200, %esi
+#endif
movl $R(_userconfig_from_boot),%edi
movl $512,%ecx
cld
@@ -557,11 +599,29 @@ identify_cpu:
popfl
testl %eax,%eax
- jnz 1f
+ jnz try486
+
+ /* NexGen CPU does not have aligment check flag. */
+ pushfl
+ movl $0x5555, %eax
+ xorl %edx, %edx
+ movl $2, %ecx
+ clc
+ divl %ecx
+ jz trynexgen
+ popfl
movl $CPU_386,R(_cpu)
jmp 3f
-1: /* Try to toggle identification flag; does not exist on early 486s. */
+trynexgen:
+ movl $CPU_NX586,R(_cpu)
+ movl $0x4778654e,R(_cpu_vendor) # store vendor string
+ movl $0x72446e65,R(_cpu_vendor+4)
+ movl $0x6e657669,R(_cpu_vendor+8)
+ movl $0,R(_cpu_vendor+12)
+ jmp 3f
+
+try486: /* Try to toggle identification flag; does not exist on early 486s. */
pushfl
popl %eax
movl %eax,%ecx
@@ -576,89 +636,40 @@ identify_cpu:
popfl
testl %eax,%eax
- jnz 1f
+ jnz trycpuid
movl $CPU_486,R(_cpu)
- /* check for Cyrix 486DLC -- based on check routine */
- /* documented in "Cx486SLC/e SMM Programmer's Guide" */
- xorw %dx,%dx
- cmpw %dx,%dx # set flags to known state
- pushfw
- popw %cx # store flags in ecx
- movw $0xffff,%ax
- movw $0x0004,%bx
- divw %bx
- pushfw
- popw %ax
- andw $0x08d5,%ax # mask off important bits
- andw $0x08d5,%cx
- cmpw %ax,%cx
-
- jnz 3f # if flags changed, Intel chip
-
- movl $CPU_486DLC,R(_cpu) # set CPU value for Cyrix
+ /*
+ * Check Cyrix CPU
+ * Cyrix CPUs do not change the undefined flags following
+ * execution of the divide instruction which divides 5 by 2.
+ *
+ * Note: CPUID is enabled on M2, so it passes another way.
+ */
+ pushfl
+ movl $0x5555, %eax
+ xorl %edx, %edx
+ movl $2, %ecx
+ clc
+ divl %ecx
+ jnc trycyrix
+ popfl
+ jmp 3f /* You may use Intel CPU. */
+
+trycyrix:
+ popfl
+ /*
+ * IBM Bluelighting CPU also doesn't change the undefined flags.
+ * Because IBM doesn't disclose the information for Bluelighting
+ * CPU, we couldn't distinguish it from Cyrix's (including IBM
+ * brand of Cyrix CPUs).
+ */
movl $0x69727943,R(_cpu_vendor) # store vendor string
- movw $0x0078,R(_cpu_vendor+4)
-
-#ifndef CYRIX_CACHE_WORKS
- /* Disable caching of the ISA hole only. */
- invd
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- orb $(CCR0_NC1|CCR0_BARB),%al
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- invd
-#else /* CYRIX_CACHE_WORKS */
- /* Set cache parameters */
- invd # Start with guaranteed clean cache
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- andb $~CCR0_NC0,%al
-#ifndef CYRIX_CACHE_REALLY_WORKS
- orb $(CCR0_NC1|CCR0_BARB),%al
-#else /* CYRIX_CACHE_REALLY_WORKS */
- orb $CCR0_NC1,%al
-#endif /* !CYRIX_CACHE_REALLY_WORKS */
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- /* clear non-cacheable region 1 */
- movb $(NCR1+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 2 */
- movb $(NCR2+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 3 */
- movb $(NCR3+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 4 */
- movb $(NCR4+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* enable caching in CR0 */
- movl %cr0,%eax
- andl $~(CR0_CD|CR0_NW),%eax
- movl %eax,%cr0
- invd
-#endif /* !CYRIX_CACHE_WORKS */
+ movl $0x736e4978,R(_cpu_vendor+4)
+ movl $0x64616574,R(_cpu_vendor+8)
jmp 3f
-1: /* Use the `cpuid' instruction. */
+trycpuid: /* Use the `cpuid' instruction. */
xorl %eax,%eax
.byte 0x0f,0xa2 # cpuid 0
movl %eax,R(_cpu_high) # highest capability
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index bf3eaa2..c1094ee 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.228 1997/02/22 09:32:26 peter Exp $
+ * $Id: machdep.c,v 1.229 1997/02/24 00:37:43 alex Exp $
*/
#include "npx.h"
@@ -122,8 +122,11 @@ extern int ptrace_single_step __P((struct proc *p));
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
extern void dblfault_handler __P((void));
-extern void identifycpu(void); /* XXX header file */
+extern void printcpuinfo(void); /* XXX header file */
extern void earlysetcpuclass(void); /* same header file */
+extern void finishidentcpu(void);
+extern void panicifcpuunsupported(void);
+extern void initializecpu(void);
static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
@@ -208,7 +211,8 @@ cpu_startup(dummy)
printf(version);
earlysetcpuclass();
startrtclock();
- identifycpu();
+ printcpuinfo();
+ panicifcpuunsupported();
#ifdef PERFMON
perfmon_init();
#endif
@@ -1059,6 +1063,10 @@ init386(first)
Debugger("Boot flags requested debugger");
#endif
+ finishidentcpu(); /* Final stage of CPU initialization */
+ setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ initializecpu(); /* Initialize CPU registers */
+
/* Use BIOS values stored in RTC CMOS RAM, since probing
* breaks certain 386 AT relics.
*/
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 5dd24b1..9cd0351 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: cpufunc.h,v 1.61 1997/02/22 09:34:08 peter Exp $
*/
/*
@@ -196,6 +196,12 @@ insl(u_int port, void *addr, size_t cnt)
}
static __inline void
+invd(void)
+{
+ __asm __volatile("invd");
+}
+
+static __inline void
invlpg(u_int addr)
{
__asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
@@ -339,6 +345,12 @@ setbits(volatile unsigned *addr, u_int bits)
}
static __inline void
+wbinvd(void)
+{
+ __asm __volatile("wbinvd");
+}
+
+static __inline void
write_eflags(u_long ef)
{
__asm __volatile("pushl %0; popfl" : : "r" (ef));
@@ -360,6 +372,7 @@ u_long inl __P((u_int port));
void insb __P((u_int port, void *addr, size_t cnt));
void insl __P((u_int port, void *addr, size_t cnt));
void insw __P((u_int port, void *addr, size_t cnt));
+void invd __P((void));
void invlpg __P((u_int addr));
void invltlb __P((void));
u_short inw __P((u_int port));
@@ -376,6 +389,7 @@ quad_t rdpmc __P((u_int pmc));
quad_t rdtsc __P((void));
u_long read_eflags __P((void));
void setbits __P((volatile unsigned *addr, u_int bits));
+void wbinvd __P((void));
void write_eflags __P((u_long ef));
void wrmsr __P((u_int msr, quad_t newval));
diff --git a/sys/amd64/include/cputypes.h b/sys/amd64/include/cputypes.h
index 4905900..695dafc 100644
--- a/sys/amd64/include/cputypes.h
+++ b/sys/amd64/include/cputypes.h
@@ -24,7 +24,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id$
+ * $Id: cputypes.h,v 1.7 1997/02/22 09:34:14 peter Exp $
*/
#ifndef _MACHINE_CPUTYPES_H_
@@ -52,5 +52,9 @@
#define CPU_586 5 /* Intel P.....m (I hate lawyers; it's TM) */
#define CPU_486DLC 6 /* Cyrix 486DLC */
#define CPU_686 7 /* Pentium Pro */
-
+#define CPU_M1SC 8 /* Cyrix M1sc (aka 5x86) */
+#define CPU_M1 9 /* Cyrix M1 (aka 6x86) */
+#define CPU_BLUE 10 /* IBM BlueLighting CPU */
+#define CPU_M2 11 /* Cyrix M2 (aka enhanced 6x86 with MMX */
+#define CPU_NX586 12 /* NexGen (now AMD) 586 */
#endif /* _MACHINE_CPUTYPES_H_ */
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index c74313f..307257c 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: md_var.h,v 1.12 1997/02/22 09:34:49 peter Exp $
*/
#ifndef _MACHINE_MD_VAR_H_
@@ -41,6 +41,7 @@ extern u_int atdevbase; /* offset in virtual memory of ISA io mem */
extern u_long cpu_feature;
extern u_long cpu_high;
extern u_long cpu_id;
+extern u_long cyrix_did;
extern char cpu_vendor[];
extern char etext[];
extern char kstack[];
@@ -72,4 +73,9 @@ void userconfig __P((void));
void vm_bounce_init __P((void));
int vm_page_zero_idle __P((void));
+#ifdef PC98
+extern int need_pre_dma_flush;
+extern int need_post_dma_flush;
+#endif
+
#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index 7344d8f..8e4dfc7 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91
- * $Id$
+ * $Id: specialreg.h,v 1.12 1997/02/22 09:35:15 peter Exp $
*/
#ifndef _MACHINE_SPECIALREG_H_
@@ -54,11 +54,12 @@
/*
* Bits in 486 special registers:
*/
-#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
-#define CR0_WP 0x00010000 /* Write Protect (honor page protect in all modes) */
-#define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */
-#define CR0_NW 0x20000000 /* Not Write-through */
-#define CR0_CD 0x40000000 /* Cache Disable */
+#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
+#define CR0_WP 0x00010000 /* Write Protect (honor page protect in
+ all modes) */
+#define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */
+#define CR0_NW 0x20000000 /* Not Write-through */
+#define CR0_CD 0x40000000 /* Cache Disable */
/*
* Bits in PPro special registers
@@ -94,26 +95,81 @@
#define CPUID_CMOV 0x8000
/*
- * Cyrix 486 DLC special registers, accessible as IO ports.
+ * Cyrix configuration registers, accessible as IO ports.
*/
-#define CCR0 0xc0 /* configuration control register 0 */
-#define CCR0_NC0 0x01 /* first 64K of each 1M memory region is
- non-cacheable */
-#define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */
-#define CCR0_A20M 0x04 /* enables A20M# input pin */
-#define CCR0_KEN 0x08 /* enables KEN# input pin */
-#define CCR0_FLUSH 0x10 /* enables FLUSH# input pin */
-#define CCR0_BARB 0x20 /* flushes internal cache when entering hold
- state */
-#define CCR0_CO 0x40 /* cache org: 1=direct mapped, 0=2x set assoc */
-#define CCR0_SUSPEND 0x80 /* enables SUSP# and SUSPA# pins */
-
-#define CCR1 0xc1 /* configuration control register 1 */
-#define CCR1_RPL 0x01 /* enables RPLSET and RPLVAL# pins */
-/* the remaining 7 bits of this register are reserved */
+#define CCR0 0xc0 /* Configuration control register 0 */
+#define CCR0_NC0 0x01 /* First 64K of each 1M memory region is
+ non-cacheable */
+#define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */
+#define CCR0_A20M 0x04 /* Enables A20M# input pin */
+#define CCR0_KEN 0x08 /* Enables KEN# input pin */
+#define CCR0_FLUSH 0x10 /* Enables FLUSH# input pin */
+#define CCR0_BARB 0x20 /* Flushes internal cache when entering hold
+ state */
+#define CCR0_CO 0x40 /* Cache org: 1=direct mapped, 0=2x set
+ assoc */
+#define CCR0_SUSPEND 0x80 /* Enables SUSP# and SUSPA# pins */
+
+#define CCR1 0xc1 /* Configuration control register 1 */
+#define CCR1_RPL 0x01 /* Enables RPLSET and RPLVAL# pins */
+#define CCR1_SMI 0x02 /* Enables SMM pins */
+#define CCR1_SMAC 0x04 /* System management memory access */
+#define CCR1_MMAC 0x08 /* Main memory access */
+#define CCR1_NO_LOCK 0x10 /* Negate LOCK# */
+#define CCR1_SM3 0x80 /* SMM address space address region 3 */
+
+#define CCR2 0xc2
+#define CCR2_WB 0x02 /* Enables WB cache interface pins */
+#define CCR2_SADS 0x02 /* Slow ADS */
+#define CCR2_LOCK_NW 0x04 /* LOCK NW Bit */
+#define CCR2_SUSP_HLT 0x08 /* Suspend on HALT */
+#define CCR2_WT1 0x10 /* WT region 1 */
+#define CCR2_WPR1 0x10 /* Write-protect region 1 */
+#define CCR2_BARB 0x20 /* Flushes write-back cache when entering
+ hold state. */
+#define CCR2_BWRT 0x40 /* Enables burst write cycles */
+#define CCR2_USE_SUSP 0x80 /* Enables suspend pins */
+
+#define CCR3 0xc3
+#define CCR3_SMILOCK 0x01 /* SMM register lock */
+#define CCR3_NMI 0x02 /* Enables NMI during SMM */
+#define CCR3_LINBRST 0x04 /* Linear address burst cycles */
+#define CCR3_SMMMODE 0x08 /* SMM Mode */
+#define CCR3_MAPEN0 0x10 /* Enables Map0 */
+#define CCR3_MAPEN1 0x20 /* Enables Map1 */
+#define CCR3_MAPEN2 0x40 /* Enables Map2 */
+#define CCR3_MAPEN3 0x80 /* Enables Map3 */
+
+#define CCR4 0xe8
+#define CCR4_IOMASK 0x07
+#define CCR4_MEM 0x08 /* Enables momory bypassing */
+#define CCR4_DTE 0x10 /* Enables directory table entry cache */
+#define CCR4_FASTFPE 0x20 /* Fast FPU exception */
+#define CCR4_CPUID 0x80 /* Enables CPUID instruction */
+
+#define CCR5 0xe9
+#define CCR5_WT_ALLOC 0x01 /* Write-through allocate */
+#define CCR5_SLOP 0x02 /* LOOP instruction slowed down */
+#define CCR5_LBR1 0x10 /* Local bus region 1 */
+#define CCR5_ARREN 0x20 /* Enables ARR region */
+
+/* Performance Control Register (5x86 only). */
+#define PCR0 0x20
+#define PCR0_RSTK 0x01 /* Enables return stack */
+#define PCR0_BTB 0x02 /* Enables branch target buffer */
+#define PCR0_LOOP 0x04 /* Enables loop */
+#define PCR0_AIS 0x08 /* Enables all instrcutions stalled to
+ serialize pipe. */
+#define PCR0_MLR 0x10 /* Enables reordering of misaligned loads */
+#define PCR0_BTBRT 0x40 /* Enables BTB test register. */
+#define PCR0_LSSER 0x80 /* Disable reorder */
+
+/* Device Identification Registers */
+#define DIR0 0xfe
+#define DIR1 0xff
/*
- * the following four 3-byte registers control the non-cacheable regions.
+ * The following four 3-byte registers control the non-cacheable regions.
* These registers must be written as three separate bytes.
*
* NCRx+0: A31-A24 of starting address
@@ -123,26 +179,98 @@
* The non-cacheable region's starting address must be aligned to the
* size indicated by the NCR_SIZE_xx field.
*/
-#define NCR1 0xc4
-#define NCR2 0xc7
-#define NCR3 0xca
-#define NCR4 0xcd
-
-#define NCR_SIZE_0K 0
-#define NCR_SIZE_4K 1
-#define NCR_SIZE_8K 2
-#define NCR_SIZE_16K 3
-#define NCR_SIZE_32K 4
-#define NCR_SIZE_64K 5
-#define NCR_SIZE_128K 6
-#define NCR_SIZE_256K 7
-#define NCR_SIZE_512K 8
-#define NCR_SIZE_1M 9
-#define NCR_SIZE_2M 10
-#define NCR_SIZE_4M 11
-#define NCR_SIZE_8M 12
-#define NCR_SIZE_16M 13
-#define NCR_SIZE_32M 14
-#define NCR_SIZE_4G 15
+#define NCR1 0xc4
+#define NCR2 0xc7
+#define NCR3 0xca
+#define NCR4 0xcd
+
+#define NCR_SIZE_0K 0
+#define NCR_SIZE_4K 1
+#define NCR_SIZE_8K 2
+#define NCR_SIZE_16K 3
+#define NCR_SIZE_32K 4
+#define NCR_SIZE_64K 5
+#define NCR_SIZE_128K 6
+#define NCR_SIZE_256K 7
+#define NCR_SIZE_512K 8
+#define NCR_SIZE_1M 9
+#define NCR_SIZE_2M 10
+#define NCR_SIZE_4M 11
+#define NCR_SIZE_8M 12
+#define NCR_SIZE_16M 13
+#define NCR_SIZE_32M 14
+#define NCR_SIZE_4G 15
+
+/*
+ * The address region registers are used to specify the location and
+ * size for the eight address regions.
+ *
+ * ARRx + 0: A31-A24 of start address
+ * ARRx + 1: A23-A16 of start address
+ * ARRx + 2: A15-A12 of start address | ARR_SIZE_xx
+ */
+#define ARR0 0xc4
+#define ARR1 0xc7
+#define ARR2 0xca
+#define ARR3 0xcd
+#define ARR4 0xd0
+#define ARR5 0xd3
+#define ARR6 0xd6
+#define ARR7 0xd9
+
+#define ARR_SIZE_0K 0
+#define ARR_SIZE_4K 1
+#define ARR_SIZE_8K 2
+#define ARR_SIZE_16K 3
+#define ARR_SIZE_32K 4
+#define ARR_SIZE_64K 5
+#define ARR_SIZE_128K 6
+#define ARR_SIZE_256K 7
+#define ARR_SIZE_512K 8
+#define ARR_SIZE_1M 9
+#define ARR_SIZE_2M 10
+#define ARR_SIZE_4M 11
+#define ARR_SIZE_8M 12
+#define ARR_SIZE_16M 13
+#define ARR_SIZE_32M 14
+#define ARR_SIZE_4G 15
+
+/*
+ * The region control registers specify the attributes associated with
+ * the ARRx addres regions.
+ */
+#define RCR0 0xdc
+#define RCR1 0xdd
+#define RCR2 0xde
+#define RCR3 0xdf
+#define RCR4 0xe0
+#define RCR5 0xe1
+#define RCR6 0xe2
+#define RCR7 0xe3
+
+#define RCR_RCD 0x01 /* Disables caching for ARRx (x = 0-6). */
+#define RCR_RCE 0x01 /* Enables caching for ARR7. */
+#define RCR_WWO 0x02 /* Weak write ordering. */
+#define RCR_WL 0x04 /* Weak locking. */
+#define RCR_WG 0x08 /* Write gathering. */
+#define RCR_WT 0x10 /* Write-through. */
+#define RCR_NLB 0x20 /* LBA# pin is not asserted. */
+
+
+#ifndef LOCORE
+static __inline u_char
+read_cyrix_reg(u_char reg)
+{
+ outb(0x22, reg);
+ return inb(0x23);
+}
+
+static __inline void
+write_cyrix_reg(u_char reg, u_char data)
+{
+ outb(0x22, reg);
+ outb(0x23, data);
+}
+#endif
#endif /* !_MACHINE_SPECIALREG_H_ */
diff --git a/sys/conf/Makefile.pc98 b/sys/conf/Makefile.pc98
index 8fe080c..ecdb567 100644
--- a/sys/conf/Makefile.pc98
+++ b/sys/conf/Makefile.pc98
@@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id$
+# $Id: Makefile.pc98,v 1.11 1997/02/22 09:43:21 peter Exp $
#
# Makefile for FreeBSD
#
@@ -58,7 +58,7 @@ DRIVER_S= ${CC} -c -x assembler-with-cpp -DLOCORE ${COPTS} $<
PROFILE_C= ${CC} -c ${CFLAGS} ${PARAM} $<
SYSTEM_CFILES= ioconf.c param.c vnode_if.c config.c
-SYSTEM_SFILES= ${PC98}/i386/locore.s
+SYSTEM_SFILES= ${I386}/i386/locore.s
SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} ioconf.o param.o config.o
SYSTEM_DEP= Makefile symbols.exclude symbols.sort ${SYSTEM_OBJS}
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
@@ -89,7 +89,7 @@ clean:
#lint: /tmp param.c
# @lint -hbxn -DGENERIC -Dvolatile= ${COPTS} ${PARAM} \
-# ${PC98}/i386/Locore.c ${CFILES} ioconf.c param.c | \
+# ${I386}/i386/Locore.c ${CFILES} ioconf.c param.c | \
# grep -v 'struct/union .* never defined' | \
# grep -v 'possible pointer alignment problem'
@@ -101,7 +101,7 @@ symbols.sort: ${I386}/i386/symbols.raw
grep -v '^#' ${I386}/i386/symbols.raw \
| sed 's/^ //' | sort -u > symbols.sort
-locore.o: ${PC98}/i386/locore.s assym.s
+locore.o: ${I386}/i386/locore.s assym.s
${NORMAL_S}
# everything potentially depends on the Makefile since everything potentially
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 76c4d17..23103b9 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.155 1997/03/16 07:09:01 gibbs Exp $
+# $Id: files.i386,v 1.156 1997/03/16 17:25:53 bde Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/*.[chyl]" \
@@ -47,6 +47,7 @@ i386/i386/i386-gdbstub.c optional ddb
i386/i386/exception.s standard
i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
+i386/i386/initcpu.c standard
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
# now normal.
# i386/i386/locore.s standard
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index 37cf0a9..b5c3dce 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.16 1997/02/22 09:43:22 peter Exp $
+# $Id: files.pc98,v 1.17 1997/03/19 16:14:25 kato Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/*.[chyl]" \
@@ -49,6 +49,7 @@ i386/i386/i386-gdbstub.c optional ddb
i386/i386/exception.s standard
i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
+i386/i386/initcpu.c standard
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
# now normal.
# i386/i386/locore.s standard
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index eba1a87..cce8411 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.36 1997/02/28 16:56:06 bde Exp $
+# $Id: options.i386,v 1.37 1997/03/12 17:41:35 joerg Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -37,10 +37,23 @@ CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
CLK_USE_I586_CALIBRATION opt_clock.h
-I386_CPU opt_cpu.h
-I486_CPU opt_cpu.h
-I586_CPU opt_cpu.h
-I686_CPU opt_cpu.h
+CPU_BLUELIGHTNING_FPU_OP_CACHE opt_cpu.h
+CPU_BLUELIGHTNING_3X opt_cpu.h
+CPU_BTB_EN opt_cpu.h
+CPU_DISABLE_5X86_LSSER opt_cpu.h
+CPU_FASTER_5X86_FPU opt_cpu.h
+CPU_I486_ON_386 opt_cpu.h
+CPU_IORT opt_cpu.h
+CPU_LOOP_EN opt_cpu.h
+CPU_RSTK_EN opt_cpu.h
+CPU_SUSP_HLT opt_cpu.h
+CPU_UPGRADE_HW_CACHE opt_cpu.h
+CYRIX_CACHE_WORKS opt_cpu.h
+CYRIX_CACHE_REALLY_WORKS opt_cpu.h
+I386_CPU opt_cpu.h
+I486_CPU opt_cpu.h
+I586_CPU opt_cpu.h
+I686_CPU opt_cpu.h
SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index cf26896..38d240f 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.17 1997/03/01 11:06:41 kato Exp $
+# $Id: options.pc98,v 1.18 1997/03/13 17:04:23 kato Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -37,10 +37,21 @@ CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
CLK_USE_I586_CALIBRATION opt_clock.h
-I386_CPU opt_cpu.h
-I486_CPU opt_cpu.h
-I586_CPU opt_cpu.h
-I686_CPU opt_cpu.h
+CPU_BTB_EN opt_cpu.h
+CPU_DISABLE_5X86_LSSER opt_cpu.h
+CPU_FASTER_5X86_FPU opt_cpu.h
+CPU_I486_ON_386 opt_cpu.h
+CPU_IORT opt_cpu.h
+CPU_LOOP_EN opt_cpu.h
+CPU_RSTK_EN opt_cpu.h
+CPU_SUSP_HLT opt_cpu.h
+CPU_UPGRADE_HW_CACHE opt_cpu.h
+CYRIX_CACHE_WORKS opt_cpu.h
+CYRIX_CACHE_REALLY_WORKS opt_cpu.h
+I386_CPU opt_cpu.h
+I486_CPU opt_cpu.h
+I586_CPU opt_cpu.h
+I686_CPU opt_cpu.h
SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 76c4d17..23103b9 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.155 1997/03/16 07:09:01 gibbs Exp $
+# $Id: files.i386,v 1.156 1997/03/16 17:25:53 bde Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/*.[chyl]" \
@@ -47,6 +47,7 @@ i386/i386/i386-gdbstub.c optional ddb
i386/i386/exception.s standard
i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
+i386/i386/initcpu.c standard
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
# now normal.
# i386/i386/locore.s standard
diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386
index eba1a87..cce8411 100644
--- a/sys/i386/conf/options.i386
+++ b/sys/i386/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.36 1997/02/28 16:56:06 bde Exp $
+# $Id: options.i386,v 1.37 1997/03/12 17:41:35 joerg Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -37,10 +37,23 @@ CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
CLK_USE_I586_CALIBRATION opt_clock.h
-I386_CPU opt_cpu.h
-I486_CPU opt_cpu.h
-I586_CPU opt_cpu.h
-I686_CPU opt_cpu.h
+CPU_BLUELIGHTNING_FPU_OP_CACHE opt_cpu.h
+CPU_BLUELIGHTNING_3X opt_cpu.h
+CPU_BTB_EN opt_cpu.h
+CPU_DISABLE_5X86_LSSER opt_cpu.h
+CPU_FASTER_5X86_FPU opt_cpu.h
+CPU_I486_ON_386 opt_cpu.h
+CPU_IORT opt_cpu.h
+CPU_LOOP_EN opt_cpu.h
+CPU_RSTK_EN opt_cpu.h
+CPU_SUSP_HLT opt_cpu.h
+CPU_UPGRADE_HW_CACHE opt_cpu.h
+CYRIX_CACHE_WORKS opt_cpu.h
+CYRIX_CACHE_REALLY_WORKS opt_cpu.h
+I386_CPU opt_cpu.h
+I486_CPU opt_cpu.h
+I586_CPU opt_cpu.h
+I686_CPU opt_cpu.h
SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index b4b8af8..e78382b 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -1,6 +1,7 @@
-/*-
+/*
* Copyright (c) 1992 Terrence R. Lambert.
* Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
+ * Copyright (c) 1997 KATO Takenori.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -35,7 +36,7 @@
* SUCH DAMAGE.
*
* from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
- * $Id$
+ * $Id: identcpu.c,v 1.13 1997/02/22 09:32:19 peter Exp $
*/
#include "opt_cpu.h"
@@ -54,12 +55,18 @@
#include <machine/sysarch.h>
#include <machine/md_var.h>
+#include <i386/isa/isa_device.h>
+
/* XXX - should be in header file */
void i486_bzero __P((void *buf, size_t len));
-void identifycpu(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);
+static void identifycyrix(void);
+u_long cyrix_did; /* Device ID of Cyirx CPU */
int cpu_class = CPUCLASS_386; /* least common denominator */
char machine[] = "i386";
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
@@ -74,13 +81,19 @@ static struct cpu_nameclass i386_cpus[] = {
{ "i486SX", CPUCLASS_486 }, /* CPU_486SX */
{ "i486DX", CPUCLASS_486 }, /* CPU_486 */
{ "Pentium", CPUCLASS_586 }, /* CPU_586 */
- { "Cy486DLC", CPUCLASS_486 }, /* CPU_486DLC */
+ { "Cyrix 486", CPUCLASS_486 }, /* CPU_486DLC */
{ "Pentium Pro", CPUCLASS_686 }, /* CPU_686 */
+ { "Cyrix 5x86", CPUCLASS_486 }, /* CPU_M1SC */
+ { "Cyrix 6x86", CPUCLASS_486 }, /* CPU_M1 */
+ { "Blue Lightning", CPUCLASS_486 }, /* CPU_BLUE */
+ { "Cyrix 6x86 MMX", CPUCLASS_586 }, /* CPU_M2 (XXX) */
+ { "NexGen 586", CPUCLASS_386 }, /* CPU_NX586 (XXX) */
};
void
-identifycpu(void)
+printcpuinfo(void)
{
+
cpu_class = i386_cpus[cpu].cpu_class;
printf("CPU: ");
strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model);
@@ -140,7 +153,6 @@ identifycpu(void)
* Values taken from AMD Processor Recognition
* http://www.amd.com/html/products/pcd/techdocs/appnotes/20734c.pdf
*/
- cpu_model[0] = '\0';
strcpy(cpu_model, "AMD ");
switch (cpu_id & 0xFF0) {
case 0x4E0:
@@ -162,8 +174,119 @@ identifycpu(void)
strcat(cpu_model, "Unknown");
break;
}
- }
+ } else if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
+ strcpy(cpu_model, "Cyrix ");
+ switch (cyrix_did & 0xf0) {
+ case 0x00:
+ switch (cyrix_did & 0x0f) {
+ case 0x00:
+ strcat(cpu_model, "486SLC");
+ break;
+ case 0x01:
+ strcat(cpu_model, "486DLC");
+ break;
+ case 0x02:
+ strcat(cpu_model, "486SLC2");
+ break;
+ case 0x03:
+ strcat(cpu_model, "486DLC2");
+ break;
+ case 0x04:
+ strcat(cpu_model, "486SRx");
+ break;
+ case 0x05:
+ strcat(cpu_model, "486DRx");
+ break;
+ case 0x06:
+ strcat(cpu_model, "486SRx2");
+ break;
+ case 0x07:
+ strcat(cpu_model, "486DRx2");
+ break;
+ case 0x08:
+ strcat(cpu_model, "486SRu");
+ break;
+ case 0x09:
+ strcat(cpu_model, "486DRu");
+ break;
+ case 0x0a:
+ strcat(cpu_model, "486SRu2");
+ break;
+ case 0x0b:
+ strcat(cpu_model, "486DRu2");
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ break;
+ case 0x10:
+ switch (cyrix_did & 0x0f) {
+ case 0x00:
+ strcat(cpu_model, "486S");
+ break;
+ case 0x01:
+ strcat(cpu_model, "486S2");
+ break;
+ case 0x02:
+ strcat(cpu_model, "486Se");
+ break;
+ case 0x03:
+ strcat(cpu_model, "486S2e");
+ break;
+ case 0x0a:
+ strcat(cpu_model, "486DX");
+ break;
+ case 0x0b:
+ strcat(cpu_model, "486DX2");
+ break;
+ case 0x0f:
+ strcat(cpu_model, "486DX4");
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ break;
+ case 0x20:
+ if ((cyrix_did & 0x0f) < 8)
+ strcat(cpu_model, "6x86"); /* Where did you get it? */
+ else
+ strcat(cpu_model, "5x86");
+ break;
+ case 0x30:
+ strcat(cpu_model, "6x86");
+ break;
+ case 0x40:
+ /* XXX */
+ strcat(cpu_model, "Gx86");
+ break;
+ case 0x50:
+ strcat(cpu_model, "Enhanced 6x86 with MMX");
+ break;
+ case 0xf0:
+ switch (cyrix_did & 0x0f) {
+ case 0x0d:
+ strcat(cpu_model, "Overdrive CPU");
+ case 0x0e:
+ strcpy(cpu_model, "Texas Instruments 486SXL");
+ break;
+ case 0x0f:
+ strcat(cpu_model, "486SLC/DLC");
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ break;
+ default:
+ strcat(cpu_model, "Unknown");
+ break;
+ }
+ } else if (strcmp(cpu_vendor,"IBM") == 0)
+ strcpy(cpu_model, "Blue Lightning CPU");
#endif
+
printf("%s (", cpu_model);
switch(cpu_class) {
case CPUCLASS_286:
@@ -238,6 +361,14 @@ identifycpu(void)
"\020CMOV"
);
}
+ } else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
+ printf(" Device ID = 0x%lx", cyrix_did);
+ printf(" Stepping=%ld", (cyrix_did & 0xf000) >> 12);
+ printf(" Revision=%ld", (cyrix_did & 0x0fff) >> 8);
+#ifndef CYRIX_CACHE_REALLY_WORKS
+ if (cpu == CPU_M1 && (cyrix_did & 0xff00) < 0x1700)
+ printf("\n CPU cache: write-through mode");
+#endif
}
/* Avoid ugly blank lines: only print newline when we have to. */
if (*cpu_vendor || cpu_id)
@@ -248,6 +379,11 @@ identifycpu(void)
* XXX - Do PPro CPUID level=2 stuff here?
*/
#endif
+}
+
+void
+panicifcpuunsupported(void)
+{
/*
* Now that we have told the user what they have,
@@ -276,6 +412,152 @@ identifycpu(void)
}
}
+
+static volatile u_int trap_by_wrmsr;
+
+/*
+ * Special exception 16 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;
+asm
+("
+ .text
+_bluetrap:
+ ss
+ movl $0xa8c1d, _trap_by_wrmsr # Don't ask meaning of the number :-).
+ addl $2, (%esp) # I know wrmsr is a 2-bytes instruction.
+ iret
+");
+
+/*
+ * Distinguish IBM Blue Lightning CPU from Cyrix CPUs that does not
+ * support cpuid instruction. This function should be called after
+ * loading interrupt descriptor table register.
+ *
+ * I don't like this method that handles fault, but I couldn't get
+ * information for any other methods. Does blue giant know?
+ */
+static int
+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 tra_by_wrmsr.
+ */
+ setidt(6, bluetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ wrmsr(0x1002, 0x03000000LL); /* Fault on Cyrix 486-class CPU. */
+
+ if (trap_by_wrmsr == 0xa8c1d)
+ return 0; /* Cyrix CPU sets the magic number. */
+
+ return 1; /* IBM Blue Lightnig CPU */
+}
+
+
+/*
+ * identifycyrix() set lower 16 bits of cyrix_did as follows:
+ *
+ * F E D C B A 9 8 7 6 5 4 3 2 1 0
+ * +-------+-------+---------------+
+ * | SID | RID | Device ID |
+ * | (DIR 1) | (DIR 0) |
+ * +-------+-------+---------------+
+ */
+static void
+identifycyrix(void)
+{
+ u_long eflags;
+ int ccr2_test = 0, dir_test = 0;
+ u_char ccr2, ccr3;
+
+ eflags = read_eflags();
+ disable_intr();
+
+ ccr2 = read_cyrix_reg(CCR2);
+ write_cyrix_reg(CCR2, ccr2 ^ CCR2_LOCK_NW);
+ read_cyrix_reg(CCR2);
+ if (read_cyrix_reg(CCR2) != ccr2)
+ ccr2_test = 1;
+ write_cyrix_reg(CCR2, ccr2);
+
+ ccr3 = read_cyrix_reg(CCR3);
+ write_cyrix_reg(CCR3, ccr3 ^ CCR3_MAPEN3);
+ read_cyrix_reg(CCR3);
+ if (read_cyrix_reg(CCR3) != ccr3)
+ dir_test = 1; /* CPU supports DIRs. */
+ write_cyrix_reg(CCR3, ccr3);
+
+ if (dir_test) {
+ /* Device ID registers are available. */
+ cyrix_did = read_cyrix_reg(DIR1) << 8;
+ cyrix_did += read_cyrix_reg(DIR0);
+ } else if (ccr2_test)
+ cyrix_did = 0x0010; /* 486S A-step */
+ else
+ cyrix_did = 0x00ff; /* Old 486SLC/DLC and TI486SXLC/SXL */
+
+ write_eflags(eflags);
+}
+
+/*
+ * Final stage of CPU identification. -- Should I check TI?
+ */
+void
+finishidentcpu(void)
+{
+
+ if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
+ if (cpu == CPU_486) {
+ /*
+ * These conditions are equivalent to:
+ * - CPU does not support cpuid instruction.
+ * - Cyrix/IBM CPU is detected.
+ */
+ if (identblue()) {
+ strcpy(cpu_vendor, "IBM");
+ cpu = CPU_BLUE;
+ return;
+ }
+ }
+ identifycyrix();
+ /*
+ * This routine contains a trick.
+ * Don't check (cpu_id & 0x00f0) == 0x50 to detect M2, now.
+ */
+ switch (cyrix_did & 0x00f0) {
+ case 0x00:
+ case 0x10:
+ case 0xf0:
+ cpu = CPU_486DLC;
+ break;
+ case 0x20:
+ if ((cyrix_did & 0x00f0) < 8)
+ cpu = CPU_M1;
+ else
+ cpu = CPU_M1SC;
+ break;
+ case 0x30:
+ cpu = CPU_M1;
+ break;
+ case 0x40:
+ cpu = CPU_M1SC;
+ break;
+ default:
+ /* M2 and later CPUs are treated as M2. */
+ cpu = CPU_M2;
+ break;
+ }
+ }
+}
+
/*
* This routine is called specifically to set up cpu_class before
* startrtclock() uses it. Probably this should be rearranged so that
@@ -287,5 +569,6 @@ identifycpu(void)
void
earlysetcpuclass(void)
{
+
cpu_class = i386_cpus[cpu].cpu_class;
}
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 95930fe..5efddc5 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id$
+ * $Id: locore.s,v 1.81 1997/02/22 09:32:22 peter Exp $
*
* originally from: locore.s, by William F. Jolitz
*
@@ -192,6 +192,21 @@ _bdb_exists: .long 0
*/
NON_GPROF_ENTRY(btext)
+#ifdef PC98
+ jmp 1f
+ .globl _pc98_system_parameter
+ .org 0x400
+_pc98_system_parameter:
+ .space 0x240 /* BIOS parameter block */
+1:
+ /* save SYSTEM PARAMETER for resume (NS/T or other) */
+ movl $0xa1000,%esi
+ movl $0x100000,%edi
+ movl $0x0630,%ecx
+ cld
+ rep
+ movsb
+#else /* IBM-PC */
#ifdef BDE_DEBUGGER
#ifdef BIOS_STEALS_3K
cmpl $0x0375c339,0x95504
@@ -205,6 +220,7 @@ NON_GPROF_ENTRY(btext)
/* Tell the bios to warmboot next time */
movw $0x1234,0x472
+#endif /* PC98 */
/* Set up a real frame in case the double return in newboot is executed. */
pushl %ebp
@@ -232,6 +248,28 @@ NON_GPROF_ENTRY(btext)
*/
movl $R(tmpstk),%esp
+#ifdef PC98
+ testb $0x02,0x100620 /* pc98_machine_type & M_EPSON_PC98 */
+ jz 3f
+ cmpb $0x0b,0x100624 /* epson_machine_id <= 0x0b */
+ ja 3f
+
+ /* count up memory */
+ movl $0x100000,%eax /* next, talley remaining memory */
+ movl $0xFFF-0x100,%ecx
+1: movl 0(%eax),%ebx /* save location to check */
+ movl $0xa55a5aa5,0(%eax) /* write test pattern */
+ cmpl $0xa55a5aa5,0(%eax) /* does not check yet for rollover */
+ jne 2f
+ movl %ebx,0(%eax) /* restore memory */
+ addl $PAGE_SIZE,%eax
+ loop 1b
+2: subl $0x100000,%eax
+ shrl $17,%eax
+ movb %al,0x100401
+3:
+#endif
+
call identify_cpu
/* clear bss */
@@ -326,7 +364,7 @@ begin:
addl $(13*4),%esp /* back to a frame we can return with */
/*
- * now we've run main() and determined what cpu-type we are, we can
+ * Now we've run main() and determined what cpu-type we are, we can
* enable write protection and alignment checking on i486 cpus and
* above.
*/
@@ -524,7 +562,11 @@ olddiskboot:
movl %eax,R(_bootdev)
#if defined(USERCONFIG_BOOT) && defined(USERCONFIG)
+#ifdef PC98
+ movl $0x90200, %esi
+#else
movl $0x10200, %esi
+#endif
movl $R(_userconfig_from_boot),%edi
movl $512,%ecx
cld
@@ -557,11 +599,29 @@ identify_cpu:
popfl
testl %eax,%eax
- jnz 1f
+ jnz try486
+
+ /* NexGen CPU does not have aligment check flag. */
+ pushfl
+ movl $0x5555, %eax
+ xorl %edx, %edx
+ movl $2, %ecx
+ clc
+ divl %ecx
+ jz trynexgen
+ popfl
movl $CPU_386,R(_cpu)
jmp 3f
-1: /* Try to toggle identification flag; does not exist on early 486s. */
+trynexgen:
+ movl $CPU_NX586,R(_cpu)
+ movl $0x4778654e,R(_cpu_vendor) # store vendor string
+ movl $0x72446e65,R(_cpu_vendor+4)
+ movl $0x6e657669,R(_cpu_vendor+8)
+ movl $0,R(_cpu_vendor+12)
+ jmp 3f
+
+try486: /* Try to toggle identification flag; does not exist on early 486s. */
pushfl
popl %eax
movl %eax,%ecx
@@ -576,89 +636,40 @@ identify_cpu:
popfl
testl %eax,%eax
- jnz 1f
+ jnz trycpuid
movl $CPU_486,R(_cpu)
- /* check for Cyrix 486DLC -- based on check routine */
- /* documented in "Cx486SLC/e SMM Programmer's Guide" */
- xorw %dx,%dx
- cmpw %dx,%dx # set flags to known state
- pushfw
- popw %cx # store flags in ecx
- movw $0xffff,%ax
- movw $0x0004,%bx
- divw %bx
- pushfw
- popw %ax
- andw $0x08d5,%ax # mask off important bits
- andw $0x08d5,%cx
- cmpw %ax,%cx
-
- jnz 3f # if flags changed, Intel chip
-
- movl $CPU_486DLC,R(_cpu) # set CPU value for Cyrix
+ /*
+ * Check Cyrix CPU
+ * Cyrix CPUs do not change the undefined flags following
+ * execution of the divide instruction which divides 5 by 2.
+ *
+ * Note: CPUID is enabled on M2, so it passes another way.
+ */
+ pushfl
+ movl $0x5555, %eax
+ xorl %edx, %edx
+ movl $2, %ecx
+ clc
+ divl %ecx
+ jnc trycyrix
+ popfl
+ jmp 3f /* You may use Intel CPU. */
+
+trycyrix:
+ popfl
+ /*
+ * IBM Bluelighting CPU also doesn't change the undefined flags.
+ * Because IBM doesn't disclose the information for Bluelighting
+ * CPU, we couldn't distinguish it from Cyrix's (including IBM
+ * brand of Cyrix CPUs).
+ */
movl $0x69727943,R(_cpu_vendor) # store vendor string
- movw $0x0078,R(_cpu_vendor+4)
-
-#ifndef CYRIX_CACHE_WORKS
- /* Disable caching of the ISA hole only. */
- invd
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- orb $(CCR0_NC1|CCR0_BARB),%al
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- invd
-#else /* CYRIX_CACHE_WORKS */
- /* Set cache parameters */
- invd # Start with guaranteed clean cache
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- andb $~CCR0_NC0,%al
-#ifndef CYRIX_CACHE_REALLY_WORKS
- orb $(CCR0_NC1|CCR0_BARB),%al
-#else /* CYRIX_CACHE_REALLY_WORKS */
- orb $CCR0_NC1,%al
-#endif /* !CYRIX_CACHE_REALLY_WORKS */
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- /* clear non-cacheable region 1 */
- movb $(NCR1+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 2 */
- movb $(NCR2+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 3 */
- movb $(NCR3+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 4 */
- movb $(NCR4+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* enable caching in CR0 */
- movl %cr0,%eax
- andl $~(CR0_CD|CR0_NW),%eax
- movl %eax,%cr0
- invd
-#endif /* !CYRIX_CACHE_WORKS */
+ movl $0x736e4978,R(_cpu_vendor+4)
+ movl $0x64616574,R(_cpu_vendor+8)
jmp 3f
-1: /* Use the `cpuid' instruction. */
+trycpuid: /* Use the `cpuid' instruction. */
xorl %eax,%eax
.byte 0x0f,0xa2 # cpuid 0
movl %eax,R(_cpu_high) # highest capability
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index bf3eaa2..c1094ee 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.228 1997/02/22 09:32:26 peter Exp $
+ * $Id: machdep.c,v 1.229 1997/02/24 00:37:43 alex Exp $
*/
#include "npx.h"
@@ -122,8 +122,11 @@ extern int ptrace_single_step __P((struct proc *p));
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
extern void dblfault_handler __P((void));
-extern void identifycpu(void); /* XXX header file */
+extern void printcpuinfo(void); /* XXX header file */
extern void earlysetcpuclass(void); /* same header file */
+extern void finishidentcpu(void);
+extern void panicifcpuunsupported(void);
+extern void initializecpu(void);
static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
@@ -208,7 +211,8 @@ cpu_startup(dummy)
printf(version);
earlysetcpuclass();
startrtclock();
- identifycpu();
+ printcpuinfo();
+ panicifcpuunsupported();
#ifdef PERFMON
perfmon_init();
#endif
@@ -1059,6 +1063,10 @@ init386(first)
Debugger("Boot flags requested debugger");
#endif
+ finishidentcpu(); /* Final stage of CPU initialization */
+ setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ initializecpu(); /* Initialize CPU registers */
+
/* Use BIOS values stored in RTC CMOS RAM, since probing
* breaks certain 386 AT relics.
*/
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index 5dd24b1..9cd0351 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: cpufunc.h,v 1.61 1997/02/22 09:34:08 peter Exp $
*/
/*
@@ -196,6 +196,12 @@ insl(u_int port, void *addr, size_t cnt)
}
static __inline void
+invd(void)
+{
+ __asm __volatile("invd");
+}
+
+static __inline void
invlpg(u_int addr)
{
__asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
@@ -339,6 +345,12 @@ setbits(volatile unsigned *addr, u_int bits)
}
static __inline void
+wbinvd(void)
+{
+ __asm __volatile("wbinvd");
+}
+
+static __inline void
write_eflags(u_long ef)
{
__asm __volatile("pushl %0; popfl" : : "r" (ef));
@@ -360,6 +372,7 @@ u_long inl __P((u_int port));
void insb __P((u_int port, void *addr, size_t cnt));
void insl __P((u_int port, void *addr, size_t cnt));
void insw __P((u_int port, void *addr, size_t cnt));
+void invd __P((void));
void invlpg __P((u_int addr));
void invltlb __P((void));
u_short inw __P((u_int port));
@@ -376,6 +389,7 @@ quad_t rdpmc __P((u_int pmc));
quad_t rdtsc __P((void));
u_long read_eflags __P((void));
void setbits __P((volatile unsigned *addr, u_int bits));
+void wbinvd __P((void));
void write_eflags __P((u_long ef));
void wrmsr __P((u_int msr, quad_t newval));
diff --git a/sys/i386/include/cputypes.h b/sys/i386/include/cputypes.h
index 4905900..695dafc 100644
--- a/sys/i386/include/cputypes.h
+++ b/sys/i386/include/cputypes.h
@@ -24,7 +24,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id$
+ * $Id: cputypes.h,v 1.7 1997/02/22 09:34:14 peter Exp $
*/
#ifndef _MACHINE_CPUTYPES_H_
@@ -52,5 +52,9 @@
#define CPU_586 5 /* Intel P.....m (I hate lawyers; it's TM) */
#define CPU_486DLC 6 /* Cyrix 486DLC */
#define CPU_686 7 /* Pentium Pro */
-
+#define CPU_M1SC 8 /* Cyrix M1sc (aka 5x86) */
+#define CPU_M1 9 /* Cyrix M1 (aka 6x86) */
+#define CPU_BLUE 10 /* IBM BlueLighting CPU */
+#define CPU_M2 11 /* Cyrix M2 (aka enhanced 6x86 with MMX */
+#define CPU_NX586 12 /* NexGen (now AMD) 586 */
#endif /* _MACHINE_CPUTYPES_H_ */
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index c74313f..307257c 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: md_var.h,v 1.12 1997/02/22 09:34:49 peter Exp $
*/
#ifndef _MACHINE_MD_VAR_H_
@@ -41,6 +41,7 @@ extern u_int atdevbase; /* offset in virtual memory of ISA io mem */
extern u_long cpu_feature;
extern u_long cpu_high;
extern u_long cpu_id;
+extern u_long cyrix_did;
extern char cpu_vendor[];
extern char etext[];
extern char kstack[];
@@ -72,4 +73,9 @@ void userconfig __P((void));
void vm_bounce_init __P((void));
int vm_page_zero_idle __P((void));
+#ifdef PC98
+extern int need_pre_dma_flush;
+extern int need_post_dma_flush;
+#endif
+
#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
index 7344d8f..8e4dfc7 100644
--- a/sys/i386/include/specialreg.h
+++ b/sys/i386/include/specialreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91
- * $Id$
+ * $Id: specialreg.h,v 1.12 1997/02/22 09:35:15 peter Exp $
*/
#ifndef _MACHINE_SPECIALREG_H_
@@ -54,11 +54,12 @@
/*
* Bits in 486 special registers:
*/
-#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
-#define CR0_WP 0x00010000 /* Write Protect (honor page protect in all modes) */
-#define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */
-#define CR0_NW 0x20000000 /* Not Write-through */
-#define CR0_CD 0x40000000 /* Cache Disable */
+#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
+#define CR0_WP 0x00010000 /* Write Protect (honor page protect in
+ all modes) */
+#define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */
+#define CR0_NW 0x20000000 /* Not Write-through */
+#define CR0_CD 0x40000000 /* Cache Disable */
/*
* Bits in PPro special registers
@@ -94,26 +95,81 @@
#define CPUID_CMOV 0x8000
/*
- * Cyrix 486 DLC special registers, accessible as IO ports.
+ * Cyrix configuration registers, accessible as IO ports.
*/
-#define CCR0 0xc0 /* configuration control register 0 */
-#define CCR0_NC0 0x01 /* first 64K of each 1M memory region is
- non-cacheable */
-#define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */
-#define CCR0_A20M 0x04 /* enables A20M# input pin */
-#define CCR0_KEN 0x08 /* enables KEN# input pin */
-#define CCR0_FLUSH 0x10 /* enables FLUSH# input pin */
-#define CCR0_BARB 0x20 /* flushes internal cache when entering hold
- state */
-#define CCR0_CO 0x40 /* cache org: 1=direct mapped, 0=2x set assoc */
-#define CCR0_SUSPEND 0x80 /* enables SUSP# and SUSPA# pins */
-
-#define CCR1 0xc1 /* configuration control register 1 */
-#define CCR1_RPL 0x01 /* enables RPLSET and RPLVAL# pins */
-/* the remaining 7 bits of this register are reserved */
+#define CCR0 0xc0 /* Configuration control register 0 */
+#define CCR0_NC0 0x01 /* First 64K of each 1M memory region is
+ non-cacheable */
+#define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */
+#define CCR0_A20M 0x04 /* Enables A20M# input pin */
+#define CCR0_KEN 0x08 /* Enables KEN# input pin */
+#define CCR0_FLUSH 0x10 /* Enables FLUSH# input pin */
+#define CCR0_BARB 0x20 /* Flushes internal cache when entering hold
+ state */
+#define CCR0_CO 0x40 /* Cache org: 1=direct mapped, 0=2x set
+ assoc */
+#define CCR0_SUSPEND 0x80 /* Enables SUSP# and SUSPA# pins */
+
+#define CCR1 0xc1 /* Configuration control register 1 */
+#define CCR1_RPL 0x01 /* Enables RPLSET and RPLVAL# pins */
+#define CCR1_SMI 0x02 /* Enables SMM pins */
+#define CCR1_SMAC 0x04 /* System management memory access */
+#define CCR1_MMAC 0x08 /* Main memory access */
+#define CCR1_NO_LOCK 0x10 /* Negate LOCK# */
+#define CCR1_SM3 0x80 /* SMM address space address region 3 */
+
+#define CCR2 0xc2
+#define CCR2_WB 0x02 /* Enables WB cache interface pins */
+#define CCR2_SADS 0x02 /* Slow ADS */
+#define CCR2_LOCK_NW 0x04 /* LOCK NW Bit */
+#define CCR2_SUSP_HLT 0x08 /* Suspend on HALT */
+#define CCR2_WT1 0x10 /* WT region 1 */
+#define CCR2_WPR1 0x10 /* Write-protect region 1 */
+#define CCR2_BARB 0x20 /* Flushes write-back cache when entering
+ hold state. */
+#define CCR2_BWRT 0x40 /* Enables burst write cycles */
+#define CCR2_USE_SUSP 0x80 /* Enables suspend pins */
+
+#define CCR3 0xc3
+#define CCR3_SMILOCK 0x01 /* SMM register lock */
+#define CCR3_NMI 0x02 /* Enables NMI during SMM */
+#define CCR3_LINBRST 0x04 /* Linear address burst cycles */
+#define CCR3_SMMMODE 0x08 /* SMM Mode */
+#define CCR3_MAPEN0 0x10 /* Enables Map0 */
+#define CCR3_MAPEN1 0x20 /* Enables Map1 */
+#define CCR3_MAPEN2 0x40 /* Enables Map2 */
+#define CCR3_MAPEN3 0x80 /* Enables Map3 */
+
+#define CCR4 0xe8
+#define CCR4_IOMASK 0x07
+#define CCR4_MEM 0x08 /* Enables momory bypassing */
+#define CCR4_DTE 0x10 /* Enables directory table entry cache */
+#define CCR4_FASTFPE 0x20 /* Fast FPU exception */
+#define CCR4_CPUID 0x80 /* Enables CPUID instruction */
+
+#define CCR5 0xe9
+#define CCR5_WT_ALLOC 0x01 /* Write-through allocate */
+#define CCR5_SLOP 0x02 /* LOOP instruction slowed down */
+#define CCR5_LBR1 0x10 /* Local bus region 1 */
+#define CCR5_ARREN 0x20 /* Enables ARR region */
+
+/* Performance Control Register (5x86 only). */
+#define PCR0 0x20
+#define PCR0_RSTK 0x01 /* Enables return stack */
+#define PCR0_BTB 0x02 /* Enables branch target buffer */
+#define PCR0_LOOP 0x04 /* Enables loop */
+#define PCR0_AIS 0x08 /* Enables all instrcutions stalled to
+ serialize pipe. */
+#define PCR0_MLR 0x10 /* Enables reordering of misaligned loads */
+#define PCR0_BTBRT 0x40 /* Enables BTB test register. */
+#define PCR0_LSSER 0x80 /* Disable reorder */
+
+/* Device Identification Registers */
+#define DIR0 0xfe
+#define DIR1 0xff
/*
- * the following four 3-byte registers control the non-cacheable regions.
+ * The following four 3-byte registers control the non-cacheable regions.
* These registers must be written as three separate bytes.
*
* NCRx+0: A31-A24 of starting address
@@ -123,26 +179,98 @@
* The non-cacheable region's starting address must be aligned to the
* size indicated by the NCR_SIZE_xx field.
*/
-#define NCR1 0xc4
-#define NCR2 0xc7
-#define NCR3 0xca
-#define NCR4 0xcd
-
-#define NCR_SIZE_0K 0
-#define NCR_SIZE_4K 1
-#define NCR_SIZE_8K 2
-#define NCR_SIZE_16K 3
-#define NCR_SIZE_32K 4
-#define NCR_SIZE_64K 5
-#define NCR_SIZE_128K 6
-#define NCR_SIZE_256K 7
-#define NCR_SIZE_512K 8
-#define NCR_SIZE_1M 9
-#define NCR_SIZE_2M 10
-#define NCR_SIZE_4M 11
-#define NCR_SIZE_8M 12
-#define NCR_SIZE_16M 13
-#define NCR_SIZE_32M 14
-#define NCR_SIZE_4G 15
+#define NCR1 0xc4
+#define NCR2 0xc7
+#define NCR3 0xca
+#define NCR4 0xcd
+
+#define NCR_SIZE_0K 0
+#define NCR_SIZE_4K 1
+#define NCR_SIZE_8K 2
+#define NCR_SIZE_16K 3
+#define NCR_SIZE_32K 4
+#define NCR_SIZE_64K 5
+#define NCR_SIZE_128K 6
+#define NCR_SIZE_256K 7
+#define NCR_SIZE_512K 8
+#define NCR_SIZE_1M 9
+#define NCR_SIZE_2M 10
+#define NCR_SIZE_4M 11
+#define NCR_SIZE_8M 12
+#define NCR_SIZE_16M 13
+#define NCR_SIZE_32M 14
+#define NCR_SIZE_4G 15
+
+/*
+ * The address region registers are used to specify the location and
+ * size for the eight address regions.
+ *
+ * ARRx + 0: A31-A24 of start address
+ * ARRx + 1: A23-A16 of start address
+ * ARRx + 2: A15-A12 of start address | ARR_SIZE_xx
+ */
+#define ARR0 0xc4
+#define ARR1 0xc7
+#define ARR2 0xca
+#define ARR3 0xcd
+#define ARR4 0xd0
+#define ARR5 0xd3
+#define ARR6 0xd6
+#define ARR7 0xd9
+
+#define ARR_SIZE_0K 0
+#define ARR_SIZE_4K 1
+#define ARR_SIZE_8K 2
+#define ARR_SIZE_16K 3
+#define ARR_SIZE_32K 4
+#define ARR_SIZE_64K 5
+#define ARR_SIZE_128K 6
+#define ARR_SIZE_256K 7
+#define ARR_SIZE_512K 8
+#define ARR_SIZE_1M 9
+#define ARR_SIZE_2M 10
+#define ARR_SIZE_4M 11
+#define ARR_SIZE_8M 12
+#define ARR_SIZE_16M 13
+#define ARR_SIZE_32M 14
+#define ARR_SIZE_4G 15
+
+/*
+ * The region control registers specify the attributes associated with
+ * the ARRx addres regions.
+ */
+#define RCR0 0xdc
+#define RCR1 0xdd
+#define RCR2 0xde
+#define RCR3 0xdf
+#define RCR4 0xe0
+#define RCR5 0xe1
+#define RCR6 0xe2
+#define RCR7 0xe3
+
+#define RCR_RCD 0x01 /* Disables caching for ARRx (x = 0-6). */
+#define RCR_RCE 0x01 /* Enables caching for ARR7. */
+#define RCR_WWO 0x02 /* Weak write ordering. */
+#define RCR_WL 0x04 /* Weak locking. */
+#define RCR_WG 0x08 /* Write gathering. */
+#define RCR_WT 0x10 /* Write-through. */
+#define RCR_NLB 0x20 /* LBA# pin is not asserted. */
+
+
+#ifndef LOCORE
+static __inline u_char
+read_cyrix_reg(u_char reg)
+{
+ outb(0x22, reg);
+ return inb(0x23);
+}
+
+static __inline void
+write_cyrix_reg(u_char reg, u_char data)
+{
+ outb(0x22, reg);
+ outb(0x23, data);
+}
+#endif
#endif /* !_MACHINE_SPECIALREG_H_ */
diff --git a/sys/i386/isa/bs/bshw_dma.c b/sys/i386/isa/bs/bshw_dma.c
index 22051a9..b5b9238 100644
--- a/sys/i386/isa/bs/bshw_dma.c
+++ b/sys/i386/isa/bs/bshw_dma.c
@@ -200,9 +200,8 @@ bshw_dmastart(bsc)
*/
/* set dma channel mode, and reset address ff */
#ifdef __FreeBSD__
-#ifdef CYRIX_5X86
- asm("wbinvd");
-#endif
+ if (need_pre_dma_flush)
+ wbinvd();
#else /* NetBSD/pc98 */
if (cpuspec->cpuspec_cache_flush_before)
(*cpuspec->cpuspec_cache_flush_before)();
@@ -247,9 +246,8 @@ bshw_dmadone(bsc)
(*bsc->sc_hw->dma_stop)(bsc);
#ifdef __FreeBSD__
-#if defined(CYRIX_486DLC) || defined(IBM_486SLC)
- asm(".byte 0x0f, 0x08");
-#endif
+ if (need_post_dma_flush)
+ invd();
#else
if (cpuspec->cpuspec_cache_flush_after)
(*cpuspec->cpuspec_cache_flush_after)();
diff --git a/sys/i386/isa/bs/bsif.h b/sys/i386/isa/bs/bsif.h
index d5b8e71..4904bd8 100644
--- a/sys/i386/isa/bs/bsif.h
+++ b/sys/i386/isa/bs/bsif.h
@@ -101,6 +101,7 @@
#include <vm/vm_kern.h>
#include <machine/clock.h>
#include <machine/cpu.h>
+#include <machine/md_var.h>
#include <machine/vmparam.h>
#include <vm/pmap.h>
#include <sys/proc.h>
diff --git a/sys/pc98/conf/Makefile.pc98 b/sys/pc98/conf/Makefile.pc98
index 8fe080c..ecdb567 100644
--- a/sys/pc98/conf/Makefile.pc98
+++ b/sys/pc98/conf/Makefile.pc98
@@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id$
+# $Id: Makefile.pc98,v 1.11 1997/02/22 09:43:21 peter Exp $
#
# Makefile for FreeBSD
#
@@ -58,7 +58,7 @@ DRIVER_S= ${CC} -c -x assembler-with-cpp -DLOCORE ${COPTS} $<
PROFILE_C= ${CC} -c ${CFLAGS} ${PARAM} $<
SYSTEM_CFILES= ioconf.c param.c vnode_if.c config.c
-SYSTEM_SFILES= ${PC98}/i386/locore.s
+SYSTEM_SFILES= ${I386}/i386/locore.s
SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} ioconf.o param.o config.o
SYSTEM_DEP= Makefile symbols.exclude symbols.sort ${SYSTEM_OBJS}
SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
@@ -89,7 +89,7 @@ clean:
#lint: /tmp param.c
# @lint -hbxn -DGENERIC -Dvolatile= ${COPTS} ${PARAM} \
-# ${PC98}/i386/Locore.c ${CFILES} ioconf.c param.c | \
+# ${I386}/i386/Locore.c ${CFILES} ioconf.c param.c | \
# grep -v 'struct/union .* never defined' | \
# grep -v 'possible pointer alignment problem'
@@ -101,7 +101,7 @@ symbols.sort: ${I386}/i386/symbols.raw
grep -v '^#' ${I386}/i386/symbols.raw \
| sed 's/^ //' | sort -u > symbols.sort
-locore.o: ${PC98}/i386/locore.s assym.s
+locore.o: ${I386}/i386/locore.s assym.s
${NORMAL_S}
# everything potentially depends on the Makefile since everything potentially
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index 37cf0a9..b5c3dce 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.16 1997/02/22 09:43:22 peter Exp $
+# $Id: files.pc98,v 1.17 1997/03/19 16:14:25 kato Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/*.[chyl]" \
@@ -49,6 +49,7 @@ i386/i386/i386-gdbstub.c optional ddb
i386/i386/exception.s standard
i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
+i386/i386/initcpu.c standard
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
# now normal.
# i386/i386/locore.s standard
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index cf26896..38d240f 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.17 1997/03/01 11:06:41 kato Exp $
+# $Id: options.pc98,v 1.18 1997/03/13 17:04:23 kato Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -37,10 +37,21 @@ CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
CLK_USE_I586_CALIBRATION opt_clock.h
-I386_CPU opt_cpu.h
-I486_CPU opt_cpu.h
-I586_CPU opt_cpu.h
-I686_CPU opt_cpu.h
+CPU_BTB_EN opt_cpu.h
+CPU_DISABLE_5X86_LSSER opt_cpu.h
+CPU_FASTER_5X86_FPU opt_cpu.h
+CPU_I486_ON_386 opt_cpu.h
+CPU_IORT opt_cpu.h
+CPU_LOOP_EN opt_cpu.h
+CPU_RSTK_EN opt_cpu.h
+CPU_SUSP_HLT opt_cpu.h
+CPU_UPGRADE_HW_CACHE opt_cpu.h
+CYRIX_CACHE_WORKS opt_cpu.h
+CYRIX_CACHE_REALLY_WORKS opt_cpu.h
+I386_CPU opt_cpu.h
+I486_CPU opt_cpu.h
+I586_CPU opt_cpu.h
+I686_CPU opt_cpu.h
SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
diff --git a/sys/pc98/i386/locore.s b/sys/pc98/i386/locore.s
deleted file mode 100644
index 039638f..0000000
--- a/sys/pc98/i386/locore.s
+++ /dev/null
@@ -1,1084 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id$
- *
- * originally from: locore.s, by William F. Jolitz
- *
- * Substantially rewritten by David Greenman, Rod Grimes,
- * Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp
- * and many others.
- */
-
-#include "apm.h"
-#include "opt_cpu.h"
-#include "opt_ddb.h"
-#include "opt_userconfig.h"
-
-#include <sys/errno.h>
-#include <sys/syscall.h>
-#include <sys/reboot.h>
-
-#include <machine/asmacros.h>
-#include <machine/cputypes.h>
-#include <machine/psl.h>
-#include <machine/pmap.h>
-#include <machine/specialreg.h>
-
-#include "assym.s"
-
-/*
- * XXX
- *
- * Note: This version greatly munged to avoid various assembler errors
- * that may be fixed in newer versions of gas. Perhaps newer versions
- * will have more pleasant appearance.
- */
-
-/*
- * PTmap is recursive pagemap at top of virtual address space.
- * Within PTmap, the page directory can be found (third indirection).
- */
- .globl _PTmap,_PTD,_PTDpde
- .set _PTmap,(PTDPTDI << PDRSHIFT)
- .set _PTD,_PTmap + (PTDPTDI * PAGE_SIZE)
- .set _PTDpde,_PTD + (PTDPTDI * PDESIZE)
-
-/*
- * APTmap, APTD is the alternate recursive pagemap.
- * It's used when modifying another process's page tables.
- */
- .globl _APTmap,_APTD,_APTDpde
- .set _APTmap,APTDPTDI << PDRSHIFT
- .set _APTD,_APTmap + (APTDPTDI * PAGE_SIZE)
- .set _APTDpde,_PTD + (APTDPTDI * PDESIZE)
-
-/*
- * Access to each processes kernel stack is via a region of
- * per-process address space (at the beginning), immediately above
- * the user process stack.
- */
- .set _kstack,USRSTACK
- .globl _kstack
-
-/*
- * Globals
- */
- .data
- ALIGN_DATA /* just to be sure */
-
- .globl tmpstk
- .space 0x2000 /* space for tmpstk - temporary stack */
-tmpstk:
-
- .globl _boothowto,_bootdev
-
- .globl _cpu,_cpu_vendor,_cpu_id,_bootinfo
- .globl _cpu_high, _cpu_feature
-
-_cpu: .long 0 /* are we 386, 386sx, or 486 */
-_cpu_id: .long 0 /* stepping ID */
-_cpu_high: .long 0 /* highest arg to CPUID */
-_cpu_feature: .long 0 /* features */
-_cpu_vendor: .space 20 /* CPU origin code */
-_bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */
-
-_KERNend: .long 0 /* phys addr end of kernel (just after bss) */
-physfree: .long 0 /* phys addr of next free page */
-p0upa: .long 0 /* phys addr of proc0's UPAGES */
-p0upt: .long 0 /* phys addr of proc0's UPAGES page table */
-
- .globl _IdlePTD
-_IdlePTD: .long 0 /* phys addr of kernel PTD */
-
-_KPTphys: .long 0 /* phys addr of kernel page tables */
-
- .globl _proc0paddr
-_proc0paddr: .long 0 /* address of proc 0 address space */
-
-#ifdef BDE_DEBUGGER
- .globl _bdb_exists /* flag to indicate BDE debugger is present */
-_bdb_exists: .long 0
-#endif
-
-
-/**********************************************************************
- *
- * Some handy macros
- *
- */
-
-#define R(foo) ((foo)-KERNBASE)
-
-#define ALLOCPAGES(foo) \
- movl R(physfree), %esi ; \
- movl $((foo)*PAGE_SIZE), %eax ; \
- addl %esi, %eax ; \
- movl %eax, R(physfree) ; \
- movl %esi, %edi ; \
- movl $((foo)*PAGE_SIZE),%ecx ; \
- xorl %eax,%eax ; \
- cld ; \
- rep ; \
- stosb
-
-/*
- * fillkpt
- * eax = page frame address
- * ebx = index into page table
- * ecx = how many pages to map
- * base = base address of page dir/table
- * prot = protection bits
- */
-#define fillkpt(base, prot) \
- shll $2,%ebx ; \
- addl base,%ebx ; \
- orl $PG_V,%eax ; \
- orl prot,%eax ; \
-1: movl %eax,(%ebx) ; \
- addl $PAGE_SIZE,%eax ; /* increment physical address */ \
- addl $4,%ebx ; /* next pte */ \
- loop 1b
-
-/*
- * fillkptphys(prot)
- * eax = physical address
- * ecx = how many pages to map
- * prot = protection bits
- */
-#define fillkptphys(prot) \
- movl %eax, %ebx ; \
- shrl $PAGE_SHIFT, %ebx ; \
- fillkpt(R(_KPTphys), prot)
-
- .text
-/**********************************************************************
- *
- * This is where the bootblocks start us, set the ball rolling...
- *
- */
-NON_GPROF_ENTRY(btext)
-
-#ifdef PC98
- jmp 1f
- .globl _pc98_system_parameter
- .org 0x400
-_pc98_system_parameter:
- .space 0x240 /* skip over warm boot shit */
-1:
- /* save SYSTEM PARAMETER for resume (NS/T or other) */
- movl $0xa1000,%esi
- movl $0x100000,%edi
- movl $0x0630,%ecx
- cld
- rep
- movsb
-#else /* IBM-PC */
-#ifdef BDE_DEBUGGER
-#ifdef BIOS_STEALS_3K
- cmpl $0x0375c339,0x95504
-#else
- cmpl $0x0375c339,0x96104 /* XXX - debugger signature */
-#endif
- jne 1f
- movb $1,R(_bdb_exists)
-1:
-#endif
-
-/* Tell the bios to warmboot next time */
- movw $0x1234,0x472
-#endif /* PC98 */
-
-/* Set up a real frame in case the double return in newboot is executed. */
- pushl %ebp
- movl %esp, %ebp
-
-/* Don't trust what the BIOS gives for eflags. */
- pushl $PSL_KERNEL
- popfl
-
-/*
- * Don't trust what the BIOS gives for %fs and %gs. Trust the bootstrap
- * to set %cs, %ds, %es and %ss.
- */
- mov %ds, %ax
- mov %ax, %fs
- mov %ax, %gs
-
- call recover_bootinfo
-
-/* Get onto a stack that we can trust. */
-/*
- * XXX this step is delayed in case recover_bootinfo needs to return via
- * the old stack, but it need not be, since recover_bootinfo actually
- * returns via the old frame.
- */
- movl $R(tmpstk),%esp
-
-#ifdef PC98
- testb $0x02,0x100620 /* pc98_machine_type & M_EPSON_PC98 */
- jz 3f
- cmpb $0x0b,0x100624 /* epson_machine_id <= 0x0b */
- ja 3f
-
- /* count up memory */
- movl $0x100000,%eax /* next, talley remaining memory */
- movl $(0xFFF-0x100),%ecx
-1: movl 0(%eax),%ebx /* save location to check */
- movl $0xa55a5aa5,0(%eax) /* write test pattern */
- cmpl $0xa55a5aa5,0(%eax) /* does not check yet for rollover */
- jne 2f
- movl %ebx,0(%eax) /* restore memory */
- addl $ PAGE_SIZE,%eax
- loop 1b
-2: subl $0x100000,%eax
- shrl $17,%eax
- movb %al,0x100401
-3:
-#endif
-
- call identify_cpu
-
-/* clear bss */
-/*
- * XXX this should be done a little earlier.
- *
- * XXX we don't check that there is memory for our bss and page tables
- * before using it.
- *
- * XXX the boot program somewhat bogusly clears the bss. We still have
- * to do it in case we were unzipped by kzipboot. Then the boot program
- * only clears kzipboot's bss.
- *
- * XXX the gdt and idt are still somewhere in the boot program. We
- * depend on the convention that the boot program is below 1MB and we
- * are above 1MB to keep the gdt and idt away from the bss and page
- * tables. The idt is only used if BDE_DEBUGGER is enabled.
- */
- movl $R(_end),%ecx
- movl $R(_edata),%edi
- subl %edi,%ecx
- xorl %eax,%eax
- cld
- rep
- stosb
-
-#if NAPM > 0
-/*
- * XXX it's not clear that APM can live in the current environonment.
- * Only pc-relative addressing works.
- */
- call _apm_setup
-#endif
-
- call create_pagetables
-
-#ifdef BDE_DEBUGGER
-/*
- * Adjust as much as possible for paging before enabling paging so that the
- * adjustments can be traced.
- */
- call bdb_prepare_paging
-#endif
-
-/* Now enable paging */
- movl R(_IdlePTD), %eax
- movl %eax,%cr3 /* load ptd addr into mmu */
- movl %cr0,%eax /* get control word */
- orl $CR0_PE|CR0_PG,%eax /* enable paging */
- movl %eax,%cr0 /* and let's page NOW! */
-
-#ifdef BDE_DEBUGGER
-/*
- * Complete the adjustments for paging so that we can keep tracing through
- * initi386() after the low (physical) addresses for the gdt and idt become
- * invalid.
- */
- call bdb_commit_paging
-#endif
-
- pushl $begin /* jump to high virtualized address */
- ret
-
-/* now running relocated at KERNBASE where the system is linked to run */
-begin:
- /* set up bootstrap stack */
- movl $_kstack+UPAGES*PAGE_SIZE,%esp /* bootstrap stack end location */
- xorl %eax,%eax /* mark end of frames */
- movl %eax,%ebp
- movl _proc0paddr,%eax
- movl _IdlePTD, %esi
- movl %esi,PCB_CR3(%eax)
-
- movl physfree, %esi
- pushl %esi /* value of first for init386(first) */
- call _init386 /* wire 386 chip for unix operation */
-#ifdef PC98
-#if defined(CYRIX_486DLC) && defined(I486_CPU)
- /* Cyrix 486DLC/SLC/DLC2/SLC2 CPU */
- cmpl $CPU_486DLC,_cpu
- jne 1f
- cli
- movl %cr0,%eax
- orl $0x40000000,%eax /* disable cache */
- mov %eax,%cr0
- .byte 0x0f,0x08 /* invd */
-
- movb $0xc0,%al
- outb %al,$0x22 /* Cyrix486[SD]LC cache controler index */
- movb $0x02,%al /* CCR0 = 0x02 (disable cache 640K-1M) */
- outb %al,$0x23 /* window */
- movb $0xc6,%al
- outb %al,$0x22
- movb $0x00,%al
- outb %al,$0x23 /* NCR1: enable cache in all area */
- movb $0x00,%al
- outb %al,$0x22 /* dummy window */
- movb $0x00,%al
- outb %al,$0x23 /* dummy write */
-
- movl %cr0,%eax
- andl $0x9fffffff,%eax /* enable cache !! */
- movl %eax,%cr0
- sti
-1:
-#endif
-#if defined(IBM_486SLC) && defined(I486_CPU)
-/* optimization */
- cli
- movl %cr0,%eax
- orl $0x40000000,%eax # disable cache
- mov %eax,%cr0
- .byte 0x0f,0x08 # invd
-
- movl $0x00000000,%edx
- movl $0x00009c92,%eax # If using Intel-FPU,set "1c92" instead.
- movl $0x00001000,%ecx
- .byte 0x0f,0x30 # wrmsr
-
- movl $0x000000d0,%edx # 13MB(0x0d) cache.(over1MB-14MB region)
- movl $0x000003ff,%eax # 0-640KB cache. (64KB block * 10)
- movl $0x00001001,%ecx
- .byte 0x0f,0x30 # wrmsr
-
- movl $0x00000000,%edx
- movl $0x03000000,%eax # "3" means double-clock-mode. or set all-zero.
- movl $0x00001002,%ecx
- .byte 0x0f,0x30 # wrmsr
-
- movl %cr0,%eax
- andl $0x9fffffff,%eax # enable cache !!
- movl %eax,%cr0
- sti
-#endif
-#ifdef CYRIX_5X86
- /* CYRIX 5x86 CPU */
- cli
-
- outb %al,$0x50 # Reset NMI F/F
- mov %cr0,%eax
- orl $0x40000000,%eax # disable cache
- movl %eax,%cr0
-
- wbinvd # flush buffer
-
- movb $0xc3,%al
- outb %al,$0x22
- inb $0x23,%al
-
- movb $0x0c1,%al # CCR1
- outb %al,$0x22
- movb $0x00,%al # No SMM support
- outb %al,$0x23
- movb $0x0c2,%al # CCR2
- outb %al,$0x22
-#ifdef SUSP_HLT
- movb $0x0a,%al # USE_WBAK, SUSP_HLT
-#else
- movb $0x02,%al # USE_WBAK
-#endif
- outb %al,$0x23
- movb $0xc3,%al # CCR3
- outb %al,$0x22 #
- movb $0x10,%al # MAPEN0 (to access CCR4)
- outb %al,$0x23
- movb $0x0e8,%al # CCR4
- outb %al,$0x22
- movb $0x18, %al # DTE_EN, MEM_BYP
-#ifdef FASTER_5X86_FPU
- orb $0x20, %al # UNDOCUMENTED OPTION
-#endif
-#ifdef CX586_IO
- orb $CX586_IO, %al
-#endif
- outb %al,$0x23
- movb $0x020,%al # PCR0
- outb %al,$0x22
- xorb %al, %al
-#ifdef RSTK_EN
- orb $0x01, %al # Return Stack Enable
-#endif
-#ifdef BTB_EN
- orb $0x02, %al # Branch Target Buffer enable
-#endif
-#ifdef LOOP_EN
- orb $0x04, %al # Loop Enable
-#endif
-#ifndef DISABLE_5X86_LSSER
- orb $0x80, %al # Reorder
-#endif
- outb %al,$0x23
- movb $0x0c3,%al # CCR3
- outb %al,$0x22
- movb $0x00,%al
- outb %al,$0x23
- movb $0x80,%al # dummy
- outb %al,$0x22
- inb $0x23,%al
-
- movl %cr0,%ebx
- andl $0x0bfffffff,%ebx # enable cache
- orl $0x020000000,%ebx # write back mode
- movl %ebx,%cr0 # go!
-
- outb %al,$0x52 # Set NMI F/F
- sti
-#endif /* CYRIX_5X86 */
-#endif /* PC98 */
- popl %esi
-
- .globl __ucodesel,__udatasel
-
- pushl $0 /* unused */
- pushl __udatasel /* ss */
- pushl $0 /* esp - filled in by execve() */
- pushl $PSL_USER /* eflags (IOPL 0, int enab) */
- pushl __ucodesel /* cs */
- pushl $0 /* eip - filled in by execve() */
- subl $(12*4),%esp /* space for rest of registers */
-
- pushl %esp /* call main with frame pointer */
- call _main /* autoconfiguration, mountroot etc */
-
- addl $(13*4),%esp /* back to a frame we can return with */
-
- /*
- * now we've run main() and determined what cpu-type we are, we can
- * enable write protection and alignment checking on i486 cpus and
- * above.
- */
-#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
- cmpl $CPUCLASS_386,_cpu_class
- je 1f
- movl %cr0,%eax /* get control word */
- orl $CR0_WP|CR0_AM,%eax /* enable i486 features */
- movl %eax,%cr0 /* and do it */
-1:
-#endif
- /*
- * on return from main(), we are process 1
- * set up address space and stack so that we can 'return' to user mode
- */
- movl __ucodesel,%eax
- movl __udatasel,%ecx
-
- movl %cx,%ds
- movl %cx,%es
- movl %ax,%fs /* double map cs to fs */
- movl %cx,%gs /* and ds to gs */
- iret /* goto user! */
-
-#define LCALL(x,y) .byte 0x9a ; .long y ; .word x
-
-/*
- * Signal trampoline, copied to top of user stack
- */
-NON_GPROF_ENTRY(sigcode)
- call SIGF_HANDLER(%esp)
- lea SIGF_SC(%esp),%eax /* scp (the call may have clobbered the */
- /* copy at 8(%esp)) */
- pushl %eax
- pushl %eax /* junk to fake return address */
- movl $SYS_sigreturn,%eax /* sigreturn() */
- LCALL(0x7,0) /* enter kernel with args on stack */
- hlt /* never gets here */
- .align 2,0x90 /* long word text-align */
-_esigcode:
-
- .data
- .globl _szsigcode
-_szsigcode:
- .long _esigcode-_sigcode
- .text
-
-/**********************************************************************
- *
- * Recover the bootinfo passed to us from the boot program
- *
- */
-recover_bootinfo:
- /*
- * This code is called in different ways depending on what loaded
- * and started the kernel. This is used to detect how we get the
- * arguments from the other code and what we do with them.
- *
- * Old disk boot blocks:
- * (*btext)(howto, bootdev, cyloffset, esym);
- * [return address == 0, and can NOT be returned to]
- * [cyloffset was not supported by the FreeBSD boot code
- * and always passed in as 0]
- * [esym is also known as total in the boot code, and
- * was never properly supported by the FreeBSD boot code]
- *
- * Old diskless netboot code:
- * (*btext)(0,0,0,0,&nfsdiskless,0,0,0);
- * [return address != 0, and can NOT be returned to]
- * If we are being booted by this code it will NOT work,
- * so we are just going to halt if we find this case.
- *
- * New uniform boot code:
- * (*btext)(howto, bootdev, 0, 0, 0, &bootinfo)
- * [return address != 0, and can be returned to]
- *
- * There may seem to be a lot of wasted arguments in here, but
- * that is so the newer boot code can still load very old kernels
- * and old boot code can load new kernels.
- */
-
- /*
- * The old style disk boot blocks fake a frame on the stack and
- * did an lret to get here. The frame on the stack has a return
- * address of 0.
- */
- cmpl $0,4(%ebp)
- je olddiskboot
-
- /*
- * We have some form of return address, so this is either the
- * old diskless netboot code, or the new uniform code. That can
- * be detected by looking at the 5th argument, if it is 0
- * we are being booted by the new uniform boot code.
- */
- cmpl $0,24(%ebp)
- je newboot
-
- /*
- * Seems we have been loaded by the old diskless boot code, we
- * don't stand a chance of running as the diskless structure
- * changed considerably between the two, so just halt.
- */
- hlt
-
- /*
- * We have been loaded by the new uniform boot code.
- * Let's check the bootinfo version, and if we do not understand
- * it we return to the loader with a status of 1 to indicate this error
- */
-newboot:
- movl 28(%ebp),%ebx /* &bootinfo.version */
- movl BI_VERSION(%ebx),%eax
- cmpl $1,%eax /* We only understand version 1 */
- je 1f
- movl $1,%eax /* Return status */
- leave
- /*
- * XXX this returns to our caller's caller (as is required) since
- * we didn't set up a frame and our caller did.
- */
- ret
-
-1:
- /*
- * If we have a kernelname copy it in
- */
- movl BI_KERNELNAME(%ebx),%esi
- cmpl $0,%esi
- je 2f /* No kernelname */
- movl $MAXPATHLEN,%ecx /* Brute force!!! */
- movl $R(_kernelname),%edi
- cmpb $'/',(%esi) /* Make sure it starts with a slash */
- je 1f
- movb $'/',(%edi)
- incl %edi
- decl %ecx
-1:
- cld
- rep
- movsb
-
-2:
- /*
- * Determine the size of the boot loader's copy of the bootinfo
- * struct. This is impossible to do properly because old versions
- * of the struct don't contain a size field and there are 2 old
- * versions with the same version number.
- */
- movl $BI_ENDCOMMON,%ecx /* prepare for sizeless version */
- testl $RB_BOOTINFO,8(%ebp) /* bi_size (and bootinfo) valid? */
- je got_bi_size /* no, sizeless version */
- movl BI_SIZE(%ebx),%ecx
-got_bi_size:
-
- /*
- * Copy the common part of the bootinfo struct
- */
- movl %ebx,%esi
- movl $R(_bootinfo),%edi
- cmpl $BOOTINFO_SIZE,%ecx
- jbe got_common_bi_size
- movl $BOOTINFO_SIZE,%ecx
-got_common_bi_size:
- cld
- rep
- movsb
-
-#ifdef NFS
- /*
- * If we have a nfs_diskless structure copy it in
- */
- movl BI_NFS_DISKLESS(%ebx),%esi
- cmpl $0,%esi
- je olddiskboot
- movl $R(_nfs_diskless),%edi
- movl $NFSDISKLESS_SIZE,%ecx
- cld
- rep
- movsb
- movl $R(_nfs_diskless_valid),%edi
- movl $1,(%edi)
-#endif
-
- /*
- * The old style disk boot.
- * (*btext)(howto, bootdev, cyloffset, esym);
- * Note that the newer boot code just falls into here to pick
- * up howto and bootdev, cyloffset and esym are no longer used
- */
-olddiskboot:
- movl 8(%ebp),%eax
- movl %eax,R(_boothowto)
- movl 12(%ebp),%eax
- movl %eax,R(_bootdev)
-
-#if defined(USERCONFIG_BOOT) && defined(USERCONFIG)
-#ifdef PC98
- movl $0x90200, %esi
-#else
- movl $0x10200, %esi
-#endif
- movl $R(_userconfig_from_boot),%edi
- movl $512,%ecx
- cld
- rep
- movsb
-#endif /* USERCONFIG_BOOT */
-
- ret
-
-
-/**********************************************************************
- *
- * Identify the CPU and initialize anything special about it
- *
- */
-identify_cpu:
-
- /* Try to toggle alignment check flag; does not exist on 386. */
- pushfl
- popl %eax
- movl %eax,%ecx
- orl $PSL_AC,%eax
- pushl %eax
- popfl
- pushfl
- popl %eax
- xorl %ecx,%eax
- andl $PSL_AC,%eax
- pushl %ecx
- popfl
-
- testl %eax,%eax
- jnz 1f
- movl $CPU_386,R(_cpu)
- jmp 3f
-
-1: /* Try to toggle identification flag; does not exist on early 486s. */
- pushfl
- popl %eax
- movl %eax,%ecx
- xorl $PSL_ID,%eax
- pushl %eax
- popfl
- pushfl
- popl %eax
- xorl %ecx,%eax
- andl $PSL_ID,%eax
- pushl %ecx
- popfl
-
- testl %eax,%eax
- jnz 1f
- movl $CPU_486,R(_cpu)
-
- /* check for Cyrix 486DLC -- based on check routine */
- /* documented in "Cx486SLC/e SMM Programmer's Guide" */
- xorw %dx,%dx
- cmpw %dx,%dx # set flags to known state
- pushfw
- popw %cx # store flags in ecx
- movw $0xffff,%ax
- movw $0x0004,%bx
- divw %bx
- pushfw
- popw %ax
- andw $0x08d5,%ax # mask off important bits
- andw $0x08d5,%cx
- cmpw %ax,%cx
-
- jnz 3f # if flags changed, Intel chip
-
- movl $CPU_486DLC,R(_cpu) # set CPU value for Cyrix
- movl $0x69727943,R(_cpu_vendor) # store vendor string
- movw $0x0078,R(_cpu_vendor+4)
-
-#ifndef CYRIX_CACHE_WORKS
- /* Disable caching of the ISA hole only. */
- invd
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- orb $(CCR0_NC1|CCR0_BARB),%al
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- invd
-#else /* CYRIX_CACHE_WORKS */
- /* Set cache parameters */
- invd # Start with guaranteed clean cache
- movb $CCR0,%al # Configuration Register index (CCR0)
- outb %al,$0x22
- inb $0x23,%al
- andb $~CCR0_NC0,%al
-#ifndef CYRIX_CACHE_REALLY_WORKS
- orb $(CCR0_NC1|CCR0_BARB),%al
-#else /* CYRIX_CACHE_REALLY_WORKS */
- orb $CCR0_NC1,%al
-#endif /* !CYRIX_CACHE_REALLY_WORKS */
- movb %al,%ah
- movb $CCR0,%al
- outb %al,$0x22
- movb %ah,%al
- outb %al,$0x23
- /* clear non-cacheable region 1 */
- movb $(NCR1+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 2 */
- movb $(NCR2+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 3 */
- movb $(NCR3+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* clear non-cacheable region 4 */
- movb $(NCR4+2),%al
- outb %al,$0x22
- movb $NCR_SIZE_0K,%al
- outb %al,$0x23
- /* enable caching in CR0 */
- movl %cr0,%eax
- andl $~(CR0_CD|CR0_NW),%eax
- movl %eax,%cr0
- invd
-#endif /* !CYRIX_CACHE_WORKS */
- jmp 3f
-
-1: /* Use the `cpuid' instruction. */
- xorl %eax,%eax
- .byte 0x0f,0xa2 # cpuid 0
- movl %eax,R(_cpu_high) # highest capability
- movl %ebx,R(_cpu_vendor) # store vendor string
- movl %edx,R(_cpu_vendor+4)
- movl %ecx,R(_cpu_vendor+8)
- movb $0,R(_cpu_vendor+12)
-
- movl $1,%eax
- .byte 0x0f,0xa2 # cpuid 1
- movl %eax,R(_cpu_id) # store cpu_id
- movl %edx,R(_cpu_feature) # store cpu_feature
- rorl $8,%eax # extract family type
- andl $15,%eax
- cmpl $5,%eax
- jae 1f
-
- /* less than Pentium; must be 486 */
- movl $CPU_486,R(_cpu)
- jmp 3f
-1:
- /* a Pentium? */
- cmpl $5,%eax
- jne 2f
- movl $CPU_586,R(_cpu)
- jmp 3f
-2:
- /* Greater than Pentium...call it a Pentium Pro */
- movl $CPU_686,R(_cpu)
-3:
- ret
-
-
-/**********************************************************************
- *
- * Create the first page directory and its page tables.
- *
- */
-
-create_pagetables:
-
- testl $CPUID_PGE, R(_cpu_feature)
- jz 1f
- movl %cr4, %eax
- orl $CR4_PGE, %eax
- movl %eax, %cr4
-1:
-
-/* Find end of kernel image (rounded up to a page boundary). */
- movl $R(_end),%esi
-
-/* include symbols in "kernel image" if they are loaded and useful */
-#ifdef DDB
- movl R(_bootinfo+BI_ESYMTAB),%edi
- testl %edi,%edi
- je over_symalloc
- movl %edi,%esi
- movl $KERNBASE,%edi
- addl %edi,R(_bootinfo+BI_SYMTAB)
- addl %edi,R(_bootinfo+BI_ESYMTAB)
-over_symalloc:
-#endif
-
- addl $PAGE_MASK,%esi
- andl $~PAGE_MASK,%esi
- movl %esi,R(_KERNend) /* save end of kernel */
- movl %esi,R(physfree) /* next free page is at end of kernel */
-
-/* Allocate Kernel Page Tables */
- ALLOCPAGES(NKPT)
- movl %esi,R(_KPTphys)
-
-/* Allocate Page Table Directory */
- ALLOCPAGES(1)
- movl %esi,R(_IdlePTD)
-
-/* Allocate UPAGES */
- ALLOCPAGES(UPAGES)
- movl %esi,R(p0upa)
- addl $KERNBASE, %esi
- movl %esi, R(_proc0paddr)
-
-/* Allocate proc0's page table for the UPAGES. */
- ALLOCPAGES(1)
- movl %esi,R(p0upt)
-
-/* Map read-only from zero to the end of the kernel text section */
- xorl %eax, %eax
-#ifdef BDE_DEBUGGER
-/* If the debugger is present, actually map everything read-write. */
- cmpl $0,R(_bdb_exists)
- jne map_read_write
-#endif
- xorl %edx,%edx
- testl $CPUID_PGE, R(_cpu_feature)
- jz 2f
- orl $PG_G,%edx
-
-2: movl $R(_etext),%ecx
- addl $PAGE_MASK,%ecx
- shrl $PAGE_SHIFT,%ecx
- fillkptphys(%edx)
-
-/* Map read-write, data, bss and symbols */
- movl $R(_etext),%eax
- addl $PAGE_MASK, %eax
- andl $~PAGE_MASK, %eax
-map_read_write:
- movl $PG_RW,%edx
- testl $CPUID_PGE, R(_cpu_feature)
- jz 1f
- orl $PG_G,%edx
-
-1: movl R(_KERNend),%ecx
- subl %eax,%ecx
- shrl $PAGE_SHIFT,%ecx
- fillkptphys(%edx)
-
-/* Map page directory. */
- movl R(_IdlePTD), %eax
- movl $1, %ecx
- fillkptphys($PG_RW)
-
-/* Map proc0's page table for the UPAGES. */
- movl R(p0upt), %eax
- movl $1, %ecx
- fillkptphys($PG_RW)
-
-/* Map proc0's UPAGES in the physical way ... */
- movl R(p0upa), %eax
- movl $UPAGES, %ecx
- fillkptphys($PG_RW)
-
-/* Map ISA hole */
- movl $ISA_HOLE_START, %eax
- movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx
- fillkptphys($PG_RW)
-
-/* Map proc0s UPAGES in the special page table for this purpose ... */
- movl R(p0upa), %eax
- movl $KSTKPTEOFF, %ebx
- movl $UPAGES, %ecx
- fillkpt(R(p0upt), $PG_RW)
-
-/* ... and put the page table in the pde. */
- movl R(p0upt), %eax
- movl $KSTKPTDI, %ebx
- movl $1, %ecx
- fillkpt(R(_IdlePTD), $PG_RW)
-
-/* install a pde for temporary double map of bottom of VA */
- movl R(_KPTphys), %eax
- xorl %ebx, %ebx
- movl $1, %ecx
- fillkpt(R(_IdlePTD), $PG_RW)
-
-/* install pde's for pt's */
- movl R(_KPTphys), %eax
- movl $KPTDI, %ebx
- movl $NKPT, %ecx
- fillkpt(R(_IdlePTD), $PG_RW)
-
-/* install a pde recursively mapping page directory as a page table */
- movl R(_IdlePTD), %eax
- movl $PTDPTDI, %ebx
- movl $1,%ecx
- fillkpt(R(_IdlePTD), $PG_RW)
-
- ret
-
-#ifdef BDE_DEBUGGER
-bdb_prepare_paging:
- cmpl $0,R(_bdb_exists)
- je bdb_prepare_paging_exit
-
- subl $6,%esp
-
- /*
- * Copy and convert debugger entries from the bootstrap gdt and idt
- * to the kernel gdt and idt. Everything is still in low memory.
- * Tracing continues to work after paging is enabled because the
- * low memory addresses remain valid until everything is relocated.
- * However, tracing through the setidt() that initializes the trace
- * trap will crash.
- */
- sgdt (%esp)
- movl 2(%esp),%esi /* base address of bootstrap gdt */
- movl $R(_gdt),%edi
- movl %edi,2(%esp) /* prepare to load kernel gdt */
- movl $8*18/4,%ecx
- cld
- rep /* copy gdt */
- movsl
- movl $R(_gdt),-8+2(%edi) /* adjust gdt self-ptr */
- movb $0x92,-8+5(%edi)
- lgdt (%esp)
-
- sidt (%esp)
- movl 2(%esp),%esi /* base address of current idt */
- movl 8+4(%esi),%eax /* convert dbg descriptor to ... */
- movw 8(%esi),%ax
- movl %eax,R(bdb_dbg_ljmp+1) /* ... immediate offset ... */
- movl 8+2(%esi),%eax
- movw %ax,R(bdb_dbg_ljmp+5) /* ... and selector for ljmp */
- movl 24+4(%esi),%eax /* same for bpt descriptor */
- movw 24(%esi),%ax
- movl %eax,R(bdb_bpt_ljmp+1)
- movl 24+2(%esi),%eax
- movw %ax,R(bdb_bpt_ljmp+5)
- movl $R(_idt),%edi
- movl %edi,2(%esp) /* prepare to load kernel idt */
- movl $8*4/4,%ecx
- cld
- rep /* copy idt */
- movsl
- lidt (%esp)
-
- addl $6,%esp
-
-bdb_prepare_paging_exit:
- ret
-
-/* Relocate debugger gdt entries and gdt and idt pointers. */
-bdb_commit_paging:
- cmpl $0,_bdb_exists
- je bdb_commit_paging_exit
-
- movl $_gdt+8*9,%eax /* adjust slots 9-17 */
- movl $9,%ecx
-reloc_gdt:
- movb $KERNBASE>>24,7(%eax) /* top byte of base addresses, was 0, */
- addl $8,%eax /* now KERNBASE>>24 */
- loop reloc_gdt
-
- subl $6,%esp
- sgdt (%esp)
- addl $KERNBASE,2(%esp)
- lgdt (%esp)
- sidt (%esp)
- addl $KERNBASE,2(%esp)
- lidt (%esp)
- addl $6,%esp
-
- int $3
-
-bdb_commit_paging_exit:
- ret
-
-#endif /* BDE_DEBUGGER */
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index 95c2823..28ebe0e 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.28 1997/02/22 09:43:27 peter Exp $
+ * $Id: machdep.c,v 1.29 1997/02/25 16:36:48 kato Exp $
*/
#include "npx.h"
@@ -126,12 +126,19 @@ extern int ptrace_single_step __P((struct proc *p));
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
extern void dblfault_handler __P((void));
-extern void identifycpu(void); /* XXX header file */
+extern void printcpuinfo(void); /* XXX header file */
extern void earlysetcpuclass(void); /* same header file */
+extern void finishidentcpu(void);
+extern void panicifcpuunsupported(void);
+extern void initializecpu(void);
static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
+#ifdef PC98
+int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */
+int need_post_dma_flush; /* If 1, use invd after DMA transfer. */
+#endif
#ifdef BOUNCE_BUFFERS
extern char *bouncememory;
@@ -215,7 +222,8 @@ cpu_startup(dummy)
printf(version);
earlysetcpuclass();
startrtclock();
- identifycpu();
+ printcpuinfo();
+ panicifcpuunsupported();
#ifdef PERFMON
perfmon_init();
#endif
@@ -1041,7 +1049,7 @@ init386(first)
setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
setidt(14, &IDTVEC(page), SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#else
setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@@ -1077,6 +1085,10 @@ init386(first)
Debugger("Boot flags requested debugger");
#endif
+ finishidentcpu(); /* Final stage of CPU initialization */
+ setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ initializecpu(); /* Initialize CPU registers */
+
#ifdef PC98
pc98_getmemsize();
biosbasemem = 640; /* 640KB */
diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c
index 38680ba..6ae005a 100644
--- a/sys/pc98/i386/trap.c
+++ b/sys/pc98/i386/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id$
+ * $Id: trap.c,v 1.13 1997/02/22 09:43:28 peter Exp $
*/
/*
@@ -91,7 +91,7 @@ extern void trap __P((struct trapframe frame));
extern int trapwrite __P((unsigned addr));
extern void syscall __P((struct trapframe frame));
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
static int trap_pfault __P((struct trapframe *, int, vm_offset_t));
#else
static int trap_pfault __P((struct trapframe *, int));
@@ -192,14 +192,14 @@ trap(frame)
#ifdef DEBUG
u_long eva;
#endif
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
vm_offset_t va;
#endif
type = frame.tf_trapno;
code = frame.tf_err;
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
/* XXX:
* CYRIX 486 CPU FIX.
* If you use cyrix cpu, you often encouter strange signal 11's?
@@ -210,7 +210,7 @@ trap(frame)
va = (vm_offset_t)(rcr2());
if( type == T_PAGEFLT && ( frame.tf_eflags & PSL_I ) )
asm("sti");
-#endif /* CYRIX_486DLC || CYRIX_5X86 */
+#endif /* CPU_BUGGY_CYRIX */
if (ISPL(frame.tf_cs) == SEL_UPL) {
/* user trap */
@@ -256,7 +256,7 @@ trap(frame)
break;
case T_PAGEFLT: /* page fault */
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
i = trap_pfault(&frame, TRUE, va);
#else
i = trap_pfault(&frame, TRUE);
@@ -332,7 +332,7 @@ trap(frame)
switch (type) {
case T_PAGEFLT: /* page fault */
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
(void) trap_pfault(&frame, FALSE, va);
#else
(void) trap_pfault(&frame, FALSE);
@@ -495,7 +495,7 @@ out:
* debugging code.
*/
static int
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
trap_pfault(frame, usermode,faultva)
struct trapframe *frame;
int usermode;
@@ -519,7 +519,7 @@ trap_pfault(frame, usermode)
else
ftype = VM_PROT_READ;
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
eva = faultva;
#else
eva = rcr2();
@@ -606,7 +606,7 @@ nogo:
#endif
int
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
trap_pfault(frame, usermode,faultva)
struct trapframe *frame;
int usermode;
@@ -625,7 +625,7 @@ trap_pfault(frame, usermode)
int eva;
struct proc *p = curproc;
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
eva = faultva;
#else
eva = rcr2();
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 95c2823..28ebe0e 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.28 1997/02/22 09:43:27 peter Exp $
+ * $Id: machdep.c,v 1.29 1997/02/25 16:36:48 kato Exp $
*/
#include "npx.h"
@@ -126,12 +126,19 @@ extern int ptrace_single_step __P((struct proc *p));
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
extern void dblfault_handler __P((void));
-extern void identifycpu(void); /* XXX header file */
+extern void printcpuinfo(void); /* XXX header file */
extern void earlysetcpuclass(void); /* same header file */
+extern void finishidentcpu(void);
+extern void panicifcpuunsupported(void);
+extern void initializecpu(void);
static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
+#ifdef PC98
+int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */
+int need_post_dma_flush; /* If 1, use invd after DMA transfer. */
+#endif
#ifdef BOUNCE_BUFFERS
extern char *bouncememory;
@@ -215,7 +222,8 @@ cpu_startup(dummy)
printf(version);
earlysetcpuclass();
startrtclock();
- identifycpu();
+ printcpuinfo();
+ panicifcpuunsupported();
#ifdef PERFMON
perfmon_init();
#endif
@@ -1041,7 +1049,7 @@ init386(first)
setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-#if defined(CYRIX_486DLC) || defined(CYRIX_5X86)
+#ifdef CPU_BUGGY_CYRIX
setidt(14, &IDTVEC(page), SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#else
setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@@ -1077,6 +1085,10 @@ init386(first)
Debugger("Boot flags requested debugger");
#endif
+ finishidentcpu(); /* Final stage of CPU initialization */
+ setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+ initializecpu(); /* Initialize CPU registers */
+
#ifdef PC98
pc98_getmemsize();
biosbasemem = 640; /* 640KB */
diff --git a/sys/pc98/pc98/pc98.c b/sys/pc98/pc98/pc98.c
index 594de6b..19eec78 100644
--- a/sys/pc98/pc98/pc98.c
+++ b/sys/pc98/pc98/pc98.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id$
+ * $Id: pc98.c,v 1.18 1997/02/22 09:43:42 peter Exp $
*/
/*
@@ -67,6 +67,7 @@
#include <vm/pmap.h>
#include <i386/isa/isa_device.h>
#ifdef PC98
+#include <machine/cpufunc.h>
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#include <pc98/pc98/epsonio.h>
@@ -734,9 +735,9 @@ void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
/* translate to physical */
phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
-#ifdef CYRIX_5X86
- asm("wbinvd"); /* wbinvd (WB cache flush) */
-#endif
+ if (need_pre_dma_flush)
+ wbinvd(); /* wbinvd (WB cache flush) */
+
#ifndef PC98
if ((chan & 4) == 0) {
@@ -814,12 +815,11 @@ void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
{
-#if defined(CYRIX_486DLC) || defined(IBM_486SLC)
if (flags & B_READ) {
/* cache flush only after reading 92/12/9 by A.Kojima */
- asm(" .byte 0x0f,0x08"); /* invd (cache flush) */
+ if (need_post_dma_flush)
+ invd();
}
-#endif
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
OpenPOWER on IntegriCloud