西田と申します。

必要に駆られて、6 用の 965/33 チップセット対応 agp パッチを作ってみました。
7 を見ながら適当に作ったので、ミスもあるかと思います。

どなたかテストして頂ければと思います。

私の 965GM なノートパソコンでは、Xorg 7.3 + Driver "intel" で一応
X が立ち上がっています。

dmesg は以下のような感じです。

agp0: <Intel GM965 SVGA controller> port 0x1800-0x1807 mem
0xf5000000-0xf50fffff,0xd0000000-0xdfffffff irq 16 at device 2.0 on pci0

それではよろしくお願いいたします。

-- 
Hiroshi Nishida
[&#x30E1;&#x30FC;&#x30EB;&#x30A2;&#x30C9;&#x30EC;&#x30B9;&#x4FDD;&#x8B77;]
--- agp_i810.c  2007-11-27 15:41:38.000000000 -0800
+++ agp_i810.c.new      2007-11-27 15:40:51.000000000 -0800
@@ -28,6 +28,7 @@
 /*
  * Fixes for 830/845G support: David Dawes 
<[&#x30E1;&#x30FC;&#x30EB;&#x30A2;&#x30C9;&#x30EC;&#x30B9;&#x4FDD;&#x8B77;]>
  * 852GM/855GM/865G support added by David Dawes 
<[&#x30E1;&#x30FC;&#x30EB;&#x30A2;&#x30C9;&#x30EC;&#x30B9;&#x4FDD;&#x8B77;]>
+ * An experimental 965/33 support added by Hiroshi Nishida
  */
 
 #include <sys/cdefs.h>
@@ -71,6 +72,8 @@
 #define CHIP_I830 1    /* 830M/845G */
 #define CHIP_I855 2    /* 852GM/855GM/865G */
 #define CHIP_I915 3    /* 915G/915GM */
+#define CHIP_I965 4    /* G965 */
+#define CHIP_G33  5    /* G33/Q33/Q35 */
 
 struct agp_i810_softc {
        struct agp_softc agp;
@@ -152,6 +155,24 @@
 
        case 0x27A28086:
                return ("Intel 82945GM (945GM GMCH) SVGA controller");
+
+       case 0x29728086:
+               return ("Intel 946GZ SVGA controller");
+
+       case 0x29828086:
+               return ("Intel G965 SVGA controller");
+
+       case 0x29928086:
+               return ("Intel Q965 SVGA controller");
+
+       case 0x29a28086:
+               return ("Intel G965 SVGA controller");
+
+       case 0x2a028086:
+               return ("Intel GM965 SVGA controller");
+
+       case 0x2a128086:
+               return ("Intel GME965 SVGA controller");
        };
 
        return NULL;
@@ -260,6 +281,12 @@
                case 0x25928086:
                case 0x27728086:        /* 945G GMCH */
                case 0x27A28086:        /* 945GM GMCH */
+               case 0x29728086:        /* 946GZ */
+               case 0x29828086:        /* G965 */
+               case 0x29928086:        /* Q965 */
+               case 0x29a28086:        /* G965 */
+               case 0x2a028086:        /* GM965 */
+               case 0x2a128086:        /* GME965 */
                        gcc1 = pci_read_config(bdev, AGP_I915_DEVEN, 4);
                        if ((gcc1 & AGP_I915_DEVEN_D2F0) ==
                            AGP_I915_DEVEN_D2F0_DISABLED) {
@@ -317,24 +344,50 @@
        case 0x27A28086:        /* 945GM GMCH */
                sc->chiptype = CHIP_I915;
                break;
+       case 0x29728086:
+       case 0x29828086:
+       case 0x29928086:
+       case 0x29a28086:
+       case 0x2a028086:
+       case 0x2a128086:
+               sc->chiptype = CHIP_I965;
+               break;
        };
 
+#if 0
        /* Same for i810 and i830 */
        if (sc->chiptype == CHIP_I915)
                rid = AGP_I915_MMADR;
        else
                rid = AGP_I810_MMADR;
+#else
+       switch (sc->chiptype) {
+       case CHIP_I915:
+       case CHIP_G33:
+               rid = AGP_I915_MMADR;
+               break;
+       case CHIP_I965:
+               rid = AGP_I965_GTTMMADR;
+               break;
+       default:
+               rid = AGP_I810_MMADR;
+               break;
+       }
+
+       printf("Chip Type: %d, rid:%x\n", sc->chiptype, rid);
+#endif
 
        sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
                                          RF_ACTIVE);
        if (!sc->regs) {
                agp_generic_detach(dev);
+               printf("ENODEV at agp_i810_attach() 1\n");
                return ENODEV;
        }
        sc->bst = rman_get_bustag(sc->regs);
        sc->bsh = rman_get_bushandle(sc->regs);
 
