The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/x86/pci/pci_early_quirks.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2018 Johannes Lundberg
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD: releng/12.0/sys/x86/pci/pci_early_quirks.c 340224 2018-11-07 17:44:27Z kib $");
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/bus.h>
   34 #include <sys/kernel.h>
   35 #include <vm/vm.h>
   36 /* XXX: enable this once the KPI is available */
   37 /* #include <x86/physmem.h> */
   38 #include <machine/pci_cfgreg.h>
   39 #include <machine/md_var.h>
   40 #include <dev/pci/pcivar.h>
   41 #include <dev/pci/pcireg.h>
   42 
   43 #include <x86/pci/pci_early_quirks.h>
   44 
   45 #define MiB(v) ((unsigned long)(v) << 20)
   46 
   47 struct pci_device_id {
   48         uint32_t        vendor;
   49         uint32_t        device;
   50         const struct intel_stolen_ops *data;
   51 };
   52 
   53 /*
   54  * These global variables are read by LinuxKPI.
   55  * LinuxKPI provide this information to the i915 driver.
   56  */
   57 vm_paddr_t intel_graphics_stolen_base = 0;
   58 vm_paddr_t intel_graphics_stolen_size = 0;
   59 
   60 /*
   61  * Intel early quirks functions
   62  */
   63 static vm_paddr_t
   64 intel_stolen_base_gen3(int bus, int slot, int func)
   65 {
   66         uint32_t ctrl;
   67         vm_paddr_t val;
   68 
   69         ctrl = pci_cfgregread(bus, slot, func, INTEL_BSM, 4);
   70         val = ctrl & INTEL_BSM_MASK;
   71         return (val);
   72 }
   73 
   74 static vm_paddr_t
   75 intel_stolen_size_gen3(int bus, int slot, int func)
   76 {
   77         uint32_t ctrl;
   78         vm_paddr_t val;
   79 
   80         ctrl = pci_cfgregread(0, 0, 0, I830_GMCH_CTRL, 2);
   81         val = ctrl & I855_GMCH_GMS_MASK;
   82 
   83         switch (val) {
   84         case I855_GMCH_GMS_STOLEN_1M:
   85                 return (MiB(1));
   86         case I855_GMCH_GMS_STOLEN_4M:
   87                 return (MiB(4));
   88         case I855_GMCH_GMS_STOLEN_8M:
   89                 return (MiB(8));
   90         case I855_GMCH_GMS_STOLEN_16M:
   91                 return (MiB(16));
   92         case I855_GMCH_GMS_STOLEN_32M:
   93                 return (MiB(32));
   94         case I915_GMCH_GMS_STOLEN_48M:
   95                 return (MiB(48));
   96         case I915_GMCH_GMS_STOLEN_64M:
   97                 return (MiB(64));
   98         case G33_GMCH_GMS_STOLEN_128M:
   99                 return (MiB(128));
  100         case G33_GMCH_GMS_STOLEN_256M:
  101                 return (MiB(256));
  102         case INTEL_GMCH_GMS_STOLEN_96M:
  103                 return (MiB(96));
  104         case INTEL_GMCH_GMS_STOLEN_160M:
  105                 return (MiB(160));
  106         case INTEL_GMCH_GMS_STOLEN_224M:
  107                 return (MiB(224));
  108         case INTEL_GMCH_GMS_STOLEN_352M:
  109                 return (MiB(352));
  110         }
  111         return (0);
  112 }
  113 
  114 static vm_paddr_t
  115 intel_stolen_size_gen6(int bus, int slot, int func)
  116 {
  117         uint32_t ctrl;
  118         vm_paddr_t val;
  119 
  120         ctrl = pci_cfgregread(bus, slot, func, SNB_GMCH_CTRL, 2);
  121         val = (ctrl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK;
  122         return (val * MiB(32));
  123 }
  124 
  125 static vm_paddr_t
  126 intel_stolen_size_gen8(int bus, int slot, int func)
  127 {
  128         uint32_t ctrl;
  129         vm_paddr_t val;
  130 
  131         ctrl = pci_cfgregread(bus, slot, func, SNB_GMCH_CTRL, 2);
  132         val = (ctrl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK;
  133         return (val * MiB(32));
  134 }
  135 
  136 static vm_paddr_t
  137 intel_stolen_size_chv(int bus, int slot, int func)
  138 {
  139         uint32_t ctrl;
  140         vm_paddr_t val;
  141 
  142         ctrl = pci_cfgregread(bus, slot, func, SNB_GMCH_CTRL, 2);
  143         val = (ctrl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK;
  144 
  145         /*
  146          * 0x0  to 0x10: 32MB increments starting at 0MB
  147          * 0x11 to 0x16: 4MB increments starting at 8MB
  148          * 0x17 to 0x1d: 4MB increments start at 36MB
  149          */
  150         if (val < 0x11)
  151                 return (val * MiB(32));
  152         else if (val < 0x17)
  153                 return ((val - 0x11) * MiB(4) + MiB(8));
  154         else
  155                 return ((val - 0x17) * MiB(4) + MiB(36));
  156 }
  157 
  158 static vm_paddr_t
  159 intel_stolen_size_gen9(int bus, int slot, int func)
  160 {
  161         uint32_t ctrl;
  162         vm_paddr_t val;
  163 
  164         ctrl = pci_cfgregread(bus, slot, func, SNB_GMCH_CTRL, 2);
  165         val = (ctrl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK;
  166 
  167         /* 0x0  to 0xEF: 32MB increments starting at 0MB */
  168         /* 0xF0 to 0xFE: 4MB increments starting at 4MB */
  169         if (val < 0xF0)
  170                 return (val * MiB(32));
  171         return ((val - 0xF0) * MiB(4) + MiB(4));
  172 }
  173 
  174 struct intel_stolen_ops {
  175         vm_paddr_t (*base)(int bus, int slot, int func);
  176         vm_paddr_t (*size)(int bus, int slot, int func);
  177 };
  178 
  179 static const struct intel_stolen_ops intel_stolen_ops_gen3 = {
  180         .base = intel_stolen_base_gen3,
  181         .size = intel_stolen_size_gen3,
  182 };
  183 
  184 static const struct intel_stolen_ops intel_stolen_ops_gen6 = {
  185         .base = intel_stolen_base_gen3,
  186         .size = intel_stolen_size_gen6,
  187 };
  188 
  189 static const struct intel_stolen_ops intel_stolen_ops_gen8 = {
  190         .base = intel_stolen_base_gen3,
  191         .size = intel_stolen_size_gen8,
  192 };
  193 
  194 static const struct intel_stolen_ops intel_stolen_ops_gen9 = {
  195         .base = intel_stolen_base_gen3,
  196         .size = intel_stolen_size_gen9,
  197 };
  198 
  199 static const struct intel_stolen_ops intel_stolen_ops_chv = {
  200         .base = intel_stolen_base_gen3,
  201         .size = intel_stolen_size_chv,
  202 };
  203 
  204 static const struct pci_device_id intel_ids[] = {
  205         INTEL_I915G_IDS(&intel_stolen_ops_gen3),
  206         INTEL_I915GM_IDS(&intel_stolen_ops_gen3),
  207         INTEL_I945G_IDS(&intel_stolen_ops_gen3),
  208         INTEL_I945GM_IDS(&intel_stolen_ops_gen3),
  209         INTEL_VLV_IDS(&intel_stolen_ops_gen6),
  210         INTEL_PINEVIEW_IDS(&intel_stolen_ops_gen3),
  211         INTEL_I965G_IDS(&intel_stolen_ops_gen3),
  212         INTEL_G33_IDS(&intel_stolen_ops_gen3),
  213         INTEL_I965GM_IDS(&intel_stolen_ops_gen3),
  214         INTEL_GM45_IDS(&intel_stolen_ops_gen3),
  215         INTEL_G45_IDS(&intel_stolen_ops_gen3),
  216         INTEL_IRONLAKE_D_IDS(&intel_stolen_ops_gen3),
  217         INTEL_IRONLAKE_M_IDS(&intel_stolen_ops_gen3),
  218         INTEL_SNB_D_IDS(&intel_stolen_ops_gen6),
  219         INTEL_SNB_M_IDS(&intel_stolen_ops_gen6),
  220         INTEL_IVB_M_IDS(&intel_stolen_ops_gen6),
  221         INTEL_IVB_D_IDS(&intel_stolen_ops_gen6),
  222         INTEL_HSW_IDS(&intel_stolen_ops_gen6),
  223         INTEL_BDW_IDS(&intel_stolen_ops_gen8),
  224         INTEL_CHV_IDS(&intel_stolen_ops_chv),
  225         INTEL_SKL_IDS(&intel_stolen_ops_gen9),
  226         INTEL_BXT_IDS(&intel_stolen_ops_gen9),
  227         INTEL_KBL_IDS(&intel_stolen_ops_gen9),
  228         INTEL_CFL_IDS(&intel_stolen_ops_gen9),
  229         INTEL_GLK_IDS(&intel_stolen_ops_gen9),
  230         INTEL_CNL_IDS(&intel_stolen_ops_gen9),
  231 };
  232 
  233 /*
  234  * Buggy BIOS don't reserve memory for the GPU properly and the OS
  235  * can claim it before the GPU driver is loaded. This function will
  236  * check the registers for base and size of this memory and reserve
  237  * it for the GPU driver.
  238  * gen3 (2004) and newer devices are supported. Support for older hw
  239  * can be ported from Linux if needed.
  240  */
  241 static void
  242 intel_graphics_stolen(void)
  243 {
  244         const struct intel_stolen_ops *ops;
  245         uint32_t vendor, device, class;
  246         int i;
  247 
  248         /* XXX: Scan bus instead of assuming 0:2:0? */
  249         const int bus = 0;
  250         const int slot = 2;
  251         const int func = 0;
  252 
  253         if (pci_cfgregopen() == 0)
  254                 return;
  255 
  256         vendor = pci_cfgregread(bus, slot, func, PCIR_VENDOR, 2);
  257         if (vendor != PCI_VENDOR_INTEL)
  258                 return;
  259 
  260         class = pci_cfgregread(bus, slot, func, PCIR_SUBCLASS, 2);
  261         if (class != PCI_CLASS_VGA)
  262                 return;
  263 
  264         device = pci_cfgregread(bus, slot, func, PCIR_DEVICE, 2);
  265         if (device == 0xFFFF)
  266                 return;
  267 
  268         for (i = 0; i < nitems(intel_ids); i++) {
  269                 if (intel_ids[i].device != device)
  270                         continue;
  271                 ops = intel_ids[i].data;
  272                 intel_graphics_stolen_base = ops->base(bus, slot, func);
  273                 intel_graphics_stolen_size = ops->size(bus, slot, func);
  274                 break;
  275         }
  276 
  277         /* XXX: enable this once the KPI is available */
  278         /* phys_avail_reserve(intel_graphics_stolen_base, */
  279         /*     intel_graphics_stolen_base + intel_graphics_stolen_size); */
  280 }
  281 
  282 void
  283 pci_early_quirks(void)
  284 {
  285 
  286         intel_graphics_stolen();
  287 }

Cache object: 1d32c23af358124b65bc107082df11dc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.