[BACK]Return to pchb.c CVS log [TXT][DIR] Up to [local] / sys / arch / amd64 / pci

Annotation of sys/arch/amd64/pci/pchb.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pchb.c,v 1.10 2007/07/04 21:30:48 ckuethe Exp $       */
                      2: /*     $NetBSD: pchb.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $    */
                      3: /*
                      4:  * Copyright (c) 2000 Michael Shalayeff
                      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 WARRANTIES
                     18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     19:  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES 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 MIND, 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
                     25:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     26:  * THE POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28: /*-
                     29:  * Copyright (c) 1996, 1998, 2000 The NetBSD Foundation, Inc.
                     30:  * All rights reserved.
                     31:  *
                     32:  * This code is derived from software contributed to The NetBSD Foundation
                     33:  * by Jason R. Thorpe.
                     34:  *
                     35:  * Redistribution and use in source and binary forms, with or without
                     36:  * modification, are permitted provided that the following conditions
                     37:  * are met:
                     38:  * 1. Redistributions of source code must retain the above copyright
                     39:  *    notice, this list of conditions and the following disclaimer.
                     40:  * 2. Redistributions in binary form must reproduce the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer in the
                     42:  *    documentation and/or other materials provided with the distribution.
                     43:  * 3. All advertising materials mentioning features or use of this software
                     44:  *    must display the following acknowledgement:
                     45:  *        This product includes software developed by the NetBSD
                     46:  *        Foundation, Inc. and its contributors.
                     47:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     48:  *    contributors may be used to endorse or promote products derived
                     49:  *    from this software without specific prior written permission.
                     50:  *
                     51:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     52:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     53:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     54:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     55:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     56:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     57:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     58:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     59:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     60:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     61:  * POSSIBILITY OF SUCH DAMAGE.
                     62:  */
                     63:
                     64: #include <sys/types.h>
                     65: #include <sys/param.h>
                     66: #include <sys/systm.h>
                     67: #include <sys/device.h>
                     68: #include <sys/timeout.h>
                     69:
                     70: #include <machine/bus.h>
                     71:
                     72: #include <dev/pci/pcivar.h>
                     73: #include <dev/pci/pcireg.h>
                     74: #include <dev/pci/pcidevs.h>
                     75:
                     76: #include <dev/rndvar.h>
                     77:
                     78: #include <dev/ic/i82802reg.h>
                     79:
                     80: #define PCISET_BRIDGETYPE_MASK 0x3
                     81: #define PCISET_TYPE_COMPAT     0x1
                     82: #define PCISET_TYPE_AUX                0x2
                     83:
                     84: #define PCISET_BUSCONFIG_REG   0x48
                     85: #define PCISET_BRIDGE_NUMBER(reg)      (((reg) >> 8) & 0xff)
                     86: #define PCISET_PCI_BUS_NUMBER(reg)     (((reg) >> 16) & 0xff)
                     87:
                     88: /* XXX should be in dev/ic/i82443reg.h */
                     89: #define        I82443BX_SDRAMC_REG     0x76
                     90:
                     91: /* XXX should be in dev/ic/i82424{reg.var}.h */
                     92: #define I82424_CPU_BCTL_REG            0x53
                     93: #define I82424_PCI_BCTL_REG            0x54
                     94:
                     95: #define I82424_BCTL_CPUMEM_POSTEN      0x01
                     96: #define I82424_BCTL_CPUPCI_POSTEN      0x02
                     97: #define I82424_BCTL_PCIMEM_BURSTEN     0x01
                     98: #define I82424_BCTL_PCI_BURSTEN                0x02
                     99:
                    100: /* XXX should be in dev/ic/amd64htreg.h */
                    101: #define AMD64HT_LDT0_BUS       0x94
                    102: #define AMD64HT_LDT0_TYPE      0x98
                    103: #define AMD64HT_LDT1_BUS       0xb4
                    104: #define AMD64HT_LDT1_TYPE      0xb8
                    105: #define AMD64HT_LDT2_BUS       0xd4
                    106: #define AMD64HT_LDT2_TYPE      0xd8
                    107:
                    108: #define AMD64HT_NUM_LDT                3
                    109:
                    110: #define AMD64HT_LDT_TYPE_MASK          0x0000001f
                    111: #define  AMD64HT_LDT_INIT_COMPLETE     0x00000002
                    112: #define  AMD64HT_LDT_NC                        0x00000004
                    113:
                    114: #define AMD64HT_LDT_SEC_BUS_NUM(reg)   (((reg) >> 8) & 0xff)
                    115:
                    116: struct pchb_softc {
                    117:        struct device sc_dev;
                    118:
                    119:        bus_space_tag_t sc_bt;
                    120:        bus_space_handle_t sc_bh;
                    121:
                    122:        int sc_rnd_i;
                    123:        u_int32_t sc_rnd_ax;
                    124:        struct timeout sc_rnd_to;
                    125: };
                    126:
                    127: int    pchbmatch(struct device *, void *, void *);
                    128: void   pchbattach(struct device *, struct device *, void *);
                    129:
                    130: int    pchb_print(void *, const char *);
                    131: void   pchb_rnd(void *);
                    132: void   pchb_amd64ht_attach (struct device *, struct pci_attach_args *, int);
                    133:
                    134: struct cfattach pchb_ca = {
                    135:        sizeof(struct pchb_softc), pchbmatch, pchbattach,
                    136: };
                    137:
                    138: struct cfdriver pchb_cd = {
                    139:        NULL, "pchb", DV_DULL
                    140: };
                    141:
                    142: int
                    143: pchbmatch(struct device *parent, void *match, void *aux)
                    144: {
                    145:        struct pci_attach_args *pa = aux;
                    146:
                    147:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
                    148:            PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) {
                    149:                return (1);
                    150:        }
                    151:
                    152:        return (0);
                    153: }
                    154:
                    155: void
                    156: pchbattach(struct device *parent, struct device *self, void *aux)
                    157: {
                    158:        struct pchb_softc *sc = (struct pchb_softc *)self;
                    159:        struct pci_attach_args *pa = aux;
                    160:        struct timeval tv1, tv2;
                    161:        int i, r;
                    162:
                    163:        switch (PCI_VENDOR(pa->pa_id)) {
                    164:        case PCI_VENDOR_AMD:
                    165:                switch (PCI_PRODUCT(pa->pa_id)) {
                    166:                case PCI_PRODUCT_AMD_AMD64_HT:
                    167:                        for (i = 0; i < AMD64HT_NUM_LDT; i++)
                    168:                                pchb_amd64ht_attach(self, pa, i);
                    169:                        break;
                    170:                }
                    171:                break;
                    172:        case PCI_VENDOR_INTEL:
                    173: #ifdef PCIAGP
                    174:                pciagp_set_pchb(pa);
                    175: #endif
                    176:                switch (PCI_PRODUCT(pa->pa_id)) {
                    177:                case PCI_PRODUCT_INTEL_82915G_HB:
                    178:                case PCI_PRODUCT_INTEL_82925X_HB:
                    179:                case PCI_PRODUCT_INTEL_82945GP_MCH:
                    180:                case PCI_PRODUCT_INTEL_82955X_HB:
                    181:                        sc->sc_bt = pa->pa_memt;
                    182:                        if (bus_space_map(sc->sc_bt, I82802_IOBASE,
                    183:                            I82802_IOSIZE, 0, &sc->sc_bh)) {
                    184:                                break;
                    185:                        }
                    186:
                    187:                        /* probe and init rng */
                    188:                        if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh,
                    189:                            I82802_RNG_HWST) & I82802_RNG_HWST_PRESENT)) {
                    190:                                break;
                    191:                        }
                    192:
                    193:                        /* enable RNG */
                    194:                        bus_space_write_1(sc->sc_bt, sc->sc_bh,
                    195:                            I82802_RNG_HWST,
                    196:                            bus_space_read_1(sc->sc_bt, sc->sc_bh,
                    197:                            I82802_RNG_HWST) | I82802_RNG_HWST_ENABLE);
                    198:
                    199:                        /* see if we can read anything */
                    200:                        for (i = 1000; i-- &&
                    201:                            !(bus_space_read_1(sc->sc_bt,sc->sc_bh,
                    202:                            I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV);)
                    203:                                DELAY(10);
                    204:
                    205:                        if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh,
                    206:                            I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV)) {
                    207:                                break;
                    208:                        }
                    209:
                    210:                        r = bus_space_read_1(sc->sc_bt, sc->sc_bh,
                    211:                            I82802_RNG_DATA);
                    212:
                    213:                        /* benchmark the RNG */
                    214:                        microtime(&tv1);
                    215:                        for (i = 8 * 1024; i--; ) {
                    216:                                while(!(bus_space_read_1(sc->sc_bt, sc->sc_bh,
                    217:                                    I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV))
                    218:                                        ;
                    219:                                r = bus_space_read_1(sc->sc_bt, sc->sc_bh,
                    220:                                    I82802_RNG_DATA);
                    221:                        }
                    222:                        microtime(&tv2);
                    223:
                    224:                        timersub(&tv2, &tv1, &tv1);
                    225:                        if (tv1.tv_sec)
                    226:                                tv1.tv_usec += 1000000 * tv1.tv_sec;
                    227:                        printf(": rng active");
                    228:                        if (tv1.tv_usec != 0)
                    229:                                printf(", %dKb/sec",
                    230:                                    8 * 1000000 / tv1.tv_usec);
                    231:
                    232:                        timeout_set(&sc->sc_rnd_to, pchb_rnd, sc);
                    233:                        sc->sc_rnd_i = 4;
                    234:                        pchb_rnd(sc);
                    235:                        break;
                    236:                }
                    237:                break;
                    238:        }
                    239:        printf("\n");
                    240: }
                    241:
                    242: int
                    243: pchb_print(void *aux, const char *pnp)
                    244: {
                    245:        struct pcibus_attach_args *pba = aux;
                    246:
                    247:        if (pnp)
                    248:                printf("%s at %s", pba->pba_busname, pnp);
                    249:        printf(" bus %d", pba->pba_bus);
                    250:        return (UNCONF);
                    251: }
                    252:
                    253: void
                    254: pchb_amd64ht_attach(struct device *self, struct pci_attach_args *pa, int i)
                    255: {
                    256:        struct pcibus_attach_args pba;
                    257:        pcireg_t type, bus;
                    258:        int reg;
                    259:
                    260:        reg = AMD64HT_LDT0_TYPE + i * 0x20;
                    261:        type = pci_conf_read(pa->pa_pc, pa->pa_tag, reg);
                    262:        if ((type & AMD64HT_LDT_INIT_COMPLETE) == 0 ||
                    263:            (type & AMD64HT_LDT_NC) == 0)
                    264:                return;
                    265:
                    266:        reg = AMD64HT_LDT0_BUS + i * 0x20;
                    267:        bus = pci_conf_read(pa->pa_pc, pa->pa_tag, reg);
                    268:        if (AMD64HT_LDT_SEC_BUS_NUM(bus) > 0) {
                    269:                pba.pba_busname = "pci";
                    270:                pba.pba_iot = pa->pa_iot;
                    271:                pba.pba_memt = pa->pa_memt;
                    272:                pba.pba_dmat = pa->pa_dmat;
                    273:                pba.pba_bus = AMD64HT_LDT_SEC_BUS_NUM(bus);
                    274:                pba.pba_bridgetag = NULL;
                    275:                pba.pba_pc = pa->pa_pc;
                    276:                config_found(self, &pba, pchb_print);
                    277:        }
                    278: }
                    279:
                    280: /*
                    281:  * Should do FIPS testing as per:
                    282:  *     http://csrc.nist.gov/publications/fips/fips140-1/fips1401.pdf
                    283:  */
                    284: void
                    285: pchb_rnd(void *v)
                    286: {
                    287:        struct pchb_softc *sc = v;
                    288:
                    289:        /*
                    290:         * Don't wait for data to be ready. If it's not there, we'll check
                    291:         * next time.
                    292:         */
                    293:        if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) &
                    294:            I82802_RNG_RNGST_DATAV)) {
                    295:
                    296:                sc->sc_rnd_ax = (sc->sc_rnd_ax << 8) |
                    297:                    bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_DATA);
                    298:
                    299:                if (!sc->sc_rnd_i--) {
                    300:                        sc->sc_rnd_i = 4;
                    301:                        add_true_randomness(sc->sc_rnd_ax);
                    302:                }
                    303:        }
                    304:
                    305:        timeout_add(&sc->sc_rnd_to, 1);
                    306: }

CVSweb