2 * Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
3 * Copyright 2011-2016, Haiku, Inc. All Rights Reserved.
4 * Distributed under the terms of the MIT License.
7 * Axel Dörfler, axeld@pinc-software.de
8 * Jerome Duval, jerome.duval@gmail.com
9 * Adrien Destugues, pulkomandy@gmail.com
10 * Michael Lotz, mmlr@mlotz.ch
11 * Alexander von Gluck IV, kallisti5@unixzen.com
15 #include <AreaKeeper.h>
16 #include <intel_extreme.h>
21 #include <KernelExport.h>
29 # define TRACE(x...) dprintf("intel_gart: " x)
31 # define TRACE(x...) ;
33 #define ERROR(x...) dprintf("intel_gart: " x)
36 # define B_KERNEL_READ_AREA 0
37 # define B_KERNEL_WRITE_AREA 0
40 /* read and write to PCI config space */
41 #define get_pci_config(info, offset, size) \
42 (sPCI->read_pci_config((info).bus, (info).device, (info).function, \
44 #define set_pci_config(info, offset, size, value) \
45 (sPCI->write_pci_config((info).bus, (info).device, (info).function, \
46 (offset), (size), (value)))
47 #define write32(address, data) \
48 (*((volatile uint32*)(address)) = (data))
49 #define read32(address) \
50 (*((volatile uint32*)(address)))
53 // PCI "Host bridge" is most cases :-)
54 const struct supported_device
{
59 } kSupportedDevices
[] = {
60 {0x3575, 0x3577, INTEL_GROUP_83x
, "i830GM"},
61 {0x2560, 0x2562, INTEL_GROUP_83x
, "i845G"},
62 {0x3580, 0x3582, INTEL_GROUP_85x
, "i855G"},
63 {0x358c, 0x358e, INTEL_GROUP_85x
, "i855G"},
64 {0x2570, 0x2572, INTEL_GROUP_85x
, "i865G"},
66 // {0x2792, INTEL_GROUP_91x, "i910"},
67 // {0x258a, INTEL_GROUP_91x, "i915"},
68 {0x2580, 0x2582, INTEL_MODEL_915
, "i915G"},
69 {0x2590, 0x2592, INTEL_MODEL_915M
, "i915GM"},
70 {0x2770, 0x2772, INTEL_MODEL_945
, "i945G"},
71 {0x27a0, 0x27a2, INTEL_MODEL_945M
, "i945GM"},
72 {0x27ac, 0x27ae, INTEL_MODEL_945M
, "i945GME"},
74 {0x2970, 0x2972, INTEL_MODEL_965
, "i946GZ"},
75 {0x2980, 0x2982, INTEL_MODEL_965
, "G35"},
76 {0x2990, 0x2992, INTEL_MODEL_965
, "i965Q"},
77 {0x29a0, 0x29a2, INTEL_MODEL_965
, "i965G"},
78 {0x2a00, 0x2a02, INTEL_MODEL_965
, "i965GM"},
79 {0x2a10, 0x2a12, INTEL_MODEL_965
, "i965GME"},
81 {0x29b0, 0x29b2, INTEL_MODEL_G33
, "G33"},
82 {0x29c0, 0x29c2, INTEL_MODEL_G33
, "Q35"},
83 {0x29d0, 0x29d2, INTEL_MODEL_G33
, "Q33"},
85 {0x2a40, 0x2a42, INTEL_MODEL_GM45
, "GM45"},
86 {0x2e00, 0x2e02, INTEL_MODEL_G45
, "IGD"},
87 {0x2e10, 0x2e12, INTEL_MODEL_G45
, "Q45"},
88 {0x2e20, 0x2e22, INTEL_MODEL_G45
, "G45"},
89 {0x2e30, 0x2e32, INTEL_MODEL_G45
, "G41"},
90 {0x2e40, 0x2e42, INTEL_MODEL_G45
, "B43"},
91 {0x2e90, 0x2e92, INTEL_MODEL_G45
, "B43"},
93 {0xa000, 0xa001, INTEL_MODEL_PINE
, "Atom D4xx"},
94 {0xa000, 0xa002, INTEL_MODEL_PINE
, "Atom D5xx"},
95 {0xa010, 0xa011, INTEL_MODEL_PINEM
, "Atom N4xx"},
96 {0xa010, 0xa012, INTEL_MODEL_PINEM
, "Atom N5xx"},
98 {0x0040, 0x0042, INTEL_MODEL_ILKG
, "IronLake Desktop"},
99 {0x0044, 0x0046, INTEL_MODEL_ILKGM
, "IronLake Mobile"},
100 {0x0062, 0x0046, INTEL_MODEL_ILKGM
, "IronLake Mobile"},
101 {0x006a, 0x0046, INTEL_MODEL_ILKGM
, "IronLake Mobile"},
103 {0x0100, 0x0102, INTEL_MODEL_SNBG
, "SandyBridge Desktop GT1"},
104 {0x0100, 0x0112, INTEL_MODEL_SNBG
, "SandyBridge Desktop GT2"},
105 {0x0100, 0x0122, INTEL_MODEL_SNBG
, "SandyBridge Desktop GT2+"},
106 {0x0104, 0x0106, INTEL_MODEL_SNBGM
, "SandyBridge Mobile GT1"},
107 {0x0104, 0x0116, INTEL_MODEL_SNBGM
, "SandyBridge Mobile GT2"},
108 {0x0104, 0x0126, INTEL_MODEL_SNBGM
, "SandyBridge Mobile GT2+"},
109 {0x0108, 0x010a, INTEL_MODEL_SNBGS
, "SandyBridge Server"},
111 {0x0150, 0x0152, INTEL_MODEL_IVBG
, "IvyBridge Desktop GT1"},
112 {0x0150, 0x0162, INTEL_MODEL_IVBG
, "IvyBridge Desktop GT2"},
113 {0x0154, 0x0156, INTEL_MODEL_IVBGM
, "IvyBridge Mobile GT1"},
114 {0x0154, 0x0166, INTEL_MODEL_IVBGM
, "IvyBridge Mobile GT2"},
115 {0x0158, 0x015a, INTEL_MODEL_IVBGS
, "IvyBridge Server GT1"},
116 {0x0158, 0x016a, INTEL_MODEL_IVBGS
, "IvyBridge Server GT2"},
118 {0x0c00, 0x0412, INTEL_MODEL_HAS
, "Haswell Desktop"},
119 {0x0c04, 0x0416, INTEL_MODEL_HASM
, "Haswell Mobile"},
120 {0x0d04, 0x0d26, INTEL_MODEL_HASM
, "Haswell Mobile"},
121 {0x0a04, 0x0a16, INTEL_MODEL_HASM
, "Haswell Mobile"},
123 // XXX: 0x0f00 only confirmed on 0x0f30, 0x0f31
124 {0x0f00, 0x0155, INTEL_MODEL_VLV
, "ValleyView Desktop"},
125 {0x0f00, 0x0f30, INTEL_MODEL_VLVM
, "ValleyView Mobile"},
126 {0x0f00, 0x0f31, INTEL_MODEL_VLVM
, "ValleyView Mobile"},
127 {0x0f00, 0x0f32, INTEL_MODEL_VLVM
, "ValleyView Mobile"},
128 {0x0f00, 0x0f33, INTEL_MODEL_VLVM
, "ValleyView Mobile"},
129 {0x0f00, 0x0157, INTEL_MODEL_VLVM
, "ValleyView Mobile"},
131 {0x1604, 0x1616, INTEL_MODEL_BDWM
, "HD Graphics 5500 (Broadwell GT2)"},
133 // XXX: 0x1904 only confirmed on 0x1916
134 {0x1904, 0x1902, INTEL_MODEL_SKY
, "Skylake GT1"},
135 {0x1904, 0x1906, INTEL_MODEL_SKYM
, "Skylake GT1"},
136 {0x1904, 0x190a, INTEL_MODEL_SKYS
, "Skylake GT1"},
137 {0x1904, 0x190b, INTEL_MODEL_SKY
, "Skylake GT1"},
138 {0x1904, 0x190e, INTEL_MODEL_SKYM
, "Skylake GT1"},
139 {0x1904, 0x1912, INTEL_MODEL_SKY
, "Skylake GT2"},
140 {0x1904, 0x1916, INTEL_MODEL_SKYM
, "Skylake GT2"},
141 {0x1904, 0x191a, INTEL_MODEL_SKYS
, "Skylake GT2"},
142 {0x1904, 0x191b, INTEL_MODEL_SKY
, "Skylake GT2"},
143 {0x1904, 0x191d, INTEL_MODEL_SKY
, "Skylake GT2"},
144 {0x1904, 0x191e, INTEL_MODEL_SKYM
, "Skylake GT2"},
145 {0x1904, 0x1921, INTEL_MODEL_SKYM
, "Skylake GT2F"},
146 {0x1904, 0x1926, INTEL_MODEL_SKYM
, "Skylake GT3"},
147 {0x1904, 0x192a, INTEL_MODEL_SKYS
, "Skylake GT3"},
148 {0x1904, 0x192b, INTEL_MODEL_SKY
, "Skylake GT3"},
157 phys_addr_t gtt_physical_base
;
160 size_t gtt_stolen_entries
;
163 area_id registers_area
;
165 addr_t aperture_base
;
166 phys_addr_t aperture_physical_base
;
167 area_id aperture_area
;
168 size_t aperture_size
;
169 size_t aperture_stolen_size
;
171 phys_addr_t scratch_page
;
172 area_id scratch_area
;
175 static intel_info sInfo
;
176 static pci_module_info
* sPCI
;
180 has_display_device(pci_info
&info
, uint32 deviceID
)
182 for (uint32 index
= 0; sPCI
->get_nth_pci_info(index
, &info
) == B_OK
;
184 if (info
.vendor_id
!= VENDOR_ID_INTEL
185 || info
.device_id
!= deviceID
186 || info
.class_base
!= PCI_display
)
197 gtt_memory_config(intel_info
&info
)
199 uint8 controlRegister
= INTEL_GRAPHICS_MEMORY_CONTROL
;
200 if (info
.type
->InGroup(INTEL_GROUP_SNB
))
201 controlRegister
= SNB_GRAPHICS_MEMORY_CONTROL
;
203 return get_pci_config(info
.bridge
, controlRegister
, 2);
208 determine_gtt_stolen(intel_info
&info
)
210 uint16 memoryConfig
= gtt_memory_config(info
);
211 size_t memorySize
= 1 << 20; // 1 MB
213 if (info
.type
->InGroup(INTEL_GROUP_83x
)) {
215 switch (memoryConfig
& STOLEN_MEMORY_MASK
) {
216 case i830_LOCAL_MEMORY_ONLY
:
217 // TODO: determine its size!
218 ERROR("getting local memory size not implemented.\n");
220 case i830_STOLEN_512K
:
230 } else if (info
.type
->InGroup(INTEL_GROUP_SNB
)) {
231 switch (memoryConfig
& SNB_STOLEN_MEMORY_MASK
) {
232 case SNB_STOLEN_MEMORY_32MB
:
235 case SNB_STOLEN_MEMORY_64MB
:
238 case SNB_STOLEN_MEMORY_96MB
:
241 case SNB_STOLEN_MEMORY_128MB
:
244 case SNB_STOLEN_MEMORY_160MB
:
247 case SNB_STOLEN_MEMORY_192MB
:
250 case SNB_STOLEN_MEMORY_224MB
:
253 case SNB_STOLEN_MEMORY_256MB
:
256 case SNB_STOLEN_MEMORY_288MB
:
259 case SNB_STOLEN_MEMORY_320MB
:
262 case SNB_STOLEN_MEMORY_352MB
:
265 case SNB_STOLEN_MEMORY_384MB
:
268 case SNB_STOLEN_MEMORY_416MB
:
271 case SNB_STOLEN_MEMORY_448MB
:
274 case SNB_STOLEN_MEMORY_480MB
:
277 case SNB_STOLEN_MEMORY_512MB
:
281 } else if (info
.type
->InGroup(INTEL_GROUP_85x
)
282 || info
.type
->InFamily(INTEL_FAMILY_9xx
)
283 || info
.type
->InFamily(INTEL_FAMILY_SER5
)
284 || info
.type
->InFamily(INTEL_FAMILY_SOC0
)
285 || info
.type
->InFamily(INTEL_FAMILY_POVR
)) {
286 switch (memoryConfig
& STOLEN_MEMORY_MASK
) {
287 case i855_STOLEN_MEMORY_4M
:
290 case i855_STOLEN_MEMORY_8M
:
293 case i855_STOLEN_MEMORY_16M
:
296 case i855_STOLEN_MEMORY_32M
:
299 case i855_STOLEN_MEMORY_48M
:
302 case i855_STOLEN_MEMORY_64M
:
305 case i855_STOLEN_MEMORY_128M
:
308 case i855_STOLEN_MEMORY_256M
:
311 case G4X_STOLEN_MEMORY_96MB
:
314 case G4X_STOLEN_MEMORY_160MB
:
317 case G4X_STOLEN_MEMORY_224MB
:
320 case G4X_STOLEN_MEMORY_352MB
:
328 return memorySize
- 4096;
333 determine_gtt_size(intel_info
&info
)
335 uint16 memoryConfig
= gtt_memory_config(info
);
338 if (info
.type
->IsModel(INTEL_MODEL_965
)) {
339 switch (memoryConfig
& i965_GTT_MASK
) {
350 } else if (info
.type
->IsModel(INTEL_MODEL_G33
)
351 || info
.type
->InGroup(INTEL_GROUP_PIN
)) {
352 switch (memoryConfig
& G33_GTT_MASK
) {
360 } else if (info
.type
->InGroup(INTEL_GROUP_G4x
)
361 || info
.type
->InGroup(INTEL_GROUP_ILK
)) {
362 switch (memoryConfig
& G4X_GTT_MASK
) {
366 case G4X_GTT_1M_NO_IVT
:
369 case G4X_GTT_2M_NO_IVT
:
380 } else if (info
.type
->InGroup(INTEL_GROUP_SNB
)) {
381 switch (memoryConfig
& SNB_GTT_SIZE_MASK
) {
382 case SNB_GTT_SIZE_NONE
:
385 case SNB_GTT_SIZE_1MB
:
388 case SNB_GTT_SIZE_2MB
:
393 // older models have the GTT as large as their frame buffer mapping
394 // TODO: check if the i9xx version works with the i8xx chips as well
395 size_t frameBufferSize
= 0;
396 if (info
.type
->InFamily(INTEL_FAMILY_8xx
)) {
397 if (info
.type
->InGroup(INTEL_GROUP_83x
)
398 && (memoryConfig
& MEMORY_MASK
) == i830_FRAME_BUFFER_64M
)
399 frameBufferSize
= 64 << 20;
401 frameBufferSize
= 128 << 20;
402 } else if (info
.type
->Generation() >= 3) {
403 frameBufferSize
= info
.display
.u
.h0
.base_register_sizes
[2];
406 TRACE("frame buffer size %lu MB\n", frameBufferSize
>> 20);
407 gttSize
= frameBufferSize
/ 1024;
414 set_gtt_entry(intel_info
&info
, uint32 offset
, phys_addr_t physicalAddress
)
416 if (info
.type
->Generation() >= 8) {
418 physicalAddress
|= (physicalAddress
>> 28) & 0x07f0;
419 // TODO: cache control?
420 } else if (info
.type
->Generation() >= 6) {
421 // SandyBridge, IronLake, IvyBridge, Haswell
422 physicalAddress
|= (physicalAddress
>> 28) & 0x0ff0;
423 physicalAddress
|= 0x02; // cache control, l3 cacheable
424 } else if (info
.type
->Generation() >= 4) {
425 // Intel 9xx minus 91x, 94x, G33
426 // possible high bits are stored in the lower end
427 physicalAddress
|= (physicalAddress
>> 28) & 0x00f0;
428 // TODO: cache control?
431 // TODO: this is not 64-bit safe!
432 write32(info
.gtt_base
+ (offset
>> GTT_PAGE_SHIFT
),
433 (uint32
)physicalAddress
| GTT_ENTRY_VALID
);
438 intel_unmap(intel_info
&info
)
440 delete_area(info
.registers_area
);
441 delete_area(info
.gtt_area
);
442 delete_area(info
.scratch_area
);
443 delete_area(info
.aperture_area
);
444 info
.aperture_size
= 0;
449 intel_map(intel_info
&info
)
453 if (info
.type
->Generation() >= 3) {
454 // for some reason Intel saw the need to change the order of the
455 // mappings with the introduction of the i9xx family
460 AreaKeeper mmioMapper
;
461 info
.registers_area
= mmioMapper
.Map("intel GMCH mmio",
462 info
.display
.u
.h0
.base_registers
[mmioIndex
],
463 info
.display
.u
.h0
.base_register_sizes
[mmioIndex
], B_ANY_KERNEL_ADDRESS
,
464 B_KERNEL_READ_AREA
| B_KERNEL_WRITE_AREA
, (void**)&info
.registers
);
466 if (mmioMapper
.InitCheck() < B_OK
) {
467 ERROR("could not map memory I/O!\n");
468 return info
.registers_area
;
471 // make sure bus master, memory-mapped I/O, and frame buffer is enabled
472 set_pci_config(info
.display
, PCI_command
, 2,
473 get_pci_config(info
.display
, PCI_command
, 2)
474 | PCI_command_io
| PCI_command_memory
| PCI_command_master
);
476 void* scratchAddress
;
477 AreaKeeper scratchCreator
;
478 info
.scratch_area
= scratchCreator
.Create("intel GMCH scratch",
479 &scratchAddress
, B_ANY_KERNEL_ADDRESS
, B_PAGE_SIZE
, B_FULL_LOCK
,
480 B_KERNEL_READ_AREA
| B_KERNEL_WRITE_AREA
);
481 if (scratchCreator
.InitCheck() < B_OK
) {
482 ERROR("could not create scratch page!\n");
483 return info
.scratch_area
;
486 physical_entry entry
;
487 if (get_memory_map(scratchAddress
, B_PAGE_SIZE
, &entry
, 1) != B_OK
)
490 // TODO: Review these
491 if (info
.type
->InFamily(INTEL_FAMILY_8xx
)) {
492 info
.gtt_physical_base
= read32(info
.registers
493 + INTEL_PAGE_TABLE_CONTROL
) & ~PAGE_TABLE_ENABLED
;
494 if (info
.gtt_physical_base
== 0) {
495 // TODO: not sure how this is supposed to work under Linux/FreeBSD,
496 // but on my i865, this code is needed for Haiku.
497 ERROR("Use GTT address fallback.\n");
498 info
.gtt_physical_base
= info
.display
.u
.h0
.base_registers
[mmioIndex
]
501 } else if (info
.type
->InGroup(INTEL_GROUP_91x
)) {
502 info
.gtt_physical_base
= get_pci_config(info
.display
, i915_GTT_BASE
, 4);
505 info
.gtt_physical_base
= info
.display
.u
.h0
.base_registers
[mmioIndex
]
509 size_t gttSize
= determine_gtt_size(info
);
510 size_t stolenSize
= determine_gtt_stolen(info
);
512 info
.gtt_entries
= gttSize
/ 4096;
513 info
.gtt_stolen_entries
= stolenSize
/ 4096;
515 TRACE("GTT base %" B_PRIxPHYSADDR
", size %lu, entries %lu, stolen %lu\n",
516 info
.gtt_physical_base
, gttSize
, info
.gtt_entries
, stolenSize
);
518 AreaKeeper gttMapper
;
519 info
.gtt_area
= gttMapper
.Map("intel GMCH gtt",
520 info
.gtt_physical_base
, gttSize
, B_ANY_KERNEL_ADDRESS
,
521 B_KERNEL_READ_AREA
| B_KERNEL_WRITE_AREA
, (void**)&info
.gtt_base
);
522 if (gttMapper
.InitCheck() < B_OK
) {
523 ERROR("could not map GTT!\n");
524 return info
.gtt_area
;
527 info
.aperture_physical_base
= info
.display
.u
.h0
.base_registers
[fbIndex
];
528 info
.aperture_stolen_size
= stolenSize
;
529 if (info
.aperture_size
== 0)
530 info
.aperture_size
= info
.display
.u
.h0
.base_register_sizes
[fbIndex
];
532 ERROR("detected %ld MB of stolen memory, aperture size %ld MB, "
533 "GTT size %ld KB\n", (stolenSize
+ (1023 << 10)) >> 20,
534 info
.aperture_size
>> 20, gttSize
>> 10);
536 ERROR("GTT base = 0x%" B_PRIxPHYSADDR
"\n", info
.gtt_physical_base
);
537 ERROR("MMIO base = 0x%" B_PRIx32
"\n",
538 info
.display
.u
.h0
.base_registers
[mmioIndex
]);
539 ERROR("GMR base = 0x%" B_PRIxPHYSADDR
"\n", info
.aperture_physical_base
);
541 AreaKeeper apertureMapper
;
542 info
.aperture_area
= apertureMapper
.Map("intel graphics aperture",
543 info
.aperture_physical_base
, info
.aperture_size
,
544 B_ANY_KERNEL_BLOCK_ADDRESS
| B_MTR_WC
,
545 B_READ_AREA
| B_WRITE_AREA
, (void**)&info
.aperture_base
);
546 if (apertureMapper
.InitCheck() < B_OK
) {
547 // try again without write combining
548 ERROR("enabling write combined mode failed.\n");
550 info
.aperture_area
= apertureMapper
.Map("intel graphics aperture",
551 info
.aperture_physical_base
, info
.aperture_size
,
552 B_ANY_KERNEL_BLOCK_ADDRESS
, B_READ_AREA
| B_WRITE_AREA
,
553 (void**)&info
.aperture_base
);
555 if (apertureMapper
.InitCheck() < B_OK
) {
556 ERROR("could not map graphics aperture!\n");
557 return info
.aperture_area
;
560 info
.scratch_page
= entry
.address
;
564 scratchCreator
.Detach();
565 apertureMapper
.Detach();
571 // #pragma mark - module interface
575 intel_create_aperture(uint8 bus
, uint8 device
, uint8 function
, size_t size
,
578 // TODO: we currently only support a single AGP bridge!
579 if ((bus
!= sInfo
.bridge
.bus
|| device
!= sInfo
.bridge
.device
580 || function
!= sInfo
.bridge
.function
)
581 && (bus
!= sInfo
.display
.bus
|| device
!= sInfo
.display
.device
582 || function
!= sInfo
.display
.function
))
585 sInfo
.aperture_size
= size
;
587 if (intel_map(sInfo
) < B_OK
)
590 uint16 gmchControl
= get_pci_config(sInfo
.bridge
,
591 INTEL_GRAPHICS_MEMORY_CONTROL
, 2) | MEMORY_CONTROL_ENABLED
;
592 set_pci_config(sInfo
.bridge
, INTEL_GRAPHICS_MEMORY_CONTROL
, 2, gmchControl
);
594 write32(sInfo
.registers
+ INTEL_PAGE_TABLE_CONTROL
,
595 sInfo
.gtt_physical_base
| PAGE_TABLE_ENABLED
);
596 read32(sInfo
.registers
+ INTEL_PAGE_TABLE_CONTROL
);
598 if (sInfo
.scratch_page
!= 0) {
599 for (size_t i
= sInfo
.gtt_stolen_entries
; i
< sInfo
.gtt_entries
; i
++) {
600 set_gtt_entry(sInfo
, i
<< GTT_PAGE_SHIFT
, sInfo
.scratch_page
);
602 read32(sInfo
.gtt_base
+ sInfo
.gtt_entries
- 1);
613 intel_delete_aperture(void* aperture
)
620 intel_get_aperture_info(void* aperture
, aperture_info
* info
)
625 info
->base
= sInfo
.aperture_base
;
626 info
->physical_base
= sInfo
.aperture_physical_base
;
627 info
->size
= sInfo
.aperture_size
;
628 info
->reserved_size
= sInfo
.aperture_stolen_size
;
635 intel_set_aperture_size(void* aperture
, size_t size
)
642 intel_bind_page(void* aperture
, uint32 offset
, phys_addr_t physicalAddress
)
644 //TRACE("bind_page(offset %lx, physical %lx)\n", offset, physicalAddress);
646 set_gtt_entry(sInfo
, offset
, physicalAddress
);
652 intel_unbind_page(void* aperture
, uint32 offset
)
654 //TRACE("unbind_page(offset %lx)\n", offset);
656 if (sInfo
.scratch_page
!= 0)
657 set_gtt_entry(sInfo
, offset
, sInfo
.scratch_page
);
664 intel_flush_tlbs(void* aperture
)
666 read32(sInfo
.gtt_base
+ sInfo
.gtt_entries
- 1);
677 TRACE("bus manager init\n");
679 if (get_module(B_PCI_MODULE_NAME
, (module_info
**)&sPCI
) != B_OK
)
682 for (uint32 index
= 0; sPCI
->get_nth_pci_info(index
, &sInfo
.bridge
) == B_OK
;
684 if (sInfo
.bridge
.vendor_id
!= VENDOR_ID_INTEL
685 || sInfo
.bridge
.class_base
!= PCI_bridge
)
689 for (uint32 i
= 0; i
< sizeof(kSupportedDevices
)
690 / sizeof(kSupportedDevices
[0]); i
++) {
691 if (sInfo
.bridge
.device_id
== kSupportedDevices
[i
].bridge_id
) {
692 sInfo
.type
= new DeviceType(kSupportedDevices
[i
].type
);
693 if (has_display_device(sInfo
.display
,
694 kSupportedDevices
[i
].display_id
)) {
695 TRACE("found intel bridge\n");
715 intel_std_ops(int32 op
, ...)
720 case B_MODULE_UNINIT
:
729 static struct agp_gart_bus_module_info sIntelModuleInfo
= {
731 "busses/agp_gart/intel/v0",
736 intel_create_aperture
,
737 intel_delete_aperture
,
739 intel_get_aperture_info
,
740 intel_set_aperture_size
,
746 module_info
* modules
[] = {
747 (module_info
*)&sIntelModuleInfo
,