summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/powerpc/aim/machdep.c9
-rw-r--r--sys/powerpc/aim/ofw_machdep.c3
-rw-r--r--sys/powerpc/booke/machdep.c1
-rw-r--r--sys/powerpc/include/cpu.h21
-rw-r--r--sys/powerpc/include/md_var.h1
-rw-r--r--sys/powerpc/powerpc/cpu.c195
6 files changed, 131 insertions, 99 deletions
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index 01272b4..7c36543 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -130,7 +130,6 @@ extern vm_offset_t ksym_start, ksym_end;
int cold = 1;
int cacheline_size = 32;
-int ppc64 = 0;
int hw_direct_map = 1;
struct pcpu __pcpu[MAXCPU];
@@ -256,6 +255,7 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
char *env;
uint32_t msr, scratch;
uint8_t *cache_check;
+ int ppc64;
end = 0;
kmdp = NULL;
@@ -405,12 +405,15 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
mfsprg2 %1;"
: "=r"(scratch), "=r"(ppc64));
+ if (ppc64)
+ cpu_features |= PPC_FEATURE_64;
+
/*
* Now copy restorebridge into all the handlers, if necessary,
* and set up the trap tables.
*/
- if (ppc64) {
+ if (cpu_features & PPC_FEATURE_64) {
/* Patch the two instances of rfi -> rfid */
bcopy(&rfid_patch,&rfi_patch1,4);
#ifdef KDB
@@ -489,7 +492,7 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
* in case the platform module had a better idea of what we
* should do.
*/
- if (ppc64)
+ if (cpu_features & PPC_FEATURE_64)
pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC);
else
pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC);
diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c
index 773d229..6e27697 100644
--- a/sys/powerpc/aim/ofw_machdep.c
+++ b/sys/powerpc/aim/ofw_machdep.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <machine/bus.h>
+#include <machine/cpu.h>
#include <machine/md_var.h>
#include <machine/platform.h>
#include <machine/ofw_machdep.h>
@@ -336,7 +337,7 @@ openfirmware(void *args)
/*
* Clear battable[] translations
*/
- if (!ppc64) {
+ if (!(cpu_features & PPC_FEATURE_64)) {
__asm __volatile("mtdbatu 2, %0\n"
"mtdbatu 3, %0" : : "r" (0));
}
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index 1eace0e..9f5960b 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -179,7 +179,6 @@ SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
CTLFLAG_RD, &cacheline_size, 0, "");
int hw_direct_map = 0;
-int ppc64 = 0;
static void cpu_e500_startup(void *);
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_e500_startup, NULL);
diff --git a/sys/powerpc/include/cpu.h b/sys/powerpc/include/cpu.h
index 9856ab0..16cabe7 100644
--- a/sys/powerpc/include/cpu.h
+++ b/sys/powerpc/include/cpu.h
@@ -39,6 +39,27 @@
#include <machine/pcb.h>
#include <machine/psl.h>
+/*
+ * CPU Feature Attributes
+ *
+ * These are defined in the PowerPC ELF ABI for the AT_HWCAP vector,
+ * and are exported to userland via the machdep.cpu_features
+ * sysctl.
+ */
+
+extern int cpu_features;
+
+#define PPC_FEATURE_32 0x80000000 /* Always true */
+#define PPC_FEATURE_64 0x40000000 /* Defined on a 64-bit CPU */
+#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
+#define PPC_FEATURE_HAS_FPU 0x08000000
+#define PPC_FEATURE_HAS_MMU 0x04000000
+#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
+
+#define PPC_FEATURE_BITMASK \
+ "\20" \
+ "\040PPC32\037PPC64\035ALTIVEC\034FPU\033MMU\031UNIFIEDCACHE"
+
#define TRAPF_USERMODE(frame) (((frame)->srr1 & PSL_PR) != 0)
#define TRAPF_PC(frame) ((frame)->srr0)
diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h
index d1785ad..bfe5ed2 100644
--- a/sys/powerpc/include/md_var.h
+++ b/sys/powerpc/include/md_var.h
@@ -46,7 +46,6 @@ extern u_long ns_per_tick;
extern int powerpc_pow_enabled;
extern int cacheline_size;
-extern int ppc64;
extern int hw_direct_map;
void __syncicache(void *, int);
diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c
index 61630a4..ebf36ee 100644
--- a/sys/powerpc/powerpc/cpu.c
+++ b/sys/powerpc/powerpc/cpu.c
@@ -67,6 +67,7 @@
#include <sys/sysctl.h>
#include <machine/bus.h>
+#include <machine/cpu.h>
#include <machine/hid.h>
#include <machine/md_var.h>
#include <machine/smp.h>
@@ -74,59 +75,102 @@
int powerpc_pow_enabled;
+static void cpu_6xx_setup(int cpuid, uint16_t vers);
+static void cpu_e500_setup(int cpuid, uint16_t vers);
+static void cpu_970_setup(int cpuid, uint16_t vers);
+
struct cputab {
const char *name;
uint16_t version;
uint16_t revfmt;
+ int features; /* Do not include PPC_FEATURE_32 or
+ * PPC_FEATURE_HAS_MMU */
+ void (*cpu_setup)(int cpuid, uint16_t vers);
};
#define REVFMT_MAJMIN 1 /* %u.%u */
#define REVFMT_HEX 2 /* 0x%04x */
#define REVFMT_DEC 3 /* %u */
static const struct cputab models[] = {
- { "Motorola PowerPC 601", MPC601, REVFMT_DEC },
- { "Motorola PowerPC 602", MPC602, REVFMT_DEC },
- { "Motorola PowerPC 603", MPC603, REVFMT_MAJMIN },
- { "Motorola PowerPC 603e", MPC603e, REVFMT_MAJMIN },
- { "Motorola PowerPC 603ev", MPC603ev, REVFMT_MAJMIN },
- { "Motorola PowerPC 604", MPC604, REVFMT_MAJMIN },
- { "Motorola PowerPC 604ev", MPC604ev, REVFMT_MAJMIN },
- { "Motorola PowerPC 620", MPC620, REVFMT_HEX },
- { "Motorola PowerPC 750", MPC750, REVFMT_MAJMIN },
- { "IBM PowerPC 750FX", IBM750FX, REVFMT_MAJMIN },
- { "IBM PowerPC 970", IBM970, REVFMT_MAJMIN },
- { "IBM PowerPC 970FX", IBM970FX, REVFMT_MAJMIN },
- { "IBM PowerPC 970GX", IBM970GX, REVFMT_MAJMIN },
- { "IBM PowerPC 970MP", IBM970MP, REVFMT_MAJMIN },
- { "Motorola PowerPC 7400", MPC7400, REVFMT_MAJMIN },
- { "Motorola PowerPC 7410", MPC7410, REVFMT_MAJMIN },
- { "Motorola PowerPC 7450", MPC7450, REVFMT_MAJMIN },
- { "Motorola PowerPC 7455", MPC7455, REVFMT_MAJMIN },
- { "Motorola PowerPC 7457", MPC7457, REVFMT_MAJMIN },
- { "Motorola PowerPC 7447A", MPC7447A, REVFMT_MAJMIN },
- { "Motorola PowerPC 7448", MPC7448, REVFMT_MAJMIN },
- { "Motorola PowerPC 8240", MPC8240, REVFMT_MAJMIN },
- { "Freescale e500v1 core", FSL_E500v1, REVFMT_MAJMIN },
- { "Freescale e500v2 core", FSL_E500v2, REVFMT_MAJMIN },
- { "Unknown PowerPC CPU", 0, REVFMT_HEX }
+ { "Motorola PowerPC 601", MPC601, REVFMT_DEC,
+ PPC_FEATURE_HAS_FPU | PPC_FEATURE_UNIFIED_CACHE, cpu_6xx_setup },
+ { "Motorola PowerPC 602", MPC602, REVFMT_DEC,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 603", MPC603, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 603e", MPC603e, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 603ev", MPC603ev, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 604", MPC604, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 604ev", MPC604ev, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 620", MPC620, REVFMT_HEX,
+ PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL },
+ { "Motorola PowerPC 750", MPC750, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "IBM PowerPC 750FX", IBM750FX, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "IBM PowerPC 970", IBM970, REVFMT_MAJMIN,
+ PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+ cpu_970_setup },
+ { "IBM PowerPC 970FX", IBM970FX, REVFMT_MAJMIN,
+ PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+ cpu_970_setup },
+ { "IBM PowerPC 970GX", IBM970GX, REVFMT_MAJMIN,
+ PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+ cpu_970_setup },
+ { "IBM PowerPC 970MP", IBM970MP, REVFMT_MAJMIN,
+ PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+ cpu_970_setup },
+ { "Motorola PowerPC 7400", MPC7400, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 7410", MPC7410, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 7450", MPC7450, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 7455", MPC7455, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 7457", MPC7457, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 7447A", MPC7447A, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 7448", MPC7448, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 8240", MPC8240, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Motorola PowerPC 8245", MPC8245, REVFMT_MAJMIN,
+ PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+ { "Freescale e500v1 core", FSL_E500v1, REVFMT_MAJMIN,
+ 0, cpu_e500_setup },
+ { "Freescale e500v2 core", FSL_E500v2, REVFMT_MAJMIN,
+ 0, cpu_e500_setup },
+ { "Unknown PowerPC CPU", 0, REVFMT_HEX, 0, NULL },
};
+static void cpu_6xx_print_cacheinfo(u_int, uint16_t);
+static int cpu_feature_bit(SYSCTL_HANDLER_ARGS);
+
static char model[64];
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
-static void cpu_print_speed(void);
+int cpu_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU;
+SYSCTL_OPAQUE(_hw, OID_AUTO, cpu_features, CTLTYPE_INT | CTLFLAG_RD,
+ &cpu_features, sizeof(cpu_features), "IX", "PowerPC CPU features");
-static void cpu_6xx_setup(int cpuid, uint16_t vers);
-static void cpu_6xx_print_cacheinfo(u_int, uint16_t);
-static void cpu_e500_setup(int cpuid, uint16_t vers);
-#ifndef E500
-static void cpu_970_setup(int cpuid, uint16_t vers);
-#endif
+/* Provide some user-friendly aliases for bits in cpu_features */
+SYSCTL_PROC(_hw, OID_AUTO, floatingpoint, CTLTYPE_INT | CTLFLAG_RD,
+ 0, PPC_FEATURE_HAS_FPU, cpu_feature_bit, "I",
+ "Floating point instructions executed in hardware");
+SYSCTL_PROC(_hw, OID_AUTO, altivec, CTLTYPE_INT | CTLFLAG_RD,
+ 0, PPC_FEATURE_HAS_ALTIVEC, cpu_feature_bit, "I", "CPU supports Altivec");
void
cpu_setup(u_int cpuid)
{
u_int pvr, maj, min;
uint16_t vers, rev, revfmt;
+ uint64_t cps;
const struct cputab *cp;
const char *name;
@@ -175,57 +219,19 @@ cpu_setup(u_int cpuid)
break;
}
+ if (cpu_est_clockrate(0, &cps) == 0)
+ printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100);
+ printf("\n");
+
+ cpu_features |= cp->features;
+ printf("cpu%d: Features %b\n", cpuid, cpu_features,
+ PPC_FEATURE_BITMASK);
+
/*
* Configure CPU
*/
- switch (vers) {
- case MPC603:
- case MPC603e:
- case MPC603ev:
- case MPC604ev:
- case MPC750:
- case IBM750FX:
- case MPC7400:
- case MPC7410:
- case MPC7447A:
- case MPC7448:
- case MPC7450:
- case MPC7455:
- case MPC7457:
- case MPC8240:
- case MPC8245:
- cpu_6xx_setup(cpuid, vers);
- break;
-
-#ifndef E500
- case IBM970:
- case IBM970FX:
- case IBM970GX:
- case IBM970MP:
- cpu_970_setup(cpuid, vers);
- break;
-#endif
-
- case FSL_E500v1:
- case FSL_E500v2:
- cpu_e500_setup(cpuid, vers);
- break;
-
- default:
- /* HID setup is unknown */
- break;
- }
-
- printf("\n");
-}
-
-void
-cpu_print_speed(void)
-{
- uint64_t cps;
-
- if (cpu_est_clockrate(0, &cps) == 0)
- printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100);
+ if (cp->cpu_setup != NULL)
+ cp->cpu_setup(cpuid, vers);
}
/* Get current clock frequency for the given cpu id. */
@@ -351,9 +357,6 @@ cpu_6xx_setup(int cpuid, uint16_t vers)
mtspr(SPR_HID0, hid0);
- cpu_print_speed();
- printf("\n");
-
if (bootverbose)
cpu_6xx_print_cacheinfo(cpuid, vers);
@@ -370,7 +373,7 @@ cpu_6xx_setup(int cpuid, uint16_t vers)
break;
}
- printf("cpu%d: HID0 %b", cpuid, (int)hid0, bitmask);
+ printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, bitmask);
}
@@ -429,16 +432,14 @@ cpu_e500_setup(int cpuid, uint16_t vers)
{
register_t hid0;
- printf("\n");
-
hid0 = mfspr(SPR_HID0);
- printf("cpu%d: HID0 %b", cpuid, (int)hid0, HID0_E500_BITMASK);
+ printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK);
}
-#ifndef E500
static void
cpu_970_setup(int cpuid, uint16_t vers)
{
+#ifdef AIM
uint32_t hid0_hi, hid0_lo;
__asm __volatile ("mfspr %0,%2; clrldi %1,%0,32; srdi %0,%0,32;"
@@ -458,11 +459,19 @@ cpu_970_setup(int cpuid, uint16_t vers)
sync; isync"
:: "r" (hid0_hi), "r"(hid0_lo), "K" (SPR_HID0));
- cpu_print_speed();
- printf("\n");
-
__asm __volatile ("mfspr %0,%1; srdi %0,%0,32;"
: "=r" (hid0_hi) : "K" (SPR_HID0));
- printf("cpu%d: HID0 %b", cpuid, (int)(hid0_hi), HID0_970_BITMASK);
-}
+ printf("cpu%d: HID0 %b\n", cpuid, (int)(hid0_hi), HID0_970_BITMASK);
#endif
+}
+
+static int
+cpu_feature_bit(SYSCTL_HANDLER_ARGS)
+{
+ int result;
+
+ result = (cpu_features & arg2) ? 1 : 0;
+
+ return (sysctl_handle_int(oidp, &result, 0, req));
+}
+
OpenPOWER on IntegriCloud