[BACK]Return to uperf_sbus.c CVS log [TXT][DIR] Up to [local] / sys / dev / sbus

Annotation of sys/dev/sbus/uperf_sbus.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: uperf_sbus.c,v 1.7 2003/06/27 01:50:52 jason Exp $    */
                      2:
                      3: /*
                      4:  * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     19:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     22:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     25:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     26:  * POSSIBILITY OF SUCH DAMAGE.
                     27:  *
                     28:  * Effort sponsored in part by the Defense Advanced Research Projects
                     29:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
                     30:  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
                     31:  *
                     32:  */
                     33:
                     34: #include <sys/types.h>
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/kernel.h>
                     38: #include <sys/errno.h>
                     39: #include <sys/device.h>
                     40: #include <sys/malloc.h>
                     41:
                     42: #include <machine/bus.h>
                     43: #include <machine/intr.h>
                     44: #include <machine/autoconf.h>
                     45:
                     46: #include <arch/sparc64/dev/uperfvar.h>
                     47: #include <dev/sun/uperfio.h>
                     48: #include <dev/sbus/sbusvar.h>
                     49: #include <dev/sbus/uperf_sbusreg.h>
                     50:
                     51: int uperf_sbus_match(struct device *, void *, void *);
                     52: void uperf_sbus_attach(struct device *, struct device *, void *);
                     53:
                     54: struct uperf_sbus_softc {
                     55:        struct uperf_softc      sc_usc;
                     56:        bus_space_tag_t         sc_bus_t;       /* direct register tag */
                     57:        bus_space_handle_t      sc_bus_h;       /* direct register handle */
                     58: };
                     59:
                     60: struct cfattach uperf_sbus_ca = {
                     61:        sizeof(struct uperf_sbus_softc), uperf_sbus_match, uperf_sbus_attach
                     62: };
                     63:
                     64: u_int32_t uperf_sbus_read_reg(struct uperf_sbus_softc *, bus_size_t);
                     65: void uperf_sbus_write_reg(struct uperf_sbus_softc *,
                     66:     bus_size_t, u_int32_t);
                     67:
                     68: int uperf_sbus_getcnt(void *, int, u_int32_t *, u_int32_t *);
                     69: int uperf_sbus_clrcnt(void *, int);
                     70: int uperf_sbus_getcntsrc(void *, int, u_int *, u_int *);
                     71: int uperf_sbus_setcntsrc(void *, int, u_int, u_int);
                     72:
                     73: struct uperf_src uperf_sbus_srcs[] = {
                     74:        { UPERFSRC_SYSCK, UPERF_CNT0|UPERF_CNT1, SEL0_SYSCK },
                     75:        { UPERFSRC_PRALL, UPERF_CNT0|UPERF_CNT1, SEL0_PRALL },
                     76:        { UPERFSRC_PRP0, UPERF_CNT0|UPERF_CNT1, SEL0_PRP0 },
                     77:        { UPERFSRC_PRU2S, UPERF_CNT0|UPERF_CNT1, SEL0_PRUS },
                     78:        { UPERFSRC_UPA128, UPERF_CNT0, SEL0_128BUSY },
                     79:        { UPERFSRC_RP0, UPERF_CNT1, SEL1_RDP0 },
                     80:        { UPERFSRC_UPA64, UPERF_CNT0, SEL0_64BUSY },
                     81:        { UPERFSRC_P0CRMR, UPERF_CNT1, SEL1_CRMP0 },
                     82:        { UPERFSRC_PIOS, UPERF_CNT0, SEL0_PIOSTALL },
                     83:        { UPERFSRC_P0PIO, UPERF_CNT1, SEL1_PIOP0 },
                     84:        { UPERFSRC_MEMRI, UPERF_CNT0|UPERF_CNT0, SEL0_MEMREQ },
                     85:        { UPERFSRC_MCBUSY, UPERF_CNT0, SEL0_MCBUSY },
                     86:        { UPERFSRC_MEMRC, UPERF_CNT1, SEL1_MRC},
                     87:        { UPERFSRC_PXSH, UPERF_CNT0, SEL0_PENDSTALL },
                     88:        { UPERFSRC_RDP0, UPERF_CNT0, SEL1_RDP1 },
                     89:        { UPERFSRC_P0CWMR, UPERF_CNT0, SEL0_CWMRP0 },
                     90:        { UPERFSRC_CRMP1, UPERF_CNT1, SEL1_CRMP1 },
                     91:        { UPERFSRC_P1CWMR, UPERF_CNT0, SEL0_CWMRP1 },
                     92:        { UPERFSRC_PIOP1, UPERF_CNT1, SEL1_PIOP1 },
                     93:        { UPERFSRC_CIT, UPERF_CNT0, SEL0_CIT },
                     94:        { UPERFSRC_CWXI, UPERF_CNT1, SEL1_CWXI },
                     95:        { UPERFSRC_U2SDAT, UPERF_CNT0|UPERF_CNT1, SEL0_DACT },
                     96:        { UPERFSRC_CRXI, UPERF_CNT0, SEL0_CRXI },
                     97:        { -1, -1, 0 }
                     98: };
                     99:
                    100: int
                    101: uperf_sbus_match(struct device *parent, void *vcf, void *aux)
                    102: {
                    103:        struct sbus_attach_args *sa = aux;
                    104:
                    105:        return (strcmp(sa->sa_name, "sc") == 0);
                    106: }
                    107:
                    108: void
                    109: uperf_sbus_attach(struct device *parent, struct device *self, void *aux)
                    110: {
                    111:        struct sbus_attach_args *sa = aux;
                    112:        struct uperf_sbus_softc *sc = (struct uperf_sbus_softc *)self;
                    113:        char *model;
                    114:        u_int32_t id;
                    115:
                    116:        sc->sc_bus_t = sa->sa_bustag;
                    117:        sc->sc_usc.usc_cookie = sc;
                    118:        sc->sc_usc.usc_getcntsrc = uperf_sbus_getcntsrc;
                    119:        sc->sc_usc.usc_setcntsrc = uperf_sbus_setcntsrc;
                    120:        sc->sc_usc.usc_clrcnt = uperf_sbus_clrcnt;
                    121:        sc->sc_usc.usc_getcnt = uperf_sbus_getcnt;
                    122:        sc->sc_usc.usc_srcs = uperf_sbus_srcs;
                    123:
                    124:        if (sa->sa_nreg != 1) {
                    125:                printf(": expected 1 register, got %d\n", sa->sa_nreg);
                    126:                return;
                    127:        }
                    128:
                    129:        if (sbus_bus_map(sc->sc_bus_t, sa->sa_reg[0].sbr_slot,
                    130:            sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size, 0, 0,
                    131:            &sc->sc_bus_h) != 0) {
                    132:                printf(": couldn't map registers\n");
                    133:                return;
                    134:        }
                    135:
                    136:        id = uperf_sbus_read_reg(sc, USC_ID);
                    137:        model = getpropstring(sa->sa_node, "model");
                    138:        if (model == NULL || strlen(model) == 0)
                    139:                model = "unknown";
                    140:
                    141:        printf(": model %s (%x/%x) ports %d\n", model,
                    142:            (id & USC_ID_IMPL_M) >> USC_ID_IMPL_S,
                    143:            (id & USC_ID_VERS_M) >> USC_ID_VERS_S,
                    144:            (id & USC_ID_UPANUM_M) >> USC_ID_UPANUM_S);
                    145: }
                    146:
                    147: /*
                    148:  * Read from an indirect register
                    149:  */
                    150: u_int32_t
                    151: uperf_sbus_read_reg(struct uperf_sbus_softc *sc, bus_size_t r)
                    152: {
                    153:        u_int32_t v;
                    154:        int s;
                    155:
                    156:        s = splhigh();
                    157:        bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, r);
                    158:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, 1,
                    159:            BUS_SPACE_BARRIER_WRITE);
                    160:
                    161:        /* Can't use multi reads because we have to gaurantee order */
                    162:
                    163:        v = bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0);
                    164:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0, 1,
                    165:            BUS_SPACE_BARRIER_READ);
                    166:
                    167:        v <<= 8;
                    168:        v |= bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1);
                    169:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1, 1,
                    170:            BUS_SPACE_BARRIER_READ);
                    171:
                    172:        v <<= 8;
                    173:        v |= bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2);
                    174:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2, 1,
                    175:            BUS_SPACE_BARRIER_READ);
                    176:
                    177:        v <<= 8;
                    178:        v |= bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3);
                    179:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3, 1,
                    180:            BUS_SPACE_BARRIER_READ);
                    181:
                    182:        splx(s);
                    183:        return (v);
                    184: }
                    185:
                    186: /*
                    187:  * Write to an indirect register
                    188:  */
                    189: void
                    190: uperf_sbus_write_reg(struct uperf_sbus_softc *sc, bus_size_t r, u_int32_t v)
                    191: {
                    192:        int s;
                    193:
                    194:        s = splhigh();
                    195:        bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, r);
                    196:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, 1,
                    197:            BUS_SPACE_BARRIER_WRITE);
                    198:
                    199:        /* Can't use multi writes because we have to gaurantee order */
                    200:
                    201:        bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0,
                    202:            (v >> 24) & 0xff);
                    203:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0, 1,
                    204:            BUS_SPACE_BARRIER_WRITE);
                    205:
                    206:        bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1,
                    207:            (v >> 16) & 0xff);
                    208:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1, 1,
                    209:            BUS_SPACE_BARRIER_WRITE);
                    210:
                    211:        bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2,
                    212:            (v >> 8) & 0xff);
                    213:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2, 1,
                    214:            BUS_SPACE_BARRIER_WRITE);
                    215:
                    216:        bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3,
                    217:            (v >> 0) & 0xff);
                    218:        bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3, 1,
                    219:            BUS_SPACE_BARRIER_WRITE);
                    220:        splx(s);
                    221: }
                    222:
                    223: int
                    224: uperf_sbus_clrcnt(void *vsc, int flags)
                    225: {
                    226:        struct uperf_sbus_softc *sc = vsc;
                    227:        u_int32_t clr = 0, oldsrc;
                    228:
                    229:        if (flags & UPERF_CNT0)
                    230:                clr |= USC_PCTRL_CLR0;
                    231:        if (flags & UPERF_CNT1)
                    232:                clr |= USC_PCTRL_CLR1;
                    233:        if (clr) {
                    234:                oldsrc = uperf_sbus_read_reg(sc, USC_PERFCTRL);
                    235:                uperf_sbus_write_reg(sc, USC_PERFCTRL, clr | oldsrc);
                    236:        }
                    237:        return (0);
                    238: }
                    239:
                    240: int
                    241: uperf_sbus_setcntsrc(void *vsc, int flags, u_int src0, u_int src1)
                    242: {
                    243:        struct uperf_sbus_softc *sc = vsc;
                    244:        u_int32_t src;
                    245:
                    246:        src = uperf_sbus_read_reg(sc, USC_PERFCTRL);
                    247:        if (flags & UPERF_CNT0) {
                    248:                src &= ~USC_PCTRL_SEL0;
                    249:                src |= ((src0 << 0) & USC_PCTRL_SEL0) | USC_PCTRL_CLR0;
                    250:        }
                    251:        if (flags & UPERF_CNT1) {
                    252:                src &= ~USC_PCTRL_SEL1;
                    253:                src |= ((src1 << 8) & USC_PCTRL_SEL1) | USC_PCTRL_CLR1;
                    254:        }
                    255:        uperf_sbus_write_reg(sc, USC_PERFCTRL, src);
                    256:        return (0);
                    257: }
                    258:
                    259: int
                    260: uperf_sbus_getcntsrc(void *vsc, int flags, u_int *srcp0, u_int *srcp1)
                    261: {
                    262:        struct uperf_sbus_softc *sc = vsc;
                    263:        u_int32_t src;
                    264:
                    265:        src = uperf_sbus_read_reg(sc, USC_PERFCTRL);
                    266:        if (flags & UPERF_CNT0)
                    267:                *srcp0 = (src & USC_PCTRL_SEL0) >> 0;
                    268:        if (flags & UPERF_CNT1)
                    269:                *srcp1 = (src & USC_PCTRL_SEL1) >> 8;
                    270:        return (0);
                    271: }
                    272:
                    273: int
                    274: uperf_sbus_getcnt(void *vsc, int flags, u_int32_t *cntp0, u_int32_t *cntp1)
                    275: {
                    276:        struct uperf_sbus_softc *sc = vsc;
                    277:        u_int32_t c0, c1;
                    278:
                    279:        c0 = uperf_sbus_read_reg(sc, USC_PERF0);
                    280:        c1 = uperf_sbus_read_reg(sc, USC_PERFSHAD);
                    281:        if (flags & UPERF_CNT0)
                    282:                *cntp0 = c0;
                    283:        if (flags & UPERF_CNT1)
                    284:                *cntp1 = c1;
                    285:        return (0);
                    286: }

CVSweb