framebuffer: remove driver & accelerant.
* Functionality provided by the framebuffer driver for UEFI systems has now been folded into the vesa driver, so is no longer needed.
This commit is contained in:
@@ -4,7 +4,6 @@ SubInclude HAIKU_TOP src add-ons accelerants 3dfx ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants ati ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants common ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants et6x00 ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants framebuffer ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants intel_810 ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants intel_extreme ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants matrox ;
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons accelerants framebuffer ;
|
||||
|
||||
UsePrivateHeaders graphics ;
|
||||
UsePrivateHeaders [ FDirName graphics vesa ] ;
|
||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
|
||||
Addon framebuffer.accelerant :
|
||||
accelerant.cpp
|
||||
engine.cpp
|
||||
hooks.cpp
|
||||
mode.cpp
|
||||
: libaccelerantscommon.a
|
||||
;
|
||||
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
#include "accelerant.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
//#define TRACE_ACCELERANT
|
||||
#ifdef TRACE_ACCELERANT
|
||||
extern "C" void _sPrintf(const char *format, ...);
|
||||
# define TRACE(x) _sPrintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
struct accelerant_info *gInfo;
|
||||
|
||||
|
||||
class AreaCloner {
|
||||
public:
|
||||
AreaCloner();
|
||||
~AreaCloner();
|
||||
|
||||
area_id Clone(const char *name, void **_address, uint32 spec,
|
||||
uint32 protection, area_id sourceArea);
|
||||
status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; }
|
||||
void Keep();
|
||||
|
||||
private:
|
||||
area_id fArea;
|
||||
};
|
||||
|
||||
|
||||
AreaCloner::AreaCloner()
|
||||
:
|
||||
fArea(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AreaCloner::~AreaCloner()
|
||||
{
|
||||
if (fArea >= B_OK)
|
||||
delete_area(fArea);
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
AreaCloner::Clone(const char *name, void **_address, uint32 spec,
|
||||
uint32 protection, area_id sourceArea)
|
||||
{
|
||||
fArea = clone_area(name, _address, spec, protection, sourceArea);
|
||||
return fArea;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AreaCloner::Keep()
|
||||
{
|
||||
fArea = -1;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
/*! This is the common accelerant_info initializer. It is called by
|
||||
both, the first accelerant and all clones.
|
||||
*/
|
||||
static status_t
|
||||
init_common(int device, bool isClone)
|
||||
{
|
||||
// initialize global accelerant info structure
|
||||
|
||||
gInfo = (accelerant_info *)malloc(sizeof(accelerant_info));
|
||||
if (gInfo == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(gInfo, 0, sizeof(accelerant_info));
|
||||
|
||||
gInfo->is_clone = isClone;
|
||||
gInfo->device = device;
|
||||
gInfo->current_mode = UINT16_MAX;
|
||||
|
||||
// get basic info from driver
|
||||
|
||||
area_id sharedArea;
|
||||
if (ioctl(device, VESA_GET_PRIVATE_DATA, &sharedArea, sizeof(area_id))
|
||||
!= 0) {
|
||||
free(gInfo);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
AreaCloner sharedCloner;
|
||||
gInfo->shared_info_area = sharedCloner.Clone("framebuffer shared info",
|
||||
(void **)&gInfo->shared_info, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, sharedArea);
|
||||
status_t status = sharedCloner.InitCheck();
|
||||
if (status < B_OK) {
|
||||
free(gInfo);
|
||||
return status;
|
||||
}
|
||||
|
||||
sharedCloner.Keep();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*! Cleans up everything done by a successful init_common(). */
|
||||
static void
|
||||
uninit_common(void)
|
||||
{
|
||||
delete_area(gInfo->shared_info_area);
|
||||
gInfo->shared_info_area = -1;
|
||||
gInfo->shared_info = NULL;
|
||||
|
||||
// close the file handle ONLY if we're the clone
|
||||
// (this is what Be tells us ;)
|
||||
if (gInfo->is_clone)
|
||||
close(gInfo->device);
|
||||
|
||||
free(gInfo);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - public accelerant functions
|
||||
|
||||
|
||||
/*! Init primary accelerant */
|
||||
status_t
|
||||
framebuffer_init_accelerant(int device)
|
||||
{
|
||||
TRACE(("framebuffer_init_accelerant()\n"));
|
||||
|
||||
status_t status = init_common(device, false);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = create_mode_list();
|
||||
if (status != B_OK) {
|
||||
uninit_common();
|
||||
return status;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
framebuffer_accelerant_clone_info_size(void)
|
||||
{
|
||||
// clone info is device name, so return its maximum size
|
||||
return B_PATH_NAME_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
framebuffer_get_accelerant_clone_info(void *info)
|
||||
{
|
||||
ioctl(gInfo->device, VESA_GET_DEVICE_NAME, info, B_PATH_NAME_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_clone_accelerant(void *info)
|
||||
{
|
||||
TRACE(("framebuffer_clone_accelerant()\n"));
|
||||
|
||||
// create full device name
|
||||
char path[MAXPATHLEN];
|
||||
strcpy(path, "/dev/");
|
||||
strcat(path, (const char *)info);
|
||||
|
||||
int fd = open(path, B_READ_WRITE);
|
||||
if (fd < 0)
|
||||
return errno;
|
||||
|
||||
status_t status = init_common(fd, true);
|
||||
if (status != B_OK)
|
||||
goto err1;
|
||||
|
||||
// get read-only clone of supported display modes
|
||||
status = gInfo->mode_list_area = clone_area(
|
||||
"framebuffer cloned modes", (void **)&gInfo->mode_list,
|
||||
B_ANY_ADDRESS, B_READ_AREA, gInfo->shared_info->mode_list_area);
|
||||
if (status < B_OK)
|
||||
goto err2;
|
||||
|
||||
return B_OK;
|
||||
|
||||
err2:
|
||||
uninit_common();
|
||||
err1:
|
||||
close(fd);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*! This function is called for both, the primary accelerant and all of
|
||||
its clones.
|
||||
*/
|
||||
void
|
||||
framebuffer_uninit_accelerant(void)
|
||||
{
|
||||
TRACE(("framebuffer_uninit_accelerant()\n"));
|
||||
|
||||
// delete accelerant instance data
|
||||
delete_area(gInfo->mode_list_area);
|
||||
gInfo->mode_list = NULL;
|
||||
|
||||
uninit_common();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_get_accelerant_device_info(accelerant_device_info *info)
|
||||
{
|
||||
info->version = B_ACCELERANT_VERSION;
|
||||
strcpy(info->name, "Framebuffer Driver");
|
||||
strcpy(info->chipset, "Framebuffer");
|
||||
// ToDo: provide some more insight here...
|
||||
strcpy(info->serial_no, "None");
|
||||
|
||||
#if 0
|
||||
info->memory = ???
|
||||
info->dac_speed = ???
|
||||
#endif
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
sem_id
|
||||
framebuffer_accelerant_retrace_semaphore()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef VESA_ACCELERANT_H
|
||||
#define VESA_ACCELERANT_H
|
||||
|
||||
|
||||
#include "vesa_info.h"
|
||||
|
||||
|
||||
typedef struct accelerant_info {
|
||||
int device;
|
||||
bool is_clone;
|
||||
|
||||
area_id shared_info_area;
|
||||
vesa_shared_info *shared_info;
|
||||
|
||||
area_id mode_list_area;
|
||||
// cloned list of standard display modes
|
||||
display_mode *mode_list;
|
||||
uint16 current_mode;
|
||||
} accelerant_info;
|
||||
|
||||
extern accelerant_info *gInfo;
|
||||
|
||||
extern status_t create_mode_list(void);
|
||||
|
||||
#endif /* VESA_ACCELERANT_H */
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2008, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ACCELERANT_PROTOS_H
|
||||
#define _ACCELERANT_PROTOS_H
|
||||
|
||||
|
||||
#include <Accelerant.h>
|
||||
#include "video_overlay.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// general
|
||||
status_t framebuffer_init_accelerant(int fd);
|
||||
ssize_t framebuffer_accelerant_clone_info_size(void);
|
||||
void framebuffer_get_accelerant_clone_info(void *data);
|
||||
status_t framebuffer_clone_accelerant(void *data);
|
||||
void framebuffer_uninit_accelerant(void);
|
||||
status_t framebuffer_get_accelerant_device_info(accelerant_device_info *adi);
|
||||
sem_id framebuffer_accelerant_retrace_semaphore(void);
|
||||
|
||||
// modes & constraints
|
||||
uint32 framebuffer_accelerant_mode_count(void);
|
||||
status_t framebuffer_get_mode_list(display_mode *dm);
|
||||
status_t framebuffer_set_display_mode(display_mode *modeToSet);
|
||||
status_t framebuffer_get_display_mode(display_mode *currentMode);
|
||||
status_t framebuffer_get_frame_buffer_config(frame_buffer_config *config);
|
||||
status_t framebuffer_get_pixel_clock_limits(display_mode *dm, uint32 *low,
|
||||
uint32 *high);
|
||||
|
||||
// accelerant engine
|
||||
uint32 framebuffer_accelerant_engine_count(void);
|
||||
status_t framebuffer_acquire_engine(uint32 capabilities, uint32 maxWait,
|
||||
sync_token *st, engine_token **et);
|
||||
status_t framebuffer_release_engine(engine_token *et, sync_token *st);
|
||||
void framebuffer_wait_engine_idle(void);
|
||||
status_t framebuffer_get_sync_token(engine_token *et, sync_token *st);
|
||||
status_t framebuffer_sync_to_token(sync_token *st);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ACCELERANT_PROTOS_H */
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
#include "vesa_info.h"
|
||||
|
||||
|
||||
static engine_token sEngineToken = {1, 0 /*B_2D_ACCELERATION*/, NULL};
|
||||
|
||||
|
||||
uint32
|
||||
framebuffer_accelerant_engine_count(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_acquire_engine(uint32 capabilities, uint32 max_wait, sync_token *syncToken,
|
||||
engine_token **_engineToken)
|
||||
{
|
||||
*_engineToken = &sEngineToken;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_release_engine(engine_token *engineToken, sync_token *syncToken)
|
||||
{
|
||||
if (syncToken != NULL)
|
||||
syncToken->engine_id = engineToken->engine_id;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
framebuffer_wait_engine_idle(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_get_sync_token(engine_token *engineToken, sync_token *syncToken)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_sync_to_token(sync_token *syncToken)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2012, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected]
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
#include "accelerant.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
|
||||
extern "C" void*
|
||||
get_accelerant_hook(uint32 feature, void* data)
|
||||
{
|
||||
switch (feature) {
|
||||
/* general */
|
||||
case B_INIT_ACCELERANT:
|
||||
return (void*)framebuffer_init_accelerant;
|
||||
case B_UNINIT_ACCELERANT:
|
||||
return (void*)framebuffer_uninit_accelerant;
|
||||
case B_CLONE_ACCELERANT:
|
||||
return (void*)framebuffer_clone_accelerant;
|
||||
case B_ACCELERANT_CLONE_INFO_SIZE:
|
||||
return (void*)framebuffer_accelerant_clone_info_size;
|
||||
case B_GET_ACCELERANT_CLONE_INFO:
|
||||
return (void*)framebuffer_get_accelerant_clone_info;
|
||||
case B_GET_ACCELERANT_DEVICE_INFO:
|
||||
return (void*)framebuffer_get_accelerant_device_info;
|
||||
case B_ACCELERANT_RETRACE_SEMAPHORE:
|
||||
return (void*)framebuffer_accelerant_retrace_semaphore;
|
||||
|
||||
/* mode configuration */
|
||||
case B_ACCELERANT_MODE_COUNT:
|
||||
return (void*)framebuffer_accelerant_mode_count;
|
||||
case B_GET_MODE_LIST:
|
||||
return (void*)framebuffer_get_mode_list;
|
||||
case B_SET_DISPLAY_MODE:
|
||||
return (void*)framebuffer_set_display_mode;
|
||||
case B_GET_DISPLAY_MODE:
|
||||
return (void*)framebuffer_get_display_mode;
|
||||
case B_GET_FRAME_BUFFER_CONFIG:
|
||||
return (void*)framebuffer_get_frame_buffer_config;
|
||||
case B_GET_PIXEL_CLOCK_LIMITS:
|
||||
return (void*)framebuffer_get_pixel_clock_limits;
|
||||
|
||||
/* engine/synchronization */
|
||||
case B_ACCELERANT_ENGINE_COUNT:
|
||||
return (void*)framebuffer_accelerant_engine_count;
|
||||
case B_ACQUIRE_ENGINE:
|
||||
return (void*)framebuffer_acquire_engine;
|
||||
case B_RELEASE_ENGINE:
|
||||
return (void*)framebuffer_release_engine;
|
||||
case B_WAIT_ENGINE_IDLE:
|
||||
return (void*)framebuffer_wait_engine_idle;
|
||||
case B_GET_SYNC_TOKEN:
|
||||
return (void*)framebuffer_get_sync_token;
|
||||
case B_SYNC_TO_TOKEN:
|
||||
return (void*)framebuffer_sync_to_token;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2015, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compute_display_timing.h>
|
||||
#include <create_display_modes.h>
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
#include "accelerant.h"
|
||||
#include "utility.h"
|
||||
|
||||
|
||||
//#define TRACE_MODE
|
||||
#ifdef TRACE_MODE
|
||||
extern "C" void _sPrintf(const char* format, ...);
|
||||
# define TRACE(x) _sPrintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
bool
|
||||
operator==(const display_mode &lhs, const display_mode &rhs)
|
||||
{
|
||||
return lhs.space == rhs.space
|
||||
&& lhs.virtual_width == rhs.virtual_width
|
||||
&& lhs.virtual_height == rhs.virtual_height
|
||||
&& lhs.h_display_start == rhs.h_display_start
|
||||
&& lhs.v_display_start == rhs.v_display_start;
|
||||
}
|
||||
|
||||
|
||||
/*! Checks if the specified \a mode can be set using VESA. */
|
||||
static bool
|
||||
is_mode_supported(display_mode* mode)
|
||||
{
|
||||
return (mode != NULL) && (*mode == gInfo->shared_info->current_mode);
|
||||
}
|
||||
|
||||
|
||||
/*! Creates the initial mode list of the primary accelerant.
|
||||
It's called from vesa_init_accelerant().
|
||||
*/
|
||||
status_t
|
||||
create_mode_list(void)
|
||||
{
|
||||
const color_space colorspace[] = {
|
||||
(color_space)gInfo->shared_info->current_mode.space
|
||||
};
|
||||
display_mode mode = gInfo->shared_info->current_mode;
|
||||
|
||||
compute_display_timing(mode.virtual_width, mode.virtual_height, 60, false,
|
||||
&mode.timing);
|
||||
fill_display_mode(mode.virtual_width, mode.virtual_height, &mode);
|
||||
|
||||
gInfo->mode_list_area = create_display_modes("framebuffer modes",
|
||||
NULL, &mode, 1, colorspace, 1, is_mode_supported, &gInfo->mode_list,
|
||||
&gInfo->shared_info->mode_count);
|
||||
|
||||
if (gInfo->mode_list_area < 0)
|
||||
return gInfo->mode_list_area;
|
||||
|
||||
gInfo->shared_info->mode_list_area = gInfo->mode_list_area;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
uint32
|
||||
framebuffer_accelerant_mode_count(void)
|
||||
{
|
||||
TRACE(("framebuffer_accelerant_mode_count() = %d\n",
|
||||
gInfo->shared_info->mode_count));
|
||||
return gInfo->shared_info->mode_count;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_get_mode_list(display_mode* modeList)
|
||||
{
|
||||
TRACE(("framebuffer_get_mode_info()\n"));
|
||||
memcpy(modeList, gInfo->mode_list,
|
||||
gInfo->shared_info->mode_count * sizeof(display_mode));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_set_display_mode(display_mode* _mode)
|
||||
{
|
||||
TRACE(("framebuffer_set_display_mode()\n"));
|
||||
if (_mode != NULL && *_mode == gInfo->shared_info->current_mode)
|
||||
return B_OK;
|
||||
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_get_display_mode(display_mode* _currentMode)
|
||||
{
|
||||
TRACE(("framebuffer_get_display_mode()\n"));
|
||||
*_currentMode = gInfo->shared_info->current_mode;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_get_frame_buffer_config(frame_buffer_config* config)
|
||||
{
|
||||
TRACE(("framebuffer_get_frame_buffer_config()\n"));
|
||||
|
||||
config->frame_buffer = gInfo->shared_info->frame_buffer;
|
||||
config->frame_buffer_dma = gInfo->shared_info->physical_frame_buffer;
|
||||
config->bytes_per_row = gInfo->shared_info->bytes_per_row;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_get_pixel_clock_limits(display_mode* mode, uint32* _low, uint32* _high)
|
||||
{
|
||||
TRACE(("framebuffer_get_pixel_clock_limits()\n"));
|
||||
|
||||
// TODO: do some real stuff here (taken from radeon driver)
|
||||
uint32 totalPixel = (uint32)mode->timing.h_total
|
||||
* (uint32)mode->timing.v_total;
|
||||
uint32 clockLimit = 2000000;
|
||||
|
||||
// lower limit of about 48Hz vertical refresh
|
||||
*_low = totalPixel * 48L / 1000L;
|
||||
if (*_low > clockLimit)
|
||||
return B_ERROR;
|
||||
|
||||
*_high = clockLimit;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics 3dfx ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics ati ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics common ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics et6x00 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics framebuffer ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics intel_810 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics intel_extreme ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics matrox ;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers graphics framebuffer ;
|
||||
|
||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
UsePrivateHeaders [ FDirName graphics vesa ] ;
|
||||
UsePrivateKernelHeaders ;
|
||||
|
||||
KernelAddon framebuffer :
|
||||
device.cpp
|
||||
driver.cpp
|
||||
framebuffer.cpp
|
||||
;
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <graphic_driver.h>
|
||||
#include <image.h>
|
||||
#include <KernelExport.h>
|
||||
#include <OS.h>
|
||||
#include <PCI.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <vesa.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "utility.h"
|
||||
#include "vesa_info.h"
|
||||
#include "framebuffer_private.h"
|
||||
|
||||
|
||||
//#define TRACE_DEVICE
|
||||
#ifdef TRACE_DEVICE
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
static status_t
|
||||
device_open(const char* name, uint32 flags, void** _cookie)
|
||||
{
|
||||
int id;
|
||||
|
||||
// find accessed device
|
||||
char* thisName;
|
||||
|
||||
// search for device name
|
||||
for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) {
|
||||
if (!strcmp(name, thisName))
|
||||
break;
|
||||
}
|
||||
if (thisName == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
framebuffer_info* info = gDeviceInfo[id];
|
||||
|
||||
mutex_lock(&gLock);
|
||||
|
||||
status_t status = B_OK;
|
||||
|
||||
if (info->open_count == 0) {
|
||||
// this device has been opened for the first time, so
|
||||
// we allocate needed resources and initialize the structure
|
||||
if (status == B_OK)
|
||||
status = framebuffer_init(*info);
|
||||
if (status == B_OK)
|
||||
info->id = id;
|
||||
}
|
||||
|
||||
if (status == B_OK) {
|
||||
info->open_count++;
|
||||
*_cookie = info;
|
||||
}
|
||||
|
||||
mutex_unlock(&gLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_close(void* cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_free(void* cookie)
|
||||
{
|
||||
struct framebuffer_info* info = (framebuffer_info*)cookie;
|
||||
|
||||
mutex_lock(&gLock);
|
||||
|
||||
if (info->open_count-- == 1) {
|
||||
// release info structure
|
||||
framebuffer_uninit(*info);
|
||||
}
|
||||
|
||||
mutex_unlock(&gLock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_ioctl(void* cookie, uint32 msg, void* buffer, size_t bufferLength)
|
||||
{
|
||||
struct framebuffer_info* info = (framebuffer_info*)cookie;
|
||||
|
||||
switch (msg) {
|
||||
case B_GET_ACCELERANT_SIGNATURE:
|
||||
dprintf(DEVICE_NAME ": acc: %s\n", ACCELERANT_NAME);
|
||||
if (user_strlcpy((char*)buffer, ACCELERANT_NAME,
|
||||
B_FILE_NAME_LENGTH) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
|
||||
// needed to share data between kernel and accelerant
|
||||
case VESA_GET_PRIVATE_DATA:
|
||||
return user_memcpy(buffer, &info->shared_area, sizeof(area_id));
|
||||
|
||||
// needed for cloning
|
||||
case VESA_GET_DEVICE_NAME:
|
||||
if (user_strlcpy((char*)buffer, gDeviceNames[info->id],
|
||||
B_PATH_NAME_LENGTH) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %lu)\n",
|
||||
msg, bufferLength));
|
||||
break;
|
||||
}
|
||||
|
||||
return B_DEV_INVALID_IOCTL;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_read(void* /*cookie*/, off_t /*pos*/, void* /*buffer*/, size_t* _length)
|
||||
{
|
||||
*_length = 0;
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_write(void* /*cookie*/, off_t /*pos*/, const void* /*buffer*/,
|
||||
size_t* _length)
|
||||
{
|
||||
*_length = 0;
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
|
||||
device_hooks gDeviceHooks = {
|
||||
device_open,
|
||||
device_close,
|
||||
device_free,
|
||||
device_ioctl,
|
||||
device_read,
|
||||
device_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef DEVICE_H
|
||||
#define DEVICE_H
|
||||
|
||||
#include <Drivers.h>
|
||||
|
||||
// The device hooks for the published device
|
||||
extern device_hooks gDeviceHooks;
|
||||
|
||||
#endif /* DEVICE_H */
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <KernelExport.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <PCI.h>
|
||||
#include <frame_buffer_console.h>
|
||||
#include <boot_item.h>
|
||||
#include <vesa_info.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "device.h"
|
||||
|
||||
|
||||
#define TRACE_DRIVER
|
||||
#ifdef TRACE_DRIVER
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
#define MAX_CARDS 1
|
||||
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
char* gDeviceNames[MAX_CARDS + 1];
|
||||
framebuffer_info* gDeviceInfo[MAX_CARDS];
|
||||
mutex gLock;
|
||||
|
||||
|
||||
extern "C" const char**
|
||||
publish_devices(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": publish_devices()\n"));
|
||||
return (const char**)gDeviceNames;
|
||||
}
|
||||
|
||||
|
||||
extern "C" status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": init_hardware()\n"));
|
||||
|
||||
// If we don't have a VESA mode list, then we are a dumb
|
||||
// framebuffer, e.g. when there are no drivers available
|
||||
// on a UEFI system.
|
||||
return (get_boot_item(VESA_MODES_BOOT_INFO, NULL) == NULL
|
||||
&& get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL) != NULL)
|
||||
? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
extern "C" status_t
|
||||
init_driver(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": init_driver()\n"));
|
||||
|
||||
gDeviceInfo[0] = (framebuffer_info*)malloc(sizeof(framebuffer_info));
|
||||
if (gDeviceInfo[0] == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
memset(gDeviceInfo[0], 0, sizeof(framebuffer_info));
|
||||
|
||||
gDeviceNames[0] = strdup("graphics/framebuffer");
|
||||
if (gDeviceNames[0] == NULL) {
|
||||
free(gDeviceNames[0]);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
gDeviceNames[1] = NULL;
|
||||
|
||||
mutex_init(&gLock, "framebuffer lock");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
uninit_driver(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": uninit_driver()\n"));
|
||||
|
||||
mutex_destroy(&gLock);
|
||||
|
||||
// free device related structures
|
||||
char* name;
|
||||
for (int32 index = 0; (name = gDeviceNames[index]) != NULL; index++) {
|
||||
free(gDeviceInfo[index]);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" device_hooks*
|
||||
find_device(const char* name)
|
||||
{
|
||||
int index;
|
||||
|
||||
TRACE((DEVICE_NAME ": find_device()\n"));
|
||||
|
||||
for (index = 0; gDeviceNames[index] != NULL; index++) {
|
||||
if (!strcmp(name, gDeviceNames[index]))
|
||||
return &gDeviceHooks;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef DRIVER_H
|
||||
#define DRIVER_H
|
||||
|
||||
|
||||
#include <ISA.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <lock.h>
|
||||
|
||||
#include "framebuffer_private.h"
|
||||
|
||||
|
||||
extern char* gDeviceNames[];
|
||||
extern framebuffer_info* gDeviceInfo[];
|
||||
extern mutex gLock;
|
||||
|
||||
#endif /* DRIVER_H */
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "framebuffer_private.h"
|
||||
#include "vesa.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <drivers/bios.h>
|
||||
|
||||
#include <boot_item.h>
|
||||
#include <frame_buffer_console.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
#include <vm/vm.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "utility.h"
|
||||
#include "vesa_info.h"
|
||||
|
||||
|
||||
static status_t
|
||||
find_graphics_card(addr_t frameBuffer, addr_t& base, size_t& size)
|
||||
{
|
||||
// TODO: when we port this over to the new driver API, this mechanism can be
|
||||
// used to find the right device_node
|
||||
pci_module_info* pci;
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info**)&pci) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
pci_info info;
|
||||
for (int32 index = 0; pci->get_nth_pci_info(index, &info) == B_OK; index++) {
|
||||
if (info.class_base != PCI_display)
|
||||
continue;
|
||||
|
||||
// check PCI BARs
|
||||
for (uint32 i = 0; i < 6; i++) {
|
||||
if (info.u.h0.base_registers[i] <= frameBuffer
|
||||
&& info.u.h0.base_registers[i] + info.u.h0.base_register_sizes[i]
|
||||
> frameBuffer) {
|
||||
// found it!
|
||||
base = info.u.h0.base_registers[i];
|
||||
size = info.u.h0.base_register_sizes[i];
|
||||
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
static uint32
|
||||
get_color_space_for_depth(uint32 depth)
|
||||
{
|
||||
switch (depth) {
|
||||
case 1:
|
||||
return B_GRAY1;
|
||||
case 4:
|
||||
return B_GRAY8;
|
||||
// the app_server is smart enough to translate this to VGA mode
|
||||
case 8:
|
||||
return B_CMAP8;
|
||||
case 15:
|
||||
return B_RGB15;
|
||||
case 16:
|
||||
return B_RGB16;
|
||||
case 24:
|
||||
return B_RGB24;
|
||||
case 32:
|
||||
return B_RGB32;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Remaps the frame buffer if necessary; if we've already mapped the complete
|
||||
frame buffer, there is no need to map it again.
|
||||
*/
|
||||
static status_t
|
||||
remap_frame_buffer(framebuffer_info& info, addr_t physicalBase, uint32 width,
|
||||
uint32 height, int8 depth, uint32 bytesPerRow, bool initializing)
|
||||
{
|
||||
vesa_shared_info& sharedInfo = *info.shared_info;
|
||||
addr_t frameBuffer = info.frame_buffer;
|
||||
|
||||
if (!info.complete_frame_buffer_mapped) {
|
||||
addr_t base = physicalBase;
|
||||
size_t size = bytesPerRow * height;
|
||||
bool remap = !initializing;
|
||||
|
||||
if (info.physical_frame_buffer_size != 0) {
|
||||
// we can map the complete frame buffer
|
||||
base = info.physical_frame_buffer;
|
||||
size = info.physical_frame_buffer_size;
|
||||
remap = true;
|
||||
}
|
||||
|
||||
if (remap) {
|
||||
area_id area = map_physical_memory("framebuffer buffer", base,
|
||||
size, B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
|
||||
(void**)&frameBuffer);
|
||||
if (area < 0)
|
||||
return area;
|
||||
|
||||
if (initializing) {
|
||||
// We need to manually update the kernel's frame buffer address,
|
||||
// since this frame buffer remapping has not been issued by the
|
||||
// app_server (which would otherwise take care of this)
|
||||
frame_buffer_update(frameBuffer, width, height, depth,
|
||||
bytesPerRow);
|
||||
}
|
||||
|
||||
delete_area(info.shared_info->frame_buffer_area);
|
||||
|
||||
info.frame_buffer = frameBuffer;
|
||||
sharedInfo.frame_buffer_area = area;
|
||||
|
||||
// Turn on write combining for the area
|
||||
vm_set_area_memory_type(area, base, B_MTR_WC);
|
||||
|
||||
if (info.physical_frame_buffer_size != 0)
|
||||
info.complete_frame_buffer_mapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.complete_frame_buffer_mapped)
|
||||
frameBuffer += physicalBase - info.physical_frame_buffer;
|
||||
|
||||
// Update shared frame buffer information
|
||||
sharedInfo.frame_buffer = (uint8*)frameBuffer;
|
||||
sharedInfo.physical_frame_buffer = (uint8*)physicalBase;
|
||||
sharedInfo.bytes_per_row = bytesPerRow;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
framebuffer_init(framebuffer_info& info)
|
||||
{
|
||||
frame_buffer_boot_info* bufferInfo
|
||||
= (frame_buffer_boot_info*)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
|
||||
if (bufferInfo == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
info.complete_frame_buffer_mapped = false;
|
||||
|
||||
// Find out which PCI device we belong to, so that we know its frame buffer
|
||||
// size
|
||||
find_graphics_card(bufferInfo->physical_frame_buffer,
|
||||
info.physical_frame_buffer, info.physical_frame_buffer_size);
|
||||
|
||||
size_t sharedSize = (sizeof(vesa_shared_info) + 7) & ~7;
|
||||
|
||||
info.shared_area = create_area("framebuffer shared info",
|
||||
(void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
|
||||
ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK,
|
||||
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
|
||||
if (info.shared_area < 0)
|
||||
return info.shared_area;
|
||||
|
||||
vesa_shared_info& sharedInfo = *info.shared_info;
|
||||
|
||||
memset(&sharedInfo, 0, sizeof(vesa_shared_info));
|
||||
|
||||
sharedInfo.frame_buffer_area = bufferInfo->area;
|
||||
|
||||
remap_frame_buffer(info, bufferInfo->physical_frame_buffer,
|
||||
bufferInfo->width, bufferInfo->height, bufferInfo->depth,
|
||||
bufferInfo->bytes_per_row, true);
|
||||
// Does not matter if this fails - the frame buffer was already mapped
|
||||
// before.
|
||||
|
||||
sharedInfo.current_mode.virtual_width = bufferInfo->width;
|
||||
sharedInfo.current_mode.virtual_height = bufferInfo->height;
|
||||
sharedInfo.current_mode.space = get_color_space_for_depth(
|
||||
bufferInfo->depth);
|
||||
|
||||
dprintf(DEVICE_NAME ": framebuffer_init() completed successfully!\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
framebuffer_uninit(framebuffer_info& info)
|
||||
{
|
||||
dprintf(DEVICE_NAME": framebuffer_uninit()\n");
|
||||
|
||||
delete_area(info.shared_info->frame_buffer_area);
|
||||
delete_area(info.shared_area);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||
* Copyright 2016, Jessica Hamilton, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef VESA_PRIVATE_H
|
||||
#define VESA_PRIVATE_H
|
||||
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <Accelerant.h>
|
||||
#include <PCI.h>
|
||||
|
||||
|
||||
#define DEVICE_NAME "framebuffer"
|
||||
#define ACCELERANT_NAME "framebuffer.accelerant"
|
||||
|
||||
|
||||
struct framebuffer_info {
|
||||
uint32 cookie_magic;
|
||||
int32 open_count;
|
||||
int32 id;
|
||||
struct vesa_shared_info* shared_info;
|
||||
area_id shared_area;
|
||||
|
||||
addr_t frame_buffer;
|
||||
addr_t physical_frame_buffer;
|
||||
size_t physical_frame_buffer_size;
|
||||
bool complete_frame_buffer_mapped;
|
||||
};
|
||||
|
||||
extern status_t framebuffer_init(framebuffer_info& info);
|
||||
extern void framebuffer_uninit(framebuffer_info& info);
|
||||
|
||||
#endif /* VESA_PRIVATE_H */
|
||||
Reference in New Issue
Block a user