diff options
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r-- | sys/arch/mips64/include/autoconf.h | 35 | ||||
-rw-r--r-- | sys/arch/mips64/include/cpu.h | 25 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/clock.c | 73 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/cpu.c | 50 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/db_machdep.c | 16 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/pmap.c | 7 |
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; |