-       if (sc->chiptype == CHIP_I915) {
+       if (sc->chiptype == CHIP_I915 || sc->chiptype == CHIP_G33) {
                rid = AGP_I915_GTTADR;
                sc->gtt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
                                                 RF_ACTIVE);
@@ -342,6 +395,7 @@
                        bus_release_resource(dev, SYS_RES_MEMORY,
                                             AGP_I915_MMADR, sc->regs);
                        agp_generic_detach(dev);
+                       printf("ENODEV at agp_i810_attach() 2\n");
                        return ENODEV;
                }
                sc->gtt_bst = rman_get_bustag(sc->gtt);
@@ -362,12 +416,28 @@
                        bus_release_resource(dev, SYS_RES_MEMORY,
                                             AGP_I915_GTTADR, sc->regs);
                        agp_generic_detach(dev);
+                       printf("ENODEV at agp_i810_attach() 3\n");
                        return ENODEV;
                }
 
        }
+       else if (sc->chiptype == CHIP_I965) {
+               rid = AGP_I915_GMADR;
+               sc->gm = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
+               if (sc->gm == NULL) {
+                       bus_release_resource(dev, SYS_RES_MEMORY,
+                                            AGP_I915_MMADR, sc->regs);
+                       agp_generic_detach(dev);
+                       printf("ENODEV at agp_i810_attach() 4\n");
+                       return ENODEV;
+               }
+       }
 
        sc->initial_aperture = AGP_GET_APERTURE(dev);
+       if (sc->initial_aperture == 0) {
+               device_printf(dev, "bad initial aperture size, disabling\n");
+               return ENXIO;
+       }
 
        gatt = malloc( sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
        if (!gatt) {
@@ -432,40 +502,82 @@
                WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
 
                gatt->ag_physical = pgtblctl & ~1;
-       } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915) {    
/* CHIP_I855 */
-               unsigned int gcc1, pgtblctl, stolen;
+       } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915 ||
+                  sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33) {
+               unsigned int gcc1, pgtblctl, stolen, gtt_size;
 
                /* Stolen memory is set up at the beginning of the aperture by
                 * the BIOS, consisting of the GATT followed by 4kb for the BIOS
                 * display.
                 */
+#if 0
                if (sc->chiptype == CHIP_I855)
                        stolen = 132;
                else
                        stolen = 260;
+#else
+               switch (sc->chiptype) {
+               case CHIP_I855:
+                       gtt_size = 128;
+                       break;
+               case CHIP_I915:
+                       gtt_size = 256;
+                       break;
+               case CHIP_I965:
+               case CHIP_G33:
+                       switch (READ4(AGP_I810_PGTBL_CTL) &
+                               AGP_I810_PGTBL_SIZE_MASK) {
+                       case AGP_I810_PGTBL_SIZE_128KB:
+                               gtt_size = 128;
+                               break;
+                       case AGP_I810_PGTBL_SIZE_256KB:
+                               gtt_size = 256;
+                               break;
+                       case AGP_I810_PGTBL_SIZE_512KB:
+                               gtt_size = 512;
+                               break;
+                       default:
+                               device_printf(dev, "Bad PGTBL size\n");
+                               agp_generic_detach(dev);
+                               return EINVAL;
+                       }
+                       break;
+               default:
+                       device_printf(dev, "Bad chiptype\n");
+                       agp_generic_detach(dev);
+                       return EINVAL;
+               }
+#endif
 
+               /* GCC1 is called MGGC on i915+ */
                gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
                switch (gcc1 & AGP_I855_GCC1_GMS) {
                        case AGP_I855_GCC1_GMS_STOLEN_1M:
-                               sc->stolen = (1024 - stolen) * 1024 / 4096;
+                               stolen = 1024;
                                break;
                        case AGP_I855_GCC1_GMS_STOLEN_4M: 
-                               sc->stolen = (4096 - stolen) * 1024 / 4096;
+                               stolen = 4096;
                                break;
                        case AGP_I855_GCC1_GMS_STOLEN_8M: 
-                               sc->stolen = (8192 - stolen) * 1024 / 4096;
+                               stolen = 8192;
                                break;
                        case AGP_I855_GCC1_GMS_STOLEN_16M: 
-                               sc->stolen = (16384 - stolen) * 1024 / 4096;
+                               stolen = 16384;
                                break;
                        case AGP_I855_GCC1_GMS_STOLEN_32M: 
-                               sc->stolen = (32768 - stolen) * 1024 / 4096;
+                               stolen = 32768;
                                break;
                        case AGP_I915_GCC1_GMS_STOLEN_48M: 
-                               sc->stolen = (49152 - stolen) * 1024 / 4096;
+                               stolen = 49152;
                                break;
                        case AGP_I915_GCC1_GMS_STOLEN_64M: 
-                               sc->stolen = (65536 - stolen) * 1024 / 4096;
+                               stolen = 65536;
+                               break;
+                       case AGP_G33_GCC1_GMS_STOLEN_128M:
+                               stolen = 128 * 1024;
+                               break;
+                       case AGP_G33_GCC1_GMS_STOLEN_256M:
+                               stolen = 256 * 1024;
                                break;
                        default:
                                sc->stolen = 0;
@@ -473,6 +585,7 @@
                                agp_generic_detach(dev);
                                return EINVAL;
                }
+               sc->stolen = (stolen - gtt_size - 4) * 1024 / 4096;
                if (sc->stolen > 0)
                        device_printf(dev, "detected %dk stolen memory\n", 
sc->stolen * 4);
                device_printf(dev, "aperture size is %dM\n", 
sc->initial_aperture / 1024 / 1024);
@@ -518,6 +631,7 @@
        }
        free(sc->gatt, M_AGP);
 
