LCOV - code coverage report
Current view: top level - arch/amd64/pci - pchb.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 123 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: pchb.c,v 1.43 2018/04/28 15:44:59 jasper 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             :  *
      44             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      45             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      46             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      47             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      48             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      49             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      50             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      51             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      52             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      53             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      54             :  * POSSIBILITY OF SUCH DAMAGE.
      55             :  */
      56             : 
      57             : #include <sys/param.h>
      58             : #include <sys/systm.h>
      59             : #include <sys/device.h>
      60             : #include <sys/timeout.h>
      61             : 
      62             : #include <machine/bus.h>
      63             : 
      64             : #include <dev/pci/pcivar.h>
      65             : #include <dev/pci/pcireg.h>
      66             : #include <dev/pci/pcidevs.h>
      67             : 
      68             : #include <dev/pci/agpvar.h>
      69             : #include <dev/pci/ppbreg.h>
      70             : 
      71             : #include <dev/rndvar.h>
      72             : 
      73             : #include <dev/ic/i82802reg.h>
      74             : 
      75             : #include "agp.h"
      76             : 
      77             : /* XXX should be in dev/ic/i82424{reg.var}.h */
      78             : #define I82424_CPU_BCTL_REG             0x53
      79             : #define I82424_PCI_BCTL_REG             0x54
      80             : 
      81             : #define I82424_BCTL_CPUMEM_POSTEN       0x01
      82             : #define I82424_BCTL_CPUPCI_POSTEN       0x02
      83             : #define I82424_BCTL_PCIMEM_BURSTEN      0x01
      84             : #define I82424_BCTL_PCI_BURSTEN         0x02
      85             : 
      86             : /* XXX should be in dev/ic/amd64htreg.h */
      87             : #define AMD64HT_LDT0_BUS        0x94
      88             : #define AMD64HT_LDT0_TYPE       0x98
      89             : #define AMD64HT_LDT1_BUS        0xb4
      90             : #define AMD64HT_LDT1_TYPE       0xb8
      91             : #define AMD64HT_LDT2_BUS        0xd4
      92             : #define AMD64HT_LDT2_TYPE       0xd8
      93             : #define AMD64HT_LDT3_BUS        0xf4
      94             : #define AMD64HT_LDT3_TYPE       0xf8
      95             : 
      96             : #define AMD64HT_NUM_LDT         4
      97             : 
      98             : #define AMD64HT_LDT_TYPE_MASK           0x0000001f
      99             : #define  AMD64HT_LDT_INIT_COMPLETE      0x00000002
     100             : #define  AMD64HT_LDT_NC                 0x00000004
     101             : 
     102             : #define AMD64HT_LDT_SEC_BUS_NUM(reg)    (((reg) >> 8) & 0xff)
     103             : 
     104             : struct pchb_softc {
     105             :         struct device sc_dev;
     106             : 
     107             :         bus_space_tag_t sc_bt;
     108             :         bus_space_handle_t sc_bh;
     109             : 
     110             :         /* rng stuff */
     111             :         int sc_rng_active;
     112             :         int sc_rng_ax;
     113             :         int sc_rng_i;
     114             :         struct timeout sc_rng_to;
     115             : };
     116             : 
     117             : int     pchbmatch(struct device *, void *, void *);
     118             : void    pchbattach(struct device *, struct device *, void *);
     119             : int     pchbactivate(struct device *, int);
     120             : 
     121             : struct cfattach pchb_ca = {
     122             :         sizeof(struct pchb_softc), pchbmatch, pchbattach, NULL,
     123             :         pchbactivate
     124             : };
     125             : 
     126             : struct cfdriver pchb_cd = {
     127             :         NULL, "pchb", DV_DULL
     128             : };
     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             : int
     135           0 : pchbmatch(struct device *parent, void *match, void *aux)
     136             : {
     137           0 :         struct pci_attach_args *pa = aux;
     138             : 
     139           0 :         if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
     140           0 :             PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST)
     141           0 :                 return (1);
     142             : 
     143           0 :         return (0);
     144           0 : }
     145             : 
     146             : void
     147           0 : pchbattach(struct device *parent, struct device *self, void *aux)
     148             : {
     149           0 :         struct pchb_softc *sc = (struct pchb_softc *)self;
     150           0 :         struct pci_attach_args *pa = aux;
     151           0 :         struct pcibus_attach_args pba;
     152             :         pcireg_t bcreg, bir;
     153             :         u_char pbnum;
     154             :         pcitag_t tag;
     155             :         int i, r;
     156             :         int doattach = 0;
     157             : 
     158           0 :         switch (PCI_VENDOR(pa->pa_id)) {
     159             :         case PCI_VENDOR_AMD:
     160           0 :                 printf("\n");
     161           0 :                 switch (PCI_PRODUCT(pa->pa_id)) {
     162             :                 case PCI_PRODUCT_AMD_AMD64_0F_HT:
     163             :                 case PCI_PRODUCT_AMD_AMD64_10_HT:
     164           0 :                         for (i = 0; i < AMD64HT_NUM_LDT; i++)
     165           0 :                                 pchb_amd64ht_attach(self, pa, i);
     166             :                         break;
     167             :                 }
     168             :                 break;
     169             :         case PCI_VENDOR_INTEL:
     170           0 :                 switch (PCI_PRODUCT(pa->pa_id)) {
     171             :                 case PCI_PRODUCT_INTEL_82915G_HB:
     172             :                 case PCI_PRODUCT_INTEL_82945G_HB:
     173             :                 case PCI_PRODUCT_INTEL_82925X_HB:
     174             :                 case PCI_PRODUCT_INTEL_82955X_HB:
     175           0 :                         sc->sc_bt = pa->pa_memt;
     176           0 :                         if (bus_space_map(sc->sc_bt, I82802_IOBASE,
     177           0 :                             I82802_IOSIZE, 0, &sc->sc_bh))
     178             :                                 break;
     179             : 
     180             :                         /* probe and init rng */
     181           0 :                         if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh,
     182           0 :                             I82802_RNG_HWST) & I82802_RNG_HWST_PRESENT))
     183             :                                 break;
     184             : 
     185             :                         /* enable RNG */
     186           0 :                         bus_space_write_1(sc->sc_bt, sc->sc_bh,
     187             :                             I82802_RNG_HWST,
     188             :                             bus_space_read_1(sc->sc_bt, sc->sc_bh,
     189             :                             I82802_RNG_HWST) | I82802_RNG_HWST_ENABLE);
     190             : 
     191             :                         /* see if we can read anything */
     192           0 :                         for (i = 1000; i-- &&
     193           0 :                             !(bus_space_read_1(sc->sc_bt, sc->sc_bh,
     194           0 :                             I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV); )
     195           0 :                                 DELAY(10);
     196             : 
     197           0 :                         if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh,
     198           0 :                             I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV))
     199             :                                 break;
     200             : 
     201           0 :                         r = bus_space_read_1(sc->sc_bt, sc->sc_bh,
     202             :                             I82802_RNG_DATA);
     203             : 
     204           0 :                         timeout_set(&sc->sc_rng_to, pchb_rnd, sc);
     205           0 :                         sc->sc_rng_i = 4;
     206           0 :                         pchb_rnd(sc);
     207           0 :                         sc->sc_rng_active = 1;
     208           0 :                         break;
     209             :                 }
     210           0 :                 printf("\n");
     211           0 :                 break;
     212             :         case PCI_VENDOR_VIATECH:
     213           0 :                 switch (PCI_PRODUCT(pa->pa_id)) {
     214             :                 case PCI_PRODUCT_VIATECH_VT8251_PCIE_0:
     215             :                         /*
     216             :                          * Bump the host bridge into PCI-PCI bridge
     217             :                          * mode by clearing magic bit on the VLINK
     218             :                          * device.  This allows us to read the bus
     219             :                          * number for the PCI bus attached to this
     220             :                          * host bridge.
     221             :                          */
     222           0 :                         tag = pci_make_tag(pa->pa_pc, 0, 17, 7);
     223           0 :                         bcreg = pci_conf_read(pa->pa_pc, tag, 0xfc);
     224           0 :                         bcreg &= ~0x00000004; /* XXX Magic */
     225           0 :                         pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg);
     226             : 
     227           0 :                         bir = pci_conf_read(pa->pa_pc,
     228           0 :                             pa->pa_tag, PPB_REG_BUSINFO);
     229           0 :                         pbnum = PPB_BUSINFO_PRIMARY(bir);
     230           0 :                         if (pbnum > 0)
     231           0 :                                 doattach = 1;
     232             : 
     233             :                         /* Switch back to host bridge mode. */
     234           0 :                         bcreg |= 0x00000004; /* XXX Magic */
     235           0 :                         pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg);
     236           0 :                         break;
     237             :                 }
     238           0 :                 printf("\n");
     239           0 :                 break;
     240             :         default:
     241           0 :                 printf("\n");
     242           0 :                 break;
     243             :         }
     244             : 
     245             : #if NAGP > 0
     246             :         /*
     247             :          * Intel IGD have an odd interface and attach at vga, however,
     248             :          * in that mode they don't have the AGP cap bit, so this
     249             :          * test should be sufficient
     250             :          */
     251           0 :         if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
     252           0 :             NULL, NULL) != 0) {
     253           0 :                 struct agp_attach_args  aa;
     254           0 :                 aa.aa_busname = "agp";
     255           0 :                 aa.aa_pa = pa;
     256             : 
     257           0 :                 config_found(self, &aa, agpdev_print);
     258           0 :         }
     259             : #endif /* NAGP > 0 */
     260             : 
     261           0 :         if (doattach == 0)
     262           0 :                 return;
     263             : 
     264           0 :         bzero(&pba, sizeof(pba));
     265           0 :         pba.pba_busname = "pci";
     266           0 :         pba.pba_iot = pa->pa_iot;
     267           0 :         pba.pba_memt = pa->pa_memt;
     268           0 :         pba.pba_dmat = pa->pa_dmat;
     269           0 :         pba.pba_busex = pa->pa_busex;
     270           0 :         pba.pba_domain = pa->pa_domain;
     271           0 :         pba.pba_bus = pbnum;
     272           0 :         pba.pba_pc = pa->pa_pc;
     273           0 :         config_found(self, &pba, pchb_print);
     274           0 : }
     275             : 
     276             : int
     277           0 : pchbactivate(struct device *self, int act)
     278             : {
     279           0 :         struct pchb_softc *sc = (struct pchb_softc *)self;
     280             :         int rv = 0;
     281             : 
     282           0 :         switch (act) {
     283             :         case DVACT_RESUME:
     284             :                 /* re-enable RNG, if we have it */
     285           0 :                 if (sc->sc_rng_active)
     286           0 :                         bus_space_write_1(sc->sc_bt, sc->sc_bh,
     287             :                             I82802_RNG_HWST,
     288             :                             bus_space_read_1(sc->sc_bt, sc->sc_bh,
     289             :                             I82802_RNG_HWST) | I82802_RNG_HWST_ENABLE);
     290           0 :                 rv = config_activate_children(self, act);
     291           0 :                 break;
     292             :         default:
     293           0 :                 rv = config_activate_children(self, act);
     294           0 :                 break;
     295             :         }
     296           0 :         return (rv);
     297             : }
     298             : 
     299             : int
     300           0 : pchb_print(void *aux, const char *pnp)
     301             : {
     302           0 :         struct pcibus_attach_args *pba = aux;
     303             : 
     304           0 :         if (pnp)
     305           0 :                 printf("%s at %s", pba->pba_busname, pnp);
     306           0 :         printf(" bus %d", pba->pba_bus);
     307           0 :         return (UNCONF);
     308             : }
     309             : 
     310             : /*
     311             :  * Should do FIPS testing as per:
     312             :  *      http://csrc.nist.gov/publications/fips/fips140-1/fips1401.pdf
     313             :  */
     314             : void
     315           0 : pchb_rnd(void *v)
     316             : {
     317           0 :         struct pchb_softc *sc = v;
     318             : 
     319             :         /*
     320             :          * Don't wait for data to be ready. If it's not there, we'll check
     321             :          * next time.
     322             :          */
     323           0 :         if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) &
     324             :             I82802_RNG_RNGST_DATAV)) {
     325             : 
     326           0 :                 sc->sc_rng_ax = (sc->sc_rng_ax << 8) |
     327           0 :                     bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_DATA);
     328             : 
     329           0 :                 if (!sc->sc_rng_i--) {
     330           0 :                         sc->sc_rng_i = 4;
     331           0 :                         enqueue_randomness(sc->sc_rng_ax);
     332           0 :                 }
     333             :         }
     334             : 
     335           0 :         timeout_add(&sc->sc_rng_to, 1);
     336           0 : }
     337             : 
     338             : void
     339           0 : pchb_amd64ht_attach(struct device *self, struct pci_attach_args *pa, int i)
     340             : {
     341           0 :         struct pcibus_attach_args pba;
     342             :         pcireg_t type, bus;
     343             :         int reg;
     344             : 
     345           0 :         reg = AMD64HT_LDT0_TYPE + i * 0x20;
     346           0 :         type = pci_conf_read(pa->pa_pc, pa->pa_tag, reg);
     347           0 :         if ((type & AMD64HT_LDT_INIT_COMPLETE) == 0 ||
     348           0 :             (type & AMD64HT_LDT_NC) == 0)
     349           0 :                 return;
     350             : 
     351           0 :         reg = AMD64HT_LDT0_BUS + i * 0x20;
     352           0 :         bus = pci_conf_read(pa->pa_pc, pa->pa_tag, reg);
     353           0 :         if (AMD64HT_LDT_SEC_BUS_NUM(bus) > 0) {
     354           0 :                 bzero(&pba, sizeof(pba));
     355           0 :                 pba.pba_busname = "pci";
     356           0 :                 pba.pba_iot = pa->pa_iot;
     357           0 :                 pba.pba_memt = pa->pa_memt;
     358           0 :                 pba.pba_dmat = pa->pa_dmat;
     359           0 :                 pba.pba_busex = pa->pa_busex;
     360           0 :                 pba.pba_domain = pa->pa_domain;
     361           0 :                 pba.pba_bus = AMD64HT_LDT_SEC_BUS_NUM(bus);
     362           0 :                 pba.pba_pc = pa->pa_pc;
     363           0 :                 config_found(self, &pba, pchb_print);
     364           0 :         }
     365           0 : }

Generated by: LCOV version 1.13