summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-07-18 12:56:54 +0000
committerphk <phk@FreeBSD.org>2002-07-18 12:56:54 +0000
commita535ae674163bf2e4c7e82bad38f699906bc0286 (patch)
tree7f65914b2426cd2a843193bdbdbd650cfaf0ecef /sys
parent22ef5eeda558acdeccae3ce8719709218305667c (diff)
downloadFreeBSD-src-a535ae674163bf2e4c7e82bad38f699906bc0286.zip
FreeBSD-src-a535ae674163bf2e4c7e82bad38f699906bc0286.tar.gz
Add initialization code for the AMD Elan sc520 which maps the MMCR
into KVM and sets the i8254 frequency to the correct value.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/identcpu.c53
-rw-r--r--sys/amd64/include/cputypes.h1
-rw-r--r--sys/amd64/include/md_var.h1
-rw-r--r--sys/amd64/pci/pci_bus.c2
-rw-r--r--sys/i386/i386/identcpu.c53
-rw-r--r--sys/i386/include/cputypes.h1
-rw-r--r--sys/i386/include/md_var.h1
-rw-r--r--sys/i386/pci/pci_bus.c2
8 files changed, 106 insertions, 8 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index 47d10ff..a195fcf 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -262,14 +262,16 @@ printcpuinfo(void)
strcat(cpu_model, "Standard Am486DX");
break;
case 0x430:
- strcat(cpu_model, "Am486DX2/4 Write-Through");
+ strcat(cpu_model, "Enhanced Am486DX2 Write-Through");
break;
case 0x470:
- case 0x490:
- strcat(cpu_model, "Enhanced Am486DX4 Write-Back");
+ strcat(cpu_model, "Enhanced Am486DX2 Write-Back");
break;
case 0x480:
- strcat(cpu_model, "Enhanced Am486DX4 Write-Through");
+ strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Through");
+ break;
+ case 0x490:
+ strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Back");
break;
case 0x4E0:
strcat(cpu_model, "Am5x86 Write-Through");
@@ -1325,3 +1327,46 @@ print_transmeta_info()
crusoe_frequency, crusoe_voltage, crusoe_percentage);
}
+/*
+ * The AMD Elan sc520 is a system-on-chip gadget which is used in embedded
+ * kind of things, see www.soekris.com for instance, and it has a few quirks
+ * we need to deal with.
+ * Unfortunately we cannot identify the gadget by CPUID output because it
+ * depends on strapping options and only the stepping field may be useful
+ * and those are undocumented from AMDs side.
+ *
+ * So instead we recognize the on-chip host-PCI bridge and call back from
+ * sys/i386/pci/pci_bus.c to here if we find it.
+ */
+
+#include <sys/proc.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+u_char *elan_mmcr;
+
+void
+init_AMD_Elan_sc520(void)
+{
+ u_int new;
+ int i;
+
+ printf("Doing h0h0magic for AMD Elan sc520\n");
+ elan_mmcr = pmap_mapdev(0xfffef000, 0x1000);
+ printf("MMCR at %p\n", elan_mmcr);
+
+ /*-
+ * The i8254 is driven with a nonstandard frequency which is
+ * derived thusly:
+ * f = 32768 * 45 * 25 / 31 = 1189161.29...
+ * We use the sysctl to get the timecounter etc into whack.
+ */
+
+ new = 1189161;
+ i = kernel_sysctlbyname(&thread0, "machdep.i8254_freq",
+ NULL, 0,
+ &new, sizeof new,
+ NULL);
+ printf("sysctl machdep.i8254_freq=%d returns %d\n", new, i);
+}
+
diff --git a/sys/amd64/include/cputypes.h b/sys/amd64/include/cputypes.h
index 585df67..999b174 100644
--- a/sys/amd64/include/cputypes.h
+++ b/sys/amd64/include/cputypes.h
@@ -68,6 +68,7 @@ struct cpu_nameclass {
extern int cpu;
extern int cpu_class;
+void init_AMD_Elan_sc520(void);
#endif
#endif /* !_MACHINE_CPUTYPES_H_ */
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index 041362f..e75994e 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -48,6 +48,7 @@ extern u_int cpu_id;
extern u_int cpu_fxsr;
extern char cpu_vendor[];
extern u_int cyrix_did;
+extern u_char *elan_mmcr;
extern char kstack[];
#ifdef PC98
extern int need_pre_dma_flush;
diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c
index 4e325b2..65ba7d3 100644
--- a/sys/amd64/pci/pci_bus.c
+++ b/sys/amd64/pci/pci_bus.c
@@ -40,6 +40,7 @@
#include <machine/nexusvar.h>
#include <machine/pci_cfgreg.h>
#include <machine/segments.h>
+#include <machine/cputypes.h>
#include <machine/pc/bios.h>
#include "pcib_if.h"
@@ -177,6 +178,7 @@ nexus_pcib_is_host_bridge(int bus, int slot, int func,
/* AMD -- vendor 0x1022 */
case 0x30001022:
s = "AMD Elan SC520 host to PCI bridge";
+ init_AMD_Elan_sc520();
break;
case 0x70061022:
s = "AMD-751 host to PCI bridge";
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index 47d10ff..a195fcf 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -262,14 +262,16 @@ printcpuinfo(void)
strcat(cpu_model, "Standard Am486DX");
break;
case 0x430:
- strcat(cpu_model, "Am486DX2/4 Write-Through");
+ strcat(cpu_model, "Enhanced Am486DX2 Write-Through");
break;
case 0x470:
- case 0x490:
- strcat(cpu_model, "Enhanced Am486DX4 Write-Back");
+ strcat(cpu_model, "Enhanced Am486DX2 Write-Back");
break;
case 0x480:
- strcat(cpu_model, "Enhanced Am486DX4 Write-Through");
+ strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Through");
+ break;
+ case 0x490:
+ strcat(cpu_model, "Enhanced Am486DX4/Am5x86 Write-Back");
break;
case 0x4E0:
strcat(cpu_model, "Am5x86 Write-Through");
@@ -1325,3 +1327,46 @@ print_transmeta_info()
crusoe_frequency, crusoe_voltage, crusoe_percentage);
}
+/*
+ * The AMD Elan sc520 is a system-on-chip gadget which is used in embedded
+ * kind of things, see www.soekris.com for instance, and it has a few quirks
+ * we need to deal with.
+ * Unfortunately we cannot identify the gadget by CPUID output because it
+ * depends on strapping options and only the stepping field may be useful
+ * and those are undocumented from AMDs side.
+ *
+ * So instead we recognize the on-chip host-PCI bridge and call back from
+ * sys/i386/pci/pci_bus.c to here if we find it.
+ */
+
+#include <sys/proc.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+u_char *elan_mmcr;
+
+void
+init_AMD_Elan_sc520(void)
+{
+ u_int new;
+ int i;
+
+ printf("Doing h0h0magic for AMD Elan sc520\n");
+ elan_mmcr = pmap_mapdev(0xfffef000, 0x1000);
+ printf("MMCR at %p\n", elan_mmcr);
+
+ /*-
+ * The i8254 is driven with a nonstandard frequency which is
+ * derived thusly:
+ * f = 32768 * 45 * 25 / 31 = 1189161.29...
+ * We use the sysctl to get the timecounter etc into whack.
+ */
+
+ new = 1189161;
+ i = kernel_sysctlbyname(&thread0, "machdep.i8254_freq",
+ NULL, 0,
+ &new, sizeof new,
+ NULL);
+ printf("sysctl machdep.i8254_freq=%d returns %d\n", new, i);
+}
+
diff --git a/sys/i386/include/cputypes.h b/sys/i386/include/cputypes.h
index 585df67..999b174 100644
--- a/sys/i386/include/cputypes.h
+++ b/sys/i386/include/cputypes.h
@@ -68,6 +68,7 @@ struct cpu_nameclass {
extern int cpu;
extern int cpu_class;
+void init_AMD_Elan_sc520(void);
#endif
#endif /* !_MACHINE_CPUTYPES_H_ */
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index 041362f..e75994e 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -48,6 +48,7 @@ extern u_int cpu_id;
extern u_int cpu_fxsr;
extern char cpu_vendor[];
extern u_int cyrix_did;
+extern u_char *elan_mmcr;
extern char kstack[];
#ifdef PC98
extern int need_pre_dma_flush;
diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c
index 4e325b2..65ba7d3 100644
--- a/sys/i386/pci/pci_bus.c
+++ b/sys/i386/pci/pci_bus.c
@@ -40,6 +40,7 @@
#include <machine/nexusvar.h>
#include <machine/pci_cfgreg.h>
#include <machine/segments.h>
+#include <machine/cputypes.h>
#include <machine/pc/bios.h>
#include "pcib_if.h"
@@ -177,6 +178,7 @@ nexus_pcib_is_host_bridge(int bus, int slot, int func,
/* AMD -- vendor 0x1022 */
case 0x30001022:
s = "AMD Elan SC520 host to PCI bridge";
+ init_AMD_Elan_sc520();
break;
case 0x70061022:
s = "AMD-751 host to PCI bridge";
OpenPOWER on IntegriCloud