Work in progress (might not work for you yet):

* Now uses the AGP GART module for memory management. This greatly simplifies
  the memory handling, and memory is now actually allocated on demand,
  instead of a fixed size (stolen memory is not freed, though).
* The Intel GART module should now also work with older chipsets.
* No longer remove the GTT size from the stolen memory; this appears to have
  been a mistake in the X driver. Not sure about the BIOS popup yet.
* The AGP module (in combination with the Intel GART module) is now mandatory
  to use the Intel driver.
* Removed now superfluous settings (like memory size). Only enabling/disabling
  the hardware cursor is still supported.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23781 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-01-29 08:55:36 +00:00
parent 3cad4dae71
commit 1c34b9b1f5
16 changed files with 208 additions and 403 deletions

View File

@ -11,8 +11,6 @@
#include "lock.h" #include "lock.h"
#include <memory_manager.h>
#include <Accelerant.h> #include <Accelerant.h>
#include <Drivers.h> #include <Drivers.h>
#include <PCI.h> #include <PCI.h>
@ -46,7 +44,6 @@ struct pll_info {
struct ring_buffer { struct ring_buffer {
struct lock lock; struct lock lock;
uint32 register_base; uint32 register_base;
uint32 handle;
uint32 offset; uint32 offset;
uint32 size; uint32 size;
uint32 position; uint32 position;
@ -66,13 +63,13 @@ struct intel_shared_info {
uint32 dpms_mode; uint32 dpms_mode;
area_id registers_area; // area of memory mapped registers area_id registers_area; // area of memory mapped registers
uint8 *physical_status_page; uint8 *status_page;
uint8 *physical_cursor_memory; addr_t physical_status_page;
area_id graphics_memory_area;
uint8 *graphics_memory; uint8 *graphics_memory;
uint8 *physical_graphics_memory; addr_t physical_graphics_memory;
uint32 graphics_memory_size; uint32 graphics_memory_size;
addr_t frame_buffer;
uint32 frame_buffer_offset; uint32 frame_buffer_offset;
struct lock accelerant_lock; struct lock accelerant_lock;
@ -84,12 +81,14 @@ struct intel_shared_info {
int32 overlay_channel_used; int32 overlay_channel_used;
bool overlay_active; bool overlay_active;
uint32 overlay_token; uint32 overlay_token;
uint8* physical_overlay_registers; addr_t physical_overlay_registers;
uint32 overlay_offset; uint32 overlay_offset;
bool hardware_cursor_enabled; bool hardware_cursor_enabled;
sem_id vblank_sem; sem_id vblank_sem;
uint8 *cursor_memory;
addr_t physical_cursor_memory;
uint32 cursor_buffer_offset; uint32 cursor_buffer_offset;
uint32 cursor_format; uint32 cursor_format;
bool cursor_visible; bool cursor_visible;
@ -125,14 +124,15 @@ struct intel_get_private_data {
struct intel_allocate_graphics_memory { struct intel_allocate_graphics_memory {
uint32 magic; uint32 magic;
uint32 size; uint32 size;
uint32 buffer_offset; uint32 alignment;
uint32 handle; uint32 flags;
uint32 buffer_base;
}; };
// free graphics memory // free graphics memory
struct intel_free_graphics_memory { struct intel_free_graphics_memory {
uint32 magic; uint32 magic;
uint32 handle; uint32 buffer_base;
}; };
//---------------------------------------------------------- //----------------------------------------------------------
@ -540,6 +540,13 @@ struct overlay_registers {
#define INTEL_i965_OVERLAY_STATE_SIZE 36864 #define INTEL_i965_OVERLAY_STATE_SIZE 36864
#define INTEL_i965_3D_CONTEXT_SIZE 32768 #define INTEL_i965_3D_CONTEXT_SIZE 32768
inline bool
intel_uses_physical_overlay(intel_shared_info &info)
{
return info.device_type != INTEL_TYPE_G33;
}
struct hardware_status { struct hardware_status {
uint32 interrupt_status_register; uint32 interrupt_status_register;
uint32 _reserved0[3]; uint32 _reserved0[3];

View File

@ -18,6 +18,8 @@
#include <unistd.h> #include <unistd.h>
#include <syslog.h> #include <syslog.h>
#include <AGP.h>
#define TRACE_ACCELERANT #define TRACE_ACCELERANT
#ifdef TRACE_ACCELERANT #ifdef TRACE_ACCELERANT
@ -133,17 +135,17 @@ init_common(int device, bool isClone)
// The overlay registers, hardware status, and cursor memory share // The overlay registers, hardware status, and cursor memory share
// a single area with the shared_info // a single area with the shared_info
gInfo->overlay_registers = (struct overlay_registers *)((uint8 *)gInfo->shared_info gInfo->overlay_registers = (struct overlay_registers *)
+ ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info))); (gInfo->shared_info->graphics_memory
gInfo->status = (hardware_status *)((uint8 *)gInfo->overlay_registers + B_PAGE_SIZE); + gInfo->shared_info->overlay_offset);
if (gInfo->shared_info->hardware_cursor_enabled)
gInfo->cursor_memory = (uint8 *)gInfo->overlay_registers + 2 * B_PAGE_SIZE;
if (gInfo->shared_info->device_type == INTEL_TYPE_965) { if (gInfo->shared_info->device_type == INTEL_TYPE_965) {
// allocate some extra memory for the 3D context // allocate some extra memory for the 3D context
intel_allocate_memory(INTEL_i965_3D_CONTEXT_SIZE, gInfo->context_handle, if (intel_allocate_memory(INTEL_i965_3D_CONTEXT_SIZE,
gInfo->context_offset); B_APERTURE_NON_RESERVED, gInfo->context_base) == B_OK) {
gInfo->context_offset = gInfo->context_base
- (addr_t)gInfo->shared_info->graphics_memory;
}
} }
return B_OK; return B_OK;
@ -154,7 +156,7 @@ init_common(int device, bool isClone)
static void static void
uninit_common(void) uninit_common(void)
{ {
intel_free_memory(gInfo->context_handle); intel_free_memory(gInfo->context_base);
delete_area(gInfo->regs_area); delete_area(gInfo->regs_area);
delete_area(gInfo->shared_info_area); delete_area(gInfo->shared_info_area);

View File

@ -17,9 +17,9 @@
struct overlay { struct overlay {
overlay_buffer buffer; overlay_buffer buffer;
uint32 buffer_handle; addr_t buffer_base;
uint32 buffer_offset; uint32 buffer_offset;
uint32 state_handle; addr_t state_base;
uint32 state_offset; uint32 state_offset;
}; };
@ -40,8 +40,6 @@ struct accelerant_info {
display_mode *mode_list; // cloned list of standard display modes display_mode *mode_list; // cloned list of standard display modes
area_id mode_list_area; area_id mode_list_area;
uint32 frame_buffer_handle;
struct overlay_registers *overlay_registers; struct overlay_registers *overlay_registers;
overlay *current_overlay; overlay *current_overlay;
overlay_view last_overlay_view; overlay_view last_overlay_view;
@ -50,14 +48,11 @@ struct accelerant_info {
uint32 last_vertical_overlay_scale; uint32 last_vertical_overlay_scale;
uint32 overlay_position_buffer_offset; uint32 overlay_position_buffer_offset;
hardware_status *status;
uint8 *cursor_memory;
edid1_info edid_info; edid1_info edid_info;
bool has_edid; bool has_edid;
// limited 3D support for overlay on i965 // limited 3D support for overlay on i965
uint32 context_handle; addr_t context_base;
uint32 context_offset; uint32 context_offset;
bool context_set; bool context_set;
@ -101,7 +96,7 @@ extern void set_frame_buffer_base(void);
extern status_t create_mode_list(void); extern status_t create_mode_list(void);
// memory.cpp // memory.cpp
extern void intel_free_memory(uint32 handle); extern void intel_free_memory(uint32 base);
extern status_t intel_allocate_memory(size_t size, uint32& handle, uint32& offset); extern status_t intel_allocate_memory(size_t size, uint32 flags, uint32 &base);
#endif /* INTEL_EXTREME_ACCELERANT_H */ #endif /* INTEL_EXTREME_ACCELERANT_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All Rights Reserved. * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All Rights Reserved. * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@ -33,7 +33,7 @@ intel_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY,
// transparent, for 0x3 it inverts the background, so only the first // transparent, for 0x3 it inverts the background, so only the first
// two palette entries will be used (since we're using the 2 color mode). // two palette entries will be used (since we're using the 2 color mode).
uint8 *data = gInfo->cursor_memory; uint8 *data = gInfo->shared_info->cursor_memory;
uint8 byteWidth = (width + 7) / 8; uint8 byteWidth = (width + 7) / 8;
for (int32 y = 0; y < height; y++) { for (int32 y = 0; y < height; y++) {

View File

@ -97,11 +97,11 @@ QueueCommands::PutOverlayFlip(uint32 mode, bool updateCoefficients)
Write(COMMAND_OVERLAY_FLIP | mode); Write(COMMAND_OVERLAY_FLIP | mode);
uint32 registers; uint32 registers;
if (gInfo->shared_info->overlay_offset != 0) { // G33 does not need a physical address for the overlay registers
// G33 does not need a physical address for the overlay registers if (intel_uses_physical_overlay(*gInfo->shared_info))
registers = gInfo->shared_info->physical_overlay_registers;
else
registers = gInfo->shared_info->overlay_offset; registers = gInfo->shared_info->overlay_offset;
} else
registers = (uint32)gInfo->shared_info->physical_overlay_registers;
Write(registers | (updateCoefficients ? OVERLAY_UPDATE_COEFFICIENTS : 0)); Write(registers | (updateCoefficients ? OVERLAY_UPDATE_COEFFICIENTS : 0));
} }

View File

@ -67,13 +67,13 @@ get_accelerant_hook(uint32 feature, void *data)
/* cursor managment */ /* cursor managment */
case B_SET_CURSOR_SHAPE: case B_SET_CURSOR_SHAPE:
if (gInfo->cursor_memory != NULL) if (gInfo->shared_info->cursor_memory != NULL)
return (void*)intel_set_cursor_shape; return (void*)intel_set_cursor_shape;
case B_MOVE_CURSOR: case B_MOVE_CURSOR:
if (gInfo->cursor_memory != NULL) if (gInfo->shared_info->cursor_memory != NULL)
return (void*)intel_move_cursor; return (void*)intel_move_cursor;
case B_SHOW_CURSOR: case B_SHOW_CURSOR:
if (gInfo->cursor_memory != NULL) if (gInfo->shared_info->cursor_memory != NULL)
return (void*)intel_show_cursor; return (void*)intel_show_cursor;
return NULL; return NULL;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All Rights Reserved. * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@ -24,32 +24,34 @@ extern "C" void _sPrintf(const char *format, ...);
void void
intel_free_memory(uint32 handle) intel_free_memory(uint32 base)
{ {
if (!handle) if (base == 0)
return; return;
intel_free_graphics_memory freeMemory; intel_free_graphics_memory freeMemory;
freeMemory.magic = INTEL_PRIVATE_DATA_MAGIC; freeMemory.magic = INTEL_PRIVATE_DATA_MAGIC;
freeMemory.handle = handle; freeMemory.buffer_base = base;
ioctl(gInfo->device, INTEL_FREE_GRAPHICS_MEMORY, &freeMemory, sizeof(freeMemory)); ioctl(gInfo->device, INTEL_FREE_GRAPHICS_MEMORY, &freeMemory,
sizeof(freeMemory));
} }
status_t status_t
intel_allocate_memory(size_t size, uint32& handle, uint32& offset) intel_allocate_memory(size_t size, uint32 flags, uint32 &base)
{ {
intel_allocate_graphics_memory allocMemory; intel_allocate_graphics_memory allocMemory;
allocMemory.magic = INTEL_PRIVATE_DATA_MAGIC; allocMemory.magic = INTEL_PRIVATE_DATA_MAGIC;
allocMemory.size = size; allocMemory.size = size;
allocMemory.alignment = 0;
allocMemory.flags = flags;
if (ioctl(gInfo->device, INTEL_ALLOCATE_GRAPHICS_MEMORY, &allocMemory, sizeof(allocMemory)) < 0) if (ioctl(gInfo->device, INTEL_ALLOCATE_GRAPHICS_MEMORY, &allocMemory,
sizeof(allocMemory)) < 0)
return errno; return errno;
handle = allocMemory.handle; base = allocMemory.buffer_base;
offset = allocMemory.buffer_offset;
return B_OK; return B_OK;
} }

View File

@ -417,16 +417,17 @@ if (first) {
// free old and allocate new frame buffer in graphics memory // free old and allocate new frame buffer in graphics memory
intel_free_memory(gInfo->frame_buffer_handle); intel_free_memory(sharedInfo.frame_buffer);
uint32 offset; uint32 base;
if (intel_allocate_memory(bytesPerRow * target.virtual_height, if (intel_allocate_memory(bytesPerRow * target.virtual_height, 0,
gInfo->frame_buffer_handle, offset) < B_OK) { base) < B_OK) {
// oh, how did that happen? Unfortunately, there is no really good way back // oh, how did that happen? Unfortunately, there is no really good way back
if (intel_allocate_memory(sharedInfo.current_mode.virtual_height if (intel_allocate_memory(sharedInfo.current_mode.virtual_height
* sharedInfo.bytes_per_row, gInfo->frame_buffer_handle, * sharedInfo.bytes_per_row, 0, base) == B_OK) {
offset) == B_OK) { sharedInfo.frame_buffer = base;
sharedInfo.frame_buffer_offset = offset; sharedInfo.frame_buffer_offset = base
- (addr_t)sharedInfo.graphics_memory;
set_frame_buffer_base(); set_frame_buffer_base();
} }
@ -434,9 +435,9 @@ if (first) {
} }
// clear frame buffer before using it // clear frame buffer before using it
memset(sharedInfo.graphics_memory + offset, 0, memset((uint8 *)base, 0, bytesPerRow * target.virtual_height);
bytesPerRow * target.virtual_height); sharedInfo.frame_buffer = base;
sharedInfo.frame_buffer_offset = offset; sharedInfo.frame_buffer_offset = base - (addr_t)sharedInfo.graphics_memory;
// make sure VGA display is disabled // make sure VGA display is disabled
write32(INTEL_VGA_DISPLAY_CONTROL, VGA_DISPLAY_DISABLED); write32(INTEL_VGA_DISPLAY_CONTROL, VGA_DISPLAY_DISABLED);
@ -673,7 +674,8 @@ intel_get_frame_buffer_config(frame_buffer_config *config)
uint32 offset = gInfo->shared_info->frame_buffer_offset; uint32 offset = gInfo->shared_info->frame_buffer_offset;
config->frame_buffer = gInfo->shared_info->graphics_memory + offset; config->frame_buffer = gInfo->shared_info->graphics_memory + offset;
config->frame_buffer_dma = gInfo->shared_info->physical_graphics_memory + offset; config->frame_buffer_dma
= (uint8 *)gInfo->shared_info->physical_graphics_memory + offset;
config->bytes_per_row = gInfo->shared_info->bytes_per_row; config->bytes_per_row = gInfo->shared_info->bytes_per_row;
return B_OK; return B_OK;

View File

@ -18,6 +18,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <AGP.h>
//#define TRACE_OVERLAY //#define TRACE_OVERLAY
#ifdef TRACE_OVERLAY #ifdef TRACE_OVERLAY
@ -42,8 +44,7 @@ struct phase_coefficient {
}; };
/*! /*! Splits the coefficient floating point value into the 3 components
Splits the coefficient floating point value into the 3 components
sign, mantissa, and exponent. sign, mantissa, and exponent.
*/ */
static bool static bool
@ -179,8 +180,8 @@ update_coefficients(int32 taps, double filterCutOff, bool horizontal, bool isY,
static void static void
set_color_key(uint8 red, uint8 green, uint8 blue, set_color_key(uint8 red, uint8 green, uint8 blue, uint8 redMask,
uint8 redMask, uint8 greenMask, uint8 blueMask) uint8 greenMask, uint8 blueMask)
{ {
overlay_registers *registers = gInfo->overlay_registers; overlay_registers *registers = gInfo->overlay_registers;
@ -224,7 +225,8 @@ set_color_key(const overlay_window *window)
static void static void
update_overlay(bool updateCoefficients) update_overlay(bool updateCoefficients)
{ {
if (!gInfo->shared_info->overlay_active) if (!gInfo->shared_info->overlay_active
|| gInfo->shared_info->device_type == INTEL_TYPE_965)
return; return;
QueueCommands queue(gInfo->shared_info->secondary_ring_buffer); QueueCommands queue(gInfo->shared_info->secondary_ring_buffer);
@ -245,7 +247,8 @@ update_overlay(bool updateCoefficients)
static void static void
show_overlay(void) show_overlay(void)
{ {
if (gInfo->shared_info->overlay_active) if (gInfo->shared_info->overlay_active
|| gInfo->shared_info->device_type == INTEL_TYPE_965)
return; return;
gInfo->shared_info->overlay_active = true; gInfo->shared_info->overlay_active = true;
@ -260,7 +263,8 @@ show_overlay(void)
static void static void
hide_overlay(void) hide_overlay(void)
{ {
if (!gInfo->shared_info->overlay_active) if (!gInfo->shared_info->overlay_active
|| gInfo->shared_info->device_type == INTEL_TYPE_965)
return; return;
overlay_registers *registers = gInfo->overlay_registers; overlay_registers *registers = gInfo->overlay_registers;
@ -364,7 +368,7 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
buffer->bytes_per_row = (width * bytesPerPixel + 0x3f) & ~0x3f; buffer->bytes_per_row = (width * bytesPerPixel + 0x3f) & ~0x3f;
status_t status = intel_allocate_memory(buffer->bytes_per_row * height, status_t status = intel_allocate_memory(buffer->bytes_per_row * height,
overlay->buffer_handle, overlay->buffer_offset); 0, overlay->buffer_base);
if (status < B_OK) { if (status < B_OK) {
free(overlay); free(overlay);
return NULL; return NULL;
@ -372,18 +376,22 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
if (sharedInfo.device_type == INTEL_TYPE_965) { if (sharedInfo.device_type == INTEL_TYPE_965) {
status = intel_allocate_memory(INTEL_i965_OVERLAY_STATE_SIZE, status = intel_allocate_memory(INTEL_i965_OVERLAY_STATE_SIZE,
overlay->state_handle, overlay->state_offset); B_APERTURE_NON_RESERVED, overlay->state_base);
if (status < B_OK) { if (status < B_OK) {
intel_free_memory(overlay->buffer_handle); intel_free_memory(overlay->buffer_base);
free(overlay); free(overlay);
return NULL; return NULL;
} }
} else
overlay->state_handle = 0;
buffer->buffer = gInfo->shared_info->graphics_memory overlay->state_offset = overlay->state_base
+ overlay->buffer_offset; - (addr_t)gInfo->shared_info->graphics_memory;
buffer->buffer_dma = gInfo->shared_info->physical_graphics_memory }
overlay->buffer_offset = overlay->buffer_base
- (addr_t)gInfo->shared_info->graphics_memory;
buffer->buffer = (uint8 *)overlay->buffer_base;
buffer->buffer_dma = (uint8 *)gInfo->shared_info->physical_graphics_memory
+ overlay->buffer_offset; + overlay->buffer_offset;
TRACE(("allocated overlay buffer: handle=%x, offset=%x, address=%x, " TRACE(("allocated overlay buffer: handle=%x, offset=%x, address=%x, "
@ -406,8 +414,9 @@ intel_release_overlay_buffer(const overlay_buffer *buffer)
if (gInfo->current_overlay == overlay) if (gInfo->current_overlay == overlay)
hide_overlay(); hide_overlay();
intel_free_memory(overlay->buffer_handle); intel_free_memory(overlay->buffer_base);
intel_free_memory(overlay->state_handle); if (gInfo->shared_info->device_type == INTEL_TYPE_965)
intel_free_memory(overlay->state_base);
free(overlay); free(overlay);
return B_OK; return B_OK;

View File

@ -127,30 +127,28 @@ determine_memory_sizes(intel_info &info, size_t &gttSize, size_t &stolenSize)
break; break;
} }
} else { } else {
#if 0
// older models have the GTT as large as their frame buffer mapping // older models have the GTT as large as their frame buffer mapping
// TODO: check if the i9xx version works with the i8xx chips as well // TODO: check if the i9xx version works with the i8xx chips as well
size_t frameBufferSize = 0; size_t frameBufferSize = 0;
if ((info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_8xx) { if ((info.type & INTEL_TYPE_8xx) != 0) {
if ((info.device_type & INTEL_TYPE_83x) != 0 if (info.type == INTEL_TYPE_83x
&& (memoryConfig & MEMORY_MASK) == i830_FRAME_BUFFER_64M) && (memoryConfig & MEMORY_MASK) == i830_FRAME_BUFFER_64M)
frameBufferSize = 64 << 20; frameBufferSize = 64 << 20;
else else
frameBufferSize = 128 << 20; frameBufferSize = 128 << 20;
} else if ((info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx) } else if ((info.type & INTEL_TYPE_9xx) != 0)
frameBufferSize = info.pci->u.h0.base_register_sizes[2]; frameBufferSize = info.display.u.h0.base_register_sizes[2];
gttSize = frameBufferSize / 1024; gttSize = frameBufferSize / 1024;
#endif
} }
#if 0
// TODO: test with different models! // TODO: test with different models!
if (info.device_type == (INTEL_TYPE_8xx | INTEL_TYPE_83x)) { if (info.type == INTEL_TYPE_83x) {
switch (memoryConfig & STOLEN_MEMORY_MASK) { switch (memoryConfig & STOLEN_MEMORY_MASK) {
case i830_LOCAL_MEMORY_ONLY: case i830_LOCAL_MEMORY_ONLY:
// TODO: determine its size! // TODO: determine its size!
dprintf("intel_gart: getting local memory size not implemented.\n");
break; break;
case i830_STOLEN_512K: case i830_STOLEN_512K:
memorySize >>= 1; memorySize >>= 1;
@ -159,10 +157,8 @@ determine_memory_sizes(intel_info &info, size_t &gttSize, size_t &stolenSize)
memorySize *= 8; memorySize *= 8;
break; break;
} }
} else if (info.device_type == (INTEL_TYPE_8xx | INTEL_TYPE_85x) } else if (info.type == INTEL_TYPE_85x
|| (info.device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx) || (info.type & INTEL_TYPE_9xx) != 0) {
#endif
{
switch (memoryConfig & STOLEN_MEMORY_MASK) { switch (memoryConfig & STOLEN_MEMORY_MASK) {
case i855_STOLEN_MEMORY_4M: case i855_STOLEN_MEMORY_4M:
memorySize *= 4; memorySize *= 4;
@ -191,7 +187,9 @@ determine_memory_sizes(intel_info &info, size_t &gttSize, size_t &stolenSize)
} }
} }
stolenSize = memorySize - gttSize - 4096; // TODO: this is probably wrong after all (taken from X driver)
// the stolen memory does not host the GTT!
stolenSize = memorySize /*- gttSize - 4096*/;
} }
@ -272,7 +270,11 @@ dprintf("GTT base %lx, size %lu, entries %lu, stolen %lu\n", info.gtt_physical_b
info.aperture_physical_base = info.display.u.h0.base_registers[fbIndex]; info.aperture_physical_base = info.display.u.h0.base_registers[fbIndex];
info.aperture_stolen_size = stolenSize; info.aperture_stolen_size = stolenSize;
if (info.aperture_size == 0) if (info.aperture_size == 0)
info.aperture_size = info.display.u.h0.base_register_sizes[0]; info.aperture_size = info.display.u.h0.base_register_sizes[fbIndex];
dprintf("intel_gart: detected %ld MB of stolen memory, aperture size %ld "
"MB, GTT size %ld KB\n", stolenSize >> 20, info.aperture_size >> 20,
gttSize >> 10);
AreaKeeper apertureMapper; AreaKeeper apertureMapper;
info.aperture_area = apertureMapper.Map("intel graphics aperture", info.aperture_area = apertureMapper.Map("intel graphics aperture",

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@ -222,8 +222,9 @@ device_ioctl(void *data, uint32 op, void *buffer, size_t bufferLength)
if (allocMemory.magic != INTEL_PRIVATE_DATA_MAGIC) if (allocMemory.magic != INTEL_PRIVATE_DATA_MAGIC)
return B_BAD_VALUE; return B_BAD_VALUE;
status_t status = mem_alloc(info->memory_manager, allocMemory.size, info, status_t status = intel_allocate_memory(*info, allocMemory.size,
&allocMemory.handle, &allocMemory.buffer_offset); allocMemory.alignment, allocMemory.flags,
(addr_t *)&allocMemory.buffer_base);
if (status == B_OK) { if (status == B_OK) {
// copy result // copy result
#ifdef __HAIKU__ #ifdef __HAIKU__
@ -231,7 +232,8 @@ device_ioctl(void *data, uint32 op, void *buffer, size_t bufferLength)
sizeof(intel_allocate_graphics_memory)) < B_OK) sizeof(intel_allocate_graphics_memory)) < B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
#else #else
memcpy(buffer, &allocMemory, sizeof(intel_allocate_graphics_memory)); memcpy(buffer, &allocMemory,
sizeof(intel_allocate_graphics_memory));
#endif #endif
} }
return status; return status;
@ -249,7 +251,7 @@ device_ioctl(void *data, uint32 op, void *buffer, size_t bufferLength)
#endif #endif
if (freeMemory.magic == INTEL_PRIVATE_DATA_MAGIC) if (freeMemory.magic == INTEL_PRIVATE_DATA_MAGIC)
return mem_free(info->memory_manager, freeMemory.handle, info); return intel_free_memory(*info, freeMemory.buffer_base);
break; break;
} }

View File

@ -132,13 +132,19 @@ init_driver(void)
return status; return status;
} }
status = init_lock(&gLock, "intel extreme ksync"); status = get_module(B_AGP_GART_MODULE_NAME, (module_info **)&gGART);
if (status < B_OK) { if (status != B_OK) {
TRACE((DEVICE_NAME ": AGP GART module unavailable\n"));
put_module(B_PCI_MODULE_NAME); put_module(B_PCI_MODULE_NAME);
return status; return status;
} }
get_module(B_AGP_GART_MODULE_NAME, (module_info **)&gGART); status = init_lock(&gLock, "intel extreme ksync");
if (status < B_OK) {
put_module(B_AGP_GART_MODULE_NAME);
put_module(B_PCI_MODULE_NAME);
return status;
}
// find devices // find devices
@ -185,6 +191,7 @@ init_driver(void)
dprintf(DEVICE_NAME ": (%ld) %s, revision = 0x%x\n", found, dprintf(DEVICE_NAME ": (%ld) %s, revision = 0x%x\n", found,
kSupportedDevices[type].name, info->revision); kSupportedDevices[type].name, info->revision);
found++; found++;
} }
@ -192,8 +199,7 @@ init_driver(void)
if (found == 0) { if (found == 0) {
uninit_lock(&gLock); uninit_lock(&gLock);
if (gGART != NULL) put_module(B_AGP_GART_MODULE_NAME);
put_module(B_AGP_GART_MODULE_NAME);
put_module(B_PCI_MODULE_NAME); put_module(B_PCI_MODULE_NAME);
return ENODEV; return ENODEV;
} }
@ -216,8 +222,7 @@ uninit_driver(void)
free(name); free(name);
} }
if (gGART != NULL) put_module(B_AGP_GART_MODULE_NAME);
put_module(B_AGP_GART_MODULE_NAME);
put_module(B_PCI_MODULE_NAME); put_module(B_PCI_MODULE_NAME);
} }

View File

@ -28,6 +28,7 @@
extern char *gDeviceNames[]; extern char *gDeviceNames[];
extern intel_info *gDeviceInfo[]; extern intel_info *gDeviceInfo[];
extern pci_module_info *gPCI; extern pci_module_info *gPCI;
extern agp_gart_module_info *gGART;
extern struct lock gLock; extern struct lock gLock;

View File

@ -42,142 +42,17 @@ init_overlay_registers(overlay_registers *registers)
static void static void
read_settings(size_t &memorySize, bool &hardwareCursor, bool &ignoreAllocated) read_settings(bool &hardwareCursor)
{ {
size_t size = 8; // 8 MB
hardwareCursor = false; hardwareCursor = false;
ignoreAllocated = false;
void *settings = load_driver_settings("intel_extreme"); void *settings = load_driver_settings("intel_extreme");
if (settings != NULL) { if (settings != NULL) {
size_t specified = 0;
const char *string = get_driver_parameter(settings,
"graphics_memory_size", "0", "0");
if (string != NULL)
specified = atoi(string);
hardwareCursor = get_driver_boolean_parameter(settings, hardwareCursor = get_driver_boolean_parameter(settings,
"hardware_cursor", true, true); "hardware_cursor", true, true);
ignoreAllocated = get_driver_boolean_parameter(settings,
"ignore_bios_allocated_memory", false, false);
unload_driver_settings(settings); unload_driver_settings(settings);
if (specified != 0) {
// take the next power of two
size_t desired = 1;
while (desired < specified) {
desired *= 2;
}
if (desired < 128)
size = desired;
}
} }
memorySize = size << 20;
}
static size_t
determine_stolen_memory_size(intel_info &info)
{
// read stolen memory from the PCI configuration of the PCI bridge
uint16 memoryConfig = gPCI->read_pci_config(0, 0, 0, INTEL_GRAPHICS_MEMORY_CONTROL, 2);
size_t memorySize = 1 << 20; // 1 MB
size_t gttSize = 0;
if (info.device_type == INTEL_TYPE_965) {
switch (memoryConfig & i965_GTT_MASK) {
case i965_GTT_128K:
gttSize = 128 << 10;
break;
case i965_GTT_256K:
gttSize = 256 << 10;
break;
case i965_GTT_512K:
gttSize = 512 << 10;
break;
}
} else if (info.device_type == INTEL_TYPE_G33) {
switch (memoryConfig & G33_GTT_MASK) {
case G33_GTT_1M:
gttSize = 1 << 20;
break;
case G33_GTT_2M:
gttSize = 2 << 20;
break;
}
} else {
// older models have the GTT as large as their frame buffer mapping
// TODO: check if the i9xx version works with the i8xx chips as well
size_t frameBufferSize = 0;
if ((info.device_type & INTEL_TYPE_8xx) != 0) {
if (info.device_type == INTEL_TYPE_83x
&& (memoryConfig & MEMORY_MASK) == i830_FRAME_BUFFER_64M)
frameBufferSize = 64 << 20;
else
frameBufferSize = 128 << 20;
} else if ((info.device_type & INTEL_TYPE_9xx) != 0)
frameBufferSize = info.pci->u.h0.base_register_sizes[2];
gttSize = frameBufferSize / 1024;
}
// TODO: test with different models!
if (info.device_type == INTEL_TYPE_83x) {
switch (memoryConfig & STOLEN_MEMORY_MASK) {
case i830_LOCAL_MEMORY_ONLY:
// TODO: determine its size!
break;
case i830_STOLEN_512K:
memorySize >>= 1;
break;
case i830_STOLEN_8M:
memorySize *= 8;
break;
}
} else if (info.device_type == INTEL_TYPE_85x
|| (info.device_type & INTEL_TYPE_9xx) != 0) {
switch (memoryConfig & STOLEN_MEMORY_MASK) {
case i855_STOLEN_MEMORY_4M:
memorySize *= 4;
break;
case i855_STOLEN_MEMORY_8M:
memorySize *= 8;
break;
case i855_STOLEN_MEMORY_16M:
memorySize *= 16;
break;
case i855_STOLEN_MEMORY_32M:
memorySize *= 32;
break;
case i855_STOLEN_MEMORY_48M:
memorySize *= 48;
break;
case i855_STOLEN_MEMORY_64M:
memorySize *= 64;
break;
case i855_STOLEN_MEMORY_128M:
memorySize *= 128;
break;
case i855_STOLEN_MEMORY_256M:
memorySize *= 256;
break;
}
}
return memorySize - gttSize - 4096;
}
static void
set_gtt_entry(intel_info &info, uint32 offset, uint8 *physicalAddress)
{
write32(info.gtt_base + (offset >> GTT_PAGE_SHIFT),
(uint32)physicalAddress | GTT_ENTRY_VALID);
} }
@ -211,7 +86,8 @@ intel_interrupt_handler(void *data)
handled = release_vblank_sem(info); handled = release_vblank_sem(info);
// make sure we'll get another one of those // make sure we'll get another one of those
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS, DISPLAY_PIPE_VBLANK_STATUS); write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS,
DISPLAY_PIPE_VBLANK_STATUS);
} }
// setting the bit clears it! // setting the bit clears it!
@ -239,8 +115,8 @@ init_interrupt_handler(intel_info &info)
status = B_ERROR; status = B_ERROR;
} }
if (status == B_OK if (status == B_OK && info.pci->u.h0.interrupt_pin != 0x00
&& info.pci->u.h0.interrupt_pin != 0x00 && info.pci->u.h0.interrupt_line != 0xff) { && info.pci->u.h0.interrupt_line != 0xff) {
// we've gotten an interrupt line for us to use // we've gotten an interrupt line for us to use
info.fake_interrupts = false; info.fake_interrupts = false;
@ -250,7 +126,8 @@ init_interrupt_handler(intel_info &info)
if (status == B_OK) { if (status == B_OK) {
// enable interrupts - we only want VBLANK interrupts // enable interrupts - we only want VBLANK interrupts
write16(info.registers + INTEL_INTERRUPT_ENABLED, write16(info.registers + INTEL_INTERRUPT_ENABLED,
read16(info.registers + INTEL_INTERRUPT_ENABLED) | INTERRUPT_VBLANK); read16(info.registers + INTEL_INTERRUPT_ENABLED)
| INTERRUPT_VBLANK);
write16(info.registers + INTEL_INTERRUPT_MASK, ~INTERRUPT_VBLANK); write16(info.registers + INTEL_INTERRUPT_MASK, ~INTERRUPT_VBLANK);
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS, write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS,
@ -259,9 +136,9 @@ init_interrupt_handler(intel_info &info)
} }
} }
if (status < B_OK) { if (status < B_OK) {
// there is no interrupt reserved for us, or we couldn't install our interrupt // There is no interrupt reserved for us, or we couldn't install our
// handler, let's fake the vblank interrupt for our clients using a timer // interrupt handler, let's fake the vblank interrupt for our clients
// interrupt // using a timer interrupt
info.fake_interrupts = true; info.fake_interrupts = true;
// TODO: fake interrupts! // TODO: fake interrupts!
@ -278,16 +155,39 @@ init_interrupt_handler(intel_info &info)
// #pragma mark - // #pragma mark -
status_t
intel_free_memory(intel_info &info, addr_t offset)
{
return gGART->deallocate_memory(info.aperture, info.aperture_base + offset);
}
status_t
intel_allocate_memory(intel_info &info, size_t size, size_t alignment,
uint32 flags, addr_t *_base, addr_t *_physicalBase)
{
return gGART->allocate_memory(info.aperture, size, alignment,
flags, _base, _physicalBase);
}
status_t status_t
intel_extreme_init(intel_info &info) intel_extreme_init(intel_info &info)
{ {
info.aperture = gGART->map_aperture(info.pci->bus, info.pci->device,
info.pci->function, 0, &info.aperture_base);
if (info.aperture < B_OK)
return info.aperture;
AreaKeeper sharedCreator; AreaKeeper sharedCreator;
info.shared_area = sharedCreator.Create("intel extreme shared info", info.shared_area = sharedCreator.Create("intel extreme shared info",
(void **)&info.shared_info, B_ANY_KERNEL_ADDRESS, (void **)&info.shared_info, B_ANY_KERNEL_ADDRESS,
ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)) + 3 * B_PAGE_SIZE, ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)) + 3 * B_PAGE_SIZE,
B_FULL_LOCK, 0); B_FULL_LOCK, 0);
if (info.shared_area < B_OK) if (info.shared_area < B_OK) {
gGART->unmap_aperture(info.aperture);
return info.shared_area; return info.shared_area;
}
memset((void *)info.shared_info, 0, sizeof(intel_shared_info)); memset((void *)info.shared_info, 0, sizeof(intel_shared_info));
@ -302,67 +202,23 @@ intel_extreme_init(intel_info &info)
// evaluate driver settings, if any // evaluate driver settings, if any
bool ignoreBIOSAllocated;
bool hardwareCursor; bool hardwareCursor;
size_t totalSize; read_settings(hardwareCursor);
read_settings(totalSize, hardwareCursor, ignoreBIOSAllocated);
// Determine the amount of "stolen" (ie. reserved by the BIOS) graphics memory
// and see if we need to allocate some more.
// TODO: make it allocate the memory on demand!
size_t stolenSize = ignoreBIOSAllocated ? 0 : determine_stolen_memory_size(info);
totalSize = max_c(totalSize, stolenSize);
dprintf(DEVICE_NAME ": detected %ld MB of stolen memory, reserving %ld MB total\n",
stolenSize >> 20, totalSize >> 20);
AreaKeeper additionalMemoryCreator;
uint8 *additionalMemory;
if (stolenSize < totalSize) {
// Every device should have at least 8 MB - we could also allocate them
// on demand only, but we're lazy here...
// TODO: overlay seems to have problem when the memory pages are too
// far spreaded - that's why we're using B_CONTIGUOUS for now.
info.additional_memory_area = additionalMemoryCreator.Create("intel additional memory",
(void **)&additionalMemory, B_ANY_KERNEL_ADDRESS,
totalSize - stolenSize, B_CONTIGUOUS /*B_FULL_LOCK*/, 0);
if (info.additional_memory_area < B_OK)
return info.additional_memory_area;
} else
info.additional_memory_area = B_ERROR;
// map frame buffer, try to map it write combined
AreaKeeper graphicsMapper;
info.graphics_memory_area = graphicsMapper.Map("intel extreme graphics memory",
(void *)info.pci->u.h0.base_registers[fbIndex],
totalSize, B_ANY_KERNEL_BLOCK_ADDRESS /*| B_MTR_WC*/,
B_READ_AREA | B_WRITE_AREA, (void **)&info.graphics_memory);
if (graphicsMapper.InitCheck() < B_OK) {
// try again without write combining
dprintf(DEVICE_NAME ": enabling write combined mode failed.\n");
info.graphics_memory_area = graphicsMapper.Map("intel extreme graphics memory",
(void *)info.pci->u.h0.base_registers[fbIndex],
totalSize/*info.pci->u.h0.base_register_sizes[0]*/, B_ANY_KERNEL_BLOCK_ADDRESS,
B_READ_AREA | B_WRITE_AREA, (void **)&info.graphics_memory);
}
if (graphicsMapper.InitCheck() < B_OK) {
dprintf(DEVICE_NAME ": could not map frame buffer!\n");
return info.graphics_memory_area;
}
// memory mapped I/O // memory mapped I/O
// TODO: registers are mapped twice (by us and intel_gart), maybe we
// can share it between the drivers
AreaKeeper mmioMapper; AreaKeeper mmioMapper;
info.registers_area = mmioMapper.Map("intel extreme mmio", info.registers_area = mmioMapper.Map("intel extreme mmio",
(void *)info.pci->u.h0.base_registers[mmioIndex], (void *)info.pci->u.h0.base_registers[mmioIndex],
info.pci->u.h0.base_register_sizes[mmioIndex], info.pci->u.h0.base_register_sizes[mmioIndex],
B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA /*0*/, (void **)&info.registers); B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
(void **)&info.registers);
if (mmioMapper.InitCheck() < B_OK) { if (mmioMapper.InitCheck() < B_OK) {
dprintf(DEVICE_NAME ": could not map memory I/O!\n"); dprintf(DEVICE_NAME ": could not map memory I/O!\n");
gGART->unmap_aperture(info.aperture);
return info.registers_area; return info.registers_area;
} }
@ -370,53 +226,24 @@ intel_extreme_init(intel_info &info)
set_pci_config(info.pci, PCI_command, 2, get_pci_config(info.pci, PCI_command, 2) set_pci_config(info.pci, PCI_command, 2, get_pci_config(info.pci, PCI_command, 2)
| PCI_command_io | PCI_command_memory | PCI_command_master); | PCI_command_io | PCI_command_memory | PCI_command_master);
// init graphics memory manager
AreaKeeper gttMapper;
info.gtt_area = -1;
if ((info.device_type & INTEL_TYPE_9xx) != 0) {
if (info.device_type == INTEL_TYPE_965) {
info.gtt_base = info.registers + i965_GTT_BASE;
info.gtt_size = i965_GTT_SIZE;
} else {
info.gtt_area = gttMapper.Map("intel extreme gtt",
(void *)info.pci->u.h0.base_registers[3], totalSize / 1024,
B_ANY_KERNEL_ADDRESS, 0, (void **)&info.gtt_base);
if (gttMapper.InitCheck() < B_OK) {
dprintf(DEVICE_NAME ": could not map GTT area!\n");
return info.gtt_area;
}
info.gtt_size = totalSize / 1024;
}
} else {
info.gtt_base = info.registers + i830_GTT_BASE;
info.gtt_size = i830_GTT_SIZE;
}
info.memory_manager = mem_init("intel extreme memory manager", 0, totalSize, 1024,
min_c(totalSize / 1024, 512));
if (info.memory_manager == NULL)
return B_NO_MEMORY;
// reserve ring buffer memory (currently, this memory is placed in // reserve ring buffer memory (currently, this memory is placed in
// the graphics memory), but this could bring us problems with // the graphics memory), but this could bring us problems with
// write combining... // write combining...
ring_buffer &primary = info.shared_info->primary_ring_buffer; ring_buffer &primary = info.shared_info->primary_ring_buffer;
if (mem_alloc(info.memory_manager, 4 * B_PAGE_SIZE, &info, if (intel_allocate_memory(info, 4 * B_PAGE_SIZE, 0, 0,
&primary.handle, &primary.offset) == B_OK) { (addr_t *)&primary.base) == B_OK) {
primary.register_base = INTEL_PRIMARY_RING_BUFFER; primary.register_base = INTEL_PRIMARY_RING_BUFFER;
primary.size = 4 * B_PAGE_SIZE; primary.size = 4 * B_PAGE_SIZE;
primary.base = info.graphics_memory + primary.offset; primary.offset = (addr_t)primary.base - info.aperture_base;
} }
ring_buffer &secondary = info.shared_info->secondary_ring_buffer; ring_buffer &secondary = info.shared_info->secondary_ring_buffer;
if (mem_alloc(info.memory_manager, B_PAGE_SIZE, &info, if (intel_allocate_memory(info, B_PAGE_SIZE, 0, 0,
&secondary.handle, &secondary.offset) == B_OK) { (addr_t *)&secondary.base) == B_OK) {
secondary.register_base = INTEL_SECONDARY_RING_BUFFER_0; secondary.register_base = INTEL_SECONDARY_RING_BUFFER_0;
secondary.size = B_PAGE_SIZE; secondary.size = B_PAGE_SIZE;
secondary.base = info.graphics_memory + secondary.offset; secondary.offset = (addr_t)secondary.base - info.aperture_base;
} }
// Fix some problems on certain chips (taken from X driver) // Fix some problems on certain chips (taken from X driver)
@ -432,18 +259,16 @@ intel_extreme_init(intel_info &info)
// no errors, so keep areas and mappings // no errors, so keep areas and mappings
sharedCreator.Detach(); sharedCreator.Detach();
additionalMemoryCreator.Detach();
graphicsMapper.Detach();
mmioMapper.Detach(); mmioMapper.Detach();
gttMapper.Detach();
info.shared_info->graphics_memory_area = info.graphics_memory_area; aperture_info apertureInfo;
gGART->get_aperture_info(info.aperture, &apertureInfo);
info.shared_info->registers_area = info.registers_area; info.shared_info->registers_area = info.registers_area;
info.shared_info->graphics_memory = info.graphics_memory; info.shared_info->graphics_memory = (uint8 *)info.aperture_base;
info.shared_info->physical_graphics_memory = (uint8 *)info.pci->u.h0.base_registers[0]; info.shared_info->physical_graphics_memory = apertureInfo.physical_base;
info.shared_info->graphics_memory_size = apertureInfo.size;
info.shared_info->graphics_memory_size = totalSize; info.shared_info->frame_buffer = 0;
info.shared_info->frame_buffer_offset = 0;
info.shared_info->dpms_mode = B_DPMS_ON; info.shared_info->dpms_mode = B_DPMS_ON;
if ((info.device_type & INTEL_TYPE_9xx) != 0) { if ((info.device_type & INTEL_TYPE_9xx) != 0) {
@ -468,62 +293,26 @@ intel_extreme_init(intel_info &info)
// setup overlay registers // setup overlay registers
if (info.device_type == INTEL_TYPE_G33) { if (intel_allocate_memory(info, B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL,
if (mem_alloc(info.memory_manager, B_PAGE_SIZE, &info, (addr_t *)&info.overlay_registers,
&info.overlay_handle, &info.overlay_offset) == B_OK) { &info.shared_info->physical_overlay_registers) == B_OK) {
info.overlay_registers = (overlay_registers *)(info.graphics_memory info.shared_info->overlay_offset = (addr_t)info.overlay_registers
+ info.overlay_offset); - info.aperture_base;
info.shared_info->overlay_offset = info.overlay_offset;
}
} else {
info.overlay_registers = (overlay_registers *)((uint8 *)info.shared_info
+ ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)));
} }
init_overlay_registers(info.overlay_registers); init_overlay_registers(info.overlay_registers);
physical_entry physicalEntry; // Allocate hardware status page and the cursor memory
get_memory_map(info.overlay_registers, sizeof(overlay_registers), &physicalEntry, 1);
info.shared_info->physical_overlay_registers = (uint8 *)physicalEntry.address;
// The hardware status page and the cursor memory share one area with if (intel_allocate_memory(info, B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL,
// the overlay registers and the shared info (addr_t *)info.shared_info->status_page,
&info.shared_info->physical_status_page) == B_OK) {
uint8 *base = (uint8 *)info.shared_info + ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)); // TODO: set status page
get_memory_map(base + B_PAGE_SIZE, B_PAGE_SIZE, &physicalEntry, 1);
info.shared_info->physical_status_page = (uint8 *)physicalEntry.address;
get_memory_map(base + 2 * B_PAGE_SIZE, B_PAGE_SIZE, &physicalEntry, 1);
info.shared_info->physical_cursor_memory = (uint8 *)physicalEntry.address;
// setup the GTT to point to include the additional memory
if (stolenSize < totalSize) {
for (size_t offset = stolenSize; offset < totalSize;) {
physical_entry physicalEntry;
get_memory_map(additionalMemory + offset - stolenSize,
totalSize - offset, &physicalEntry, 1);
for (size_t i = 0; i < physicalEntry.size; i += B_PAGE_SIZE) {
set_gtt_entry(info, offset + i, (uint8 *)physicalEntry.address + i);
}
offset += physicalEntry.size;
}
} }
// We also need to map the cursor memory into the GTT
info.shared_info->hardware_cursor_enabled = hardwareCursor;
if (hardwareCursor) { if (hardwareCursor) {
// This could also be part of the usual graphics memory, but since we intel_allocate_memory(info, B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL,
// need to make sure it's not in the graphics local memory (and I don't (addr_t *)&info.shared_info->cursor_memory,
// even know yet how to determine that a chip has local memory...), we &info.shared_info->physical_cursor_memory);
// keep the current strategy and put it into the shared area.
// Unfortunately, the GTT is not readable until it has been written into
// the double buffered register set; we cannot get its original contents.
set_gtt_entry(info, totalSize, info.shared_info->physical_cursor_memory);
info.shared_info->cursor_buffer_offset = totalSize;
} }
init_interrupt_handler(info); init_interrupt_handler(info);
@ -547,15 +336,9 @@ intel_extreme_uninit(intel_info &info)
intel_interrupt_handler, &info); intel_interrupt_handler, &info);
} }
mem_destroy(info.memory_manager); gGART->unmap_aperture(info.aperture);
delete_area(info.graphics_memory_area);
delete_area(info.gtt_area);
delete_area(info.registers_area); delete_area(info.registers_area);
delete_area(info.shared_area); delete_area(info.shared_area);
// we may or may not have allocated additional graphics memory
if (info.additional_memory_area >= B_OK)
delete_area(info.additional_memory_area);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@ -9,6 +9,7 @@
#define INTEL_EXTREME_PRIVATE_H #define INTEL_EXTREME_PRIVATE_H
#include <AGP.h>
#include <KernelExport.h> #include <KernelExport.h>
#include <PCI.h> #include <PCI.h>
@ -21,24 +22,14 @@ struct intel_info {
status_t init_status; status_t init_status;
int32 id; int32 id;
pci_info *pci; pci_info *pci;
addr_t aperture_base;
aperture_id aperture;
uint8 *registers; uint8 *registers;
area_id registers_area; area_id registers_area;
struct intel_shared_info *shared_info; struct intel_shared_info *shared_info;
area_id shared_area; area_id shared_area;
uint32 overlay_handle;
uint32 overlay_offset;
struct overlay_registers *overlay_registers; struct overlay_registers *overlay_registers;
// update buffer, shares an area with shared_info
uint8 *gtt_base;
size_t gtt_size;
area_id gtt_area;
uint8 *graphics_memory;
area_id graphics_memory_area;
area_id additional_memory_area;
// allocated memory beyond the "stolen" amount
mem_info *memory_manager;
bool fake_interrupts; bool fake_interrupts;
@ -46,6 +37,10 @@ struct intel_info {
uint32 device_type; uint32 device_type;
}; };
extern status_t intel_free_memory(intel_info &info, addr_t offset);
extern status_t intel_allocate_memory(intel_info &info, size_t size,
size_t alignment, uint32 flags, addr_t *_offset,
addr_t *_physicalBase = NULL);
extern status_t intel_extreme_init(intel_info &info); extern status_t intel_extreme_init(intel_info &info);
extern void intel_extreme_uninit(intel_info &info); extern void intel_extreme_uninit(intel_info &info);