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/dev/agp/agp_i810.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2000 Doug Rabson
    3  * Copyright (c) 2000 Ruslan Ermilov
    4  * Copyright (c) 2011 The FreeBSD Foundation
    5  * All rights reserved.
    6  *
    7  * Portions of this software were developed by Konstantin Belousov
    8  * under sponsorship from the FreeBSD Foundation.
    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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
   34  * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
   35  *
   36  * This is generic Intel GTT handling code, morphed from the AGP
   37  * bridge code.
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD: stable/10/sys/dev/agp/agp_i810.c 275406 2014-12-02 13:46:13Z tijl $");
   42 
   43 #if 0
   44 #define KTR_AGP_I810    KTR_DEV
   45 #else
   46 #define KTR_AGP_I810    0
   47 #endif
   48 
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/malloc.h>
   52 #include <sys/kernel.h>
   53 #include <sys/ktr.h>
   54 #include <sys/module.h>
   55 #include <sys/bus.h>
   56 #include <sys/lock.h>
   57 #include <sys/mutex.h>
   58 #include <sys/proc.h>
   59 #include <sys/rwlock.h>
   60 
   61 #include <dev/agp/agppriv.h>
   62 #include <dev/agp/agpreg.h>
   63 #include <dev/agp/agp_i810.h>
   64 #include <dev/pci/pcivar.h>
   65 #include <dev/pci/pcireg.h>
   66 #include <dev/pci/pci_private.h>
   67 
   68 #include <vm/vm.h>
   69 #include <vm/vm_extern.h>
   70 #include <vm/vm_kern.h>
   71 #include <vm/vm_param.h>
   72 #include <vm/vm_object.h>
   73 #include <vm/vm_page.h>
   74 #include <vm/vm_pageout.h>
   75 #include <vm/pmap.h>
   76 
   77 #include <machine/bus.h>
   78 #include <machine/resource.h>
   79 #include <machine/md_var.h>
   80 #include <sys/rman.h>
   81 
   82 MALLOC_DECLARE(M_AGP);
   83 
   84 struct agp_i810_match;
   85 
   86 static int agp_i810_check_active(device_t bridge_dev);
   87 static int agp_i830_check_active(device_t bridge_dev);
   88 static int agp_i915_check_active(device_t bridge_dev);
   89 static int agp_sb_check_active(device_t bridge_dev);
   90 
   91 static void agp_82852_set_desc(device_t dev,
   92     const struct agp_i810_match *match);
   93 static void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match);
   94 
   95 static void agp_i810_dump_regs(device_t dev);
   96 static void agp_i830_dump_regs(device_t dev);
   97 static void agp_i855_dump_regs(device_t dev);
   98 static void agp_i915_dump_regs(device_t dev);
   99 static void agp_i965_dump_regs(device_t dev);
  100 static void agp_sb_dump_regs(device_t dev);
  101 
  102 static int agp_i810_get_stolen_size(device_t dev);
  103 static int agp_i830_get_stolen_size(device_t dev);
  104 static int agp_i915_get_stolen_size(device_t dev);
  105 static int agp_sb_get_stolen_size(device_t dev);
  106 
  107 static int agp_i810_get_gtt_mappable_entries(device_t dev);
  108 static int agp_i830_get_gtt_mappable_entries(device_t dev);
  109 static int agp_i915_get_gtt_mappable_entries(device_t dev);
  110 
  111 static int agp_i810_get_gtt_total_entries(device_t dev);
  112 static int agp_i965_get_gtt_total_entries(device_t dev);
  113 static int agp_gen5_get_gtt_total_entries(device_t dev);
  114 static int agp_sb_get_gtt_total_entries(device_t dev);
  115 
  116 static int agp_i810_install_gatt(device_t dev);
  117 static int agp_i830_install_gatt(device_t dev);
  118 static int agp_i965_install_gatt(device_t dev);
  119 static int agp_g4x_install_gatt(device_t dev);
  120 
  121 static void agp_i810_deinstall_gatt(device_t dev);
  122 static void agp_i830_deinstall_gatt(device_t dev);
  123 
  124 static void agp_i810_install_gtt_pte(device_t dev, u_int index,
  125     vm_offset_t physical, int flags);
  126 static void agp_i830_install_gtt_pte(device_t dev, u_int index,
  127     vm_offset_t physical, int flags);
  128 static void agp_i915_install_gtt_pte(device_t dev, u_int index,
  129     vm_offset_t physical, int flags);
  130 static void agp_i965_install_gtt_pte(device_t dev, u_int index,
  131     vm_offset_t physical, int flags);
  132 static void agp_g4x_install_gtt_pte(device_t dev, u_int index,
  133     vm_offset_t physical, int flags);
  134 static void agp_sb_install_gtt_pte(device_t dev, u_int index,
  135     vm_offset_t physical, int flags);
  136 
  137 static void agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte);
  138 static void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte);
  139 static void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte);
  140 static void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte);
  141 static void agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte);
  142 
  143 static u_int32_t agp_i810_read_gtt_pte(device_t dev, u_int index);
  144 static u_int32_t agp_i915_read_gtt_pte(device_t dev, u_int index);
  145 static u_int32_t agp_i965_read_gtt_pte(device_t dev, u_int index);
  146 static u_int32_t agp_g4x_read_gtt_pte(device_t dev, u_int index);
  147 
  148 static vm_paddr_t agp_i810_read_gtt_pte_paddr(device_t dev, u_int index);
  149 static vm_paddr_t agp_i915_read_gtt_pte_paddr(device_t dev, u_int index);
  150 static vm_paddr_t agp_sb_read_gtt_pte_paddr(device_t dev, u_int index);
  151 
  152 static int agp_i810_set_aperture(device_t dev, u_int32_t aperture);
  153 static int agp_i830_set_aperture(device_t dev, u_int32_t aperture);
  154 static int agp_i915_set_aperture(device_t dev, u_int32_t aperture);
  155 
  156 static int agp_i810_chipset_flush_setup(device_t dev);
  157 static int agp_i915_chipset_flush_setup(device_t dev);
  158 static int agp_i965_chipset_flush_setup(device_t dev);
  159 
  160 static void agp_i810_chipset_flush_teardown(device_t dev);
  161 static void agp_i915_chipset_flush_teardown(device_t dev);
  162 static void agp_i965_chipset_flush_teardown(device_t dev);
  163 
  164 static void agp_i810_chipset_flush(device_t dev);
  165 static void agp_i830_chipset_flush(device_t dev);
  166 static void agp_i915_chipset_flush(device_t dev);
  167 
  168 enum {
  169         CHIP_I810,      /* i810/i815 */
  170         CHIP_I830,      /* 830M/845G */
  171         CHIP_I855,      /* 852GM/855GM/865G */
  172         CHIP_I915,      /* 915G/915GM */
  173         CHIP_I965,      /* G965 */
  174         CHIP_G33,       /* G33/Q33/Q35 */
  175         CHIP_IGD,       /* Pineview */
  176         CHIP_G4X,       /* G45/Q45 */
  177         CHIP_SB,        /* SandyBridge */
  178 };
  179 
  180 /* The i810 through i855 have the registers at BAR 1, and the GATT gets
  181  * allocated by us.  The i915 has registers in BAR 0 and the GATT is at the
  182  * start of the stolen memory, and should only be accessed by the OS through
  183  * BAR 3.  The G965 has registers and GATT in the same BAR (0) -- first 512KB
  184  * is registers, second 512KB is GATT.
  185  */
  186 static struct resource_spec agp_i810_res_spec[] = {
  187         { SYS_RES_MEMORY, AGP_I810_MMADR, RF_ACTIVE | RF_SHAREABLE },
  188         { -1, 0 }
  189 };
  190 
  191 static struct resource_spec agp_i915_res_spec[] = {
  192         { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE },
  193         { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE },
  194         { -1, 0 }
  195 };
  196 
  197 static struct resource_spec agp_i965_res_spec[] = {
  198         { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE },
  199         { -1, 0 }
  200 };
  201 
  202 static struct resource_spec agp_g4x_res_spec[] = {
  203         { SYS_RES_MEMORY, AGP_G4X_MMADR, RF_ACTIVE | RF_SHAREABLE },
  204         { SYS_RES_MEMORY, AGP_G4X_GTTADR, RF_ACTIVE | RF_SHAREABLE },
  205         { -1, 0 }
  206 };
  207 
  208 struct agp_i810_softc {
  209         struct agp_softc agp;
  210         u_int32_t initial_aperture;     /* aperture size at startup */
  211         struct agp_gatt *gatt;
  212         u_int32_t dcache_size;          /* i810 only */
  213         u_int32_t stolen;               /* number of i830/845 gtt
  214                                            entries for stolen memory */
  215         u_int stolen_size;              /* BIOS-reserved graphics memory */
  216         u_int gtt_total_entries;        /* Total number of gtt ptes */
  217         u_int gtt_mappable_entries;     /* Number of gtt ptes mappable by CPU */
  218         device_t bdev;                  /* bridge device */
  219         void *argb_cursor;              /* contigmalloc area for ARGB cursor */
  220         struct resource *sc_res[2];
  221         const struct agp_i810_match *match;
  222         int sc_flush_page_rid;
  223         struct resource *sc_flush_page_res;
  224         void *sc_flush_page_vaddr;
  225         int sc_bios_allocated_flush_page;
  226 };
  227 
  228 static device_t intel_agp;
  229 
  230 struct agp_i810_driver {
  231         int chiptype;
  232         int gen;
  233         int busdma_addr_mask_sz;
  234         struct resource_spec *res_spec;
  235         int (*check_active)(device_t);
  236         void (*set_desc)(device_t, const struct agp_i810_match *);
  237         void (*dump_regs)(device_t);
  238         int (*get_stolen_size)(device_t);
  239         int (*get_gtt_total_entries)(device_t);
  240         int (*get_gtt_mappable_entries)(device_t);
  241         int (*install_gatt)(device_t);
  242         void (*deinstall_gatt)(device_t);
  243         void (*write_gtt)(device_t, u_int, uint32_t);
  244         void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int);
  245         u_int32_t (*read_gtt_pte)(device_t, u_int);
  246         vm_paddr_t (*read_gtt_pte_paddr)(device_t , u_int);
  247         int (*set_aperture)(device_t, u_int32_t);
  248         int (*chipset_flush_setup)(device_t);
  249         void (*chipset_flush_teardown)(device_t);
  250         void (*chipset_flush)(device_t);
  251 };
  252 
  253 static const struct agp_i810_driver agp_i810_i810_driver = {
  254         .chiptype = CHIP_I810,
  255         .gen = 1,
  256         .busdma_addr_mask_sz = 32,
  257         .res_spec = agp_i810_res_spec,
  258         .check_active = agp_i810_check_active,
  259         .set_desc = agp_i810_set_desc,
  260         .dump_regs = agp_i810_dump_regs,
  261         .get_stolen_size = agp_i810_get_stolen_size,
  262         .get_gtt_mappable_entries = agp_i810_get_gtt_mappable_entries,
  263         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  264         .install_gatt = agp_i810_install_gatt,
  265         .deinstall_gatt = agp_i810_deinstall_gatt,
  266         .write_gtt = agp_i810_write_gtt,
  267         .install_gtt_pte = agp_i810_install_gtt_pte,
  268         .read_gtt_pte = agp_i810_read_gtt_pte,
  269         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  270         .set_aperture = agp_i810_set_aperture,
  271         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  272         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  273         .chipset_flush = agp_i810_chipset_flush,
  274 };
  275 
  276 static const struct agp_i810_driver agp_i810_i815_driver = {
  277         .chiptype = CHIP_I810,
  278         .gen = 2,
  279         .busdma_addr_mask_sz = 32,
  280         .res_spec = agp_i810_res_spec,
  281         .check_active = agp_i810_check_active,
  282         .set_desc = agp_i810_set_desc,
  283         .dump_regs = agp_i810_dump_regs,
  284         .get_stolen_size = agp_i810_get_stolen_size,
  285         .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
  286         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  287         .install_gatt = agp_i810_install_gatt,
  288         .deinstall_gatt = agp_i810_deinstall_gatt,
  289         .write_gtt = agp_i810_write_gtt,
  290         .install_gtt_pte = agp_i810_install_gtt_pte,
  291         .read_gtt_pte = agp_i810_read_gtt_pte,
  292         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  293         .set_aperture = agp_i810_set_aperture,
  294         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  295         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  296         .chipset_flush = agp_i830_chipset_flush,
  297 };
  298 
  299 static const struct agp_i810_driver agp_i810_i830_driver = {
  300         .chiptype = CHIP_I830,
  301         .gen = 2,
  302         .busdma_addr_mask_sz = 32,
  303         .res_spec = agp_i810_res_spec,
  304         .check_active = agp_i830_check_active,
  305         .set_desc = agp_i810_set_desc,
  306         .dump_regs = agp_i830_dump_regs,
  307         .get_stolen_size = agp_i830_get_stolen_size,
  308         .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
  309         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  310         .install_gatt = agp_i830_install_gatt,
  311         .deinstall_gatt = agp_i830_deinstall_gatt,
  312         .write_gtt = agp_i810_write_gtt,
  313         .install_gtt_pte = agp_i830_install_gtt_pte,
  314         .read_gtt_pte = agp_i810_read_gtt_pte,
  315         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  316         .set_aperture = agp_i830_set_aperture,
  317         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  318         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  319         .chipset_flush = agp_i830_chipset_flush,
  320 };
  321 
  322 static const struct agp_i810_driver agp_i810_i855_driver = {
  323         .chiptype = CHIP_I855,
  324         .gen = 2,
  325         .busdma_addr_mask_sz = 32,
  326         .res_spec = agp_i810_res_spec,
  327         .check_active = agp_i830_check_active,
  328         .set_desc = agp_82852_set_desc,
  329         .dump_regs = agp_i855_dump_regs,
  330         .get_stolen_size = agp_i915_get_stolen_size,
  331         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  332         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  333         .install_gatt = agp_i830_install_gatt,
  334         .deinstall_gatt = agp_i830_deinstall_gatt,
  335         .write_gtt = agp_i810_write_gtt,
  336         .install_gtt_pte = agp_i830_install_gtt_pte,
  337         .read_gtt_pte = agp_i810_read_gtt_pte,
  338         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  339         .set_aperture = agp_i830_set_aperture,
  340         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  341         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  342         .chipset_flush = agp_i830_chipset_flush,
  343 };
  344 
  345 static const struct agp_i810_driver agp_i810_i865_driver = {
  346         .chiptype = CHIP_I855,
  347         .gen = 2,
  348         .busdma_addr_mask_sz = 32,
  349         .res_spec = agp_i810_res_spec,
  350         .check_active = agp_i830_check_active,
  351         .set_desc = agp_i810_set_desc,
  352         .dump_regs = agp_i855_dump_regs,
  353         .get_stolen_size = agp_i915_get_stolen_size,
  354         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  355         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  356         .install_gatt = agp_i830_install_gatt,
  357         .deinstall_gatt = agp_i830_deinstall_gatt,
  358         .write_gtt = agp_i810_write_gtt,
  359         .install_gtt_pte = agp_i830_install_gtt_pte,
  360         .read_gtt_pte = agp_i810_read_gtt_pte,
  361         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  362         .set_aperture = agp_i915_set_aperture,
  363         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  364         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  365         .chipset_flush = agp_i830_chipset_flush,
  366 };
  367 
  368 static const struct agp_i810_driver agp_i810_i915_driver = {
  369         .chiptype = CHIP_I915,
  370         .gen = 3,
  371         .busdma_addr_mask_sz = 32,
  372         .res_spec = agp_i915_res_spec,
  373         .check_active = agp_i915_check_active,
  374         .set_desc = agp_i810_set_desc,
  375         .dump_regs = agp_i915_dump_regs,
  376         .get_stolen_size = agp_i915_get_stolen_size,
  377         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  378         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  379         .install_gatt = agp_i830_install_gatt,
  380         .deinstall_gatt = agp_i830_deinstall_gatt,
  381         .write_gtt = agp_i915_write_gtt,
  382         .install_gtt_pte = agp_i915_install_gtt_pte,
  383         .read_gtt_pte = agp_i915_read_gtt_pte,
  384         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  385         .set_aperture = agp_i915_set_aperture,
  386         .chipset_flush_setup = agp_i915_chipset_flush_setup,
  387         .chipset_flush_teardown = agp_i915_chipset_flush_teardown,
  388         .chipset_flush = agp_i915_chipset_flush,
  389 };
  390 
  391 static const struct agp_i810_driver agp_i810_g965_driver = {
  392         .chiptype = CHIP_I965,
  393         .gen = 4,
  394         .busdma_addr_mask_sz = 36,
  395         .res_spec = agp_i965_res_spec,
  396         .check_active = agp_i915_check_active,
  397         .set_desc = agp_i810_set_desc,
  398         .dump_regs = agp_i965_dump_regs,
  399         .get_stolen_size = agp_i915_get_stolen_size,
  400         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  401         .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
  402         .install_gatt = agp_i965_install_gatt,
  403         .deinstall_gatt = agp_i830_deinstall_gatt,
  404         .write_gtt = agp_i965_write_gtt,
  405         .install_gtt_pte = agp_i965_install_gtt_pte,
  406         .read_gtt_pte = agp_i965_read_gtt_pte,
  407         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  408         .set_aperture = agp_i915_set_aperture,
  409         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  410         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  411         .chipset_flush = agp_i915_chipset_flush,
  412 };
  413 
  414 static const struct agp_i810_driver agp_i810_g33_driver = {
  415         .chiptype = CHIP_G33,
  416         .gen = 3,
  417         .busdma_addr_mask_sz = 36,
  418         .res_spec = agp_i915_res_spec,
  419         .check_active = agp_i915_check_active,
  420         .set_desc = agp_i810_set_desc,
  421         .dump_regs = agp_i965_dump_regs,
  422         .get_stolen_size = agp_i915_get_stolen_size,
  423         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  424         .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
  425         .install_gatt = agp_i830_install_gatt,
  426         .deinstall_gatt = agp_i830_deinstall_gatt,
  427         .write_gtt = agp_i915_write_gtt,
  428         .install_gtt_pte = agp_i915_install_gtt_pte,
  429         .read_gtt_pte = agp_i915_read_gtt_pte,
  430         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  431         .set_aperture = agp_i915_set_aperture,
  432         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  433         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  434         .chipset_flush = agp_i915_chipset_flush,
  435 };
  436 
  437 static const struct agp_i810_driver agp_i810_igd_driver = {
  438         .chiptype = CHIP_IGD,
  439         .gen = 3,
  440         .busdma_addr_mask_sz = 36,
  441         .res_spec = agp_i915_res_spec,
  442         .check_active = agp_i915_check_active,
  443         .set_desc = agp_i810_set_desc,
  444         .dump_regs = agp_i915_dump_regs,
  445         .get_stolen_size = agp_i915_get_stolen_size,
  446         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  447         .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
  448         .install_gatt = agp_i830_install_gatt,
  449         .deinstall_gatt = agp_i830_deinstall_gatt,
  450         .write_gtt = agp_i915_write_gtt,
  451         .install_gtt_pte = agp_i915_install_gtt_pte,
  452         .read_gtt_pte = agp_i915_read_gtt_pte,
  453         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  454         .set_aperture = agp_i915_set_aperture,
  455         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  456         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  457         .chipset_flush = agp_i915_chipset_flush,
  458 };
  459 
  460 static const struct agp_i810_driver agp_i810_g4x_driver = {
  461         .chiptype = CHIP_G4X,
  462         .gen = 5,
  463         .busdma_addr_mask_sz = 36,
  464         .res_spec = agp_i965_res_spec,
  465         .check_active = agp_i915_check_active,
  466         .set_desc = agp_i810_set_desc,
  467         .dump_regs = agp_i965_dump_regs,
  468         .get_stolen_size = agp_i915_get_stolen_size,
  469         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  470         .get_gtt_total_entries = agp_gen5_get_gtt_total_entries,
  471         .install_gatt = agp_g4x_install_gatt,
  472         .deinstall_gatt = agp_i830_deinstall_gatt,
  473         .write_gtt = agp_g4x_write_gtt,
  474         .install_gtt_pte = agp_g4x_install_gtt_pte,
  475         .read_gtt_pte = agp_g4x_read_gtt_pte,
  476         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  477         .set_aperture = agp_i915_set_aperture,
  478         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  479         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  480         .chipset_flush = agp_i915_chipset_flush,
  481 };
  482 
  483 static const struct agp_i810_driver agp_i810_sb_driver = {
  484         .chiptype = CHIP_SB,
  485         .gen = 6,
  486         .busdma_addr_mask_sz = 40,
  487         .res_spec = agp_g4x_res_spec,
  488         .check_active = agp_sb_check_active,
  489         .set_desc = agp_i810_set_desc,
  490         .dump_regs = agp_sb_dump_regs,
  491         .get_stolen_size = agp_sb_get_stolen_size,
  492         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  493         .get_gtt_total_entries = agp_sb_get_gtt_total_entries,
  494         .install_gatt = agp_g4x_install_gatt,
  495         .deinstall_gatt = agp_i830_deinstall_gatt,
  496         .write_gtt = agp_sb_write_gtt,
  497         .install_gtt_pte = agp_sb_install_gtt_pte,
  498         .read_gtt_pte = agp_g4x_read_gtt_pte,
  499         .read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr,
  500         .set_aperture = agp_i915_set_aperture,
  501         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  502         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  503         .chipset_flush = agp_i810_chipset_flush,
  504 };
  505 
  506 static const struct agp_i810_driver agp_i810_hsw_driver = {
  507         .chiptype = CHIP_SB,
  508         .gen = 7,
  509         .busdma_addr_mask_sz = 40,
  510         .res_spec = agp_g4x_res_spec,
  511         .check_active = agp_sb_check_active,
  512         .set_desc = agp_i810_set_desc,
  513         .dump_regs = agp_sb_dump_regs,
  514         .get_stolen_size = agp_sb_get_stolen_size,
  515         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  516         .get_gtt_total_entries = agp_sb_get_gtt_total_entries,
  517         .install_gatt = agp_g4x_install_gatt,
  518         .deinstall_gatt = agp_i830_deinstall_gatt,
  519         .write_gtt = agp_sb_write_gtt,
  520         .install_gtt_pte = agp_sb_install_gtt_pte,
  521         .read_gtt_pte = agp_g4x_read_gtt_pte,
  522         .read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr,
  523         .set_aperture = agp_i915_set_aperture,
  524         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  525         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  526         .chipset_flush = agp_i810_chipset_flush,
  527 };
  528 
  529 /* For adding new devices, devid is the id of the graphics controller
  530  * (pci:0:2:0, for example).  The placeholder (usually at pci:0:2:1) for the
  531  * second head should never be added.  The bridge_offset is the offset to
  532  * subtract from devid to get the id of the hostb that the device is on.
  533  */
  534 static const struct agp_i810_match {
  535         int devid;
  536         char *name;
  537         const struct agp_i810_driver *driver;
  538 } agp_i810_matches[] = {
  539         {
  540                 .devid = 0x71218086,
  541                 .name = "Intel 82810 (i810 GMCH) SVGA controller",
  542                 .driver = &agp_i810_i810_driver
  543         },
  544         {
  545                 .devid = 0x71238086,
  546                 .name = "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller",
  547                 .driver = &agp_i810_i810_driver
  548         },
  549         {
  550                 .devid = 0x71258086,
  551                 .name = "Intel 82810E (i810E GMCH) SVGA controller",
  552                 .driver = &agp_i810_i810_driver
  553         },
  554         {
  555                 .devid = 0x11328086,
  556                 .name = "Intel 82815 (i815 GMCH) SVGA controller",
  557                 .driver = &agp_i810_i815_driver
  558         },
  559         {
  560                 .devid = 0x35778086,
  561                 .name = "Intel 82830M (830M GMCH) SVGA controller",
  562                 .driver = &agp_i810_i830_driver
  563         },
  564         {
  565                 .devid = 0x25628086,
  566                 .name = "Intel 82845M (845M GMCH) SVGA controller",
  567                 .driver = &agp_i810_i830_driver
  568         },
  569         {
  570                 .devid = 0x35828086,
  571                 .name = "Intel 82852/855GM SVGA controller",
  572                 .driver = &agp_i810_i855_driver
  573         },
  574         {
  575                 .devid = 0x25728086,
  576                 .name = "Intel 82865G (865G GMCH) SVGA controller",
  577                 .driver = &agp_i810_i865_driver
  578         },
  579         {
  580                 .devid = 0x25828086,
  581                 .name = "Intel 82915G (915G GMCH) SVGA controller",
  582                 .driver = &agp_i810_i915_driver
  583         },
  584         {
  585                 .devid = 0x258A8086,
  586                 .name = "Intel E7221 SVGA controller",
  587                 .driver = &agp_i810_i915_driver
  588         },
  589         {
  590                 .devid = 0x25928086,
  591                 .name = "Intel 82915GM (915GM GMCH) SVGA controller",
  592                 .driver = &agp_i810_i915_driver
  593         },
  594         {
  595                 .devid = 0x27728086,
  596                 .name = "Intel 82945G (945G GMCH) SVGA controller",
  597                 .driver = &agp_i810_i915_driver
  598         },
  599         {
  600                 .devid = 0x27A28086,
  601                 .name = "Intel 82945GM (945GM GMCH) SVGA controller",
  602                 .driver = &agp_i810_i915_driver
  603         },
  604         {
  605                 .devid = 0x27AE8086,
  606                 .name = "Intel 945GME SVGA controller",
  607                 .driver = &agp_i810_i915_driver
  608         },
  609         {
  610                 .devid = 0x29728086,
  611                 .name = "Intel 946GZ SVGA controller",
  612                 .driver = &agp_i810_g965_driver
  613         },
  614         {
  615                 .devid = 0x29828086,
  616                 .name = "Intel G965 SVGA controller",
  617                 .driver = &agp_i810_g965_driver
  618         },
  619         {
  620                 .devid = 0x29928086,
  621                 .name = "Intel Q965 SVGA controller",
  622                 .driver = &agp_i810_g965_driver
  623         },
  624         {
  625                 .devid = 0x29A28086,
  626                 .name = "Intel G965 SVGA controller",
  627                 .driver = &agp_i810_g965_driver
  628         },
  629         {
  630                 .devid = 0x29B28086,
  631                 .name = "Intel Q35 SVGA controller",
  632                 .driver = &agp_i810_g33_driver
  633         },
  634         {
  635                 .devid = 0x29C28086,
  636                 .name = "Intel G33 SVGA controller",
  637                 .driver = &agp_i810_g33_driver
  638         },
  639         {
  640                 .devid = 0x29D28086,
  641                 .name = "Intel Q33 SVGA controller",
  642                 .driver = &agp_i810_g33_driver
  643         },
  644         {
  645                 .devid = 0xA0018086,
  646                 .name = "Intel Pineview SVGA controller",
  647                 .driver = &agp_i810_igd_driver
  648         },
  649         {
  650                 .devid = 0xA0118086,
  651                 .name = "Intel Pineview (M) SVGA controller",
  652                 .driver = &agp_i810_igd_driver
  653         },
  654         {
  655                 .devid = 0x2A028086,
  656                 .name = "Intel GM965 SVGA controller",
  657                 .driver = &agp_i810_g965_driver
  658         },
  659         {
  660                 .devid = 0x2A128086,
  661                 .name = "Intel GME965 SVGA controller",
  662                 .driver = &agp_i810_g965_driver
  663         },
  664         {
  665                 .devid = 0x2A428086,
  666                 .name = "Intel GM45 SVGA controller",
  667                 .driver = &agp_i810_g4x_driver
  668         },
  669         {
  670                 .devid = 0x2E028086,
  671                 .name = "Intel Eaglelake SVGA controller",
  672                 .driver = &agp_i810_g4x_driver
  673         },
  674         {
  675                 .devid = 0x2E128086,
  676                 .name = "Intel Q45 SVGA controller",
  677                 .driver = &agp_i810_g4x_driver
  678         },
  679         {
  680                 .devid = 0x2E228086,
  681                 .name = "Intel G45 SVGA controller",
  682                 .driver = &agp_i810_g4x_driver
  683         },
  684         {
  685                 .devid = 0x2E328086,
  686                 .name = "Intel G41 SVGA controller",
  687                 .driver = &agp_i810_g4x_driver
  688         },
  689         {
  690                 .devid = 0x00428086,
  691                 .name = "Intel Ironlake (D) SVGA controller",
  692                 .driver = &agp_i810_g4x_driver
  693         },
  694         {
  695                 .devid = 0x00468086,
  696                 .name = "Intel Ironlake (M) SVGA controller",
  697                 .driver = &agp_i810_g4x_driver
  698         },
  699         {
  700                 .devid = 0x01028086,
  701                 .name = "SandyBridge desktop GT1 IG",
  702                 .driver = &agp_i810_sb_driver
  703         },
  704         {
  705                 .devid = 0x01128086,
  706                 .name = "SandyBridge desktop GT2 IG",
  707                 .driver = &agp_i810_sb_driver
  708         },
  709         {
  710                 .devid = 0x01228086,
  711                 .name = "SandyBridge desktop GT2+ IG",
  712                 .driver = &agp_i810_sb_driver
  713         },
  714         {
  715                 .devid = 0x01068086,
  716                 .name = "SandyBridge mobile GT1 IG",
  717                 .driver = &agp_i810_sb_driver
  718         },
  719         {
  720                 .devid = 0x01168086,
  721                 .name = "SandyBridge mobile GT2 IG",
  722                 .driver = &agp_i810_sb_driver
  723         },
  724         {
  725                 .devid = 0x01268086,
  726                 .name = "SandyBridge mobile GT2+ IG",
  727                 .driver = &agp_i810_sb_driver
  728         },
  729         {
  730                 .devid = 0x010a8086,
  731                 .name = "SandyBridge server IG",
  732                 .driver = &agp_i810_sb_driver
  733         },
  734         {
  735                 .devid = 0x01528086,
  736                 .name = "IvyBridge desktop GT1 IG",
  737                 .driver = &agp_i810_sb_driver
  738         },
  739         {
  740                 .devid = 0x01628086,
  741                 .name = "IvyBridge desktop GT2 IG",
  742                 .driver = &agp_i810_sb_driver
  743         },
  744         {
  745                 .devid = 0x01568086,
  746                 .name = "IvyBridge mobile GT1 IG",
  747                 .driver = &agp_i810_sb_driver
  748         },
  749         {
  750                 .devid = 0x01668086,
  751                 .name = "IvyBridge mobile GT2 IG",
  752                 .driver = &agp_i810_sb_driver
  753         },
  754         {
  755                 .devid = 0x015a8086,
  756                 .name = "IvyBridge server GT1 IG",
  757                 .driver = &agp_i810_sb_driver
  758         },
  759         {
  760                 .devid = 0x016a8086,
  761                 .name = "IvyBridge server GT2 IG",
  762                 .driver = &agp_i810_sb_driver
  763         },
  764         {
  765                 .devid = 0x04028086,
  766                 .name = "Haswell desktop GT1",
  767                 .driver = &agp_i810_hsw_driver
  768         },
  769         {
  770                 .devid = 0x04128086,
  771                 .name = "Haswell desktop GT2",
  772                 .driver = &agp_i810_hsw_driver
  773         },
  774         {
  775                 .devid = 0x040a8086,
  776                 .name = "Haswell server GT1",
  777                 .driver = &agp_i810_hsw_driver
  778         },
  779         {
  780                 .devid = 0x041a8086,
  781                 .name = "Haswell server GT2",
  782                 .driver = &agp_i810_hsw_driver
  783         },
  784         {
  785                 .devid = 0x04068086,
  786                 .name = "Haswell mobile GT1",
  787                 .driver = &agp_i810_hsw_driver
  788         },
  789         {
  790                 .devid = 0x04168086,
  791                 .name = "Haswell mobile GT2",
  792                 .driver = &agp_i810_hsw_driver
  793         },
  794         {
  795                 .devid = 0x0c168086,
  796                 .name = "Haswell SDV",
  797                 .driver = &agp_i810_hsw_driver
  798         },
  799         {
  800                 .devid = 0,
  801         }
  802 };
  803 
  804 static const struct agp_i810_match*
  805 agp_i810_match(device_t dev)
  806 {
  807         int i, devid;
  808 
  809         if (pci_get_class(dev) != PCIC_DISPLAY
  810             || (pci_get_subclass(dev) != PCIS_DISPLAY_VGA &&
  811             pci_get_subclass(dev) != PCIS_DISPLAY_OTHER))
  812                 return (NULL);
  813 
  814         devid = pci_get_devid(dev);
  815         for (i = 0; agp_i810_matches[i].devid != 0; i++) {
  816                 if (agp_i810_matches[i].devid == devid)
  817                         break;
  818         }
  819         if (agp_i810_matches[i].devid == 0)
  820                 return (NULL);
  821         else
  822                 return (&agp_i810_matches[i]);
  823 }
  824 
  825 /*
  826  * Find bridge device.
  827  */
  828 static device_t
  829 agp_i810_find_bridge(device_t dev)
  830 {
  831 
  832         return (pci_find_dbsf(0, 0, 0, 0));
  833 }
  834 
  835 static void
  836 agp_i810_identify(driver_t *driver, device_t parent)
  837 {
  838 
  839         if (device_find_child(parent, "agp", -1) == NULL &&
  840             agp_i810_match(parent))
  841                 device_add_child(parent, "agp", -1);
  842 }
  843 
  844 static int
  845 agp_i810_check_active(device_t bridge_dev)
  846 {
  847         u_int8_t smram;
  848 
  849         smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1);
  850         if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED)
  851                 return (ENXIO);
  852         return (0);
  853 }
  854 
  855 static int
  856 agp_i830_check_active(device_t bridge_dev)
  857 {
  858         int gcc1;
  859 
  860         gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1);
  861         if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED)
  862                 return (ENXIO);
  863         return (0);
  864 }
  865 
  866 static int
  867 agp_i915_check_active(device_t bridge_dev)
  868 {
  869         int deven;
  870 
  871         deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
  872         if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
  873                 return (ENXIO);
  874         return (0);
  875 }
  876 
  877 static int
  878 agp_sb_check_active(device_t bridge_dev)
  879 {
  880         int deven;
  881 
  882         deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
  883         if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED)
  884                 return (ENXIO);
  885         return (0);
  886 }
  887 
  888 static void
  889 agp_82852_set_desc(device_t dev, const struct agp_i810_match *match)
  890 {
  891 
  892         switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
  893         case AGP_I855_GME:
  894                 device_set_desc(dev,
  895                     "Intel 82855GME (855GME GMCH) SVGA controller");
  896                 break;
  897         case AGP_I855_GM:
  898                 device_set_desc(dev,
  899                     "Intel 82855GM (855GM GMCH) SVGA controller");
  900                 break;
  901         case AGP_I852_GME:
  902                 device_set_desc(dev,
  903                     "Intel 82852GME (852GME GMCH) SVGA controller");
  904                 break;
  905         case AGP_I852_GM:
  906                 device_set_desc(dev,
  907                     "Intel 82852GM (852GM GMCH) SVGA controller");
  908                 break;
  909         default:
  910                 device_set_desc(dev,
  911                     "Intel 8285xM (85xGM GMCH) SVGA controller");
  912                 break;
  913         }
  914 }
  915 
  916 static void
  917 agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
  918 {
  919 
  920         device_set_desc(dev, match->name);
  921 }
  922 
  923 static int
  924 agp_i810_probe(device_t dev)
  925 {
  926         device_t bdev;
  927         const struct agp_i810_match *match;
  928         int err;
  929 
  930         if (resource_disabled("agp", device_get_unit(dev)))
  931                 return (ENXIO);
  932         match = agp_i810_match(dev);
  933         if (match == NULL)
  934                 return (ENXIO);
  935 
  936         bdev = agp_i810_find_bridge(dev);
  937         if (bdev == NULL) {
  938                 if (bootverbose)
  939                         printf("I810: can't find bridge device\n");
  940                 return (ENXIO);
  941         }
  942 
  943         /*
  944          * checking whether internal graphics device has been activated.
  945          */
  946         err = match->driver->check_active(bdev);
  947         if (err != 0) {
  948                 if (bootverbose)
  949                         printf("i810: disabled, not probing\n");
  950                 return (err);
  951         }
  952 
  953         match->driver->set_desc(dev, match);
  954         return (BUS_PROBE_DEFAULT);
  955 }
  956 
  957 static void
  958 agp_i810_dump_regs(device_t dev)
  959 {
  960         struct agp_i810_softc *sc = device_get_softc(dev);
  961 
  962         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  963             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  964         device_printf(dev, "AGP_I810_MISCC: 0x%04x\n",
  965             pci_read_config(sc->bdev, AGP_I810_MISCC, 2));
  966 }
  967 
  968 static void
  969 agp_i830_dump_regs(device_t dev)
  970 {
  971         struct agp_i810_softc *sc = device_get_softc(dev);
  972 
  973         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  974             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  975         device_printf(dev, "AGP_I830_GCC1: 0x%02x\n",
  976             pci_read_config(sc->bdev, AGP_I830_GCC1, 1));
  977 }
  978 
  979 static void
  980 agp_i855_dump_regs(device_t dev)
  981 {
  982         struct agp_i810_softc *sc = device_get_softc(dev);
  983 
  984         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  985             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  986         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  987             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  988 }
  989 
  990 static void
  991 agp_i915_dump_regs(device_t dev)
  992 {
  993         struct agp_i810_softc *sc = device_get_softc(dev);
  994 
  995         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  996             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  997         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  998             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  999         device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
 1000             pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
 1001 }
 1002 
 1003 static void
 1004 agp_i965_dump_regs(device_t dev)
 1005 {
 1006         struct agp_i810_softc *sc = device_get_softc(dev);
 1007 
 1008         device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
 1009             bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
 1010         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
 1011             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
 1012         device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
 1013             pci_read_config(sc->bdev, AGP_I965_MSAC, 1));
 1014 }
 1015 
 1016 static void
 1017 agp_sb_dump_regs(device_t dev)
 1018 {
 1019         struct agp_i810_softc *sc = device_get_softc(dev);
 1020 
 1021         device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n",
 1022             bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE));
 1023         device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n",
 1024             pci_read_config(sc->bdev, AGP_SNB_GCC1, 2));
 1025 }
 1026 
 1027 static int
 1028 agp_i810_get_stolen_size(device_t dev)
 1029 {
 1030         struct agp_i810_softc *sc;
 1031 
 1032         sc = device_get_softc(dev);
 1033         sc->stolen = 0;
 1034         sc->stolen_size = 0;
 1035         return (0);
 1036 }
 1037 
 1038 static int
 1039 agp_i830_get_stolen_size(device_t dev)
 1040 {
 1041         struct agp_i810_softc *sc;
 1042         unsigned int gcc1;
 1043 
 1044         sc = device_get_softc(dev);
 1045 
 1046         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
 1047         switch (gcc1 & AGP_I830_GCC1_GMS) {
 1048         case AGP_I830_GCC1_GMS_STOLEN_512:
 1049                 sc->stolen = (512 - 132) * 1024 / 4096;
 1050                 sc->stolen_size = 512 * 1024;
 1051                 break;
 1052         case AGP_I830_GCC1_GMS_STOLEN_1024: 
 1053                 sc->stolen = (1024 - 132) * 1024 / 4096;
 1054                 sc->stolen_size = 1024 * 1024;
 1055                 break;
 1056         case AGP_I830_GCC1_GMS_STOLEN_8192: 
 1057                 sc->stolen = (8192 - 132) * 1024 / 4096;
 1058                 sc->stolen_size = 8192 * 1024;
 1059                 break;
 1060         default:
 1061                 sc->stolen = 0;
 1062                 device_printf(dev,
 1063                     "unknown memory configuration, disabling (GCC1 %x)\n",
 1064                     gcc1);
 1065                 return (EINVAL);
 1066         }
 1067         return (0);
 1068 }
 1069 
 1070 static int
 1071 agp_i915_get_stolen_size(device_t dev)
 1072 {
 1073         struct agp_i810_softc *sc;
 1074         unsigned int gcc1, stolen, gtt_size;
 1075 
 1076         sc = device_get_softc(dev);
 1077 
 1078         /*
 1079          * Stolen memory is set up at the beginning of the aperture by
 1080          * the BIOS, consisting of the GATT followed by 4kb for the
 1081          * BIOS display.
 1082          */
 1083         switch (sc->match->driver->chiptype) {
 1084         case CHIP_I855:
 1085                 gtt_size = 128;
 1086                 break;
 1087         case CHIP_I915:
 1088                 gtt_size = 256;
 1089                 break;
 1090         case CHIP_I965:
 1091                 switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
 1092                         AGP_I810_PGTBL_SIZE_MASK) {
 1093                 case AGP_I810_PGTBL_SIZE_128KB:
 1094                         gtt_size = 128;
 1095                         break;
 1096                 case AGP_I810_PGTBL_SIZE_256KB:
 1097                         gtt_size = 256;
 1098                         break;
 1099                 case AGP_I810_PGTBL_SIZE_512KB:
 1100                         gtt_size = 512;
 1101                         break;
 1102                 case AGP_I965_PGTBL_SIZE_1MB:
 1103                         gtt_size = 1024;
 1104                         break;
 1105                 case AGP_I965_PGTBL_SIZE_2MB:
 1106                         gtt_size = 2048;
 1107                         break;
 1108                 case AGP_I965_PGTBL_SIZE_1_5MB:
 1109                         gtt_size = 1024 + 512;
 1110                         break;
 1111                 default:
 1112                         device_printf(dev, "Bad PGTBL size\n");
 1113                         return (EINVAL);
 1114                 }
 1115                 break;
 1116         case CHIP_G33:
 1117                 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
 1118                 switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
 1119                 case AGP_G33_MGGC_GGMS_SIZE_1M:
 1120                         gtt_size = 1024;
 1121                         break;
 1122                 case AGP_G33_MGGC_GGMS_SIZE_2M:
 1123                         gtt_size = 2048;
 1124                         break;
 1125                 default:
 1126                         device_printf(dev, "Bad PGTBL size\n");
 1127                         return (EINVAL);
 1128                 }
 1129                 break;
 1130         case CHIP_IGD:
 1131         case CHIP_G4X:
 1132                 gtt_size = 0;
 1133                 break;
 1134         default:
 1135                 device_printf(dev, "Bad chiptype\n");
 1136                 return (EINVAL);
 1137         }
 1138 
 1139         /* GCC1 is called MGGC on i915+ */
 1140         gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
 1141         switch (gcc1 & AGP_I855_GCC1_GMS) {
 1142         case AGP_I855_GCC1_GMS_STOLEN_1M:
 1143                 stolen = 1024;
 1144                 break;
 1145         case AGP_I855_GCC1_GMS_STOLEN_4M:
 1146                 stolen = 4 * 1024;
 1147                 break;
 1148         case AGP_I855_GCC1_GMS_STOLEN_8M:
 1149                 stolen = 8 * 1024;
 1150                 break;
 1151         case AGP_I855_GCC1_GMS_STOLEN_16M:
 1152                 stolen = 16 * 1024;
 1153                 break;
 1154         case AGP_I855_GCC1_GMS_STOLEN_32M:
 1155                 stolen = 32 * 1024;
 1156                 break;
 1157         case AGP_I915_GCC1_GMS_STOLEN_48M:
 1158                 stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
 1159                 break;
 1160         case AGP_I915_GCC1_GMS_STOLEN_64M:
 1161                 stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
 1162                 break;
 1163         case AGP_G33_GCC1_GMS_STOLEN_128M:
 1164                 stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
 1165                 break;
 1166         case AGP_G33_GCC1_GMS_STOLEN_256M:
 1167                 stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
 1168                 break;
 1169         case AGP_G4X_GCC1_GMS_STOLEN_96M:
 1170                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1171                     sc->match->driver->chiptype == CHIP_G4X)
 1172                         stolen = 96 * 1024;
 1173                 else
 1174                         stolen = 0;
 1175                 break;
 1176         case AGP_G4X_GCC1_GMS_STOLEN_160M:
 1177                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1178                     sc->match->driver->chiptype == CHIP_G4X)
 1179                         stolen = 160 * 1024;
 1180                 else
 1181                         stolen = 0;
 1182                 break;
 1183         case AGP_G4X_GCC1_GMS_STOLEN_224M:
 1184                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1185                     sc->match->driver->chiptype == CHIP_G4X)
 1186                         stolen = 224 * 1024;
 1187                 else
 1188                         stolen = 0;
 1189                 break;
 1190         case AGP_G4X_GCC1_GMS_STOLEN_352M:
 1191                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1192                     sc->match->driver->chiptype == CHIP_G4X)
 1193                         stolen = 352 * 1024;
 1194                 else
 1195                         stolen = 0;
 1196                 break;
 1197         default:
 1198                 device_printf(dev,
 1199                     "unknown memory configuration, disabling (GCC1 %x)\n",
 1200                     gcc1);
 1201                 return (EINVAL);
 1202         }
 1203 
 1204         gtt_size += 4;
 1205         sc->stolen_size = stolen * 1024;
 1206         sc->stolen = (stolen - gtt_size) * 1024 / 4096;
 1207 
 1208         return (0);
 1209 }
 1210 
 1211 static int
 1212 agp_sb_get_stolen_size(device_t dev)
 1213 {
 1214         struct agp_i810_softc *sc;
 1215         uint16_t gmch_ctl;
 1216 
 1217         sc = device_get_softc(dev);
 1218         gmch_ctl = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
 1219         switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) {
 1220         case AGP_SNB_GMCH_GMS_STOLEN_32M:
 1221                 sc->stolen_size = 32 * 1024 * 1024;
 1222                 break;
 1223         case AGP_SNB_GMCH_GMS_STOLEN_64M:
 1224                 sc->stolen_size = 64 * 1024 * 1024;
 1225                 break;
 1226         case AGP_SNB_GMCH_GMS_STOLEN_96M:
 1227                 sc->stolen_size = 96 * 1024 * 1024;
 1228                 break;
 1229         case AGP_SNB_GMCH_GMS_STOLEN_128M:
 1230                 sc->stolen_size = 128 * 1024 * 1024;
 1231                 break;
 1232         case AGP_SNB_GMCH_GMS_STOLEN_160M:
 1233                 sc->stolen_size = 160 * 1024 * 1024;
 1234                 break;
 1235         case AGP_SNB_GMCH_GMS_STOLEN_192M:
 1236                 sc->stolen_size = 192 * 1024 * 1024;
 1237                 break;
 1238         case AGP_SNB_GMCH_GMS_STOLEN_224M:
 1239                 sc->stolen_size = 224 * 1024 * 1024;
 1240                 break;
 1241         case AGP_SNB_GMCH_GMS_STOLEN_256M:
 1242                 sc->stolen_size = 256 * 1024 * 1024;
 1243                 break;
 1244         case AGP_SNB_GMCH_GMS_STOLEN_288M:
 1245                 sc->stolen_size = 288 * 1024 * 1024;
 1246                 break;
 1247         case AGP_SNB_GMCH_GMS_STOLEN_320M:
 1248                 sc->stolen_size = 320 * 1024 * 1024;
 1249                 break;
 1250         case AGP_SNB_GMCH_GMS_STOLEN_352M:
 1251                 sc->stolen_size = 352 * 1024 * 1024;
 1252                 break;
 1253         case AGP_SNB_GMCH_GMS_STOLEN_384M:
 1254                 sc->stolen_size = 384 * 1024 * 1024;
 1255                 break;
 1256         case AGP_SNB_GMCH_GMS_STOLEN_416M:
 1257                 sc->stolen_size = 416 * 1024 * 1024;
 1258                 break;
 1259         case AGP_SNB_GMCH_GMS_STOLEN_448M:
 1260                 sc->stolen_size = 448 * 1024 * 1024;
 1261                 break;
 1262         case AGP_SNB_GMCH_GMS_STOLEN_480M:
 1263                 sc->stolen_size = 480 * 1024 * 1024;
 1264                 break;
 1265         case AGP_SNB_GMCH_GMS_STOLEN_512M:
 1266                 sc->stolen_size = 512 * 1024 * 1024;
 1267                 break;
 1268         }
 1269         sc->stolen = (sc->stolen_size - 4) / 4096;
 1270         return (0);
 1271 }
 1272 
 1273 static int
 1274 agp_i810_get_gtt_mappable_entries(device_t dev)
 1275 {
 1276         struct agp_i810_softc *sc;
 1277         uint32_t ap;
 1278         uint16_t miscc;
 1279 
 1280         sc = device_get_softc(dev);
 1281         miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
 1282         if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32)
 1283                 ap = 32;
 1284         else
 1285                 ap = 64;
 1286         sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
 1287         return (0);
 1288 }
 1289 
 1290 static int
 1291 agp_i830_get_gtt_mappable_entries(device_t dev)
 1292 {
 1293         struct agp_i810_softc *sc;
 1294         uint32_t ap;
 1295         uint16_t gmch_ctl;
 1296 
 1297         sc = device_get_softc(dev);
 1298         gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1299         if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
 1300                 ap = 64;
 1301         else
 1302                 ap = 128;
 1303         sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
 1304         return (0);
 1305 }
 1306 
 1307 static int
 1308 agp_i915_get_gtt_mappable_entries(device_t dev)
 1309 {
 1310         struct agp_i810_softc *sc;
 1311         uint32_t ap;
 1312 
 1313         sc = device_get_softc(dev);
 1314         ap = AGP_GET_APERTURE(dev);
 1315         sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
 1316         return (0);
 1317 }
 1318 
 1319 static int
 1320 agp_i810_get_gtt_total_entries(device_t dev)
 1321 {
 1322         struct agp_i810_softc *sc;
 1323 
 1324         sc = device_get_softc(dev);
 1325         sc->gtt_total_entries = sc->gtt_mappable_entries;
 1326         return (0);
 1327 }
 1328 
 1329 static int
 1330 agp_i965_get_gtt_total_entries(device_t dev)
 1331 {
 1332         struct agp_i810_softc *sc;
 1333         uint32_t pgetbl_ctl;
 1334         int error;
 1335 
 1336         sc = device_get_softc(dev);
 1337         error = 0;
 1338         pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1339         switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
 1340         case AGP_I810_PGTBL_SIZE_128KB:
 1341                 sc->gtt_total_entries = 128 * 1024 / 4;
 1342                 break;
 1343         case AGP_I810_PGTBL_SIZE_256KB:
 1344                 sc->gtt_total_entries = 256 * 1024 / 4;
 1345                 break;
 1346         case AGP_I810_PGTBL_SIZE_512KB:
 1347                 sc->gtt_total_entries = 512 * 1024 / 4;
 1348                 break;
 1349         /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
 1350         case AGP_I810_PGTBL_SIZE_1MB:
 1351                 sc->gtt_total_entries = 1024 * 1024 / 4;
 1352                 break;
 1353         case AGP_I810_PGTBL_SIZE_2MB:
 1354                 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
 1355                 break;
 1356         case AGP_I810_PGTBL_SIZE_1_5MB:
 1357                 sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
 1358                 break;
 1359         default:
 1360                 device_printf(dev, "Unknown page table size\n");
 1361                 error = ENXIO;
 1362         }
 1363         return (error);
 1364 }
 1365 
 1366 static void
 1367 agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
 1368 {
 1369         struct agp_i810_softc *sc;
 1370         uint32_t pgetbl_ctl, pgetbl_ctl2;
 1371 
 1372         sc = device_get_softc(dev);
 1373 
 1374         /* Disable per-process page table. */
 1375         pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
 1376         pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
 1377         bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
 1378 
 1379         /* Write the new ggtt size. */
 1380         pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1381         pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
 1382         pgetbl_ctl |= sz;
 1383         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
 1384 }
 1385 
 1386 static int
 1387 agp_gen5_get_gtt_total_entries(device_t dev)
 1388 {
 1389         struct agp_i810_softc *sc;
 1390         uint16_t gcc1;
 1391 
 1392         sc = device_get_softc(dev);
 1393 
 1394         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1395         switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
 1396         case AGP_G4x_GCC1_SIZE_1M:
 1397         case AGP_G4x_GCC1_SIZE_VT_1M:
 1398                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
 1399                 break;
 1400         case AGP_G4x_GCC1_SIZE_VT_1_5M:
 1401                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
 1402                 break;
 1403         case AGP_G4x_GCC1_SIZE_2M:
 1404         case AGP_G4x_GCC1_SIZE_VT_2M:
 1405                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
 1406                 break;
 1407         default:
 1408                 device_printf(dev, "Unknown page table size\n");
 1409                 return (ENXIO);
 1410         }
 1411 
 1412         return (agp_i965_get_gtt_total_entries(dev));
 1413 }
 1414 
 1415 static int
 1416 agp_sb_get_gtt_total_entries(device_t dev)
 1417 {
 1418         struct agp_i810_softc *sc;
 1419         uint16_t gcc1;
 1420 
 1421         sc = device_get_softc(dev);
 1422 
 1423         gcc1 = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
 1424         switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) {
 1425         default:
 1426         case AGP_SNB_GTT_SIZE_0M:
 1427                 printf("Bad GTT size mask: 0x%04x\n", gcc1);
 1428                 return (ENXIO);
 1429         case AGP_SNB_GTT_SIZE_1M:
 1430                 sc->gtt_total_entries = 1024 * 1024 / 4;
 1431                 break;
 1432         case AGP_SNB_GTT_SIZE_2M:
 1433                 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
 1434                 break;
 1435         }
 1436         return (0);
 1437 }
 1438 
 1439 static int
 1440 agp_i810_install_gatt(device_t dev)
 1441 {
 1442         struct agp_i810_softc *sc;
 1443 
 1444         sc = device_get_softc(dev);
 1445 
 1446         /* Some i810s have on-chip memory called dcache. */
 1447         if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
 1448             != 0)
 1449                 sc->dcache_size = 4 * 1024 * 1024;
 1450         else
 1451                 sc->dcache_size = 0;
 1452 
 1453         /* According to the specs the gatt on the i810 must be 64k. */
 1454         sc->gatt->ag_virtual = (void *)kmem_alloc_contig(kernel_arena,
 1455             64 * 1024, M_NOWAIT | M_ZERO, 0, ~0, PAGE_SIZE,
 1456             0, VM_MEMATTR_WRITE_COMBINING);
 1457         if (sc->gatt->ag_virtual == NULL) {
 1458                 if (bootverbose)
 1459                         device_printf(dev, "contiguous allocation failed\n");
 1460                 return (ENOMEM);
 1461         }
 1462 
 1463         sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual);
 1464         /* Install the GATT. */
 1465         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
 1466             sc->gatt->ag_physical | 1);
 1467         return (0);
 1468 }
 1469 
 1470 static void
 1471 agp_i830_install_gatt_init(struct agp_i810_softc *sc)
 1472 {
 1473         uint32_t pgtblctl;
 1474 
 1475         /*
 1476          * The i830 automatically initializes the 128k gatt on boot.
 1477          * GATT address is already in there, make sure it's enabled.
 1478          */
 1479         pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1480         pgtblctl |= 1;
 1481         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
 1482         
 1483         sc->gatt->ag_physical = pgtblctl & ~1;
 1484 }
 1485 
 1486 static int
 1487 agp_i830_install_gatt(device_t dev)
 1488 {
 1489         struct agp_i810_softc *sc;
 1490 
 1491         sc = device_get_softc(dev);
 1492         agp_i830_install_gatt_init(sc);
 1493         return (0);
 1494 }
 1495 
 1496 static int
 1497 agp_gen4_install_gatt(device_t dev, const vm_size_t gtt_offset)
 1498 {
 1499         struct agp_i810_softc *sc;
 1500 
 1501         sc = device_get_softc(dev);
 1502         pmap_change_attr((vm_offset_t)rman_get_virtual(sc->sc_res[0]) +
 1503             gtt_offset, rman_get_size(sc->sc_res[0]) - gtt_offset,
 1504             VM_MEMATTR_WRITE_COMBINING);
 1505         agp_i830_install_gatt_init(sc);
 1506         return (0);
 1507 }
 1508 
 1509 static int
 1510 agp_i965_install_gatt(device_t dev)
 1511 {
 1512 
 1513         return (agp_gen4_install_gatt(dev, 512 * 1024));
 1514 }
 1515 
 1516 static int
 1517 agp_g4x_install_gatt(device_t dev)
 1518 {
 1519 
 1520         return (agp_gen4_install_gatt(dev, 2 * 1024 * 1024));
 1521 }
 1522 
 1523 static int
 1524 agp_i810_attach(device_t dev)
 1525 {
 1526         struct agp_i810_softc *sc;
 1527         int error;
 1528 
 1529         sc = device_get_softc(dev);
 1530         sc->bdev = agp_i810_find_bridge(dev);
 1531         if (sc->bdev == NULL)
 1532                 return (ENOENT);
 1533 
 1534         sc->match = agp_i810_match(dev);
 1535 
 1536         agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ?
 1537             AGP_APBASE : AGP_I915_GMADR);
 1538         error = agp_generic_attach(dev);
 1539         if (error)
 1540                 return (error);
 1541 
 1542         if (ptoa((vm_paddr_t)Maxmem) >
 1543             (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
 1544                 device_printf(dev, "agp_i810 does not support physical "
 1545                     "memory above %ju.\n", (uintmax_t)(1ULL <<
 1546                     sc->match->driver->busdma_addr_mask_sz) - 1);
 1547                 return (ENOENT);
 1548         }
 1549 
 1550         if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) {
 1551                 agp_generic_detach(dev);
 1552                 return (ENODEV);
 1553         }
 1554 
 1555         sc->initial_aperture = AGP_GET_APERTURE(dev);
 1556         sc->gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK);
 1557         sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
 1558 
 1559         if ((error = sc->match->driver->get_stolen_size(dev)) != 0 ||
 1560             (error = sc->match->driver->install_gatt(dev)) != 0 ||
 1561             (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 ||
 1562             (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 ||
 1563             (error = sc->match->driver->chipset_flush_setup(dev)) != 0) {
 1564                 bus_release_resources(dev, sc->match->driver->res_spec,
 1565                     sc->sc_res);
 1566                 free(sc->gatt, M_AGP);
 1567                 agp_generic_detach(dev);
 1568                 return (error);
 1569         }
 1570 
 1571         intel_agp = dev;
 1572         device_printf(dev, "aperture size is %dM",
 1573             sc->initial_aperture / 1024 / 1024);
 1574         if (sc->stolen > 0)
 1575                 printf(", detected %dk stolen memory\n", sc->stolen * 4);
 1576         else
 1577                 printf("\n");
 1578         if (bootverbose) {
 1579                 sc->match->driver->dump_regs(dev);
 1580                 device_printf(dev, "Mappable GTT entries: %d\n",
 1581                     sc->gtt_mappable_entries);
 1582                 device_printf(dev, "Total GTT entries: %d\n",
 1583                     sc->gtt_total_entries);
 1584         }
 1585         return (0);
 1586 }
 1587 
 1588 static void
 1589 agp_i810_deinstall_gatt(device_t dev)
 1590 {
 1591         struct agp_i810_softc *sc;
 1592 
 1593         sc = device_get_softc(dev);
 1594         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0);
 1595         kmem_free(kernel_arena, (vm_offset_t)sc->gatt->ag_virtual, 64 * 1024);
 1596 }
 1597 
 1598 static void
 1599 agp_i830_deinstall_gatt(device_t dev)
 1600 {
 1601         struct agp_i810_softc *sc;
 1602         unsigned int pgtblctl;
 1603 
 1604         sc = device_get_softc(dev);
 1605         pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1606         pgtblctl &= ~1;
 1607         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
 1608 }
 1609 
 1610 static int
 1611 agp_i810_detach(device_t dev)
 1612 {
 1613         struct agp_i810_softc *sc;
 1614 
 1615         sc = device_get_softc(dev);
 1616         agp_free_cdev(dev);
 1617 
 1618         /* Clear the GATT base. */
 1619         sc->match->driver->deinstall_gatt(dev);
 1620 
 1621         sc->match->driver->chipset_flush_teardown(dev);
 1622 
 1623         /* Put the aperture back the way it started. */
 1624         AGP_SET_APERTURE(dev, sc->initial_aperture);
 1625 
 1626         free(sc->gatt, M_AGP);
 1627         bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res);
 1628         agp_free_res(dev);
 1629 
 1630         return (0);
 1631 }
 1632 
 1633 static int
 1634 agp_i810_resume(device_t dev)
 1635 {
 1636         struct agp_i810_softc *sc;
 1637         sc = device_get_softc(dev);
 1638 
 1639         AGP_SET_APERTURE(dev, sc->initial_aperture);
 1640 
 1641         /* Install the GATT. */
 1642         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
 1643         sc->gatt->ag_physical | 1);
 1644 
 1645         return (bus_generic_resume(dev));
 1646 }
 1647 
 1648 /**
 1649  * Sets the PCI resource size of the aperture on i830-class and below chipsets,
 1650  * while returning failure on later chipsets when an actual change is
 1651  * requested.
 1652  *
 1653  * This whole function is likely bogus, as the kernel would probably need to
 1654  * reconfigure the placement of the AGP aperture if a larger size is requested,
 1655  * which doesn't happen currently.
 1656  */
 1657 static int
 1658 agp_i810_set_aperture(device_t dev, u_int32_t aperture)
 1659 {
 1660         struct agp_i810_softc *sc;
 1661         u_int16_t miscc;
 1662 
 1663         sc = device_get_softc(dev);
 1664         /*
 1665          * Double check for sanity.
 1666          */
 1667         if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) {
 1668                 device_printf(dev, "bad aperture size %d\n", aperture);
 1669                 return (EINVAL);
 1670         }
 1671 
 1672         miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
 1673         miscc &= ~AGP_I810_MISCC_WINSIZE;
 1674         if (aperture == 32 * 1024 * 1024)
 1675                 miscc |= AGP_I810_MISCC_WINSIZE_32;
 1676         else
 1677                 miscc |= AGP_I810_MISCC_WINSIZE_64;
 1678         
 1679         pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2);
 1680         return (0);
 1681 }
 1682 
 1683 static int
 1684 agp_i830_set_aperture(device_t dev, u_int32_t aperture)
 1685 {
 1686         struct agp_i810_softc *sc;
 1687         u_int16_t gcc1;
 1688 
 1689         sc = device_get_softc(dev);
 1690 
 1691         if (aperture != 64 * 1024 * 1024 &&
 1692             aperture != 128 * 1024 * 1024) {
 1693                 device_printf(dev, "bad aperture size %d\n", aperture);
 1694                 return (EINVAL);
 1695         }
 1696         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1697         gcc1 &= ~AGP_I830_GCC1_GMASIZE;
 1698         if (aperture == 64 * 1024 * 1024)
 1699                 gcc1 |= AGP_I830_GCC1_GMASIZE_64;
 1700         else
 1701                 gcc1 |= AGP_I830_GCC1_GMASIZE_128;
 1702 
 1703         pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2);
 1704         return (0);
 1705 }
 1706 
 1707 static int
 1708 agp_i915_set_aperture(device_t dev, u_int32_t aperture)
 1709 {
 1710 
 1711         return (agp_generic_set_aperture(dev, aperture));
 1712 }
 1713 
 1714 static int
 1715 agp_i810_method_set_aperture(device_t dev, u_int32_t aperture)
 1716 {
 1717         struct agp_i810_softc *sc;
 1718 
 1719         sc = device_get_softc(dev);
 1720         return (sc->match->driver->set_aperture(dev, aperture));
 1721 }
 1722 
 1723 /**
 1724  * Writes a GTT entry mapping the page at the given offset from the
 1725  * beginning of the aperture to the given physical address.  Setup the
 1726  * caching mode according to flags.
 1727  *
 1728  * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset
 1729  * from corresponding BAR start. For gen 4, offset is 512KB +
 1730  * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT.
 1731  *
 1732  * Also, the bits of the physical page address above 4GB needs to be
 1733  * placed into bits 40-32 of PTE.
 1734  */
 1735 static void
 1736 agp_i810_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1737     int flags)
 1738 {
 1739         uint32_t pte;
 1740 
 1741         pte = (u_int32_t)physical | I810_PTE_VALID;
 1742         if (flags == AGP_DCACHE_MEMORY)
 1743                 pte |= I810_PTE_LOCAL;
 1744         else if (flags == AGP_USER_CACHED_MEMORY)
 1745                 pte |= I830_PTE_SYSTEM_CACHED;
 1746         agp_i810_write_gtt(dev, index, pte);
 1747 }
 1748 
 1749 static void
 1750 agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte)
 1751 {
 1752         struct agp_i810_softc *sc;
 1753 
 1754         sc = device_get_softc(dev);
 1755         bus_write_4(sc->sc_res[0], AGP_I810_GTT + index * 4, pte);
 1756         CTR2(KTR_AGP_I810, "810_pte %x %x", index, pte);
 1757 }
 1758 
 1759 static void
 1760 agp_i830_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1761     int flags)
 1762 {
 1763         uint32_t pte;
 1764 
 1765         pte = (u_int32_t)physical | I810_PTE_VALID;
 1766         if (flags == AGP_USER_CACHED_MEMORY)
 1767                 pte |= I830_PTE_SYSTEM_CACHED;
 1768         agp_i810_write_gtt(dev, index, pte);
 1769 }
 1770 
 1771 static void
 1772 agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1773     int flags)
 1774 {
 1775         uint32_t pte;
 1776 
 1777         pte = (u_int32_t)physical | I810_PTE_VALID;
 1778         if (flags == AGP_USER_CACHED_MEMORY)
 1779                 pte |= I830_PTE_SYSTEM_CACHED;
 1780         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1781         agp_i915_write_gtt(dev, index, pte);
 1782 }
 1783 
 1784 static void
 1785 agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte)
 1786 {
 1787         struct agp_i810_softc *sc;
 1788 
 1789         sc = device_get_softc(dev);
 1790         bus_write_4(sc->sc_res[1], index * 4, pte);
 1791         CTR2(KTR_AGP_I810, "915_pte %x %x", index, pte);
 1792 }
 1793 
 1794 static void
 1795 agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1796     int flags)
 1797 {
 1798         uint32_t pte;
 1799 
 1800         pte = (u_int32_t)physical | I810_PTE_VALID;
 1801         if (flags == AGP_USER_CACHED_MEMORY)
 1802                 pte |= I830_PTE_SYSTEM_CACHED;
 1803         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1804         agp_i965_write_gtt(dev, index, pte);
 1805 }
 1806 
 1807 static void
 1808 agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte)
 1809 {
 1810         struct agp_i810_softc *sc;
 1811 
 1812         sc = device_get_softc(dev);
 1813         bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte);
 1814         CTR2(KTR_AGP_I810, "965_pte %x %x", index, pte);
 1815 }
 1816 
 1817 static void
 1818 agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1819     int flags)
 1820 {
 1821         uint32_t pte;
 1822 
 1823         pte = (u_int32_t)physical | I810_PTE_VALID;
 1824         if (flags == AGP_USER_CACHED_MEMORY)
 1825                 pte |= I830_PTE_SYSTEM_CACHED;
 1826         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1827         agp_g4x_write_gtt(dev, index, pte);
 1828 }
 1829 
 1830 static void
 1831 agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte)
 1832 {
 1833         struct agp_i810_softc *sc;
 1834 
 1835         sc = device_get_softc(dev);
 1836         bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
 1837         CTR2(KTR_AGP_I810, "g4x_pte %x %x", index, pte);
 1838 }
 1839 
 1840 static void
 1841 agp_sb_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1842     int flags)
 1843 {
 1844         int type_mask, gfdt;
 1845         uint32_t pte;
 1846 
 1847         pte = (u_int32_t)physical | I810_PTE_VALID;
 1848         type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT;
 1849         gfdt = (flags & AGP_USER_CACHED_MEMORY_GFDT) != 0 ? GEN6_PTE_GFDT : 0;
 1850 
 1851         if (type_mask == AGP_USER_MEMORY)
 1852                 pte |= GEN6_PTE_UNCACHED;
 1853         else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
 1854                 pte |= GEN6_PTE_LLC_MLC | gfdt;
 1855         else
 1856                 pte |= GEN6_PTE_LLC | gfdt;
 1857 
 1858         pte |= (physical & 0x000000ff00000000ull) >> 28;
 1859         agp_sb_write_gtt(dev, index, pte);
 1860 }
 1861 
 1862 static void
 1863 agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte)
 1864 {
 1865         struct agp_i810_softc *sc;
 1866 
 1867         sc = device_get_softc(dev);
 1868         bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
 1869         CTR2(KTR_AGP_I810, "sb_pte %x %x", index, pte);
 1870 }
 1871 
 1872 static int
 1873 agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
 1874 {
 1875         struct agp_i810_softc *sc = device_get_softc(dev);
 1876         u_int index;
 1877 
 1878         if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
 1879                 device_printf(dev, "failed: offset is 0x%08jx, "
 1880                     "shift is %d, entries is %d\n", (intmax_t)offset,
 1881                     AGP_PAGE_SHIFT, sc->gatt->ag_entries);
 1882                 return (EINVAL);
 1883         }
 1884         index = offset >> AGP_PAGE_SHIFT;
 1885         if (sc->stolen != 0 && index < sc->stolen) {
 1886                 device_printf(dev, "trying to bind into stolen memory\n");
 1887                 return (EINVAL);
 1888         }
 1889         sc->match->driver->install_gtt_pte(dev, index, physical, 0);
 1890         return (0);
 1891 }
 1892 
 1893 static int
 1894 agp_i810_unbind_page(device_t dev, vm_offset_t offset)
 1895 {
 1896         struct agp_i810_softc *sc;
 1897         u_int index;
 1898 
 1899         sc = device_get_softc(dev);
 1900         if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
 1901                 return (EINVAL);
 1902         index = offset >> AGP_PAGE_SHIFT;
 1903         if (sc->stolen != 0 && index < sc->stolen) {
 1904                 device_printf(dev, "trying to unbind from stolen memory\n");
 1905                 return (EINVAL);
 1906         }
 1907         sc->match->driver->install_gtt_pte(dev, index, 0, 0);
 1908         return (0);
 1909 }
 1910 
 1911 static u_int32_t
 1912 agp_i810_read_gtt_pte(device_t dev, u_int index)
 1913 {
 1914         struct agp_i810_softc *sc;
 1915         u_int32_t pte;
 1916 
 1917         sc = device_get_softc(dev);
 1918         pte = bus_read_4(sc->sc_res[0], AGP_I810_GTT + index * 4);
 1919         return (pte);
 1920 }
 1921 
 1922 static u_int32_t
 1923 agp_i915_read_gtt_pte(device_t dev, u_int index)
 1924 {
 1925         struct agp_i810_softc *sc;
 1926         u_int32_t pte;
 1927 
 1928         sc = device_get_softc(dev);
 1929         pte = bus_read_4(sc->sc_res[1], index * 4);
 1930         return (pte);
 1931 }
 1932 
 1933 static u_int32_t
 1934 agp_i965_read_gtt_pte(device_t dev, u_int index)
 1935 {
 1936         struct agp_i810_softc *sc;
 1937         u_int32_t pte;
 1938 
 1939         sc = device_get_softc(dev);
 1940         pte = bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024));
 1941         return (pte);
 1942 }
 1943 
 1944 static u_int32_t
 1945 agp_g4x_read_gtt_pte(device_t dev, u_int index)
 1946 {
 1947         struct agp_i810_softc *sc;
 1948         u_int32_t pte;
 1949 
 1950         sc = device_get_softc(dev);
 1951         pte = bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024));
 1952         return (pte);
 1953 }
 1954 
 1955 static vm_paddr_t
 1956 agp_i810_read_gtt_pte_paddr(device_t dev, u_int index)
 1957 {
 1958         struct agp_i810_softc *sc;
 1959         u_int32_t pte;
 1960         vm_paddr_t res;
 1961 
 1962         sc = device_get_softc(dev);
 1963         pte = sc->match->driver->read_gtt_pte(dev, index);
 1964         res = pte & ~PAGE_MASK;
 1965         return (res);
 1966 }
 1967 
 1968 static vm_paddr_t
 1969 agp_i915_read_gtt_pte_paddr(device_t dev, u_int index)
 1970 {
 1971         struct agp_i810_softc *sc;
 1972         u_int32_t pte;
 1973         vm_paddr_t res;
 1974 
 1975         sc = device_get_softc(dev);
 1976         pte = sc->match->driver->read_gtt_pte(dev, index);
 1977         res = (pte & ~PAGE_MASK) | ((pte & 0xf0) << 28);
 1978         return (res);
 1979 }
 1980 
 1981 static vm_paddr_t
 1982 agp_sb_read_gtt_pte_paddr(device_t dev, u_int index)
 1983 {
 1984         struct agp_i810_softc *sc;
 1985         u_int32_t pte;
 1986         vm_paddr_t res;
 1987 
 1988         sc = device_get_softc(dev);
 1989         pte = sc->match->driver->read_gtt_pte(dev, index);
 1990         res = (pte & ~PAGE_MASK) | ((pte & 0xff0) << 28);
 1991         return (res);
 1992 }
 1993 
 1994 /*
 1995  * Writing via memory mapped registers already flushes all TLBs.
 1996  */
 1997 static void
 1998 agp_i810_flush_tlb(device_t dev)
 1999 {
 2000 }
 2001 
 2002 static int
 2003 agp_i810_enable(device_t dev, u_int32_t mode)
 2004 {
 2005 
 2006         return (0);
 2007 }
 2008 
 2009 static struct agp_memory *
 2010 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
 2011 {
 2012         struct agp_i810_softc *sc;
 2013         struct agp_memory *mem;
 2014         vm_page_t m;
 2015 
 2016         sc = device_get_softc(dev);
 2017 
 2018         if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
 2019             sc->agp.as_allocated + size > sc->agp.as_maxmem)
 2020                 return (0);
 2021 
 2022         if (type == 1) {
 2023                 /*
 2024                  * Mapping local DRAM into GATT.
 2025                  */
 2026                 if (sc->match->driver->chiptype != CHIP_I810)
 2027                         return (0);
 2028                 if (size != sc->dcache_size)
 2029                         return (0);
 2030         } else if (type == 2) {
 2031                 /*
 2032                  * Type 2 is the contiguous physical memory type, that hands
 2033                  * back a physical address.  This is used for cursors on i810.
 2034                  * Hand back as many single pages with physical as the user
 2035                  * wants, but only allow one larger allocation (ARGB cursor)
 2036                  * for simplicity.
 2037                  */
 2038                 if (size != AGP_PAGE_SIZE) {
 2039                         if (sc->argb_cursor != NULL)
 2040                                 return (0);
 2041 
 2042                         /* Allocate memory for ARGB cursor, if we can. */
 2043                         sc->argb_cursor = contigmalloc(size, M_AGP,
 2044                            0, 0, ~0, PAGE_SIZE, 0);
 2045                         if (sc->argb_cursor == NULL)
 2046                                 return (0);
 2047                 }
 2048         }
 2049 
 2050         mem = malloc(sizeof *mem, M_AGP, M_WAITOK);
 2051         mem->am_id = sc->agp.as_nextid++;
 2052         mem->am_size = size;
 2053         mem->am_type = type;
 2054         if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
 2055                 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
 2056                     atop(round_page(size)));
 2057         else
 2058                 mem->am_obj = 0;
 2059 
 2060         if (type == 2) {
 2061                 if (size == AGP_PAGE_SIZE) {
 2062                         /*
 2063                          * Allocate and wire down the page now so that we can
 2064                          * get its physical address.
 2065                          */
 2066                         VM_OBJECT_WLOCK(mem->am_obj);
 2067                         m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY |
 2068                             VM_ALLOC_WIRED | VM_ALLOC_ZERO);
 2069                         VM_OBJECT_WUNLOCK(mem->am_obj);
 2070                         mem->am_physical = VM_PAGE_TO_PHYS(m);
 2071                 } else {
 2072                         /* Our allocation is already nicely wired down for us.
 2073                          * Just grab the physical address.
 2074                          */
 2075                         mem->am_physical = vtophys(sc->argb_cursor);
 2076                 }
 2077         } else
 2078                 mem->am_physical = 0;
 2079 
 2080         mem->am_offset = 0;
 2081         mem->am_is_bound = 0;
 2082         TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
 2083         sc->agp.as_allocated += size;
 2084 
 2085         return (mem);
 2086 }
 2087 
 2088 static int
 2089 agp_i810_free_memory(device_t dev, struct agp_memory *mem)
 2090 {
 2091         struct agp_i810_softc *sc;
 2092         vm_page_t m;
 2093 
 2094         if (mem->am_is_bound)
 2095                 return (EBUSY);
 2096 
 2097         sc = device_get_softc(dev);
 2098 
 2099         if (mem->am_type == 2) {
 2100                 if (mem->am_size == AGP_PAGE_SIZE) {
 2101                         /*
 2102                          * Unwire the page which we wired in alloc_memory.
 2103                          */
 2104                         VM_OBJECT_WLOCK(mem->am_obj);
 2105                         m = vm_page_lookup(mem->am_obj, 0);
 2106                         vm_page_lock(m);
 2107                         vm_page_unwire(m, 0);
 2108                         vm_page_unlock(m);
 2109                         VM_OBJECT_WUNLOCK(mem->am_obj);
 2110                 } else {
 2111                         contigfree(sc->argb_cursor, mem->am_size, M_AGP);
 2112                         sc->argb_cursor = NULL;
 2113                 }
 2114         }
 2115 
 2116         sc->agp.as_allocated -= mem->am_size;
 2117         TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
 2118         if (mem->am_obj)
 2119                 vm_object_deallocate(mem->am_obj);
 2120         free(mem, M_AGP);
 2121         return (0);
 2122 }
 2123 
 2124 static int
 2125 agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
 2126 {
 2127         struct agp_i810_softc *sc;
 2128         vm_offset_t i;
 2129 
 2130         /* Do some sanity checks first. */
 2131         if ((offset & (AGP_PAGE_SIZE - 1)) != 0 ||
 2132             offset + mem->am_size > AGP_GET_APERTURE(dev)) {
 2133                 device_printf(dev, "binding memory at bad offset %#x\n",
 2134                     (int)offset);
 2135                 return (EINVAL);
 2136         }
 2137 
 2138         sc = device_get_softc(dev);
 2139         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
 2140                 mtx_lock(&sc->agp.as_lock);
 2141                 if (mem->am_is_bound) {
 2142                         mtx_unlock(&sc->agp.as_lock);
 2143                         return (EINVAL);
 2144                 }
 2145                 /* The memory's already wired down, just stick it in the GTT. */
 2146                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2147                         sc->match->driver->install_gtt_pte(dev, (offset + i) >>
 2148                             AGP_PAGE_SHIFT, mem->am_physical + i, 0);
 2149                 }
 2150                 mem->am_offset = offset;
 2151                 mem->am_is_bound = 1;
 2152                 mtx_unlock(&sc->agp.as_lock);
 2153                 return (0);
 2154         }
 2155 
 2156         if (mem->am_type != 1)
 2157                 return (agp_generic_bind_memory(dev, mem, offset));
 2158 
 2159         /*
 2160          * Mapping local DRAM into GATT.
 2161          */
 2162         if (sc->match->driver->chiptype != CHIP_I810)
 2163                 return (EINVAL);
 2164         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
 2165                 bus_write_4(sc->sc_res[0],
 2166                     AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
 2167 
 2168         return (0);
 2169 }
 2170 
 2171 static int
 2172 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
 2173 {
 2174         struct agp_i810_softc *sc;
 2175         vm_offset_t i;
 2176 
 2177         sc = device_get_softc(dev);
 2178 
 2179         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
 2180                 mtx_lock(&sc->agp.as_lock);
 2181                 if (!mem->am_is_bound) {
 2182                         mtx_unlock(&sc->agp.as_lock);
 2183                         return (EINVAL);
 2184                 }
 2185 
 2186                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2187                         sc->match->driver->install_gtt_pte(dev,
 2188                             (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
 2189                 }
 2190                 mem->am_is_bound = 0;
 2191                 mtx_unlock(&sc->agp.as_lock);
 2192                 return (0);
 2193         }
 2194 
 2195         if (mem->am_type != 1)
 2196                 return (agp_generic_unbind_memory(dev, mem));
 2197 
 2198         if (sc->match->driver->chiptype != CHIP_I810)
 2199                 return (EINVAL);
 2200         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2201                 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
 2202                     0, 0);
 2203         }
 2204         return (0);
 2205 }
 2206 
 2207 static device_method_t agp_i810_methods[] = {
 2208         /* Device interface */
 2209         DEVMETHOD(device_identify,      agp_i810_identify),
 2210         DEVMETHOD(device_probe,         agp_i810_probe),
 2211         DEVMETHOD(device_attach,        agp_i810_attach),
 2212         DEVMETHOD(device_detach,        agp_i810_detach),
 2213         DEVMETHOD(device_suspend,       bus_generic_suspend),
 2214         DEVMETHOD(device_resume,        agp_i810_resume),
 2215 
 2216         /* AGP interface */
 2217         DEVMETHOD(agp_get_aperture,     agp_generic_get_aperture),
 2218         DEVMETHOD(agp_set_aperture,     agp_i810_method_set_aperture),
 2219         DEVMETHOD(agp_bind_page,        agp_i810_bind_page),
 2220         DEVMETHOD(agp_unbind_page,      agp_i810_unbind_page),
 2221         DEVMETHOD(agp_flush_tlb,        agp_i810_flush_tlb),
 2222         DEVMETHOD(agp_enable,           agp_i810_enable),
 2223         DEVMETHOD(agp_alloc_memory,     agp_i810_alloc_memory),
 2224         DEVMETHOD(agp_free_memory,      agp_i810_free_memory),
 2225         DEVMETHOD(agp_bind_memory,      agp_i810_bind_memory),
 2226         DEVMETHOD(agp_unbind_memory,    agp_i810_unbind_memory),
 2227         DEVMETHOD(agp_chipset_flush,    agp_intel_gtt_chipset_flush),
 2228 
 2229         { 0, 0 }
 2230 };
 2231 
 2232 static driver_t agp_i810_driver = {
 2233         "agp",
 2234         agp_i810_methods,
 2235         sizeof(struct agp_i810_softc),
 2236 };
 2237 
 2238 static devclass_t agp_devclass;
 2239 
 2240 DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0);
 2241 MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
 2242 MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
 2243 
 2244 extern vm_page_t bogus_page;
 2245 
 2246 void
 2247 agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
 2248 {
 2249         struct agp_i810_softc *sc;
 2250         u_int i;
 2251 
 2252         sc = device_get_softc(dev);
 2253         for (i = 0; i < num_entries; i++)
 2254                 sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2255                     VM_PAGE_TO_PHYS(bogus_page), 0);
 2256         sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
 2257 }
 2258 
 2259 void
 2260 agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
 2261     vm_page_t *pages, u_int flags)
 2262 {
 2263         struct agp_i810_softc *sc;
 2264         u_int i;
 2265 
 2266         sc = device_get_softc(dev);
 2267         for (i = 0; i < num_entries; i++) {
 2268                 MPASS(pages[i]->valid == VM_PAGE_BITS_ALL);
 2269                 MPASS(pages[i]->wire_count > 0);
 2270                 sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2271                     VM_PAGE_TO_PHYS(pages[i]), flags);
 2272         }
 2273         sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
 2274 }
 2275 
 2276 struct intel_gtt
 2277 agp_intel_gtt_get(device_t dev)
 2278 {
 2279         struct agp_i810_softc *sc;
 2280         struct intel_gtt res;
 2281 
 2282         sc = device_get_softc(dev);
 2283         res.stolen_size = sc->stolen_size;
 2284         res.gtt_total_entries = sc->gtt_total_entries;
 2285         res.gtt_mappable_entries = sc->gtt_mappable_entries;
 2286         res.do_idle_maps = 0;
 2287         res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
 2288         return (res);
 2289 }
 2290 
 2291 static int
 2292 agp_i810_chipset_flush_setup(device_t dev)
 2293 {
 2294 
 2295         return (0);
 2296 }
 2297 
 2298 static void
 2299 agp_i810_chipset_flush_teardown(device_t dev)
 2300 {
 2301 
 2302         /* Nothing to do. */
 2303 }
 2304 
 2305 static void
 2306 agp_i810_chipset_flush(device_t dev)
 2307 {
 2308 
 2309         /* Nothing to do. */
 2310 }
 2311 
 2312 static void
 2313 agp_i830_chipset_flush(device_t dev)
 2314 {
 2315         struct agp_i810_softc *sc;
 2316         uint32_t hic;
 2317         int i;
 2318 
 2319         sc = device_get_softc(dev);
 2320         pmap_invalidate_cache();
 2321         hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
 2322         bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1U << 31));
 2323         for (i = 0; i < 20000 /* 1 sec */; i++) {
 2324                 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
 2325                 if ((hic & (1U << 31)) == 0)
 2326                         break;
 2327                 DELAY(50);
 2328         }
 2329 }
 2330 
 2331 static int
 2332 agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
 2333 {
 2334         struct agp_i810_softc *sc;
 2335         device_t vga;
 2336 
 2337         sc = device_get_softc(dev);
 2338         vga = device_get_parent(dev);
 2339         sc->sc_flush_page_rid = 100;
 2340         sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
 2341             SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
 2342             RF_ACTIVE);
 2343         if (sc->sc_flush_page_res == NULL) {
 2344                 device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
 2345                     (uintmax_t)start);
 2346                 return (EINVAL);
 2347         }
 2348         sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
 2349         if (bootverbose) {
 2350                 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
 2351                     (uintmax_t)rman_get_start(sc->sc_flush_page_res),
 2352                     sc->sc_flush_page_vaddr);
 2353         }
 2354         return (0);
 2355 }
 2356 
 2357 static void
 2358 agp_i915_chipset_flush_free_page(device_t dev)
 2359 {
 2360         struct agp_i810_softc *sc;
 2361         device_t vga;
 2362 
 2363         sc = device_get_softc(dev);
 2364         vga = device_get_parent(dev);
 2365         if (sc->sc_flush_page_res == NULL)
 2366                 return;
 2367         BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
 2368             sc->sc_flush_page_rid, sc->sc_flush_page_res);
 2369         BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
 2370             sc->sc_flush_page_rid, sc->sc_flush_page_res);
 2371 }
 2372 
 2373 static int
 2374 agp_i915_chipset_flush_setup(device_t dev)
 2375 {
 2376         struct agp_i810_softc *sc;
 2377         uint32_t temp;
 2378         int error;
 2379 
 2380         sc = device_get_softc(dev);
 2381         temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
 2382         if ((temp & 1) != 0) {
 2383                 temp &= ~1;
 2384                 if (bootverbose)
 2385                         device_printf(dev,
 2386                             "Found already configured flush page at 0x%jx\n",
 2387                             (uintmax_t)temp);
 2388                 sc->sc_bios_allocated_flush_page = 1;
 2389                 /*
 2390                  * In the case BIOS initialized the flush pointer (?)
 2391                  * register, expect that BIOS also set up the resource
 2392                  * for the page.
 2393                  */
 2394                 error = agp_i915_chipset_flush_alloc_page(dev, temp,
 2395                     temp + PAGE_SIZE - 1);
 2396                 if (error != 0)
 2397                         return (error);
 2398         } else {
 2399                 sc->sc_bios_allocated_flush_page = 0;
 2400                 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
 2401                 if (error != 0)
 2402                         return (error);
 2403                 temp = rman_get_start(sc->sc_flush_page_res);
 2404                 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
 2405         }
 2406         return (0);
 2407 }
 2408 
 2409 static void
 2410 agp_i915_chipset_flush_teardown(device_t dev)
 2411 {
 2412         struct agp_i810_softc *sc;
 2413         uint32_t temp;
 2414 
 2415         sc = device_get_softc(dev);
 2416         if (sc->sc_flush_page_res == NULL)
 2417                 return;
 2418         if (!sc->sc_bios_allocated_flush_page) {
 2419                 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
 2420                 temp &= ~1;
 2421                 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
 2422         }               
 2423         agp_i915_chipset_flush_free_page(dev);
 2424 }
 2425 
 2426 static int
 2427 agp_i965_chipset_flush_setup(device_t dev)
 2428 {
 2429         struct agp_i810_softc *sc;
 2430         uint64_t temp;
 2431         uint32_t temp_hi, temp_lo;
 2432         int error;
 2433 
 2434         sc = device_get_softc(dev);
 2435 
 2436         temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
 2437         temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
 2438 
 2439         if ((temp_lo & 1) != 0) {
 2440                 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
 2441                 if (bootverbose)
 2442                         device_printf(dev,
 2443                             "Found already configured flush page at 0x%jx\n",
 2444                             (uintmax_t)temp);
 2445                 sc->sc_bios_allocated_flush_page = 1;
 2446                 /*
 2447                  * In the case BIOS initialized the flush pointer (?)
 2448                  * register, expect that BIOS also set up the resource
 2449                  * for the page.
 2450                  */
 2451                 error = agp_i915_chipset_flush_alloc_page(dev, temp,
 2452                     temp + PAGE_SIZE - 1);
 2453                 if (error != 0)
 2454                         return (error);
 2455         } else {
 2456                 sc->sc_bios_allocated_flush_page = 0;
 2457                 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
 2458                 if (error != 0)
 2459                         return (error);
 2460                 temp = rman_get_start(sc->sc_flush_page_res);
 2461                 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
 2462                     (temp >> 32) & UINT32_MAX, 4);
 2463                 pci_write_config(sc->bdev, AGP_I965_IFPADDR,
 2464                     (temp & UINT32_MAX) | 1, 4);
 2465         }
 2466         return (0);
 2467 }
 2468 
 2469 static void
 2470 agp_i965_chipset_flush_teardown(device_t dev)
 2471 {
 2472         struct agp_i810_softc *sc;
 2473         uint32_t temp_lo;
 2474 
 2475         sc = device_get_softc(dev);
 2476         if (sc->sc_flush_page_res == NULL)
 2477                 return;
 2478         if (!sc->sc_bios_allocated_flush_page) {
 2479                 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
 2480                 temp_lo &= ~1;
 2481                 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
 2482         }
 2483         agp_i915_chipset_flush_free_page(dev);
 2484 }
 2485 
 2486 static void
 2487 agp_i915_chipset_flush(device_t dev)
 2488 {
 2489         struct agp_i810_softc *sc;
 2490 
 2491         sc = device_get_softc(dev);
 2492         *(uint32_t *)sc->sc_flush_page_vaddr = 1;
 2493 }
 2494 
 2495 int
 2496 agp_intel_gtt_chipset_flush(device_t dev)
 2497 {
 2498         struct agp_i810_softc *sc;
 2499 
 2500         sc = device_get_softc(dev);
 2501         sc->match->driver->chipset_flush(dev);
 2502         return (0);
 2503 }
 2504 
 2505 void
 2506 agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list)
 2507 {
 2508 }
 2509 
 2510 int
 2511 agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
 2512     struct sglist **sg_list)
 2513 {
 2514         struct agp_i810_softc *sc;
 2515         struct sglist *sg;
 2516         int i;
 2517 #if 0
 2518         int error;
 2519         bus_dma_tag_t dmat;
 2520 #endif
 2521 
 2522         if (*sg_list != NULL)
 2523                 return (0);
 2524         sc = device_get_softc(dev);
 2525         sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */);
 2526         for (i = 0; i < num_entries; i++) {
 2527                 sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]);
 2528                 sg->sg_segs[i].ss_len = PAGE_SIZE;
 2529         }
 2530 
 2531 #if 0
 2532         error = bus_dma_tag_create(bus_get_dma_tag(dev),
 2533             1 /* alignment */, 0 /* boundary */,
 2534             1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */,
 2535             BUS_SPACE_MAXADDR /* highaddr */,
 2536             NULL /* filtfunc */, NULL /* filtfuncarg */,
 2537             BUS_SPACE_MAXADDR /* maxsize */,
 2538             BUS_SPACE_UNRESTRICTED /* nsegments */,
 2539             BUS_SPACE_MAXADDR /* maxsegsz */,
 2540             0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */,
 2541             &dmat);
 2542         if (error != 0) {
 2543                 sglist_free(sg);
 2544                 return (error);
 2545         }
 2546         /* XXXKIB */
 2547 #endif
 2548         *sg_list = sg;
 2549         return (0);
 2550 }
 2551 
 2552 void
 2553 agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
 2554     u_int first_entry, u_int flags)
 2555 {
 2556         struct agp_i810_softc *sc;
 2557         vm_paddr_t spaddr;
 2558         size_t slen;
 2559         u_int i, j;
 2560 
 2561         sc = device_get_softc(dev);
 2562         for (i = j = 0; j < sg_list->sg_nseg; j++) {
 2563                 spaddr = sg_list->sg_segs[i].ss_paddr;
 2564                 slen = sg_list->sg_segs[i].ss_len;
 2565                 for (; slen > 0; i++) {
 2566                         sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2567                             spaddr, flags);
 2568                         spaddr += AGP_PAGE_SIZE;
 2569                         slen -= AGP_PAGE_SIZE;
 2570                 }
 2571         }
 2572         sc->match->driver->read_gtt_pte(dev, first_entry + i - 1);
 2573 }
 2574 
 2575 void
 2576 intel_gtt_clear_range(u_int first_entry, u_int num_entries)
 2577 {
 2578 
 2579         agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
 2580 }
 2581 
 2582 void
 2583 intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages,
 2584     u_int flags)
 2585 {
 2586 
 2587         agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries,
 2588             pages, flags);
 2589 }
 2590 
 2591 struct intel_gtt
 2592 intel_gtt_get(void)
 2593 {
 2594 
 2595         return (agp_intel_gtt_get(intel_agp));
 2596 }
 2597 
 2598 int
 2599 intel_gtt_chipset_flush(void)
 2600 {
 2601 
 2602         return (agp_intel_gtt_chipset_flush(intel_agp));
 2603 }
 2604 
 2605 void
 2606 intel_gtt_unmap_memory(struct sglist *sg_list)
 2607 {
 2608 
 2609         agp_intel_gtt_unmap_memory(intel_agp, sg_list);
 2610 }
 2611 
 2612 int
 2613 intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
 2614     struct sglist **sg_list)
 2615 {
 2616 
 2617         return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries,
 2618             sg_list));
 2619 }
 2620 
 2621 void
 2622 intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry,
 2623     u_int flags)
 2624 {
 2625 
 2626         agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags);
 2627 }
 2628 
 2629 device_t
 2630 intel_gtt_get_bridge_device(void)
 2631 {
 2632         struct agp_i810_softc *sc;
 2633 
 2634         sc = device_get_softc(intel_agp);
 2635         return (sc->bdev);
 2636 }
 2637 
 2638 vm_paddr_t
 2639 intel_gtt_read_pte_paddr(u_int entry)
 2640 {
 2641         struct agp_i810_softc *sc;
 2642 
 2643         sc = device_get_softc(intel_agp);
 2644         return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry));
 2645 }
 2646 
 2647 u_int32_t
 2648 intel_gtt_read_pte(u_int entry)
 2649 {
 2650         struct agp_i810_softc *sc;
 2651 
 2652         sc = device_get_softc(intel_agp);
 2653         return (sc->match->driver->read_gtt_pte(intel_agp, entry));
 2654 }
 2655 
 2656 void
 2657 intel_gtt_write(u_int entry, uint32_t val)
 2658 {
 2659         struct agp_i810_softc *sc;
 2660 
 2661         sc = device_get_softc(intel_agp);
 2662         return (sc->match->driver->write_gtt(intel_agp, entry, val));
 2663 }

Cache object: 2a71917023afaf6ae3a7ead3ebf55a84


[ 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.