* Now using Thomas memory manager to manage the graphics memory; allocation

of graphics memory is now possible.
* Changed driver name to start with "intel_extreme" to have a nicer device
  name.
* Renamed frame_buffer* stuff to graphics_memory* as the frame buffer just
  happens to be located somewhere in the graphics memory.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17224 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-04-24 18:18:46 +00:00
parent e911acae67
commit 5da6291b99
11 changed files with 163 additions and 43 deletions
@@ -9,6 +9,8 @@
#define INTEL_EXTREME_H
#include <memory_manager.h>
#include <Accelerant.h>
#include <Drivers.h>
#include <PCI.h>
@@ -45,13 +47,14 @@ struct intel_shared_info {
uint32 bytes_per_row;
uint32 dpms_mode;
area_id registers_area; // area of memory mapped registers
area_id frame_buffer_area; // area of frame buffer
uint8 *frame_buffer; // pointer to frame buffer (visible by all apps!)
uint8 *physical_frame_buffer;
area_id registers_area; // area of memory mapped registers
area_id graphics_memory_area;
uint8 *graphics_memory;
uint8 *physical_graphics_memory;
uint32 graphics_memory_size;
uint32 frame_buffer_offset;
uint32 device_type;
char device_identifier[32];
struct pll_info pll_info;
@@ -66,8 +69,9 @@ struct intel_info {
area_id registers_area;
struct intel_shared_info *shared_info;
area_id shared_area;
uint8 *frame_buffer;
area_id frame_buffer_area;
uint8 *graphics_memory;
area_id graphics_memory_area;
mem_info *memory_manager;
const char *device_identifier;
uint32 device_type;
@@ -83,8 +87,8 @@ enum {
INTEL_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
INTEL_GET_DEVICE_NAME,
INTEL_ALLOC_LOCAL_MEMORY,
INTEL_FREE_LOCAL_MEMORY
INTEL_ALLOCATE_GRAPHICS_MEMORY,
INTEL_FREE_GRAPHICS_MEMORY
};
// retrieve the area_id of the kernel/accelerant shared info
@@ -97,7 +101,7 @@ struct intel_get_private_data {
struct intel_allocate_graphics_memory {
uint32 magic;
uint32 size;
uint32 fb_offset;
uint32 buffer_offset;
uint32 handle;
};
@@ -11,6 +11,7 @@ Addon intel_extreme.accelerant : accelerants :
dpms.cpp
engine.cpp
hooks.cpp
memory.cpp
mode.cpp
: false
: be
@@ -22,6 +22,8 @@ typedef struct accelerant_info {
display_mode *mode_list; // cloned list of standard display modes
area_id mode_list_area;
uint32 frame_buffer_handle;
int device;
bool is_clone;
} accelerant_info;
@@ -50,4 +52,8 @@ extern void set_display_power_mode(uint32 mode);
// modes.cpp
extern status_t create_mode_list(void);
// memory.cpp
extern void intel_free_memory(uint32 handle);
extern status_t intel_allocate_memory(size_t size, uint32& handle, uint32& offset);
#endif /* INTEL_EXTREME_ACCELERANT_H */
@@ -32,7 +32,7 @@ enable_display_plane(bool enable)
// when disabling it, we have to trigger the update using a write to
// the display base address
write32(INTEL_DISPLAY_CONTROL, oldValue & ~DISPLAY_CONTROL_ENABLED);
write32(INTEL_DISPLAY_BASE, 0);
write32(INTEL_DISPLAY_BASE, gInfo->shared_info->frame_buffer_offset);
}
}
@@ -23,7 +23,7 @@ extern "C" void _sPrintf(const char *format, ...);
static engine_token sEngineToken = {1, 0 /*B_2D_ACCELERATION*/, NULL};
// public function: return number of hardware engine
/** Return number of hardware engines */
uint32
intel_accelerant_engine_count(void)
@@ -0,0 +1,54 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
*/
#include "accelerant.h"
#include "intel_extreme.h"
#include <errno.h>
//#define TRACE_MEMORY
#ifdef TRACE_MEMORY
extern "C" void _sPrintf(const char *format, ...);
# define TRACE(x) _sPrintf x
#else
# define TRACE(x) ;
#endif
void
intel_free_memory(uint32 handle)
{
if (!handle)
return;
intel_free_graphics_memory freeMemory;
freeMemory.magic = INTEL_PRIVATE_DATA_MAGIC;
freeMemory.handle = handle;
ioctl(gInfo->device, INTEL_FREE_GRAPHICS_MEMORY, &freeMemory, sizeof(freeMemory));
}
status_t
intel_allocate_memory(size_t size, uint32& handle, uint32& offset)
{
intel_allocate_graphics_memory allocMemory;
allocMemory.magic = INTEL_PRIVATE_DATA_MAGIC;
allocMemory.size = size;
if (ioctl(gInfo->device, INTEL_ALLOCATE_GRAPHICS_MEMORY, &allocMemory, sizeof(allocMemory)) < 0)
return errno;
handle = allocMemory.handle;
offset = allocMemory.buffer_offset;
return B_OK;
}
+28 -4
View File
@@ -12,7 +12,7 @@
#include "utility.h"
//#define TRACE_MODE
#define TRACE_MODE
#ifdef TRACE_MODE
extern "C" void _sPrintf(const char *format, ...);
# define TRACE(x) _sPrintf x
@@ -228,6 +228,8 @@ intel_set_display_mode(display_mode *mode)
{
TRACE(("intel_set_display_mode()\n"));
// TODO: locking!
if (mode == NULL)
return B_BAD_VALUE;
@@ -238,6 +240,26 @@ intel_set_display_mode(display_mode *mode)
uint32 colorMode, bytesPerRow;
get_color_space_format(current, colorMode, bytesPerRow);
// free old and allocate new frame buffer in graphics memory
intel_free_memory(gInfo->frame_buffer_handle);
uint32 offset;
if (intel_allocate_memory(bytesPerRow * current.timing.v_display,
gInfo->frame_buffer_handle, offset) < B_OK) {
// oh, how did that happen? Unfortunately, there is no really good way back
if (intel_allocate_memory(gInfo->shared_info->current_mode.timing.v_display
* gInfo->shared_info->bytes_per_row, gInfo->frame_buffer_handle,
offset) == B_OK) {
gInfo->shared_info->frame_buffer_offset = offset;
write32(INTEL_DISPLAY_BASE, offset);
}
return B_NO_MEMORY;
}
gInfo->shared_info->frame_buffer_offset = offset;
// update timing parameters
write32(INTEL_DISPLAY_HTOTAL, ((uint32)(current.timing.h_total - 1) << 16)
@@ -288,7 +310,7 @@ intel_set_display_mode(display_mode *mode)
// changing bytes per row seems to be ignored if the plane/pipe is turned off
write32(INTEL_DISPLAY_BYTES_PER_ROW, bytesPerRow);
write32(INTEL_DISPLAY_BASE, 0);
write32(INTEL_DISPLAY_BASE, gInfo->shared_info->frame_buffer_offset);
// triggers writing back double-buffered registers
// update shared info
@@ -313,8 +335,10 @@ intel_get_frame_buffer_config(frame_buffer_config *config)
{
TRACE(("intel_get_frame_buffer_config()\n"));
config->frame_buffer = gInfo->shared_info->frame_buffer;
config->frame_buffer_dma = gInfo->shared_info->physical_frame_buffer;
uint32 offset = gInfo->shared_info->frame_buffer_offset;
config->frame_buffer = gInfo->shared_info->graphics_memory + offset;
config->frame_buffer_dma = gInfo->shared_info->physical_graphics_memory + offset;
config->bytes_per_row = gInfo->shared_info->bytes_per_row;
return B_OK;
@@ -12,6 +12,8 @@ KernelAddon intel_extreme : kernel drivers bin :
intel_extreme.cpp
kernel_cpp.cpp
: libgraphicscommon.a
;
SEARCH on [ FGristFiles
@@ -181,28 +181,48 @@ device_ioctl(void *data, uint32 op, void *buffer, size_t bufferLength)
#endif
return B_OK;
/*
// graphics mem manager
case INTEL_ALLOC_LOCAL_MEMORY:
case INTEL_ALLOCATE_GRAPHICS_MEMORY:
{
intel_alloc_local_mem *allocMemory = (intel_alloc_local_mem *)buffer;
intel_allocate_graphics_memory allocMemory;
#ifdef __HAIKU__
if (user_memcpy(&allocMemory, buffer, sizeof(intel_allocate_graphics_memory)) < B_OK)
return B_BAD_ADDRESS;
#else
memcpy(&allocMemory, buffer, sizeof(intel_allocate_graphics_memory));
#endif
if (allocMemory->magic == INTEL_PRIVATE_DATA_MAGIC) {
return mem_alloc(di->local_memmgr, allocMemory->size, dev,
&allocMemory->handle, &am->fb_offset);
if (allocMemory.magic != INTEL_PRIVATE_DATA_MAGIC)
return B_BAD_VALUE;
status_t status = mem_alloc(info->memory_manager, allocMemory.size, info,
&allocMemory.handle, &allocMemory.buffer_offset);
if (status == B_OK) {
// copy result
#ifdef __HAIKU__
if (user_memcpy(buffer, &allocMemory, sizeof(intel_allocate_graphics_memory)) < B_OK)
return B_BAD_ADDRESS;
#else
memcpy(buffer, &allocMemory, sizeof(intel_allocate_graphics_memory));
#endif
}
break;
return status;
}
case INTEL_FREE_LOCAL_MEMORY:
case INTEL_FREE_GRAPHICS_MEMORY:
{
intel_free_local_mem *freeMemory = (intel_free_local_mem *)buffer;
intel_free_graphics_memory freeMemory;
#ifdef __HAIKU__
if (user_memcpy(&freeMemory, buffer, sizeof(intel_free_graphics_memory)) < B_OK)
return B_BAD_ADDRESS;
#else
memcpy(&freeMemory, buffer, sizeof(intel_free_graphics_memory));
#endif
if (freeMemory->magic == INTEL_PRIVATE_DATA_MAGIC)
return mem_free(di->local_memmgr, freeMemory->handle, dev);
if (freeMemory.magic == INTEL_PRIVATE_DATA_MAGIC)
return mem_free(info->memory_manager, freeMemory.handle, info);
break;
}
*/
default:
TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %ld)\n",
@@ -137,8 +137,7 @@ init_driver(void)
// create device names & allocate device info structure
char name[64];
sprintf(name, "graphics/%04X_%04X_%02X%02X%02X",
info->vendor_id, info->device_id,
sprintf(name, "graphics/intel_extreme_%02x%02x%02x",
info->bus, info->device,
info->function);
@@ -90,23 +90,23 @@ intel_extreme_init(intel_info &info)
// map frame buffer, try to map it write combined
PhysicalMemoryMapper fbMapper;
info.frame_buffer_area = fbMapper.Map("intel extreme frame buffer",
PhysicalMemoryMapper graphicsMapper;
info.graphics_memory_area = graphicsMapper.Map("intel extreme graphics memory",
(void *)info.pci->u.h0.base_registers[0],
memorySize, B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC,
B_READ_AREA | B_WRITE_AREA, (void **)&info.frame_buffer);
if (fbMapper.InitCheck() < B_OK) {
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.frame_buffer_area = fbMapper.Map("intel extreme frame buffer",
info.graphics_memory_area = graphicsMapper.Map("intel extreme graphics memory",
(void *)info.pci->u.h0.base_registers[0],
memorySize/*info.pci->u.h0.base_register_sizes[0]*/, B_ANY_KERNEL_BLOCK_ADDRESS,
B_READ_AREA | B_WRITE_AREA, (void **)&info.frame_buffer);
B_READ_AREA | B_WRITE_AREA, (void **)&info.graphics_memory);
}
if (fbMapper.InitCheck() < B_OK) {
if (graphicsMapper.InitCheck() < B_OK) {
dprintf(DEVICE_NAME ": could not map frame buffer!\n");
return info.frame_buffer_area;
return info.graphics_memory_area;
}
// memory mapped I/O
@@ -123,16 +123,24 @@ intel_extreme_init(intel_info &info)
return info.registers_area;
}
// init graphics memory manager
info.memory_manager = mem_init("intel extreme memory manager", 0, memorySize, 1024,
min_c(memorySize / 1024, 512));
if (info.memory_manager == NULL)
return B_NO_MEMORY;
// no errors, so keep mappings
fbMapper.Keep();
graphicsMapper.Keep();
mmioMapper.Keep();
info.shared_info->frame_buffer_area = info.frame_buffer_area;
info.shared_info->graphics_memory_area = info.graphics_memory_area;
info.shared_info->registers_area = info.registers_area;
info.shared_info->frame_buffer = info.frame_buffer;
info.shared_info->physical_frame_buffer = (uint8 *)info.pci->u.h0.base_registers[0];
info.shared_info->graphics_memory = info.graphics_memory;
info.shared_info->physical_graphics_memory = (uint8 *)info.pci->u.h0.base_registers[0];
info.shared_info->graphics_memory_size = memorySize;
info.shared_info->frame_buffer_offset = 0;
info.shared_info->dpms_mode = B_DPMS_ON;
info.shared_info->pll_info.reference_frequency = 48000; // 48 kHz
info.shared_info->pll_info.min_frequency = 25000; // 25 MHz (not tested)
@@ -161,7 +169,9 @@ intel_extreme_uninit(intel_info &info)
{
dprintf(DEVICE_NAME": intel_extreme_uninit()\n");
delete_area(info.frame_buffer_area);
mem_destroy(info.memory_manager);
delete_area(info.graphics_memory_area);
delete_area(info.registers_area);
delete_area(info.shared_area);
}