Annotation of sys/arch/vax/vax/ka43.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ka43.c,v 1.10 2006/06/30 16:14:31 miod Exp $ */
! 2: /* $NetBSD: ka43.c,v 1.19 1999/09/06 19:52:53 ragge Exp $ */
! 3: /*
! 4: * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
! 5: * All rights reserved.
! 6: *
! 7: * This code is derived from software contributed to Ludd by Bertram Barth.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: * 3. All advertising materials mentioning features or use of this software
! 18: * must display the following acknowledgement:
! 19: * This product includes software developed at Ludd, University of
! 20: * Lule}, Sweden and its contributors.
! 21: * 4. The name of the author may not be used to endorse or promote products
! 22: * derived from this software without specific prior written permission
! 23: *
! 24: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 25: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 26: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 27: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 28: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 29: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 30: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 31: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 32: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 33: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 34: */
! 35:
! 36: #include <sys/param.h>
! 37: #include <sys/types.h>
! 38: #include <sys/device.h>
! 39: #include <sys/kernel.h>
! 40: #include <sys/systm.h>
! 41:
! 42: #include <uvm/uvm_extern.h>
! 43:
! 44: #include <machine/pte.h>
! 45: #include <machine/cpu.h>
! 46: #include <machine/mtpr.h>
! 47: #include <machine/sid.h>
! 48: #include <machine/pmap.h>
! 49: #include <machine/nexus.h>
! 50: #include <machine/uvax.h>
! 51: #include <machine/vsbus.h>
! 52: #include <machine/ka43.h>
! 53: #include <machine/clock.h>
! 54:
! 55: static void ka43_conf(void);
! 56: static void ka43_steal_pages(void);
! 57:
! 58: static int ka43_mchk(caddr_t);
! 59: static void ka43_memerr(void);
! 60: #if 0
! 61: static void ka43_clear_errors(void);
! 62: #endif
! 63: static int ka43_cache_init(void); /* "int mapen" as argument? */
! 64: static int ka43_cache_reset(void);
! 65: static int ka43_cache_enable(void);
! 66: static int ka43_cache_disable(void);
! 67: static int ka43_cache_invalidate(void);
! 68: static void ka43_halt(void);
! 69: static void ka43_reboot(int);
! 70: static void ka43_clrf(void);
! 71:
! 72:
! 73: struct cpu_dep ka43_calls = {
! 74: ka43_steal_pages,
! 75: ka43_mchk,
! 76: ka43_memerr,
! 77: ka43_conf,
! 78: chip_clkread,
! 79: chip_clkwrite,
! 80: 7, /* 7.6 VUP */
! 81: 2, /* SCB pages */
! 82: ka43_halt,
! 83: ka43_reboot,
! 84: ka43_clrf,
! 85: };
! 86:
! 87: /*
! 88: * ka43_steal_pages() is called with MMU disabled, after that call MMU gets
! 89: * enabled. Thus we initialize these four pointers with physical addresses,
! 90: * but before leving ka43_steal_pages() we reset them to virtual addresses.
! 91: */
! 92: static volatile struct ka43_cpu *ka43_cpu = (void *)KA43_CPU_BASE;
! 93: static volatile u_int *ka43_creg = (void *)KA43_CH2_CREG;
! 94: static volatile u_int *ka43_ctag = (void *)KA43_CT2_BASE;
! 95:
! 96: #define KA43_MC_RESTART 0x00008000 /* Restart possible*/
! 97: #define KA43_PSL_FPDONE 0x00010000 /* First Part Done */
! 98:
! 99: struct ka43_mcframe { /* Format of RigelMAX machine check frame: */
! 100: int mc43_bcnt; /* byte count, always 24 (0x18) */
! 101: int mc43_code; /* machine check type code and restart bit */
! 102: int mc43_addr; /* most recent (faulting?) virtual address */
! 103: int mc43_viba; /* contents of VIBA register */
! 104: int mc43_sisr; /* ICCS bit 6 and SISR bits 15:0 */
! 105: int mc43_istate; /* internal state */
! 106: int mc43_sc; /* shift count register */
! 107: int mc43_pc; /* trapped PC */
! 108: int mc43_psl; /* trapped PSL */
! 109: };
! 110:
! 111: static char *ka43_mctype[] = {
! 112: "no error (0)", /* Code 0: No error */
! 113: "FPA: protocol error", /* Code 1-5: FPA errors */
! 114: "FPA: illegal opcode",
! 115: "FPA: operand parity error",
! 116: "FPA: unknown status",
! 117: "FPA: result parity error",
! 118: "unused (6)", /* Code 6-7: Unused */
! 119: "unused (7)",
! 120: "MMU error (TLB miss)", /* Code 8-9: MMU errors */
! 121: "MMU error (TLB hit)",
! 122: "HW interrupt at unused IPL", /* Code 10: Interrupt error */
! 123: "MOVCx impossible state", /* Code 11-13: Microcode errors */
! 124: "undefined trap code (i-box)",
! 125: "undefined control store address",
! 126: "unused (14)", /* Code 14-15: Unused */
! 127: "unused (15)",
! 128: "PC tag or data parity error", /* Code 16: Cache error */
! 129: "data bus parity error", /* Code 17: Read error */
! 130: "data bus error (NXM)", /* Code 18: Write error */
! 131: "undefined data bus state", /* Code 19: Bus error */
! 132: };
! 133: #define MC43_MAX 19
! 134:
! 135: static int ka43_error_count = 0;
! 136:
! 137: int
! 138: ka43_mchk(addr)
! 139: caddr_t addr;
! 140: {
! 141: register struct ka43_mcframe *mcf = (void *)addr;
! 142:
! 143: mtpr(0x00, PR_MCESR); /* Acknowledge the machine check */
! 144: printf("machine check %d (0x%x)\n", mcf->mc43_code, mcf->mc43_code);
! 145: printf("reason: %s\n", ka43_mctype[mcf->mc43_code & 0xff]);
! 146: if (++ka43_error_count > 10) {
! 147: printf("error_count exceeded: %d\n", ka43_error_count);
! 148: return (-1);
! 149: }
! 150:
! 151: /*
! 152: * If either the Restart flag is set or the First-Part-Done flag
! 153: * is set, and the TRAP2 (double error) bit is not set, then the
! 154: * error is recoverable.
! 155: */
! 156: if (mfpr(PR_PCSTS) & KA43_PCS_TRAP2) {
! 157: printf("TRAP2 (double error) in ka43_mchk.\n");
! 158: panic("unrecoverable state in ka43_mchk.");
! 159: return (-1);
! 160: }
! 161: if ((mcf->mc43_code & KA43_MC_RESTART) ||
! 162: (mcf->mc43_psl & KA43_PSL_FPDONE)) {
! 163: printf("ka43_mchk: recovering from machine-check.\n");
! 164: ka43_cache_reset(); /* reset caches */
! 165: return (0); /* go on; */
! 166: }
! 167:
! 168: /*
! 169: * Unknown error state, panic/halt the machine!
! 170: */
! 171: printf("ka43_mchk: unknown error state!\n");
! 172: return (-1);
! 173: }
! 174:
! 175: void
! 176: ka43_memerr()
! 177: {
! 178: /*
! 179: * Don\'t know what to do here. So just print some messages
! 180: * and try to go on...
! 181: */
! 182: printf("memory error!\n");
! 183: printf("primary cache status: %b\n", mfpr(PR_PCSTS), KA43_PCSTS_BITS);
! 184: printf("secondary cache status: %b\n", *ka43_creg, KA43_SESR_BITS);
! 185: }
! 186:
! 187: int
! 188: ka43_cache_init()
! 189: {
! 190: return (ka43_cache_reset());
! 191: }
! 192:
! 193: #if 0
! 194: void
! 195: ka43_clear_errors()
! 196: {
! 197: int val = *ka43_creg;
! 198: val |= KA43_SESR_SERR | KA43_SESR_LERR | KA43_SESR_CERR;
! 199: *ka43_creg = val;
! 200: }
! 201: #endif
! 202:
! 203: int
! 204: ka43_cache_reset()
! 205: {
! 206: /*
! 207: * resetting primary and secondary caches is done in three steps:
! 208: * 1. disable both caches
! 209: * 2. manually clear secondary cache
! 210: * 3. enable both caches
! 211: */
! 212: ka43_cache_disable();
! 213: ka43_cache_invalidate();
! 214: ka43_cache_enable();
! 215:
! 216: printf("primary cache status: %b\n", mfpr(PR_PCSTS), KA43_PCSTS_BITS);
! 217: printf("secondary cache status: %b\n", *ka43_creg, KA43_SESR_BITS);
! 218:
! 219: return (0);
! 220: }
! 221:
! 222: int
! 223: ka43_cache_disable()
! 224: {
! 225: int val;
! 226:
! 227: /*
! 228: * first disable primary cache and clear error flags
! 229: */
! 230: mtpr(KA43_PCS_REFRESH, PR_PCSTS); /* disable primary cache */
! 231: val = mfpr(PR_PCSTS);
! 232: mtpr(val, PR_PCSTS); /* clear error flags */
! 233:
! 234: /*
! 235: * now disable secondary cache and clear error flags
! 236: */
! 237: val = *ka43_creg & ~KA43_SESR_CENB; /* BICL !!! */
! 238: *ka43_creg = val; /* disable secondary cache */
! 239: val = KA43_SESR_SERR | KA43_SESR_LERR | KA43_SESR_CERR;
! 240: *ka43_creg = val; /* clear error flags */
! 241:
! 242: return (0);
! 243: }
! 244:
! 245: int
! 246: ka43_cache_invalidate()
! 247: {
! 248: int i, val;
! 249:
! 250: val = KA43_PCTAG_PARITY; /* clear valid flag, set parity bit */
! 251: for (i = 0; i < 256; i++) { /* 256 Quadword entries */
! 252: mtpr(i*8, PR_PCIDX); /* write index of tag */
! 253: mtpr(val, PR_PCTAG); /* write value into tag */
! 254: }
! 255: val = KA43_PCS_FLUSH | KA43_PCS_REFRESH;
! 256: mtpr(val, PR_PCSTS); /* flush primary cache */
! 257:
! 258: /*
! 259: * Rigel\'s secondary cache doesn\'t implement a valid-flag.
! 260: * Thus we initialize all entries with out-of-range/dummy
! 261: * addresses which will never be referenced (ie. never hit).
! 262: * After enabling cache we also access 128K of memory starting
! 263: * at 0x00 so that secondary cache will be filled with these
! 264: * valid addresses...
! 265: */
! 266: val = 0xff;
! 267: /* if (memory > 28 MB) val = 0x55; */
! 268: for (i = 0; i < KA43_CT2_SIZE; i+= 4) { /* Quadword entries ?? */
! 269: ka43_ctag[i/4] = val; /* reset upper and lower */
! 270: }
! 271:
! 272: return (0);
! 273: }
! 274:
! 275:
! 276: int
! 277: ka43_cache_enable()
! 278: {
! 279: volatile char *membase = (void *)0x80000000; /* physical 0x00 */
! 280: int i, val;
! 281:
! 282: val = KA43_PCS_FLUSH | KA43_PCS_REFRESH;
! 283: mtpr(val, PR_PCSTS); /* flush primary cache */
! 284:
! 285: /*
! 286: * now we enable secondary cache and access first 128K of memory
! 287: * so that secondary cache gets really initialized and holds
! 288: * valid addresses/data...
! 289: */
! 290: *ka43_creg = KA43_SESR_CENB; /* enable secondary cache */
! 291: for (i=0; i<128*1024; i++) {
! 292: val += membase[i]; /* some dummy operation... */
! 293: }
! 294:
! 295: val = KA43_PCS_ENABLE | KA43_PCS_REFRESH;
! 296: mtpr(val, PR_PCSTS); /* enable primary cache */
! 297:
! 298: return (0);
! 299: }
! 300:
! 301: void
! 302: ka43_conf()
! 303: {
! 304: printf("cpu: KA43\n");
! 305: ka43_cpu = (void *)vax_map_physmem(VS_REGS, 1);
! 306:
! 307: ka43_creg = (void *)vax_map_physmem(KA43_CH2_CREG, 1);
! 308: ka43_ctag = (void *)vax_map_physmem(KA43_CT2_BASE,
! 309: (KA43_CT2_SIZE/VAX_NBPG));
! 310:
! 311: /*
! 312: * ka43_conf() gets called with MMU enabled, now it's safe to
! 313: * init/reset the caches.
! 314: */
! 315: ka43_cache_init();
! 316:
! 317: clk_adrshift = 1; /* Addressed at long's... */
! 318: clk_tweak = 2; /* ...and shift two */
! 319: clk_page = (short *)vax_map_physmem(VS_CLOCK, 1);
! 320: }
! 321:
! 322:
! 323: /*
! 324: * The interface for communication with the LANCE ethernet controller
! 325: * is setup in the xxx_steal_pages() routine. We decrease highest
! 326: * available address by 64K and use this area as communication buffer.
! 327: */
! 328:
! 329: void
! 330: ka43_steal_pages()
! 331: {
! 332: int val;
! 333:
! 334:
! 335: /*
! 336: * if LANCE\'s io-buffer is above 16 MB, then the appropriate flag
! 337: * in the parity control register has to be set (it works as an
! 338: * additional address bit). In any case, don\'t enable CPEN and
! 339: * DPEN in the PARCTL register, somewhow they are internally managed
! 340: * by the RIGEL chip itself!?!
! 341: */
! 342: val = ka43_cpu->parctl & 0x03; /* read the old value */
! 343: ka43_cpu->parctl = val; /* and write new value */
! 344: }
! 345:
! 346: static void
! 347: ka43_clrf()
! 348: {
! 349: struct ka43_clock *clk = (void *)clk_page;
! 350:
! 351: /*
! 352: * Clear restart and boot in progress flags in the CPMBX.
! 353: */
! 354: clk->cpmbx = (clk->cpmbx & ~0xf0);
! 355: }
! 356:
! 357: static void
! 358: ka43_halt()
! 359: {
! 360: asm("movl $0xc, (%0)"::"r"((int)clk_page + 0x38)); /* Don't ask */
! 361: asm("halt");
! 362: }
! 363:
! 364: static void
! 365: ka43_reboot(arg)
! 366: int arg;
! 367: {
! 368: asm("movl $0xc, (%0)"::"r"((int)clk_page + 0x38)); /* Don't ask */
! 369: asm("halt");
! 370: }
! 371:
CVSweb