+#if 0
        if (sc->chiptype == CHIP_I915) {
                bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GMADR,
                                     sc->gm);
@@ -529,6 +643,35 @@
                bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR,
                                     sc->regs);
        }
+#else
+       switch (sc->chiptype) {
+       case CHIP_I810:
+       case CHIP_I830:
+       case CHIP_I855:
+               bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR,
+                                    sc->regs);
+               break;
+       case CHIP_I915:
+       case CHIP_G33:
+               bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GMADR,
+                                    sc->gm);
+               bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR,
+                                    sc->gtt);
+               bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_MMADR,
+                                    sc->regs);
+               break;
+       case CHIP_I965:
+               bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR,
+                                    sc->gtt);
+               bus_release_resource(dev, SYS_RES_MEMORY, AGP_I965_GTTMMADR,
+                                    sc->regs);
+               break;
+       default:
+               device_printf(dev, "Bad chiptype at agp_i810_detach()\n");
+               agp_generic_detach(dev);
+               return EINVAL;
+       }
+#endif
        agp_free_res(dev);
 
        child = device_find_child( dev, "drmsub", 0 );
@@ -561,6 +704,8 @@
        case CHIP_I855:
                return 128 * 1024 * 1024;
        case CHIP_I915:
+       case CHIP_I965:
+       case CHIP_G33:
                /* The documentation states that AGP_I915_MSAC should have bit
                 * 1 set if the aperture is 128MB instead of 256.  However,
                 * that bit appears to not get set, so we instead use the
@@ -620,6 +765,8 @@
                }
                break;
        case CHIP_I915:
+       case CHIP_I965:
+       case CHIP_G33:
                temp = pci_read_config(dev, AGP_I915_MSAC, 1);
                temp &= ~AGP_I915_MSAC_GMASIZE;
 
@@ -642,6 +789,46 @@
        return 0;
 }
 
+/**
+ * Writes a GTT entry mapping the page at the given offset from the beginning
+ * of the aperture to the given physical address.
+ */
+static void
+agp_i810_write_gtt_entry(device_t dev, int offset, vm_offset_t physical,
+                        int enabled)
+{
+       struct agp_i810_softc *sc = device_get_softc(dev);
+       u_int32_t pte;
+
+       pte = (u_int32_t)physical | 1;
+       if (sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33) {
+               pte |= (physical & 0x0000000f00000000ull) >> 28;
+       } else {
+               /* If we do actually have memory above 4GB on an older system,
+                * crash cleanly rather than scribble on system memory,
+                * so we know we need to fix it.
+                */
+               KASSERT((pte & 0x0000000f00000000ull) == 0,
+                   (">4GB physical address in agp"));
+       }
+
+       switch (sc->chiptype) {
+       case CHIP_I810:
+       case CHIP_I830:
+       case CHIP_I855:
+               WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4,
+                   physical | 1);
+               break;
+       case CHIP_I915:
+       case CHIP_G33:
+               WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, pte);
+               break;
+       case CHIP_I965:
+               WRITE4((offset >> AGP_PAGE_SHIFT) * 4 + (512 * 1024), pte);
+               break;
+       }
+}
+
 static int
 agp_i810_bind_page(device_t dev, int offset, vm_offset_t physical)
 {
@@ -659,11 +846,15 @@
                }
        }
 
