Annotation of sys/arch/vax/vax/ka650.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ka650.c,v 1.13 2004/01/29 21:34:17 deraadt Exp $ */
! 2: /* $NetBSD: ka650.c,v 1.25 2001/04/27 15:02:37 ragge Exp $ */
! 3: /*
! 4: * Copyright (c) 1988 The Regents of the University of California.
! 5: * All rights reserved.
! 6: *
! 7: * This code is derived from software contributed to Berkeley by
! 8: * Mt. Xinu.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. Neither the name of the University nor the names of its contributors
! 19: * may be used to endorse or promote products derived from this software
! 20: * without specific prior written permission.
! 21: *
! 22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 32: * SUCH DAMAGE.
! 33: *
! 34: * @(#)ka650.c 7.7 (Berkeley) 12/16/90
! 35: */
! 36:
! 37: /*
! 38: * vax650-specific code.
! 39: */
! 40:
! 41: #include <sys/param.h>
! 42: #include <sys/time.h>
! 43: #include <sys/kernel.h>
! 44: #include <sys/systm.h>
! 45: #include <sys/device.h>
! 46: #include <uvm/uvm_extern.h>
! 47:
! 48: #include <machine/ka650.h>
! 49: #include <machine/clock.h>
! 50: #include <machine/cpu.h>
! 51: #include <machine/psl.h>
! 52: #include <machine/mtpr.h>
! 53: #include <machine/sid.h>
! 54:
! 55: struct ka650_merr *ka650merr_ptr;
! 56: struct ka650_cbd *ka650cbd_ptr;
! 57: struct ka650_ssc *ka650ssc_ptr;
! 58: struct ka650_ipcr *ka650ipcr_ptr;
! 59: int *KA650_CACHE_ptr;
! 60:
! 61: #define CACHEOFF 0
! 62: #define CACHEON 1
! 63:
! 64: static void ka650setcache(int);
! 65: static void ka650_halt(void);
! 66: static void ka650_reboot(int);
! 67: static void uvaxIII_conf(void);
! 68: static void uvaxIII_memerr(void);
! 69: static int uvaxIII_mchk(caddr_t);
! 70:
! 71: struct cpu_dep ka650_calls = {
! 72: 0, /* No special page stealing anymore */
! 73: uvaxIII_mchk,
! 74: uvaxIII_memerr,
! 75: uvaxIII_conf,
! 76: generic_clkread,
! 77: generic_clkwrite,
! 78: 4, /* ~VUPS */
! 79: 2, /* SCB pages */
! 80: ka650_halt,
! 81: ka650_reboot,
! 82: };
! 83:
! 84: /*
! 85: * uvaxIII_conf() is called by cpu_attach to do the cpu_specific setup.
! 86: */
! 87: void
! 88: uvaxIII_conf()
! 89: {
! 90: int syssub = GETSYSSUBT(vax_siedata);
! 91:
! 92: /*
! 93: * MicroVAX III: We map in memory error registers,
! 94: * cache control registers, SSC registers,
! 95: * interprocessor registers and cache diag space.
! 96: */
! 97: ka650merr_ptr = (void *)vax_map_physmem(KA650_MERR, 1);
! 98: ka650cbd_ptr = (void *)vax_map_physmem(KA650_CBD, 1);
! 99: ka650ssc_ptr = (void *)vax_map_physmem(KA650_SSC, 3);
! 100: ka650ipcr_ptr = (void *)vax_map_physmem(KA650_IPCR, 1);
! 101: KA650_CACHE_ptr = (void *)vax_map_physmem(KA650_CACHE,
! 102: (KA650_CACHESIZE/VAX_NBPG));
! 103:
! 104: printf("cpu: KA6%d%d, CVAX microcode rev %d Firmware rev %d\n",
! 105: syssub == VAX_SIE_KA640 ? 4 : 5,
! 106: syssub == VAX_SIE_KA655 ? 5 : 0,
! 107: (vax_cpudata & 0xff), GETFRMREV(vax_siedata));
! 108: ka650setcache(CACHEON);
! 109: if (ctob(physmem) > ka650merr_ptr->merr_qbmbr) {
! 110: printf("physmem(0x%x) > qbmbr(0x%x)\n",
! 111: ctob(physmem), (int)ka650merr_ptr->merr_qbmbr);
! 112: panic("qbus map unprotected");
! 113: }
! 114: if (mfpr(PR_TODR) == 0)
! 115: mtpr(1, PR_TODR);
! 116: }
! 117:
! 118: void
! 119: uvaxIII_memerr()
! 120: {
! 121: printf("memory err!\n");
! 122: #if 0 /* XXX Fix this */
! 123: register char *cp = (char *)0;
! 124: register int m;
! 125: extern u_int cache2tag;
! 126:
! 127: if (ka650cbd.cbd_cacr & CACR_CPE) {
! 128: printf("cache 2 tag parity error: ");
! 129: if (time.tv_sec - cache2tag < 7) {
! 130: ka650setcache(CACHEOFF);
! 131: printf("caching disabled\n");
! 132: } else {
! 133: cache2tag = time.tv_sec;
! 134: printf("flushing cache\n");
! 135: ka650setcache(CACHEON);
! 136: }
! 137: }
! 138: m = ka650merr.merr_errstat;
! 139: ka650merr.merr_errstat = MEM_EMASK;
! 140: if (m & MEM_CDAL) {
! 141: cp = "Bus Parity";
! 142: } else if (m & MEM_RDS) {
! 143: cp = "Hard ECC";
! 144: } else if (m & MEM_CRD) {
! 145: cp = "Soft ECC";
! 146: }
! 147: if (cp) {
! 148: printf("%sMemory %s Error: page 0x%x\n",
! 149: (m & MEM_DMA) ? "DMA " : "", cp,
! 150: (m & MEM_PAGE) >> MEM_PAGESHFT);
! 151: }
! 152: #endif
! 153: }
! 154:
! 155: #define NMC650 15
! 156: char *mc650[] = {
! 157: 0, "FPA proto err", "FPA resv inst",
! 158: "FPA Ill Stat 2", "FPA Ill Stat 1", "PTE in P0, TB miss",
! 159: "PTE in P1, TB miss", "PTE in P0, Mod", "PTE in P1, Mod",
! 160: "Illegal intr IPL", "MOVC state error", "bus read error",
! 161: "SCB read error", "bus write error", "PCB write error"
! 162: };
! 163: u_int cache1tag;
! 164: u_int cache1data;
! 165: u_int cdalerr;
! 166: u_int cache2tag;
! 167:
! 168: struct mc650frame {
! 169: int mc65_bcnt; /* byte count == 0xc */
! 170: int mc65_summary; /* summary parameter */
! 171: int mc65_mrvaddr; /* most recent vad */
! 172: int mc65_istate1; /* internal state */
! 173: int mc65_istate2; /* internal state */
! 174: int mc65_pc; /* trapped pc */
! 175: int mc65_psl; /* trapped psl */
! 176: };
! 177:
! 178: int
! 179: uvaxIII_mchk(cmcf)
! 180: caddr_t cmcf;
! 181: {
! 182: register struct mc650frame *mcf = (struct mc650frame *)cmcf;
! 183: register u_int type = mcf->mc65_summary;
! 184: register u_int i;
! 185:
! 186: printf("machine check %x", type);
! 187: if (type >= 0x80 && type <= 0x83)
! 188: type -= (0x80 + 11);
! 189: if (type < NMC650 && mc650[type])
! 190: printf(": %s", mc650[type]);
! 191: printf("\n\tvap %x istate1 %x istate2 %x pc %x psl %x\n",
! 192: mcf->mc65_mrvaddr, mcf->mc65_istate1, mcf->mc65_istate2,
! 193: mcf->mc65_pc, mcf->mc65_psl);
! 194: printf("dmaser=0x%b qbear=0x%x dmaear=0x%x\n",
! 195: ka650merr_ptr->merr_dser, DMASER_BITS,
! 196: (int)ka650merr_ptr->merr_qbear,
! 197: (int)ka650merr_ptr->merr_dear);
! 198: ka650merr_ptr->merr_dser = DSER_CLEAR;
! 199:
! 200: i = mfpr(PR_CAER);
! 201: mtpr(CAER_MCC | CAER_DAT | CAER_TAG, PR_CAER);
! 202: if (i & CAER_MCC) {
! 203: printf("cache 1 ");
! 204: if (i & CAER_DAT) {
! 205: printf("data");
! 206: i = cache1data;
! 207: cache1data = time.tv_sec;
! 208: }
! 209: if (i & CAER_TAG) {
! 210: printf("tag");
! 211: i = cache1tag;
! 212: cache1tag = time.tv_sec;
! 213: }
! 214: } else if ((i & CAER_MCD) || (ka650merr_ptr->merr_errstat & MEM_CDAL)) {
! 215: printf("CDAL");
! 216: i = cdalerr;
! 217: cdalerr = time.tv_sec;
! 218: }
! 219: if (time.tv_sec - i < 7) {
! 220: ka650setcache(CACHEOFF);
! 221: printf(" parity error: caching disabled\n");
! 222: } else {
! 223: printf(" parity error: flushing cache\n");
! 224: ka650setcache(CACHEON);
! 225: }
! 226: /*
! 227: * May be able to recover if type is 1-4, 0x80 or 0x81, but
! 228: * only if FPD is set in the saved PSL, or bit VCR in Istate2
! 229: * is clear.
! 230: */
! 231: if ((type > 0 && type < 5) || type == 11 || type == 12) {
! 232: if ((mcf->mc65_psl & PSL_FPD)
! 233: || !(mcf->mc65_istate2 & IS2_VCR)) {
! 234: uvaxIII_memerr();
! 235: return 0;
! 236: }
! 237: }
! 238: return -1;
! 239: }
! 240:
! 241: /*
! 242: * Make sure both caches are off and not in diagnostic mode. Clear the
! 243: * 2nd level cache (by writing to each quadword entry), then enable it.
! 244: * Enable 1st level cache too.
! 245: */
! 246: void
! 247: ka650setcache(int state)
! 248: {
! 249: int syssub = GETSYSSUBT(vax_siedata);
! 250: int i;
! 251:
! 252: /*
! 253: * Before doing anything, disable the cache.
! 254: */
! 255: mtpr(0, PR_CADR);
! 256: if (syssub != VAX_SIE_KA640)
! 257: ka650cbd_ptr->cbd_cacr = CACR_CPE;
! 258:
! 259: /*
! 260: * Check what we want to do, enable or disable.
! 261: */
! 262: if (state == CACHEON) {
! 263: mtpr(CADR_SEN2 | CADR_SEN1 | CADR_CENI | CADR_CEND, PR_CADR);
! 264: if (syssub != VAX_SIE_KA640) {
! 265: for (i = 0;
! 266: i < (KA650_CACHESIZE / sizeof(KA650_CACHE_ptr[0]));
! 267: i += 2)
! 268: KA650_CACHE_ptr[i] = 0;
! 269: ka650cbd_ptr->cbd_cacr = CACR_CEN;
! 270: }
! 271: }
! 272: }
! 273:
! 274: static void
! 275: ka650_halt()
! 276: {
! 277: ka650ssc_ptr->ssc_cpmbx = CPMB650_DOTHIS | CPMB650_HALT;
! 278: asm("halt");
! 279: }
! 280:
! 281: static void
! 282: ka650_reboot(arg)
! 283: int arg;
! 284: {
! 285: ka650ssc_ptr->ssc_cpmbx = CPMB650_DOTHIS | CPMB650_REBOOT;
! 286: }
CVSweb