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:
Jessica Hamilton
2017-06-16 20:31:24 +12:00
parent b9eacd390d
commit 72fc5e6a71
16 changed files with 0 additions and 1182 deletions
-1
View File
@@ -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 */