From 5da6291b99c3bd38505f6306dcb6398b9485783d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 24 Apr 2006 18:18:46 +0000 Subject: [PATCH] * 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 --- .../graphics/intel_extreme/intel_extreme.h | 24 +++++---- src/add-ons/accelerants/intel_extreme/Jamfile | 1 + .../accelerants/intel_extreme/accelerant.h | 6 +++ .../accelerants/intel_extreme/dpms.cpp | 2 +- .../accelerants/intel_extreme/engine.cpp | 2 +- .../accelerants/intel_extreme/memory.cpp | 54 +++++++++++++++++++ .../accelerants/intel_extreme/mode.cpp | 32 +++++++++-- .../drivers/graphics/intel_extreme/Jamfile | 2 + .../drivers/graphics/intel_extreme/device.cpp | 44 ++++++++++----- .../drivers/graphics/intel_extreme/driver.cpp | 3 +- .../graphics/intel_extreme/intel_extreme.cpp | 36 ++++++++----- 11 files changed, 163 insertions(+), 43 deletions(-) create mode 100644 src/add-ons/accelerants/intel_extreme/memory.cpp diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 89022ce720..c4859a9d62 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -9,6 +9,8 @@ #define INTEL_EXTREME_H +#include + #include #include #include @@ -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; }; diff --git a/src/add-ons/accelerants/intel_extreme/Jamfile b/src/add-ons/accelerants/intel_extreme/Jamfile index 195a98490c..3c5289b37a 100644 --- a/src/add-ons/accelerants/intel_extreme/Jamfile +++ b/src/add-ons/accelerants/intel_extreme/Jamfile @@ -11,6 +11,7 @@ Addon intel_extreme.accelerant : accelerants : dpms.cpp engine.cpp hooks.cpp + memory.cpp mode.cpp : false : be diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index a35fa9b222..e6a454b23c 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -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 */ diff --git a/src/add-ons/accelerants/intel_extreme/dpms.cpp b/src/add-ons/accelerants/intel_extreme/dpms.cpp index bb6916d446..1e49e41b3d 100644 --- a/src/add-ons/accelerants/intel_extreme/dpms.cpp +++ b/src/add-ons/accelerants/intel_extreme/dpms.cpp @@ -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); } } diff --git a/src/add-ons/accelerants/intel_extreme/engine.cpp b/src/add-ons/accelerants/intel_extreme/engine.cpp index 958e9fcc8b..4fcda44eee 100644 --- a/src/add-ons/accelerants/intel_extreme/engine.cpp +++ b/src/add-ons/accelerants/intel_extreme/engine.cpp @@ -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) diff --git a/src/add-ons/accelerants/intel_extreme/memory.cpp b/src/add-ons/accelerants/intel_extreme/memory.cpp new file mode 100644 index 0000000000..2107151dcb --- /dev/null +++ b/src/add-ons/accelerants/intel_extreme/memory.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ + + +#include "accelerant.h" +#include "intel_extreme.h" + +#include + + +//#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; +} + diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index e2737c31e0..f45a096c1a 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -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; diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/Jamfile b/src/add-ons/kernel/drivers/graphics/intel_extreme/Jamfile index 1e59e38319..04da3a5c8a 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/Jamfile +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/Jamfile @@ -12,6 +12,8 @@ KernelAddon intel_extreme : kernel drivers bin : intel_extreme.cpp kernel_cpp.cpp + + : libgraphicscommon.a ; SEARCH on [ FGristFiles diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp index af9fc012b4..11fdf1cd8b 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp @@ -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", diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp index a9c3af2a47..2cb162d07f 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp @@ -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); diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index c22fb640f6..0c687c8ded 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -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); }