1 /*        $NetBSD: pchb.c,v 1.37 2021/08/07 16:19:08 thorpej Exp $ */
2 
3 /*-
4  * Copyright (c) 1996, 1998, 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
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  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.37 2021/08/07 16:19:08 thorpej Exp $");
34 
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/device.h>
39 
40 #include <sys/bus.h>
41 
42 #include <dev/pci/pcivar.h>
43 #include <dev/pci/pcireg.h>
44 
45 #include <dev/pci/pcidevs.h>
46 
47 #include <dev/pci/agpreg.h>
48 #include <dev/pci/agpvar.h>
49 
50 #include <arch/x86/pci/pchbvar.h>
51 
52 #define PCISET_BRIDGETYPE_MASK          0x3
53 #define PCISET_TYPE_COMPAT    0x1
54 #define PCISET_TYPE_AUX                 0x2
55 
56 #define PCISET_BUSCONFIG_REG  0x48
57 #define PCISET_BRIDGE_NUMBER(reg)       (((reg) >> 8) & 0xff)
58 #define PCISET_PCI_BUS_NUMBER(reg)      (((reg) >> 16) & 0xff)
59 
60 /* XXX should be in dev/ic/i82443reg.h */
61 #define   I82443BX_SDRAMC_REG 0x74 /* upper 16 bits */
62 
63 /* XXX should be in dev/ic/i82424{reg.var}.h */
64 #define I82424_CPU_BCTL_REG             0x50 /* upper 8 bits */
65 #define I82424_PCI_BCTL_REG             0x54
66 
67 #define I82424_BCTL_CPUMEM_POSTEN       0x01000000
68 #define I82424_BCTL_CPUPCI_POSTEN       0x02000000
69 #define I82424_BCTL_PCIMEM_BURSTEN      0x01000000
70 #define I82424_BCTL_PCI_BURSTEN                   0x02000000
71 
72 static int          pchbmatch(device_t, cfdata_t, void *);
73 static void         pchbattach(device_t, device_t, void *);
74 static int          pchbdetach(device_t, int);
75 
76 static bool         pchb_resume(device_t, const pmf_qual_t *);
77 static bool         pchb_suspend(device_t, const pmf_qual_t *);
78 
79 CFATTACH_DECL3_NEW(pchb, sizeof(struct pchb_softc),
80     pchbmatch, pchbattach, pchbdetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
81 
82 static int
pchbmatch(device_t parent,cfdata_t match,void * aux)83 pchbmatch(device_t parent, cfdata_t match, void *aux)
84 {
85           struct pci_attach_args *pa = aux;
86 
87           if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
88               PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST)
89                     return 1;
90 
91           return 0;
92 }
93 
94 int
pchb_get_bus_number(pci_chipset_tag_t pc,pcitag_t tag)95 pchb_get_bus_number(pci_chipset_tag_t pc, pcitag_t tag)
96 {
97           pcireg_t dev_id;
98           int bus, dev, func;
99           int bcreg, pbnum;
100 
101           pci_decompose_tag(pc, tag, &bus, &dev, &func);
102 
103           dev_id = pci_conf_read(pc, tag, PCI_ID_REG);
104           switch (PCI_VENDOR(dev_id)) {
105           case PCI_VENDOR_SERVERWORKS:
106                     return pci_conf_read(pc, tag, 0x44) & 0xff;
107           case PCI_VENDOR_INTEL:
108                     switch (PCI_PRODUCT(dev_id)) {
109                     case PCI_PRODUCT_INTEL_82452_PB:
110                               bcreg = pci_conf_read(pc, tag, 0x40);
111                               pbnum = PCISET_BRIDGE_NUMBER(bcreg);
112                               if (pbnum != 0xff)
113                                         return pbnum + 1;
114 
115                               break;
116                     case PCI_PRODUCT_INTEL_PCI450_PB:
117                               bcreg = pci_conf_read(pc, tag, PCISET_BUSCONFIG_REG);
118                               return PCISET_PCI_BUS_NUMBER(bcreg);
119                     case PCI_PRODUCT_INTEL_82451NX_PXB:
120                               pbnum = 0;
121                               switch (dev) {
122                               case 18: /* PXB 0 bus A - primary bus */
123                                         break;
124                               case 19: /* PXB 0 bus B */
125                                         /* read SUBA0 from MIOC */
126                                         tag = pci_make_tag(pc, 0, 16, 0);
127                                         bcreg = pci_conf_read(pc, tag, 0xd0);
128                                         pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
129                                         break;
130                               case 20: /* PXB 1 bus A */
131                                         /* read BUSNO1 from MIOC */
132                                         tag = pci_make_tag(pc, 0, 16, 0);
133                                         bcreg = pci_conf_read(pc, tag, 0xd0);
134                                         pbnum = (bcreg & 0xff000000) >> 24;
135                                         break;
136                               case 21: /* PXB 1 bus B */
137                                         /* read SUBA1 from MIOC */
138                                         tag = pci_make_tag(pc, 0, 16, 0);
139                                         bcreg = pci_conf_read(pc, tag, 0xd4);
140                                         pbnum = (bcreg & 0x000000ff) + 1;
141                                         break;
142                               }
143                               return pbnum;
144                     }
145           }
146           return -1;
147 }
148 
149 static void
pchbattach(device_t parent,device_t self,void * aux)150 pchbattach(device_t parent, device_t self, void *aux)
151 {
152           struct pchb_softc *sc = device_private(self);
153           const struct pci_attach_args *pa = aux;
154           struct pcibus_attach_args pba;
155           struct agpbus_attach_args apa;
156           pcireg_t bcreg;
157           u_char bdnum, pbnum = 0; /* XXX: gcc */
158           pcitag_t tag;
159           int doattach, attachflags, has_agp;
160 
161           doattach = 0;
162           has_agp = 0;
163           attachflags = pa->pa_flags;
164 
165           sc->sc_dev = self;
166           sc->sc_pc = pa->pa_pc;
167           sc->sc_tag = pa->pa_tag;
168 
169           /*
170            * Print out a description, and configure certain chipsets which
171            * have auxiliary PCI buses.
172            */
173 
174           pci_aprint_devinfo(pa, NULL);
175 
176           switch (PCI_VENDOR(pa->pa_id)) {
177           /*
178            * i386 stuff.
179            */
180           case PCI_VENDOR_SERVERWORKS:
181                     pbnum = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xff;
182 
183                     if (pbnum == 0)
184                               break;
185 
186                     /*
187                      * This host bridge has a second PCI bus.
188                      * Configure it.
189                      */
190                     switch (PCI_PRODUCT(pa->pa_id)) {
191                     case PCI_PRODUCT_SERVERWORKS_CSB5:
192                     case PCI_PRODUCT_SERVERWORKS_CSB6:
193                               /* These devices show up as host bridges, but are
194                                  really southbridges. */
195                               break;
196                     case PCI_PRODUCT_SERVERWORKS_CMIC_HE:
197                     case PCI_PRODUCT_SERVERWORKS_CMIC_LE:
198                     case PCI_PRODUCT_SERVERWORKS_CMIC_SL:
199                               /* CNBs and CIOBs are connected to these using a
200                                  private bus.  The bus number register is that of
201                                  the first PCI bus hanging off the CIOB.  We let
202                                  the CIOB attachment handle configuring the PCI
203                                  buses. */
204                               break;
205                     default:
206                               aprint_error_dev(self,
207                                   "unknown ServerWorks chip ID 0x%04x; trying "
208                                   "to attach PCI buses behind it\n",
209                                   PCI_PRODUCT(pa->pa_id));
210                               /* FALLTHROUGH */
211                     case PCI_PRODUCT_SERVERWORKS_CNB20_LE_AGP:
212                     case PCI_PRODUCT_SERVERWORKS_CNB30_LE_PCI:
213                     case PCI_PRODUCT_SERVERWORKS_CNB20_LE_PCI:
214                     case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI:
215                     case PCI_PRODUCT_SERVERWORKS_CNB20_HE_AGP:
216                     case PCI_PRODUCT_SERVERWORKS_CIOB_X:
217                     case PCI_PRODUCT_SERVERWORKS_CNB30_HE:
218                     case PCI_PRODUCT_SERVERWORKS_CNB20_HE_PCI2:
219                     case PCI_PRODUCT_SERVERWORKS_CIOB_X2:
220                     case PCI_PRODUCT_SERVERWORKS_CIOB_E:
221                               switch (attachflags &
222                                   (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) {
223                               case 0:
224                                         /* Doesn't smell like there's anything there. */
225                                         break;
226                               case PCI_FLAGS_MEM_OKAY:
227                                         attachflags |= PCI_FLAGS_IO_OKAY;
228                                         /* FALLTHROUGH */
229                               default:
230                                         doattach = 1;
231                                         break;
232                               }
233                               break;
234                     }
235                     break;
236           case PCI_VENDOR_INTEL:
237                     switch (PCI_PRODUCT(pa->pa_id)) {
238                     case PCI_PRODUCT_INTEL_82452_PB:
239                               bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
240                               pbnum = PCISET_BRIDGE_NUMBER(bcreg);
241                               if (pbnum != 0xff) {
242                                         pbnum++;
243                                         doattach = 1;
244                               }
245                               break;
246                     case PCI_PRODUCT_INTEL_82443BX_AGP:
247                     case PCI_PRODUCT_INTEL_82443BX_NOAGP:
248                     /*
249                      * http://www.intel.com/design/chipsets/specupdt/290639.htm
250                      * says this bug is fixed in steppings >= C0 (erratum 11),
251                      * so don't tweak the bits in that case.
252                      */
253                               if (!(PCI_REVISION(pa->pa_class) >= 0x03)) {
254                                         /*
255                                          * BIOS BUG WORKAROUND!  The 82443BX
256                                          * datasheet indicates that the only
257                                          * legal setting for the "Idle/Pipeline
258                                          * DRAM Leadoff Timing (IPLDT)" parameter
259                                          * (bits 9:8) is 01.  Unfortunately, some
260                                          * BIOSs do not set these bits properly.
261                                          */
262                                         bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
263                                             I82443BX_SDRAMC_REG);
264                                         if ((bcreg & 0x03000000) != 0x01000000) {
265                                                   aprint_verbose_dev(self, "fixing "
266                                                       "Idle/Pipeline DRAM "
267                                                       "Leadoff Timing\n");
268                                                   bcreg &= ~0x03000000;
269                                                   bcreg |=  0x01000000;
270                                                   pci_conf_write(pa->pa_pc, pa->pa_tag,
271                                                       I82443BX_SDRAMC_REG, bcreg);
272                                         }
273                               }
274                               break;
275 
276                     case PCI_PRODUCT_INTEL_PCI450_PB:
277                               bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
278                                                         PCISET_BUSCONFIG_REG);
279                               bdnum = PCISET_BRIDGE_NUMBER(bcreg);
280                               pbnum = PCISET_PCI_BUS_NUMBER(bcreg);
281                               switch (bdnum & PCISET_BRIDGETYPE_MASK) {
282                               default:
283                                         aprint_error_dev(self, "bdnum=%x (reserved)\n",
284                                                bdnum);
285                                         break;
286                               case PCISET_TYPE_COMPAT:
287                                         aprint_verbose_dev(self,
288                                             "Compatibility PB (bus %d)\n", pbnum);
289                                         break;
290                               case PCISET_TYPE_AUX:
291                                         aprint_verbose_dev(self,
292                                             "Auxiliary PB (bus %d)\n",pbnum);
293                                         /*
294                                          * This host bridge has a second PCI bus.
295                                          * Configure it.
296                                          */
297                                         doattach = 1;
298                                         break;
299                               }
300                               break;
301                     case PCI_PRODUCT_INTEL_CDC:
302                               bcreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
303                                                         I82424_CPU_BCTL_REG);
304                               if (bcreg & I82424_BCTL_CPUPCI_POSTEN) {
305                                         bcreg &= ~I82424_BCTL_CPUPCI_POSTEN;
306                                         pci_conf_write(pa->pa_pc, pa->pa_tag,
307                                                          I82424_CPU_BCTL_REG, bcreg);
308                                         aprint_verbose_dev(self,
309                                             "disabled CPU-PCI write posting\n");
310                               }
311                               break;
312                     case PCI_PRODUCT_INTEL_82451NX_PXB:
313                               /*
314                                * The NX chipset supports up to 2 "PXB" chips
315                                * which can drive 2 PCI buses each. Each bus
316                                * shows up as logical PCI device, with fixed
317                                * device numbers between 18 and 21.
318                                * See the datasheet at
319                     ftp://download.intel.com/design/chipsets/datashts/24377102.pdf
320                                * for details.
321                                * (It would be easier to attach all the buses
322                                * at the MIOC, but less aesthetical imho.)
323                                */
324                               if ((attachflags &
325                                   (PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY)) ==
326                                   PCI_FLAGS_MEM_OKAY)
327                                         attachflags |= PCI_FLAGS_IO_OKAY;
328 
329                               pbnum = 0;
330                               switch (pa->pa_device) {
331                               case 18: /* PXB 0 bus A - primary bus */
332                                         break;
333                               case 19: /* PXB 0 bus B */
334                                         /* read SUBA0 from MIOC */
335                                         tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
336                                         bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
337                                         pbnum = ((bcreg & 0x0000ff00) >> 8) + 1;
338                                         break;
339                               case 20: /* PXB 1 bus A */
340                                         /* read BUSNO1 from MIOC */
341                                         tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
342                                         bcreg = pci_conf_read(pa->pa_pc, tag, 0xd0);
343                                         pbnum = (bcreg & 0xff000000) >> 24;
344                                         break;
345                               case 21: /* PXB 1 bus B */
346                                         /* read SUBA1 from MIOC */
347                                         tag = pci_make_tag(pa->pa_pc, 0, 16, 0);
348                                         bcreg = pci_conf_read(pa->pa_pc, tag, 0xd4);
349                                         pbnum = (bcreg & 0x000000ff) + 1;
350                                         break;
351                               }
352                               if (pbnum != 0)
353                                         doattach = 1;
354                               break;
355 
356                     /*
357                      * i386 and amd64 stuff.
358                      */
359                     case PCI_PRODUCT_INTEL_82810_MCH:
360                     case PCI_PRODUCT_INTEL_82810_DC100_MCH:
361                     case PCI_PRODUCT_INTEL_82810E_MCH:
362                     case PCI_PRODUCT_INTEL_82815_FULL_HUB:
363                     case PCI_PRODUCT_INTEL_82830MP_IO_1:
364                     case PCI_PRODUCT_INTEL_82845G_DRAM:
365                     case PCI_PRODUCT_INTEL_82855GM_MCH:
366                     case PCI_PRODUCT_INTEL_82865_HB:
367                     case PCI_PRODUCT_INTEL_82915G_HB:
368                     case PCI_PRODUCT_INTEL_82915GM_HB:
369                     case PCI_PRODUCT_INTEL_82945P_MCH:
370                     case PCI_PRODUCT_INTEL_82945GM_HB:
371                     case PCI_PRODUCT_INTEL_82945GME_HB:
372                     case PCI_PRODUCT_INTEL_82946GZ_HB:
373                     case PCI_PRODUCT_INTEL_82965Q_HB:
374                     case PCI_PRODUCT_INTEL_82965G_HB:
375                     case PCI_PRODUCT_INTEL_82965PM_HB:
376                     case PCI_PRODUCT_INTEL_82Q35_HB:
377                     case PCI_PRODUCT_INTEL_82G33_HB:
378                     case PCI_PRODUCT_INTEL_82Q33_HB:
379                     case PCI_PRODUCT_INTEL_82G35_HB:
380                     case PCI_PRODUCT_INTEL_82GM45_HB:
381                     case PCI_PRODUCT_INTEL_82IGD_E_HB:
382                     case PCI_PRODUCT_INTEL_82Q45_HB:
383                     case PCI_PRODUCT_INTEL_82G45_HB:
384                     case PCI_PRODUCT_INTEL_82G41_HB:
385                     case PCI_PRODUCT_INTEL_E7221_HB:
386                     case PCI_PRODUCT_INTEL_82965GME_HB:
387                     case PCI_PRODUCT_INTEL_82B43_HB:
388                     case PCI_PRODUCT_INTEL_IRONLAKE_D_HB:
389                     case PCI_PRODUCT_INTEL_IRONLAKE_M_HB:
390                     case PCI_PRODUCT_INTEL_IRONLAKE_MA_HB:
391                     case PCI_PRODUCT_INTEL_IRONLAKE_MC2_HB:
392                     case PCI_PRODUCT_INTEL_PINEVIEW_HB:
393                     case PCI_PRODUCT_INTEL_PINEVIEW_M_HB:
394                               /*
395                                * The host bridge is either in GFX mode (internal
396                                * graphics) or in AGP mode. In GFX mode, we pretend
397                                * to have AGP because the graphics memory access
398                                * is very similar and the AGP GATT code will
399                                * deal with this. In the latter case, the
400                                * pci_get_capability(PCI_CAP_AGP) test below will
401                                * fire, so we do no harm by already setting the flag.
402                                */
403                               has_agp = 1;
404                               break;
405                     }
406                     break;
407           }
408 
409           if (!pmf_device_register(self, pchb_suspend, pchb_resume))
410                     aprint_error_dev(self, "couldn't establish power handler\n");
411 
412           /*
413            * If we haven't detected AGP yet (via a product ID),
414            * then check for AGP capability on the device.
415            */
416           if (has_agp ||
417               pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
418                                      NULL, NULL) != 0) {
419                     apa.apa_pci_args = *pa;
420                     config_found(self, &apa, agpbusprint,
421                         CFARGS(.iattr = "agpbus"));
422           }
423 
424           if (doattach) {
425                     pba.pba_iot = pa->pa_iot;
426                     pba.pba_memt = pa->pa_memt;
427                     pba.pba_dmat = pa->pa_dmat;
428                     pba.pba_dmat64 = pa->pa_dmat64;
429                     pba.pba_pc = pa->pa_pc;
430                     pba.pba_flags = attachflags;
431                     pba.pba_bus = pbnum;
432                     pba.pba_bridgetag = NULL;
433                     pba.pba_pc = pa->pa_pc;
434                     pba.pba_intrswiz = 0;
435                     memset(&pba.pba_intrtag, 0, sizeof(pba.pba_intrtag));
436                     config_found(self, &pba, pcibusprint,
437                         CFARGS(.iattr = "pcibus"));
438           }
439 }
440 
441 static int
pchbdetach(device_t self,int flags)442 pchbdetach(device_t self, int flags)
443 {
444           int rc;
445 
446           if ((rc = config_detach_children(self, flags)) != 0)
447                     return rc;
448 
449           pmf_device_deregister(self);
450 
451           return 0;
452 }
453 
454 static bool
pchb_suspend(device_t dv,const pmf_qual_t * qual)455 pchb_suspend(device_t dv, const pmf_qual_t *qual)
456 {
457           struct pchb_softc *sc = device_private(dv);
458           pci_chipset_tag_t pc;
459           pcitag_t tag;
460           int off;
461 
462           pc = sc->sc_pc;
463           tag = sc->sc_tag;
464 
465           for (off = 0x40; off <= 0xff; off += 4)
466                     sc->sc_pciconfext[(off - 0x40) / 4] = pci_conf_read(pc, tag, off);
467 
468           return true;
469 }
470 
471 static bool
pchb_resume(device_t dv,const pmf_qual_t * qual)472 pchb_resume(device_t dv, const pmf_qual_t *qual)
473 {
474           struct pchb_softc *sc = device_private(dv);
475           pci_chipset_tag_t pc;
476           pcitag_t tag;
477           int off;
478 
479           pc = sc->sc_pc;
480           tag = sc->sc_tag;
481 
482           for (off = 0x40; off <= 0xff; off += 4)
483                     pci_conf_write(pc, tag, off, sc->sc_pciconfext[(off - 0x40) / 4]);
484 
485           return true;
486 }
487