PERFORCE change 30017 for review
Juli Mallett
jmallett at FreeBSD.org
Mon Apr 28 18:13:50 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=30017
Change 30017 by jmallett at jmallett_dalek on 2003/04/28 18:12:49
Add NetBSD IP22 code.
Extend the exception vectors for 64-bit addrs.
Hide the BEV switchoff, it b0rks things good for now.
Hide some unused code.
Treat mips3 as mips64 for our purposes...
Call vector_init manually.
Call init_param stuff as early as it makes sense to.
Have ARCS flush all caches on startup.
Affected files ...
.. //depot/projects/mips/sys/conf/files.mips#16 edit
.. //depot/projects/mips/sys/mips/include/cpuregs.h#5 edit
.. //depot/projects/mips/sys/mips/mips/machdep.c#17 edit
.. //depot/projects/mips/sys/mips/sgimips/intr.h#3 edit
.. //depot/projects/mips/sys/mips/sgimips/ip22.c#2 edit
.. //depot/projects/mips/sys/mips/sgimips/ip22_cache.S#1 add
.. //depot/projects/mips/sys/mips/sgimips/machdep_sgimips.c#13 edit
.. //depot/projects/mips/sys/mips/sgimips/sysconf.h#1 add
Differences ...
==== //depot/projects/mips/sys/conf/files.mips#16 (text+ko) ====
@@ -37,6 +37,7 @@
# This stanza is model files, per platform then per model.
mips/sgimips/ip22.c optional sgimips ip22
+mips/sgimips/ip22_cache.S optional sgimips ip22
# This stanza is device files.
dev/arcbios/arcbios.c optional arcbios
==== //depot/projects/mips/sys/mips/include/cpuregs.h#5 (text+ko) ====
@@ -366,20 +366,20 @@
*
* Common vectors: reset and UTLB miss.
*/
-#define MIPS_RESET_EXC_VEC 0xBFC00000
-#define MIPS_UTLB_MISS_EXC_VEC 0x80000000
+#define MIPS_RESET_EXC_VEC 0xFFFFFFFFBFC00000
+#define MIPS_UTLB_MISS_EXC_VEC 0xFFFFFFFF80000000
/*
* MIPS-1 general exception vector (everything else)
*/
-#define MIPS1_GEN_EXC_VEC 0x80000080
+#define MIPS1_GEN_EXC_VEC 0xFFFFFFFF80000080
/*
* MIPS-III exception vectors
*/
-#define MIPS3_XTLB_MISS_EXC_VEC 0x80000080
-#define MIPS3_CACHE_ERR_EXC_VEC 0x80000100
-#define MIPS3_GEN_EXC_VEC 0x80000180
+#define MIPS3_XTLB_MISS_EXC_VEC 0xFFFFFFFF80000080
+#define MIPS3_CACHE_ERR_EXC_VEC 0xFFFFFFFF80000100
+#define MIPS3_GEN_EXC_VEC 0xFFFFFFFF80000180
/*
* TX79 (R5900) exception vectors
@@ -390,7 +390,7 @@
/*
* MIPS32/MIPS64 (and some MIPS3) dedicated interrupt vector.
*/
-#define MIPS3_INTR_EXC_VEC 0x80000200
+#define MIPS3_INTR_EXC_VEC 0xFFFFFFFF80000200
/*
* Coprocessor 0 registers:
==== //depot/projects/mips/sys/mips/mips/machdep.c#17 (text+ko) ====
@@ -156,6 +156,7 @@
#include <machine/cache.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
#include <machine/cpuregs.h>
#include <machine/hwfunc.h>
#include <machine/locore.h>
@@ -177,13 +178,14 @@
static struct pcpu pcpu0;
struct pcpu *pcpup = &pcpu0;
+struct cpu_info cpu_info_store;
+
vm_offset_t kstack0;
vm_paddr_t kstack0_phys;
void
mips_init(void)
{
- mips_vector_init();
cpu_identify();
proc_linkup(&proc0, &ksegrp0, &kse0, &thread0);
thread0.td_kstack = kstack0;
@@ -572,9 +574,9 @@
memcpy((void *)MIPS3_GEN_EXC_VEC, mips64_exception,
mips64_exceptionEnd - mips64_exception);
+#if 0 /* XXX - why doesn't mipsNN_intr() work? */
if (mips64_intrEnd - mips64_intr > 0x80)
panic("startup: interrupt exception vector code too large");
-#if 0 /* XXX - why doesn't mipsNN_intr() work? */
memcpy((void *)MIPS3_INTR_EXC_VEC, mips64_intr,
mips64_intrEnd - mips64_intr);
#else
@@ -592,7 +594,8 @@
mips_dcache_wbinv_all();
/* Clear BEV in SR so we start handling our own exceptions */
- mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
+ if (0)
+ mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV);
}
/*
@@ -714,6 +717,7 @@
* Now initialize our ISA-dependent function vector.
*/
switch (cpu_arch) {
+ case CPU_ARCH_MIPS3:
case CPU_ARCH_MIPS64:
mips3_cp0_wired_write(0);
mips64_TBIA(mips_num_tlb_entries);
@@ -726,7 +730,6 @@
cpu_halt();
}
-/* XXX simonb: ugg, another ugly #ifdef check... */
/*
* Install power-saving idle routines.
*/
==== //depot/projects/mips/sys/mips/sgimips/intr.h#3 (text+ko) ====
@@ -68,11 +68,34 @@
#ifdef _KERNEL
#ifndef LOCORE
-/*
- * XXX Fill in C code functionlets.
- */
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <machine/cpuregs.h>
+
+#define NINTR 32
+
+struct sgimips_intrhand {
+ LIST_ENTRY(sgimips_intrhand)
+ ih_q;
+ int (*ih_fun) __P((void *));
+ void *ih_arg;
+ struct sgimips_intr *ih_intrhead;
+ int ih_pending;
+};
+
+struct sgimips_intr {
+ LIST_HEAD(,sgimips_intrhand)
+ intr_q;
+#if notyet
+ struct evcnt ih_evcnt;
+#endif
+ unsigned long intr_ipl;
+};
+
+extern struct sgimips_intrhand intrtab[];
#endif /* LOCORE */
#endif /* !_KERNEL */
#endif /* !_SGIMIPS_INTR_H_ */
+
==== //depot/projects/mips/sys/mips/sgimips/ip22.c#2 (text+ko) ====
@@ -1,5 +1,8 @@
-/*-
- * Copyright (c) 2003 Juli Mallett. All rights reserved.
+/* $NetBSD: ip22.c,v 1.14 2002/11/09 19:21:12 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2001, 2002 Rafal K. Boni
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -9,20 +12,19 @@
* 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#include <sys/param.h>
@@ -30,15 +32,57 @@
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <machine/locore.h>
+#include <machine/cache.h>
#include <machine/cpu.h>
-#include <machine/cpuregs.h>
+#include <machine/cpuinfo.h>
+#include <platform/intr.h>
#include <platform/models.h>
+#include <platform/sysconf.h>
+
+u_int32_t next_clk_intr;
+u_int32_t missed_clk_intrs;
+static unsigned long last_clk_intr;
+
+#if notyet
+static struct evcnt mips_int5_evcnt =
+ EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 5 (clock)");
+static struct evcnt mips_spurint_evcnt =
+ EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "spurious interrupts");
+#endif
+
+static u_int32_t iocwrite; /* IOC write register: read-only */
+static u_int32_t iocreset; /* IOC reset register: read-only */
+
+void ip22_bus_reset(void);
+int ip22_local0_intr(void);
+int ip22_local1_intr(void);
+int ip22_mappable_intr(void *);
+void ip22_intr(u_int, u_int, u_int, u_int);
+void ip22_intr_establish(int, int, int (*)(void *), void *);
+
+unsigned long ip22_clkread(void);
+unsigned long ip22_cal_timer(u_int32_t, u_int32_t);
+
+/* ip22_cache.S */
+extern void ip22_sdcache_do_wbinv(vaddr_t, vaddr_t);
+extern void ip22_sdcache_enable(void);
+extern void ip22_sdcache_disable(void);
+
void
ip22_init(void)
{
+ u_int i;
u_int32_t sysid;
+ u_int32_t int23addr;
+ unsigned long cps;
+ unsigned long ctrdiff[3];
+
+ /* enable watchdog timer, clear it */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa00004) |= 0x100;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa00014) = 0;
sysid = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9858);
@@ -48,4 +92,418 @@
mach_subtype = MACH_SGI_IP22_GUINESS;
mach_boardrev = (sysid >> 1) & 0x0f;
+
+ printf("IOC rev %d, machine %s, board rev %d\n", (sysid >> 5) & 0x07,
+ (sysid & 1) ? "Indigo2 (Fullhouse)" : "Indy (Guiness)",
+ (sysid >> 1) & 0x0f);
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ /* Reset timer interrupts */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x20) = 3;
+
+ /*
+ * Reset Parallel port, Keyboard/mouse and EISA. Turn LED off.
+ * For Fullhouse, toggle magic GIO reset bit.
+ */
+ iocreset = 0x17;
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ iocreset |= 0x08;
+
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9870) = iocreset;
+
+ /*
+ * Set the 10BaseT port to use UTP cable, set autoselect mode for
+ * the ethernet interface (AUI vs. TP), set the two serial ports
+ * to PC mode.
+ */
+ iocwrite = 0x3a;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9878) = iocwrite;
+
+ /* Clean out interrupt masks */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x04) = 0x00;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x0c) = 0x00;
+
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x14) = 0x00;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x18) = 0x00;
+
+ /* Set the general control registers for Guiness */
+ if (mach_subtype == MACH_SGI_IP22_GUINESS) {
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9848) = 0xff;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd984c) = 0xff;
+ }
+
+ platform.iointr = ip22_intr;
+ platform.bus_reset = ip22_bus_reset;
+ platform.intr_establish = ip22_intr_establish;
+
+#if maybenever
+ biomask = 0x0700;
+ netmask = 0x0700;
+ ttymask = 0x0f00;
+ clockmask = 0xbf00;
+#endif
+
+ /* Hardcode interrupts 7, 11 to mappable interrupt 0,1 handlers */
+ intrtab[7].ih_fun = ip22_mappable_intr;
+ intrtab[7].ih_arg = (void*) 0;
+
+ intrtab[11].ih_fun = ip22_mappable_intr;
+ intrtab[11].ih_arg = (void*) 1;
+
+ /* Prime cache */
+ ip22_cal_timer(int23addr + 0x3c, int23addr + 0x38);
+
+ cps = 0;
+ for(i = 0; i < sizeof(ctrdiff) / sizeof(ctrdiff[0]); i++) {
+ do {
+ ctrdiff[i] = ip22_cal_timer(int23addr + 0x3c,
+ int23addr + 0x38);
+ } while (ctrdiff[i] == 0);
+
+ cps += ctrdiff[i];
+ }
+
+ cps = cps / (sizeof(ctrdiff) / sizeof(ctrdiff[0]));
+
+ printf("Timer calibration, got %lu cycles (%lu, %lu, %lu)\n", cps,
+ ctrdiff[0], ctrdiff[1], ctrdiff[2]);
+
+ platform.clkread = ip22_clkread;
+
+ /* Counter on R4k/R4400/R4600/R5k counts at half the CPU frequency */
+ curcpu()->ci_cpu_freq = 2 * cps * hz;
+ curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz);
+ curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / (2 * 1000000);
+ MIPS_SET_CI_RECIPRICAL(curcpu());
+
+#if notyet
+ evcnt_attach_static(&mips_int5_evcnt);
+ evcnt_attach_static(&mips_spurint_evcnt);
+#endif
+
+ printf("CPU clock speed = %lu.%02luMhz\n",
+ curcpu()->ci_cpu_freq / 1000000,
+ (curcpu()->ci_cpu_freq / 10000) % 100);
+}
+
+void
+ip22_bus_reset(void)
+{
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000ec) = 0;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000fc) = 0;
+}
+
+/*
+ * NB: Do not re-enable interrupts here -- reentrancy here can cause all
+ * sorts of Bad Things(tm) to happen, including kernel stack overflows.
+ */
+void
+ip22_intr(status, cause, pc, ipending)
+ u_int32_t status;
+ u_int32_t cause;
+ u_int32_t pc;
+ u_int32_t ipending;
+{
+ u_int32_t newcnt;
+ struct clockframe cf;
+
+ /* Tickle Indy/I2 MC watchdog timer */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa00014) = 0;
+
+ if (ipending & MIPS_INT_MASK_5) {
+ last_clk_intr = mips3_cp0_count_read();
+
+ next_clk_intr += curcpu()->ci_cycles_per_hz;
+ mips3_cp0_compare_write(next_clk_intr);
+ newcnt = mips3_cp0_count_read();
+
+ /*
+ * Missed one or more clock interrupts, so let's start
+ * counting again from the current value.
+ */
+ if ((next_clk_intr - newcnt) & 0x80000000) {
+ missed_clk_intrs++;
+
+ next_clk_intr = newcnt + curcpu()->ci_cycles_per_hz;
+ mips3_cp0_compare_write(next_clk_intr);
+ }
+
+ cf.pc = pc;
+ cf.sr = status;
+
+ hardclock(&cf);
+#if notyet
+ mips_int5_evcnt.ev_count++;
+#endif
+
+ cause &= ~MIPS_INT_MASK_5;
+ }
+
+ if (ipending & MIPS_INT_MASK_0) {
+ if (ip22_local0_intr())
+ cause &= ~MIPS_INT_MASK_0;
+ }
+
+ if (ipending & MIPS_INT_MASK_1) {
+ if (ip22_local1_intr())
+ cause &= ~MIPS_INT_MASK_1;
+ }
+
+ if (ipending & MIPS_INT_MASK_4) {
+ printf("IP22 bus error: cpu_stat %08x addr %08x, "
+ "gio_stat %08x addr %08x\n",
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000ec),
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000e4),
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000fc),
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000f4));
+ ip22_bus_reset();
+ cause &= ~MIPS_INT_MASK_4;
+ }
+
+#if notyet
+ if (cause & status & MIPS_HARD_INT_MASK)
+ mips_spurint_evcnt.ev_count++;
+#endif
+}
+
+int
+ip22_mappable_intr(void* arg)
+{
+ int i;
+ int ret;
+ int intnum;
+ u_int32_t mstat;
+ u_int32_t mmask;
+ u_int32_t int23addr;
+ int which = (int)arg;
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ ret = 0;
+ mstat = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x10);
+ mmask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x14 +
+ (which * 4));
+
+ mstat &= mmask;
+
+ for (i = 0; i < 8; i++) {
+ intnum = i + 16 + (which * 8);
+ if (mstat & (1 << i)) {
+ if (intrtab[intnum].ih_fun != NULL)
+ ret |= (intrtab[intnum].ih_fun)
+ (intrtab[intnum].ih_arg);
+ else
+ printf("Unexpected mappable interrupt %d\n",
+ intnum);
+ }
+ }
+
+ return ret;
+}
+
+int
+ip22_local0_intr()
+{
+ int i;
+ int ret;
+ u_int32_t l0stat;
+ u_int32_t l0mask;
+ u_int32_t int23addr;
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ ret = 0;
+ l0stat = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x00);
+ l0mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x04);
+
+ l0stat &= l0mask;
+
+ for (i = 0; i < 8; i++) {
+ if (l0stat & (1 << i)) {
+ if (intrtab[i].ih_fun != NULL)
+ ret |= (intrtab[i].ih_fun)(intrtab[i].ih_arg);
+ else
+ printf("Unexpected local0 interrupt %d\n", i);
+ }
+ }
+
+ return ret;
+}
+
+int
+ip22_local1_intr()
+{
+ int i;
+ int ret;
+ u_int32_t l1stat;
+ u_int32_t l1mask;
+ u_int32_t int23addr;
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ l1stat = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x08);
+ l1mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x0c);
+
+ l1stat &= l1mask;
+
+ ret = 0;
+ for (i = 0; i < 8; i++) {
+ if (l1stat & (1 << i)) {
+ if (intrtab[8 + i].ih_fun != NULL)
+ ret |= (intrtab[8 + i].ih_fun)
+ (intrtab[8 + i].ih_arg);
+ else
+ printf("Unexpected local1 interrupt %x\n",
+ 8 + i );
+ }
+ }
+
+ return ret;
+}
+
+void
+ip22_intr_establish(level, ipl, handler, arg)
+ int level;
+ int ipl;
+ int (*handler) __P((void *));
+ void *arg;
+{
+ u_int32_t mask;
+ u_int32_t int23addr;
+
+ if (level < 0 || level >= NINTR)
+ panic("invalid interrupt level");
+
+ if (intrtab[level].ih_fun != NULL)
+ panic("cannot share CPU interrupts");
+
+ intrtab[level].ih_fun = handler;
+ intrtab[level].ih_arg = arg;
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ if (level < 8) {
+ mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x4);
+ mask |= (1 << level);
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x4) = mask;
+ } else if (level < 16) {
+ mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0xc);
+ mask |= (1 << (level - 8));
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0xc) = mask;
+ } else if (level < 24) {
+ /* Map0 interrupt maps to l0 interrupt bit 7, so turn that on too */
+ mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x4);
+ mask |= (1 << 7);
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x4) = mask;
+
+ mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x14);
+ mask |= (1 << (level - 16));
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x14) = mask;
+ } else {
+ /* Map1 interrupt maps to l1 interrupt bit 3, so turn that on too */
+ mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0xc);
+ mask |= (1 << 3);
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0xc) = mask;
+
+ mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x18);
+ mask |= (1 << (level - 24));
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x18) = mask;
+ }
+}
+
+unsigned long
+ip22_clkread(void)
+{
+ uint32_t res, count;
+
+ count = mips3_cp0_count_read() - last_clk_intr;
+ MIPS_COUNT_TO_MHZ(curcpu(), count, res);
+ return (res);
+}
+
+unsigned long
+ip22_cal_timer(u_int32_t tctrl, u_int32_t tcount)
+{
+ int s;
+ int roundtime;
+ int sampletime;
+ int startmsb, lsb, msb;
+ unsigned long startctr, endctr;
+
+ /*
+ * NOTE: HZ must be greater than 15 for this to work, as otherwise
+ * we'll overflow the counter. We round the answer to hearest 1
+ * MHz of the master (2x) clock.
+ */
+ roundtime = (1000000 / hz) / 2;
+ sampletime = (1000000 / hz) + 0xff;
+ startmsb = (sampletime >> 8);
+
+ s = splhigh();
+
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(tctrl) = 0x80 | 0x30 | 0x04;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(tcount) = sampletime & 0xff;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(tcount) = sampletime >> 8;
+
+ startctr = mips3_cp0_count_read();
+
+ /* Wait for the MSB to count down to zero */
+ do {
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(tctrl) = 0x80 | 0x00;
+ lsb = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(tcount) & 0xff;
+ msb = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(tcount) & 0xff;
+
+ endctr = mips3_cp0_count_read();
+ } while (msb);
+
+ /* Turn off timer */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(tctrl) = 0x80 | 0x30 | 0x08;
+
+ splx(s);
+
+ return (endctr - startctr) / roundtime * roundtime;
+}
+
+void ip22_cache_init(void);
+
+void
+ip22_cache_init(void)
+{
+
+ /*
+ * If we don't have an R4000-style cache, then initialize the
+ * IP22 SysAD L2 cache.
+ *
+ * XXX: For now we disable the SysAD cache on R4600/R5k systems,
+ * as there's no code to drive it; also make sure to clear the
+ * flags used by the generic MIPS code so it doesn't attempt to
+ * use the L2.
+ */
+ switch (MIPS_PRID_IMPL(cpu_id)) {
+ case MIPS_R4600:
+#ifndef ENABLE_MIPS_R3NKK
+ case MIPS_R5000:
+#endif
+ mips_sdcache_size = 0;
+ mips_sdcache_line_size = 0;
+ printf("disabling IP22 SysAD L2 cache\n");
+ ip22_sdcache_disable();
+ break;
+ }
}
==== //depot/projects/mips/sys/mips/sgimips/machdep_sgimips.c#13 (text+ko) ====
@@ -34,7 +34,9 @@
#include <machine/hwfunc.h>
#include <machine/md_var.h>
+#include <platform/intr.h>
#include <platform/models.h>
+#include <platform/sysconf.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -56,6 +58,10 @@
int arcsmem, availmem;
int mach_type, mach_subtype, mach_boardrev;
+struct platform platform;
+
+struct sgimips_intrhand intrtab[NINTR];
+
void
platform_halt(void)
{
@@ -82,10 +88,15 @@
arcbios_init(MIPS_PHYS_TO_KSEG1(0x00001000));
arcbios_cnattach();
+ ARCBIOS->FlushAllCaches();
+
cpufreq = ARCBIOS->GetEnvironmentVariable("cpufreq");
if (cpufreq == NULL)
panic("$cpufreq not set");
+ /* Set up hz, among others. */
+ init_param1();
+
for (mtp = machines; mtp->identifier != NULL; mtp++) {
if (strcmp(mtp->identifier, arcbios_system_identifier) == 0)
break;
@@ -141,6 +152,8 @@
printf("avail memory = %d (%d MB)\n", ctob(availmem),
ctob(availmem) / (1024 * 1024));
+ init_param2(ctob(availmem));
+ mips_vector_init();
pmap_bootstrap();
mips_init();
}
More information about the p4-projects
mailing list