From owner-p4-projects@FreeBSD.ORG Mon Apr 28 18:13:50 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6925137B404; Mon, 28 Apr 2003 18:13:49 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1C5D237B401 for ; Mon, 28 Apr 2003 18:13:49 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4E75743FB1 for ; Mon, 28 Apr 2003 18:13:48 -0700 (PDT) (envelope-from jmallett@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h3T1Dm0U074241 for ; Mon, 28 Apr 2003 18:13:48 -0700 (PDT) (envelope-from jmallett@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h3T1Dllf074233 for perforce@freebsd.org; Mon, 28 Apr 2003 18:13:47 -0700 (PDT) Date: Mon, 28 Apr 2003 18:13:47 -0700 (PDT) Message-Id: <200304290113.h3T1Dllf074233@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jmallett@freebsd.org using -f From: Juli Mallett To: Perforce Change Reviews Subject: PERFORCE change 30017 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Apr 2003 01:13:50 -0000 http://perforce.freebsd.org/chv.cgi?CH=30017 Change 30017 by jmallett@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 #include #include +#include #include #include #include @@ -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 +#include +#include + +#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 @@ -30,15 +32,57 @@ #include #include +#include +#include #include -#include +#include +#include #include +#include + +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 #include +#include #include +#include #include #include @@ -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(); }