[BACK]Return to ka820.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / vax

Annotation of sys/arch/vax/vax/ka820.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ka820.c,v 1.12 2003/11/10 21:05:06 miod Exp $ */
                      2: /*     $NetBSD: ka820.c,v 1.22 2000/06/04 02:19:27 matt Exp $  */
                      3: /*
                      4:  * Copyright (c) 1988 Regents of the University of California.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Chris Torek.
                      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:  *     @(#)ka820.c     7.4 (Berkeley) 12/16/90
                     35:  */
                     36:
                     37: /*
                     38:  * KA820 specific CPU code.  (Note that the VAX8200 uses a KA820, not
                     39:  * a KA8200.  Sigh.)
                     40:  */
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/time.h>
                     44: #include <sys/kernel.h>
                     45: #include <sys/device.h>
                     46: #include <sys/systm.h>
                     47:
                     48: #include <uvm/uvm_extern.h>
                     49:
                     50: #include <machine/ka820.h>
                     51: #include <machine/cpu.h>
                     52: #include <machine/mtpr.h>
                     53: #include <machine/nexus.h>
                     54: #include <machine/clock.h>
                     55: #include <machine/scb.h>
                     56: #include <machine/bus.h>
                     57:
                     58: #include <vax/bi/bireg.h>
                     59: #include <vax/bi/bivar.h>
                     60:
                     61: #include <vax/vax/crx.h>
                     62:
                     63: struct ka820port *ka820port_ptr;
                     64: struct rx50device *rx50device_ptr;
                     65: static volatile struct ka820clock *ka820_clkpage;
                     66:
                     67: static int ka820_match(struct device *, struct cfdata *, void *);
                     68: static void ka820_attach(struct device *, struct device *, void *);
                     69: static void ka820_memerr(void);
                     70: static void ka820_conf(void);
                     71: static int ka820_mchk(caddr_t);
                     72: static int ka820_clkread(time_t base);
                     73: static void ka820_clkwrite(void);
                     74: static void rxcdintr(void *);
                     75: static void vaxbierr(void *);
                     76:
                     77: struct cpu_dep ka820_calls = {
                     78:        0,
                     79:        ka820_mchk,
                     80:        ka820_memerr,
                     81:        ka820_conf,
                     82:        ka820_clkread,
                     83:        ka820_clkwrite,
                     84:        3,      /* ~VUPS */
                     85:        5,      /* SCB pages */
                     86: };
                     87:
                     88: struct cfattach cpu_bi_ca = {
                     89:        sizeof(struct device), ka820_match, ka820_attach
                     90: };
                     91:
                     92: #ifdef notyet
                     93: extern pt_entry_t BRAMmap[];
                     94: extern pt_entry_t EEPROMmap[];
                     95: char bootram[KA820_BRPAGES * VAX_NBPG];
                     96: char eeprom[KA820_EEPAGES * VAX_NBPG];
                     97: #endif
                     98:
                     99: int
                    100: ka820_match(parent, cf, aux)
                    101:        struct device *parent;
                    102:        struct cfdata *cf;
                    103:        void    *aux;
                    104: {
                    105:        struct bi_attach_args *ba = aux;
                    106:
                    107:        if (bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) != BIDT_KA820)
                    108:                return 0;
                    109:
                    110:        if (ba->ba_nodenr != mastercpu)
                    111:                return 0;
                    112:
                    113:        if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT &&
                    114:            cf->cf_loc[BICF_NODE] != ba->ba_nodenr)
                    115:                return 0;
                    116:
                    117:        return 1;
                    118: }
                    119:
                    120: void
                    121: ka820_attach(parent, self, aux)
                    122:        struct  device *parent, *self;
                    123:        void    *aux;
                    124: {
                    125:        struct bi_attach_args *ba = aux;
                    126:        register int csr;
                    127:        u_short rev;
                    128:
                    129:        rev = bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) >> 16;
                    130:        strlcpy(cpu_model, "VAX 8200", sizeof cpu_model);
                    131:        cpu_model[6] = rev & 0x8000 ? '5' : '0';
                    132:        printf(": ka82%c (%s) cpu rev %d, u patch rev %d, sec patch %d\n",
                    133:            cpu_model[6], mastercpu == ba->ba_nodenr ? "master" : "slave",
                    134:            ((rev >> 11) & 15), ((rev >> 1) &1023), rev & 1);
                    135:
                    136:        /* reset the console and enable the RX50 */
                    137:        ka820port_ptr = (void *)vax_map_physmem(KA820_PORTADDR, 1);
                    138:        csr = ka820port_ptr->csr;
                    139:        csr &= ~KA820PORT_RSTHALT;      /* ??? */
                    140:        csr |= KA820PORT_CONSCLR | KA820PORT_CRDCLR | KA820PORT_CONSEN |
                    141:                KA820PORT_RXIE;
                    142:        ka820port_ptr->csr = csr;
                    143:        bus_space_write_4(ba->ba_iot, ba->ba_ioh,
                    144:            BIREG_INTRDES, ba->ba_intcpu);
                    145:        bus_space_write_4(ba->ba_iot, ba->ba_ioh, BIREG_VAXBICSR,
                    146:            bus_space_read_4(ba->ba_iot, ba->ba_ioh, BIREG_VAXBICSR) |
                    147:            BICSR_SEIE | BICSR_HEIE);
                    148:
                    149: }
                    150:
                    151: void
                    152: ka820_conf()
                    153: {
                    154:        /*
                    155:         * Setup parameters necessary to read time from clock chip.
                    156:         */
                    157:        ka820_clkpage = (void *)vax_map_physmem(KA820_CLOCKADDR, 1);
                    158:
                    159:        /* Steal the interrupt vectors that are unique for us */
                    160:        scb_vecalloc(KA820_INT_RXCD, rxcdintr, NULL, SCB_ISTACK, NULL);
                    161:        scb_vecalloc(0x50, vaxbierr, NULL, SCB_ISTACK, NULL);
                    162:
                    163:        /* XXX - should be done somewhere else */
                    164:        scb_vecalloc(SCB_RX50, crxintr, NULL, SCB_ISTACK, NULL);
                    165:        rx50device_ptr = (void *)vax_map_physmem(KA820_RX50ADDR, 1);
                    166: }
                    167:
                    168: void
                    169: vaxbierr(void *arg)
                    170: {
                    171:        if (cold == 0)
                    172:                panic("vaxbierr");
                    173: }
                    174:
                    175: #ifdef notdef
                    176: /*
                    177:  * MS820 support.
                    178:  */
                    179: struct ms820regs {
                    180:        struct  biiregs biic;           /* BI interface chip */
                    181:        u_long  ms_gpr[4];              /* the four gprs (unused) */
                    182:        int     ms_csr1;                /* control/status register 1 */
                    183:        int     ms_csr2;                /* control/status register 2 */
                    184: };
                    185: #endif
                    186:
                    187: #define        MEMRD(reg) bus_space_read_4(sc->sc_iot, sc->sc_ioh, (reg))
                    188: #define MEMWR(reg, val) bus_space_write_4(sc->sc_iot, sc->sc_ioh, (reg), (val))
                    189:
                    190: #define        MSREG_CSR1      0x100
                    191: #define        MSREG_CSR2      0x104
                    192: /*
                    193:  * Bits in CSR1.
                    194:  */
                    195: #define MS1_ERRSUM     0x80000000      /* error summary (ro) */
                    196: #define MS1_ECCDIAG    0x40000000      /* ecc diagnostic (rw) */
                    197: #define MS1_ECCDISABLE 0x20000000      /* ecc disable (rw) */
                    198: #define MS1_MSIZEMASK  0x1ffc0000      /* mask for memory size (ro) */
                    199: #define MS1_RAMTYMASK  0x00030000      /* mask for ram type (ro) */
                    200: #define MS1_RAMTY64K   0x00000000      /* 64K chips */
                    201: #define MS1_RAMTY256K  0x00010000      /* 256K chips */
                    202: #define MS1_RAMTY1MB   0x00020000      /* 1MB chips */
                    203:                                        /* type 3 reserved */
                    204: #define MS1_CRDINH     0x00008000      /* inhibit crd interrupts (rw) */
                    205: #define MS1_MEMVALID   0x00004000      /* memory has been written (ro) */
                    206: #define MS1_INTLK      0x00002000      /* interlock flag (ro) */
                    207: #define MS1_BROKE      0x00001000      /* broken (rw) */
                    208: #define MS1_MBZ                0x00000880      /* zero */
                    209: #define MS1_MWRITEERR  0x00000400      /* rds during masked write (rw) */
                    210: #define MS1_CNTLERR    0x00000200      /* internal timing busted (rw) */
                    211: #define MS1_INTLV      0x00000100      /* internally interleaved (ro) */
                    212: #define MS1_DIAGC      0x0000007f      /* ecc diagnostic bits (rw) */
                    213:
                    214: /*
                    215:  * Bits in CSR2.
                    216:  */
                    217: #define MS2_RDSERR     0x80000000      /* rds error (rw) */
                    218: #define MS2_HIERR      0x40000000      /* high error rate (rw) */
                    219: #define MS2_CRDERR     0x20000000      /* crd error (rw) */
                    220: #define MS2_ADRSERR    0x10000000      /* rds due to addr par err (rw) */
                    221: #define MS2_MBZ                0x0f000080      /* zero */
                    222: #define MS2_ADDR       0x00fffe00      /* address in error (relative) (ro) */
                    223: #define MS2_INTLVADDR  0x00000100      /* error was in bank 1 (ro) */
                    224: #define MS2_SYN                0x0000007f      /* error syndrome (ro, rw diag) */
                    225:
                    226: static int ms820_match(struct device *, struct cfdata *, void *);
                    227: static void ms820_attach(struct device *, struct device *, void *);
                    228:
                    229: struct mem_bi_softc {
                    230:        struct device sc_dev;
                    231:        bus_space_tag_t sc_iot;
                    232:        bus_space_handle_t sc_ioh;
                    233: };
                    234:
                    235: struct cfattach mem_bi_ca = {
                    236:        sizeof(struct mem_bi_softc), ms820_match, ms820_attach
                    237: };
                    238:
                    239: static int
                    240: ms820_match(parent, cf, aux)
                    241:        struct  device  *parent;
                    242:        struct cfdata *cf;
                    243:        void    *aux;
                    244: {
                    245:        struct bi_attach_args *ba = aux;
                    246:
                    247:        if (bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) != BIDT_MS820)
                    248:                return 0;
                    249:
                    250:        if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT &&
                    251:            cf->cf_loc[BICF_NODE] != ba->ba_nodenr)
                    252:                return 0;
                    253:
                    254:        return 1;
                    255: }
                    256:
                    257: static void
                    258: ms820_attach(parent, self, aux)
                    259:        struct  device  *parent, *self;
                    260:        void    *aux;
                    261: {
                    262:        struct mem_bi_softc *sc = (void *)self;
                    263:        struct bi_attach_args *ba = aux;
                    264:
                    265:        sc->sc_iot = ba->ba_iot;
                    266:        sc->sc_ioh = ba->ba_ioh;
                    267:
                    268:        if ((MEMRD(BIREG_VAXBICSR) & BICSR_STS) == 0)
                    269:                printf(": failed self test\n");
                    270:        else
                    271:                printf(": size %dMB, %s chips\n", ((MEMRD(MSREG_CSR1) &
                    272:                    MS1_MSIZEMASK) >> 20), (MEMRD(MSREG_CSR1) & MS1_RAMTYMASK
                    273:                    ? MEMRD(MSREG_CSR1) & MS1_RAMTY256K ? "256K":"1M":"64K"));
                    274:
                    275:        MEMWR(BIREG_INTRDES, ba->ba_intcpu);
                    276:        MEMWR(BIREG_VAXBICSR, MEMRD(BIREG_VAXBICSR) | BICSR_SEIE | BICSR_HEIE);
                    277:
                    278:        MEMWR(MSREG_CSR1, MS1_MWRITEERR | MS1_CNTLERR);
                    279:        MEMWR(MSREG_CSR2, MS2_RDSERR | MS2_HIERR | MS2_CRDERR | MS2_ADRSERR);
                    280: }
                    281:
                    282: void
                    283: ka820_memerr()
                    284: {
                    285:        struct mem_bi_softc *sc;
                    286:        int m, hard, csr1, csr2;
                    287:        char *type;
                    288: static char b1[] = "\20\40ERRSUM\37ECCDIAG\36ECCDISABLE\20CRDINH\17VALID\
                    289: \16INTLK\15BROKE\13MWRITEERR\12CNTLERR\11INTLV";
                    290: static char b2[] = "\20\40RDS\37HIERR\36CRD\35ADRS";
                    291:
                    292:        for (m = 0; m < mem_cd.cd_ndevs; m++) {
                    293:                sc = mem_cd.cd_devs[m];
                    294:                if (sc == NULL)
                    295:                        continue;
                    296:                csr1 = MEMRD(MSREG_CSR1);
                    297:                csr2 = MEMRD(MSREG_CSR2);
                    298:                printf("%s: csr1=%b csr2=%b\n", sc->sc_dev.dv_xname,
                    299:                    csr1, b1, csr2, b2);
                    300:                if ((csr1 & MS1_ERRSUM) == 0)
                    301:                        continue;
                    302:                hard = 1;
                    303:                if (csr1 & MS1_BROKE)
                    304:                        type = "broke";
                    305:                else if (csr1 & MS1_CNTLERR)
                    306:                        type = "cntl err";
                    307:                else if (csr2 & MS2_ADRSERR)
                    308:                        type = "address parity err";
                    309:                else if (csr2 & MS2_RDSERR)
                    310:                        type = "rds err";
                    311:                else if (csr2 & MS2_CRDERR) {
                    312:                        hard = 0;
                    313:                        type = "";
                    314:                } else
                    315:                        type = "mysterious error";
                    316:                printf("%s: %s%s%s addr %x bank %x syn %x\n",
                    317:                    sc->sc_dev.dv_xname, hard ? "hard error: " : "soft ecc",
                    318:                    type, csr2 & MS2_HIERR ?  " (+ other rds or crd err)" : "",
                    319:                    ((csr2 & MS2_ADDR) + MEMRD(BIREG_SADR)) >> 9,
                    320:                    (csr2 & MS2_INTLVADDR) != 0, csr2 & MS2_SYN);
                    321:                MEMWR(MSREG_CSR1, csr1 | MS1_CRDINH);
                    322:                MEMWR(MSREG_CSR2, csr2);
                    323:        }
                    324: }
                    325:
                    326: /* these are bits 0 to 6 in the summary field */
                    327: char *mc8200[] = {
                    328:        "cpu bad ipl",          "ucode lost err",
                    329:        "ucode par err",        "DAL par err",
                    330:        "BI bus err",           "BTB tag par",
                    331:        "cache tag par",
                    332: };
                    333: #define MC8200_BADIPL  0x01
                    334: #define MC8200_UERR    0x02
                    335: #define MC8200_UPAR    0x04
                    336: #define MC8200_DPAR    0x08
                    337: #define MC8200_BIERR   0x10
                    338: #define MC8200_BTAGPAR 0x20
                    339: #define MC8200_CTAGPAR 0x40
                    340:
                    341: struct mc8200frame {
                    342:        int     mc82_bcnt;              /* byte count == 0x20 */
                    343:        int     mc82_summary;           /* summary parameter */
                    344:        int     mc82_param1;            /* parameter 1 */
                    345:        int     mc82_va;                /* va register */
                    346:        int     mc82_vap;               /* va prime register */
                    347:        int     mc82_ma;                /* memory address */
                    348:        int     mc82_status;            /* status word */
                    349:        int     mc82_epc;               /* error pc */
                    350:        int     mc82_upc;               /* micro pc */
                    351:        int     mc82_pc;                /* current pc */
                    352:        int     mc82_psl;               /* current psl */
                    353: };
                    354:
                    355: int
                    356: ka820_mchk(cmcf)
                    357:        caddr_t cmcf;
                    358: {
                    359:        register struct mc8200frame *mcf = (struct mc8200frame *)cmcf;
                    360:        register int i, type = mcf->mc82_summary;
                    361:
                    362:        /* ignore BI bus errors during configuration */
                    363:        if (cold && type == MC8200_BIERR) {
                    364:                mtpr(PR_MCESR, 0xf);
                    365:                return (MCHK_RECOVERED);
                    366:        }
                    367:
                    368:        /*
                    369:         * SOME ERRORS ARE RECOVERABLE
                    370:         * do it later
                    371:         */
                    372:        printf("machine check %x: ", type);
                    373:        for (i = 0; i < sizeof (mc8200) / sizeof (mc8200[0]); i++)
                    374:                if (type & (1 << i))
                    375:                        printf(" %s,", mc8200[i]);
                    376:        printf(" param1 %x\n", mcf->mc82_param1);
                    377:        printf(
                    378: "\tva %x va' %x ma %x pc %x psl %x\n\tstatus %x errpc %x upc %x\n",
                    379:                mcf->mc82_va, mcf->mc82_vap, mcf->mc82_ma,
                    380:                mcf->mc82_pc, mcf->mc82_psl,
                    381:                mcf->mc82_status, mcf->mc82_epc, mcf->mc82_upc);
                    382:        return (MCHK_PANIC);
                    383: }
                    384:
                    385: /*
                    386:  * Receive a character from logical console.
                    387:  */
                    388: void
                    389: rxcdintr(arg)
                    390:        void *arg;
                    391: {
                    392:        register int c = mfpr(PR_RXCD);
                    393:
                    394:        /* not sure what (if anything) to do with these */
                    395:        printf("rxcd node %x c=0x%x\n", (c >> 8) & 0xf, c & 0xff);
                    396: }
                    397:
                    398: int
                    399: ka820_clkread(time_t base)
                    400: {
                    401:        struct clock_ymdhms c;
                    402:        int s;
                    403:
                    404:        while (ka820_clkpage->csr0 & KA820CLK_0_BUSY)
                    405:                ;
                    406:        s = splhigh();
                    407:        c.dt_sec = ka820_clkpage->sec;
                    408:        c.dt_min = ka820_clkpage->min;
                    409:        c.dt_hour = ka820_clkpage->hr;
                    410:        c.dt_wday = ka820_clkpage->dayofwk;
                    411:        c.dt_day = ka820_clkpage->day;
                    412:        c.dt_mon = ka820_clkpage->mon;
                    413:        c.dt_year = ka820_clkpage->yr;
                    414:        splx(s);
                    415:
                    416:        /* strange conversion */
                    417:        c.dt_sec = ((c.dt_sec << 7) | (c.dt_sec >> 1)) & 0377;
                    418:        c.dt_min = ((c.dt_min << 7) | (c.dt_min >> 1)) & 0377;
                    419:        c.dt_hour = ((c.dt_hour << 7) | (c.dt_hour >> 1)) & 0377;
                    420:        c.dt_wday = ((c.dt_wday << 7) | (c.dt_wday >> 1)) & 0377;
                    421:        c.dt_day = ((c.dt_day << 7) | (c.dt_day >> 1)) & 0377;
                    422:        c.dt_mon = ((c.dt_mon << 7) | (c.dt_mon >> 1)) & 0377;
                    423:        c.dt_year = ((c.dt_year << 7) | (c.dt_year >> 1)) & 0377;
                    424:
                    425:        time.tv_sec = clock_ymdhms_to_secs(&c);
                    426:        return CLKREAD_OK;
                    427: }
                    428:
                    429: void
                    430: ka820_clkwrite(void)
                    431: {
                    432:        struct clock_ymdhms c;
                    433:
                    434:        clock_secs_to_ymdhms(time.tv_sec, &c);
                    435:
                    436:        ka820_clkpage->csr1 = KA820CLK_1_SET;
                    437:        ka820_clkpage->sec = ((c.dt_sec << 1) | (c.dt_sec >> 7)) & 0377;
                    438:        ka820_clkpage->min = ((c.dt_min << 1) | (c.dt_min >> 7)) & 0377;
                    439:        ka820_clkpage->hr = ((c.dt_hour << 1) | (c.dt_hour >> 7)) & 0377;
                    440:        ka820_clkpage->dayofwk = ((c.dt_wday << 1) | (c.dt_wday >> 7)) & 0377;
                    441:        ka820_clkpage->day = ((c.dt_day << 1) | (c.dt_day >> 7)) & 0377;
                    442:        ka820_clkpage->mon = ((c.dt_mon << 1) | (c.dt_mon >> 7)) & 0377;
                    443:        ka820_clkpage->yr = ((c.dt_year << 1) | (c.dt_year >> 7)) & 0377;
                    444:
                    445:        ka820_clkpage->csr1 = KA820CLK_1_GO;
                    446: }

CVSweb