+#if 0
        if (sc->chiptype == CHIP_I915) {
                WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, physical | 1);
        } else {
                WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, physical 
| 1);
        }
+#else
+       agp_i810_write_gtt_entry(dev, offset, physical, 1);
+#endif
 
        return 0;
 }
@@ -683,11 +874,15 @@
                }
        }
 
+#if 0
        if (sc->chiptype == CHIP_I915) {
                WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, 0);
        } else {
                WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 0);
        }
+#else
+       agp_i810_write_gtt_entry(dev, offset, 0, 0);
+#endif
        
        return 0;
 }
@@ -848,6 +1043,7 @@
                for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
                        u_int32_t physical = mem->am_physical + i;
 
+#if 0
                        if (sc->chiptype == CHIP_I915) {
                                WRITEGTT(((offset + i) >> AGP_PAGE_SHIFT) * 4,
                                    physical | 1);
@@ -856,6 +1052,9 @@
                                    ((offset + i) >> AGP_PAGE_SHIFT) * 4,
                                    physical | 1);
                        }
+#else
+                       agp_i810_write_gtt_entry(dev, offset + i, physical, 1);
+#endif
                }
                agp_flush_cache();
                mem->am_offset = offset;
@@ -894,6 +1093,7 @@
                for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
                        vm_offset_t offset = mem->am_offset;
 
+#if 0
                        if (sc->chiptype == CHIP_I915) {
                                WRITEGTT(((offset + i) >> AGP_PAGE_SHIFT) * 4,
                                    0);
@@ -901,6 +1101,9 @@
                                WRITE4(AGP_I810_GTT +
                                    ((offset + i) >> AGP_PAGE_SHIFT) * 4, 0);
                        }
+#else
+                       agp_i810_write_gtt_entry(dev, offset + i, 0, 0);
+#endif
                }
                agp_flush_cache();
                mem->am_is_bound = 0;
--- agpreg.h    2007-11-27 15:41:49.000000000 -0800
+++ agpreg.h.new        2007-11-27 15:32:40.000000000 -0800
@@ -180,10 +180,19 @@
  * Memory mapped register offsets for i810 chipset.
  */
 #define AGP_I810_PGTBL_CTL     0x2020
-#define AGP_I810_DRT           0x3000
-#define AGP_I810_DRT_UNPOPULATED 0x00
-#define AGP_I810_DRT_POPULATED 0x01
-#define AGP_I810_GTT           0x10000
+
+/**
+ * This field determines the actual size of the global GTT on the 965
+ * and G33
+ */
+#define AGP_I810_PGTBL_SIZE_MASK       0x0000000e
+#define AGP_I810_PGTBL_SIZE_512KB      (0 << 1)
+#define AGP_I810_PGTBL_SIZE_256KB      (1 << 1)
+#define AGP_I810_PGTBL_SIZE_128KB      (2 << 1)
+#define AGP_I810_DRT                   0x3000
+#define AGP_I810_DRT_UNPOPULATED       0x00
+#define AGP_I810_DRT_POPULATED         0x01
+#define AGP_I810_GTT                   0x10000
  
 /*
  * Config registers for i830MG device 0
@@ -244,6 +253,21 @@
 #define AGP_I915_MSAC_GMASIZE_256      0x00
 
 /*
+ * G965 registers
+ */
+#define AGP_I965_GTTMMADR              0x10
+#define AGP_I965_MSAC                  0x62
+#define AGP_I965_MSAC_GMASIZE_128      0x00
+#define AGP_I965_MSAC_GMASIZE_256      0x02
+#define AGP_I965_MSAC_GMASIZE_512      0x06
+
+/*
+ * G33 registers
+ */
+#define AGP_G33_GCC1_GMS_STOLEN_128M   0x80
+#define AGP_G33_GCC1_GMS_STOLEN_256M   0x90
+
+/*
  * NVIDIA nForce/nForce2 registers
  */
 #define        AGP_NVIDIA_0_APBASE             0x10

メールによる返信