summaryrefslogtreecommitdiff
path: root/sys/arch/mips64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r--sys/arch/mips64/include/autoconf.h35
-rw-r--r--sys/arch/mips64/include/cpu.h25
-rw-r--r--sys/arch/mips64/mips64/clock.c73
-rw-r--r--sys/arch/mips64/mips64/cpu.c50
-rw-r--r--sys/arch/mips64/mips64/db_machdep.c16
-rw-r--r--sys/arch/mips64/mips64/pmap.c7
6 files changed, 133 insertions, 73 deletions
diff --git a/sys/arch/mips64/include/autoconf.h b/sys/arch/mips64/include/autoconf.h
new file mode 100644
index 00000000000..1a1519f9971
--- /dev/null
+++ b/sys/arch/mips64/include/autoconf.h
@@ -0,0 +1,35 @@
+/* $OpenBSD: autoconf.h,v 1.1 2010/01/09 20:33:16 miod Exp $ */
+
+/*
+ * Copyright (c) 2010 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Common defines used by autoconf on all mips64-based platforms.
+ */
+
+#ifndef _MIPS64_AUTOCONF_H_
+#define _MIPS64_AUTOCONF_H_
+
+#include <machine/cpu.h> /* for struct cpu_hwinfo */
+
+struct cpu_attach_args {
+ struct mainbus_attach_args caa_maa;
+ struct cpu_hwinfo *caa_hw;
+};
+
+extern struct cpu_hwinfo bootcpu_hwinfo;
+
+#endif /* _MIPS64_AUTOCONF_H_ */
diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h
index cb2d70e10d1..e60cd3f65d1 100644
--- a/sys/arch/mips64/include/cpu.h
+++ b/sys/arch/mips64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.51 2010/01/08 01:35:52 syuu Exp $ */
+/* $OpenBSD: cpu.h,v 1.52 2010/01/09 20:33:16 miod Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -364,21 +364,30 @@ extern vaddr_t uncached_base;
#include <machine/intr.h>
+struct cpu_hwinfo {
+ uint32_t c0prid;
+ uint32_t c1prid;
+ uint32_t clock; /* Hz */
+ uint32_t tlbsize;
+ uint type;
+};
+
struct cpu_info {
- struct device *ci_dev; /* our device */
- struct cpu_info *ci_self; /* pointer to this structure */
- struct cpu_info *ci_next; /* next cpu */
+ struct device *ci_dev; /* our device */
+ struct cpu_info *ci_self; /* pointer to this structure */
+ struct cpu_info *ci_next; /* next cpu */
struct proc *ci_curproc;
struct user *ci_curprocpaddr;
struct proc *ci_fpuproc; /* pointer to last proc to use FP */
-
+ struct cpu_hwinfo
+ ci_hw;
struct schedstate_percpu
ci_schedstate;
int ci_want_resched; /* need_resched() invoked */
- cpuid_t ci_cpuid; /* our CPU ID */
+ cpuid_t ci_cpuid; /* our CPU ID */
uint32_t ci_randseed; /* per cpu random seed */
- int ci_ipl; /* software IPL */
- uint32_t ci_softpending; /* pending soft interrupts */
+ int ci_ipl; /* software IPL */
+ uint32_t ci_softpending; /* pending soft interrupts */
int ci_clock_started;
u_int32_t ci_cpu_counter_last;
u_int32_t ci_cpu_counter_interval;
diff --git a/sys/arch/mips64/mips64/clock.c b/sys/arch/mips64/mips64/clock.c
index 02c7de179dc..a0f7f530d06 100644
--- a/sys/arch/mips64/mips64/clock.c
+++ b/sys/arch/mips64/mips64/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.31 2009/12/28 06:55:27 syuu Exp $ */
+/* $OpenBSD: clock.c,v 1.32 2010/01/09 20:33:16 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -52,6 +52,7 @@ struct cfattach clock_ca = {
sizeof(struct device), clockmatch, clockattach
};
+void clock_calibrate(struct cpu_info *);
uint32_t clock_int5(uint32_t, struct trap_frame *);
u_int cp0_get_timecount(struct timecounter *);
@@ -188,9 +189,10 @@ delay(int n)
{
int dly;
int p, c;
+ struct cpu_info *ci = curcpu();
p = cp0_get_count();
- dly = (sys_config.cpu[0].clock / 1000000) * n / 2;
+ dly = (ci->ci_hw.clock / 1000000) * n / 2;
while (dly > 0) {
c = cp0_get_count();
dly -= c - p;
@@ -205,49 +207,57 @@ delay(int n)
struct tod_desc sys_tod;
/*
- * Start the real-time and statistics clocks. Leave stathz 0 since there
- * are no other timers available.
+ * Calibrate cpu clock against the TOD clock if available.
*/
void
-cpu_initclocks()
+clock_calibrate(struct cpu_info *ci)
{
struct tod_desc *cd = &sys_tod;
struct tod_time ct;
u_int first_cp0, second_cp0, cycles_per_sec;
int first_sec;
+
+ if (cd->tod_get == NULL)
+ return;
+
+ (*cd->tod_get)(cd->tod_cookie, 0, &ct);
+ first_sec = ct.sec;
+
+ /* Let the clock tick one second. */
+ do {
+ first_cp0 = cp0_get_count();
+ (*cd->tod_get)(cd->tod_cookie, 0, &ct);
+ } while (ct.sec == first_sec);
+ first_sec = ct.sec;
+ /* Let the clock tick one more second. */
+ do {
+ second_cp0 = cp0_get_count();
+ (*cd->tod_get)(cd->tod_cookie, 0, &ct);
+ } while (ct.sec == first_sec);
+
+ cycles_per_sec = second_cp0 - first_cp0;
+ ci->ci_hw.clock = cycles_per_sec * 2;
+}
+
+/*
+ * Start the real-time and statistics clocks. Leave stathz 0 since there
+ * are no other timers available.
+ */
+void
+cpu_initclocks()
+{
struct cpu_info *ci = curcpu();
hz = 100;
profhz = 100;
stathz = 0; /* XXX no stat clock yet */
- /*
- * Calibrate the cycle counter frequency.
- */
- if (cd->tod_get != NULL) {
- (*cd->tod_get)(cd->tod_cookie, 0, &ct);
- first_sec = ct.sec;
-
- /* Let the clock tick one second. */
- do {
- first_cp0 = cp0_get_count();
- (*cd->tod_get)(cd->tod_cookie, 0, &ct);
- } while (ct.sec == first_sec);
- first_sec = ct.sec;
- /* Let the clock tick one more second. */
- do {
- second_cp0 = cp0_get_count();
- (*cd->tod_get)(cd->tod_cookie, 0, &ct);
- } while (ct.sec == first_sec);
-
- cycles_per_sec = second_cp0 - first_cp0;
- sys_config.cpu[0].clock = cycles_per_sec * 2;
- }
+ clock_calibrate(ci);
tick = 1000000 / hz; /* number of micro-seconds between interrupts */
tickadj = 240000 / (60 * hz); /* can adjust 240ms in 60s */
- cp0_timecounter.tc_frequency = sys_config.cpu[0].clock / 2;
+ cp0_timecounter.tc_frequency = (uint64_t)ci->ci_hw.clock / 2;
tc_init(&cp0_timecounter);
cpu_startclock(ci);
}
@@ -264,11 +274,13 @@ cpu_startclock(struct cpu_info *ci)
/* try to avoid getting clock interrupts early */
cp0_set_compare(cp0_get_count() - 1);
+
+ clock_calibrate(ci);
}
/* Start the clock. */
s = splclock();
- ci->ci_cpu_counter_interval = cp0_timecounter.tc_frequency / hz;
+ ci->ci_cpu_counter_interval = (ci->ci_hw.clock / 2) / hz;
ci->ci_cpu_counter_last = cp0_get_count() + ci->ci_cpu_counter_interval;
cp0_set_compare(ci->ci_cpu_counter_last);
ci->ci_clock_started++;
@@ -309,7 +321,7 @@ inittodr(time_t base)
if (base < 35 * SECYR) {
printf("WARNING: preposterous time in file system");
/* read the system clock anyway */
- base = 38 * SECYR; /* 2008 */
+ base = 40 * SECYR; /* 2010 */
}
/*
@@ -414,5 +426,6 @@ resettodr()
u_int
cp0_get_timecount(struct timecounter *tc)
{
+ /* XXX SMP */
return (cp0_get_count());
}
diff --git a/sys/arch/mips64/mips64/cpu.c b/sys/arch/mips64/mips64/cpu.c
index 0dd44178805..5c7a6e5d2e3 100644
--- a/sys/arch/mips64/mips64/cpu.c
+++ b/sys/arch/mips64/mips64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.23 2010/01/08 01:35:52 syuu Exp $ */
+/* $OpenBSD: cpu.c,v 1.24 2010/01/09 20:33:16 miod Exp $ */
/*
* Copyright (c) 1997-2004 Opsycon AB (www.opsycon.se)
@@ -80,13 +80,10 @@ struct cfdriver cpu_cd = {
int
cpumatch(struct device *parent, void *match, void *aux)
{
- struct cfdata *cf = match;
- struct mainbus_attach_args *maa = aux;
+ struct cpu_attach_args *caa = aux;
/* make sure that we're looking for a CPU. */
- if (strcmp(maa->maa_name, cpu_cd.cd_name) != 0)
- return 0;
- if (cf->cf_unit >= MAX_CPUS)
+ if (strcmp(caa->caa_maa.maa_name, cpu_cd.cd_name) != 0)
return 0;
return 20; /* Make CPU probe first */
@@ -95,9 +92,12 @@ cpumatch(struct device *parent, void *match, void *aux)
void
cpuattach(struct device *parent, struct device *dev, void *aux)
{
+ struct cpu_attach_args *caa = aux;
+ struct cpu_hwinfo *ch = caa->caa_hw;
struct cpu_info *ci;
int cpuno = dev->dv_unit;
int isr16k = 0;
+ int fptype, vers_maj, vers_min;
int displayver;
if (cpuno == 0) {
@@ -122,11 +122,14 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
ci->ci_self = ci;
ci->ci_cpuid = cpuno;
ci->ci_dev = dev;
+ bcopy(ch, &ci->ci_hw, sizeof(struct cpu_hwinfo));
printf(": ");
displayver = 1;
- switch (sys_config.cpu[cpuno].type) {
+ vers_maj = (ch->c0prid >> 4) & 0x0f;
+ vers_min = ch->c0prid & 0x0f;
+ switch (ch->type) {
case MIPS_R4000:
if (CpuPrimaryInstCacheSize == 16384)
printf("MIPS R4400 CPU");
@@ -143,8 +146,8 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
printf("MIPS R12000 CPU");
break;
case MIPS_R14000:
- if (sys_config.cpu[cpuno].vers_maj > 2) {
- sys_config.cpu[cpuno].vers_maj -= 2;
+ if (vers_maj > 2) {
+ vers_maj -= 2;
isr16k = 1;
}
printf("R1%d000 CPU", isr16k ? 6 : 4);
@@ -168,7 +171,7 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
printf("PMC-Sierra RM52X0 CPU");
break;
case MIPS_RM7000:
- if (sys_config.cpu[cpuno].vers_maj < 2)
+ if (vers_maj < 2)
printf("PMC-Sierra RM7000 CPU");
else
printf("PMC-Sierra RM7000A CPU");
@@ -178,21 +181,22 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
printf("PMC-Sierra RM9000 CPU");
break;
case MIPS_LOONGSON2:
- printf("STC Loongson2%c CPU",
- 'C' + sys_config.cpu[cpuno].vers_min);
+ printf("STC Loongson2%c CPU", 'C' + vers_min);
displayver = 0;
break;
default:
- printf("Unknown CPU type (0x%x)",sys_config.cpu[cpuno].type);
+ printf("Unknown CPU type (0x%x)", ch->type);
break;
}
if (displayver != 0)
- printf(" rev %d.%d", sys_config.cpu[cpuno].vers_maj,
- sys_config.cpu[cpuno].vers_min);
- printf(" %d MHz, ", sys_config.cpu[cpuno].clock / 1000000);
+ printf(" rev %d.%d", vers_maj, vers_min);
+ printf(" %d MHz, ", ch->clock / 1000000);
displayver = 1;
- switch (sys_config.cpu[cpuno].fptype) {
+ fptype = (ch->c1prid >> 8) & 0xff;
+ vers_maj = (ch->c1prid >> 4) & 0x0f;
+ vers_min = ch->c1prid & 0x0f;
+ switch (fptype) {
case MIPS_SOFT:
printf("Software FP emulation");
break;
@@ -230,17 +234,15 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
printf("RM9000 FPC");
break;
case MIPS_LOONGSON2:
- printf("STC Loongson2%c FPU",
- 'C' + sys_config.cpu[cpuno].fpvers_min);
+ printf("STC Loongson2%c FPU", 'C' + vers_min);
displayver = 0;
break;
default:
- printf("Unknown FPU type (0x%x)", sys_config.cpu[cpuno].fptype);
+ printf("Unknown FPU type (0x%x)", fptype);
break;
}
if (displayver != 0)
- printf(" rev %d.%d", sys_config.cpu[cpuno].fpvers_maj,
- sys_config.cpu[cpuno].fpvers_min);
+ printf(" rev %d.%d", vers_maj, vers_min);
printf("\n");
printf("cpu%d: cache L1-I %dKB", cpuno, CpuPrimaryInstCacheSize / 1024);
@@ -259,7 +261,7 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
}
if (CpuSecondaryCacheSize != 0) {
- switch (sys_config.cpu[cpuno].type) {
+ switch (ch->type) {
case MIPS_R10000:
case MIPS_R12000:
case MIPS_R14000:
@@ -285,7 +287,7 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
printf("cpu%d: Alias mask 0x%x\n", cpuno, CpuCacheAliasMask);
printf("cpu%d: Config Register %x\n", cpuno, CpuConfigRegister);
printf("cpu%d: Cache type %x\n", cpuno, CpuCacheType);
- if (sys_config.cpu[cpuno].fptype == MIPS_RM7000) {
+ if (ch->type == MIPS_RM7000) {
u_int tmp = CpuConfigRegister;
printf("cpu%d: ", cpuno);
diff --git a/sys/arch/mips64/mips64/db_machdep.c b/sys/arch/mips64/mips64/db_machdep.c
index 4dc4e3b8f80..9cd02ddadf2 100644
--- a/sys/arch/mips64/mips64/db_machdep.c
+++ b/sys/arch/mips64/mips64/db_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_machdep.c,v 1.21 2009/12/25 21:02:15 miod Exp $ */
+/* $OpenBSD: db_machdep.c,v 1.22 2010/01/09 20:33:16 miod Exp $ */
/*
* Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se)
@@ -552,6 +552,7 @@ db_dump_tlb_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *m)
{
int tlbno, last, check, pid;
struct tlb_entry tlb, tlbp;
+ struct cpu_info *ci = curcpu();
char *attr[] = {
"WTNA", "WTA ", "UCBL", "CWB ", "RES ", "RES ", "UCNB", "BPAS"
};
@@ -562,10 +563,10 @@ char *attr[] = {
if (have_addr && addr < 256) {
pid = addr;
tlbno = 0;
- count = sys_config.cpu[0].tlbsize;
+ count = ci->ci_hw.tlbsize;
}
} else if (m[0] == 'c') {
- last = sys_config.cpu[0].tlbsize;
+ last = ci->ci_hw.tlbsize;
for (tlbno = 0; tlbno < last; tlbno++) {
tlb_read(tlbno, &tlb);
for (check = tlbno + 1; check < last; check++) {
@@ -581,17 +582,16 @@ if ((tlbp.tlb_hi == tlb.tlb_hi && (tlb.tlb_lo0 & PG_V || tlb.tlb_lo1 & PG_V)) ||
}
return;
} else {
- if (have_addr && addr < sys_config.cpu[0].tlbsize) {
+ if (have_addr && addr < ci->ci_hw.tlbsize) {
tlbno = addr;
- }
- else {
+ } else {
tlbno = 0;
- count = sys_config.cpu[0].tlbsize;
+ count = ci->ci_hw.tlbsize;
}
}
last = tlbno + count;
- for (; tlbno < sys_config.cpu[0].tlbsize && tlbno < last; tlbno++) {
+ for (; tlbno < ci->ci_hw.tlbsize && tlbno < last; tlbno++) {
tlb_read(tlbno, &tlb);
if (pid >= 0 && (tlb.tlb_hi & 0xff) != pid)
diff --git a/sys/arch/mips64/mips64/pmap.c b/sys/arch/mips64/mips64/pmap.c
index e3d3bb607ed..6f274949350 100644
--- a/sys/arch/mips64/mips64/pmap.c
+++ b/sys/arch/mips64/mips64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.46 2010/01/05 06:44:58 syuu Exp $ */
+/* $OpenBSD: pmap.c,v 1.47 2010/01/09 20:33:16 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -1385,14 +1385,15 @@ pmap_alloc_tlbpid(struct proc *p)
{
pmap_t pmap;
uint id;
- u_long cpuid = cpu_number();
+ struct cpu_info *ci = curcpu();
+ u_long cpuid = ci->ci_cpuid;
pmap = p->p_vmspace->vm_map.pmap;
if (pmap->pm_asid[cpuid].pma_asidgen !=
pmap_asid_info[cpuid].pma_asidgen) {
id = pmap_asid_info[cpuid].pma_asid;
if (id >= VMNUM_PIDS) {
- tlb_flush(sys_config.cpu[0].tlbsize);
+ tlb_flush(ci->ci_hw.tlbsize);
/* reserve tlbpid_gen == 0 to alway mean invalid */
if (++pmap_asid_info[cpuid].pma_asidgen == 0)
pmap_asid_info[cpuid].pma_asidgen = 1;