Added very basic VESA driver. Will be improved in the future (right now
it doesn't really do anything, it just passes the initial frame buffer on to the app_server). While it seems to work on real hardware (if you set the video mode to 640x480x32, app_server restriction), under Bochs, the app_server crashes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12273 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
07ce63458b
commit
93ee21046d
10
headers/private/graphics/vesa/utility.h
Normal file
10
headers/private/graphics/vesa/utility.h
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef UTILITY_H
|
||||
#define UTILITY_H
|
||||
|
||||
#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1))
|
||||
|
||||
#endif /* UTILITY_H */
|
59
headers/private/graphics/vesa/vesa_info.h
Normal file
59
headers/private/graphics/vesa/vesa_info.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef VESA_INFO_H
|
||||
#define VESA_INFO_H
|
||||
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <Accelerant.h>
|
||||
#include <PCI.h>
|
||||
|
||||
|
||||
#define DEVICE_NAME "vesa"
|
||||
#define VESA_ACCELERANT_NAME "vesa.accelerant"
|
||||
|
||||
|
||||
struct vesa_shared_info {
|
||||
int32 type;
|
||||
area_id mode_list_area; // area containing display mode list
|
||||
uint32 mode_count;
|
||||
display_mode current_mode;
|
||||
uint32 bytes_per_row;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct vesa_info {
|
||||
uint32 cookie_magic;
|
||||
int32 open_count;
|
||||
int32 id;
|
||||
pci_info *pci;
|
||||
uint8 *registers;
|
||||
area_id registers_area;
|
||||
struct vesa_shared_info *shared_info;
|
||||
area_id shared_area;
|
||||
uint8 *frame_buffer;
|
||||
area_id frame_buffer_area;
|
||||
uint8 *reloc_io;
|
||||
area_id reloc_io_area;
|
||||
};
|
||||
|
||||
//----------------- ioctl() interface ----------------
|
||||
|
||||
// list ioctls
|
||||
enum {
|
||||
VESA_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
|
||||
VESA_GET_DEVICE_NAME,
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
extern status_t vesa_init(vesa_info &info);
|
||||
extern void vesa_uninit(vesa_info &info);
|
||||
|
||||
#endif /* VESA_INFO_H */
|
@ -8,5 +8,6 @@ SubInclude OBOS_TOP src add-ons accelerants nvidia ;
|
||||
SubInclude OBOS_TOP src add-ons accelerants radeon ;
|
||||
SubInclude OBOS_TOP src add-ons accelerants tdfx ;
|
||||
SubInclude OBOS_TOP src add-ons accelerants skeleton ;
|
||||
SubInclude OBOS_TOP src add-ons accelerants vesa ;
|
||||
|
||||
SubIncludeGPL OBOS_TOP src add-ons accelerants atimach64 ;
|
||||
|
15
src/add-ons/accelerants/vesa/Jamfile
Normal file
15
src/add-ons/accelerants/vesa/Jamfile
Normal file
@ -0,0 +1,15 @@
|
||||
SubDir OBOS_TOP src add-ons accelerants vesa ;
|
||||
|
||||
UsePrivateHeaders graphics ;
|
||||
UsePrivateHeaders [ FDirName graphics vesa ] ;
|
||||
|
||||
#AddResources vesa.accelerant : vesa.accelerant.rdef ;
|
||||
|
||||
Addon vesa.accelerant : accelerants :
|
||||
accelerant.cpp
|
||||
dpms.cpp
|
||||
engine.cpp
|
||||
hooks.cpp
|
||||
mode.cpp
|
||||
: false # this add-on is not executable
|
||||
;
|
252
src/add-ons/accelerants/vesa/accelerant.cpp
Normal file
252
src/add-ons/accelerants/vesa/accelerant.cpp
Normal file
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* 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 <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;
|
||||
|
||||
// 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("vesa 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
|
||||
vesa_init_accelerant(int device)
|
||||
{
|
||||
TRACE(("vesa_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
|
||||
vesa_accelerant_clone_info_size(void)
|
||||
{
|
||||
// clone info is device name, so return its maximum size
|
||||
return B_PATH_NAME_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vesa_get_accelerant_clone_info(void *info)
|
||||
{
|
||||
ioctl(gInfo->device, VESA_GET_DEVICE_NAME, info, B_PATH_NAME_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_clone_accelerant(void *info)
|
||||
{
|
||||
TRACE(("vesa_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 fd;
|
||||
|
||||
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(
|
||||
"vesa 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
|
||||
vesa_uninit_accelerant(void)
|
||||
{
|
||||
TRACE(("vesa_uninit_accelerant()\n"));
|
||||
|
||||
// delete accelerant instance data
|
||||
delete_area(gInfo->mode_list_area);
|
||||
gInfo->mode_list = NULL;
|
||||
|
||||
uninit_common();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_get_accelerant_device_info(accelerant_device_info *info)
|
||||
{
|
||||
info->version = B_ACCELERANT_VERSION;
|
||||
strcpy(info->name, "VESA Driver");
|
||||
strcpy(info->chipset, "VESA");
|
||||
// ToDo: provide some more insight here...
|
||||
strcpy(info->serial_no, "None");
|
||||
|
||||
#if 0
|
||||
info->memory = ???
|
||||
info->dac_speed = ???
|
||||
#endif
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
sem_id
|
||||
vesa_accelerant_retrace_semaphore()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
27
src/add-ons/accelerants/vesa/accelerant.h
Normal file
27
src/add-ons/accelerants/vesa/accelerant.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* 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; // file descriptor of kernel 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;
|
||||
} accelerant_info;
|
||||
|
||||
extern accelerant_info *gInfo;
|
||||
|
||||
extern status_t create_mode_list(void);
|
||||
|
||||
#endif /* VESA_ACCELERANT_H */
|
77
src/add-ons/accelerants/vesa/accelerant_protos.h
Normal file
77
src/add-ons/accelerants/vesa/accelerant_protos.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. 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 vesa_init_accelerant(int fd);
|
||||
ssize_t vesa_accelerant_clone_info_size(void);
|
||||
void vesa_get_accelerant_clone_info(void *data);
|
||||
status_t vesa_clone_accelerant(void *data);
|
||||
void vesa_uninit_accelerant(void);
|
||||
status_t vesa_get_accelerant_device_info(accelerant_device_info *adi);
|
||||
sem_id vesa_accelerant_retrace_semaphore(void);
|
||||
|
||||
// modes & constraints
|
||||
uint32 vesa_accelerant_mode_count(void);
|
||||
status_t vesa_get_mode_list(display_mode *dm);
|
||||
status_t vesa_propose_display_mode(display_mode *target, const display_mode *low, const display_mode *high);
|
||||
status_t vesa_set_display_mode(display_mode *mode_to_set);
|
||||
status_t vesa_get_display_mode(display_mode *current_mode);
|
||||
status_t vesa_get_frame_buffer_config(frame_buffer_config *config);
|
||||
status_t vesa_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high);
|
||||
status_t vesa_move_display(uint16 h_display_start, uint16 v_display_start);
|
||||
status_t vesa_get_timing_constraints(display_timing_constraints *dtc);
|
||||
void vesa_set_indexed_colors(uint count, uint8 first, uint8 *color_data, uint32 flags);
|
||||
|
||||
// DPMS
|
||||
uint32 vesa_dpms_capabilities(void);
|
||||
uint32 vesa_dpms_mode(void);
|
||||
status_t vesa_set_dpms_mode(uint32 dpms_flags);
|
||||
|
||||
// cursor
|
||||
status_t vesa_set_cursor_shape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask);
|
||||
void vesa_move_cursor(uint16 x, uint16 y);
|
||||
void vesa_show_cursor(bool is_visible);
|
||||
|
||||
// accelerant engine
|
||||
uint32 vesa_accelerant_engine_count(void);
|
||||
status_t vesa_acquire_engine(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et);
|
||||
status_t vesa_release_engine(engine_token *et, sync_token *st);
|
||||
void vesa_wait_engine_idle(void);
|
||||
status_t vesa_get_sync_token(engine_token *et, sync_token *st);
|
||||
status_t vesa_sync_to_token(sync_token *st);
|
||||
|
||||
// 2D acceleration
|
||||
void vesa_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count);
|
||||
void vesa_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
|
||||
void vesa_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count);
|
||||
void vesa_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count);
|
||||
|
||||
// overlay
|
||||
uint32 vesa_overlay_count(const display_mode *dm);
|
||||
const uint32 *vesa_overlay_supported_spaces(const display_mode *dm);
|
||||
uint32 vesa_overlay_supported_features(uint32 a_color_space);
|
||||
const overlay_buffer *vesa_allocate_overlay_buffer(color_space cs, uint16 width, uint16 height);
|
||||
status_t vesa_release_overlay_buffer(const overlay_buffer *ob);
|
||||
status_t vesa_get_overlay_constraints(const display_mode *dm, const overlay_buffer *ob, overlay_constraints *oc);
|
||||
overlay_token vesa_allocate_overlay(void);
|
||||
status_t vesa_release_overlay(overlay_token ot);
|
||||
status_t vesa_configure_overlay(overlay_token ot, const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ACCELERANT_PROTOS_H */
|
30
src/add-ons/accelerants/vesa/dpms.cpp
Normal file
30
src/add-ons/accelerants/vesa/dpms.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
#include "accelerant.h"
|
||||
|
||||
|
||||
uint32
|
||||
vesa_dpms_capabilities(void)
|
||||
{
|
||||
return B_DPMS_ON;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
vesa_dpms_mode(void)
|
||||
{
|
||||
return B_DPMS_ON;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_set_dpms_mode(uint32 dpms_flags)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
59
src/add-ons/accelerants/vesa/engine.cpp
Normal file
59
src/add-ons/accelerants/vesa/engine.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. 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
|
||||
vesa_accelerant_engine_count(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_acquire_engine(uint32 capabilities, uint32 max_wait, sync_token *syncToken,
|
||||
engine_token **_engineToken)
|
||||
{
|
||||
*_engineToken = &sEngineToken;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_release_engine(engine_token *engineToken, sync_token *syncToken)
|
||||
{
|
||||
if (syncToken != NULL)
|
||||
syncToken->engine_id = engineToken->engine_id;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vesa_wait_engine_idle(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_get_sync_token(engine_token *engineToken, sync_token *syncToken)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_sync_to_token(sync_token *syncToken)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
106
src/add-ons/accelerants/vesa/hooks.cpp
Normal file
106
src/add-ons/accelerants/vesa/hooks.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
|
||||
|
||||
// ToDo: these are some temporary dummy functions to see if this helps with our current app_server
|
||||
|
||||
status_t
|
||||
vesa_set_cursor_shape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vesa_move_cursor(uint16 x, uint16 y)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vesa_show_cursor(bool is_visible)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
extern "C" void *
|
||||
get_accelerant_hook(uint32 feature, void *data)
|
||||
{
|
||||
switch (feature) {
|
||||
/* general */
|
||||
case B_INIT_ACCELERANT:
|
||||
return vesa_init_accelerant;
|
||||
case B_UNINIT_ACCELERANT:
|
||||
return vesa_uninit_accelerant;
|
||||
case B_CLONE_ACCELERANT:
|
||||
return vesa_clone_accelerant;
|
||||
case B_ACCELERANT_CLONE_INFO_SIZE:
|
||||
return vesa_accelerant_clone_info_size;
|
||||
case B_GET_ACCELERANT_CLONE_INFO:
|
||||
return vesa_get_accelerant_clone_info;
|
||||
case B_GET_ACCELERANT_DEVICE_INFO:
|
||||
return vesa_get_accelerant_device_info;
|
||||
case B_ACCELERANT_RETRACE_SEMAPHORE:
|
||||
return vesa_accelerant_retrace_semaphore;
|
||||
|
||||
/* mode configuration */
|
||||
case B_ACCELERANT_MODE_COUNT:
|
||||
return vesa_accelerant_mode_count;
|
||||
case B_GET_MODE_LIST:
|
||||
return vesa_get_mode_list;
|
||||
case B_PROPOSE_DISPLAY_MODE:
|
||||
return vesa_propose_display_mode;
|
||||
case B_SET_DISPLAY_MODE:
|
||||
return vesa_set_display_mode;
|
||||
case B_GET_DISPLAY_MODE:
|
||||
return vesa_get_display_mode;
|
||||
case B_GET_FRAME_BUFFER_CONFIG:
|
||||
return vesa_get_frame_buffer_config;
|
||||
case B_GET_PIXEL_CLOCK_LIMITS:
|
||||
return vesa_get_pixel_clock_limits;
|
||||
case B_MOVE_DISPLAY:
|
||||
return vesa_move_display;
|
||||
case B_SET_INDEXED_COLORS:
|
||||
return vesa_set_indexed_colors;
|
||||
case B_GET_TIMING_CONSTRAINTS:
|
||||
return vesa_get_timing_constraints;
|
||||
|
||||
/* DPMS */
|
||||
case B_DPMS_CAPABILITIES:
|
||||
return vesa_dpms_capabilities;
|
||||
case B_DPMS_MODE:
|
||||
return vesa_dpms_mode;
|
||||
case B_SET_DPMS_MODE:
|
||||
return vesa_set_dpms_mode;
|
||||
|
||||
/* cursor managment */
|
||||
case B_SET_CURSOR_SHAPE:
|
||||
return vesa_set_cursor_shape;
|
||||
case B_MOVE_CURSOR:
|
||||
return vesa_move_cursor;
|
||||
case B_SHOW_CURSOR:
|
||||
return vesa_show_cursor;
|
||||
|
||||
/* engine/synchronization */
|
||||
case B_ACCELERANT_ENGINE_COUNT:
|
||||
return vesa_accelerant_engine_count;
|
||||
case B_ACQUIRE_ENGINE:
|
||||
return vesa_acquire_engine;
|
||||
case B_RELEASE_ENGINE:
|
||||
return vesa_release_engine;
|
||||
case B_WAIT_ENGINE_IDLE:
|
||||
return vesa_wait_engine_idle;
|
||||
case B_GET_SYNC_TOKEN:
|
||||
return vesa_get_sync_token;
|
||||
case B_SYNC_TO_TOKEN:
|
||||
return vesa_sync_to_token;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
234
src/add-ons/accelerants/vesa/mode.cpp
Normal file
234
src/add-ons/accelerants/vesa/mode.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
#define T_POSITIVE_SYNC (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC)
|
||||
#define MODE_FLAGS (B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS | B_DPMS /*| B_SUPPORTS_OVERLAYS*/)
|
||||
|
||||
static const display_mode kBaseModeList[] = {
|
||||
{ { 25175, 640, 656, 752, 800, 350, 387, 389, 449, B_POSITIVE_HSYNC}, B_CMAP8, 640, 350, 0, 0, MODE_FLAGS}, /* 640x350 - www.epanorama.net/documents/pc/vga_timing.html) */
|
||||
{ { 25175, 640, 656, 752, 800, 400, 412, 414, 449, B_POSITIVE_VSYNC}, B_CMAP8, 640, 400, 0, 0, MODE_FLAGS}, /* 640x400 - www.epanorama.net/documents/pc/vga_timing.html) */
|
||||
{ { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */
|
||||
{ { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */
|
||||
{ { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */
|
||||
{ { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */
|
||||
{ { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */
|
||||
{ { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */
|
||||
{ { 38100, 800, 832, 960, 1088, 600, 602, 606, 620, 0}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* SVGA_800X600X56HzNI */
|
||||
{ { 40000, 800, 840, 968, 1056, 600, 601, 605, 628, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(800X600X8.Z1) */
|
||||
{ { 49500, 800, 816, 896, 1056, 600, 601, 604, 625, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(800X600X8.Z1) */
|
||||
{ { 50000, 800, 856, 976, 1040, 600, 637, 643, 666, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(800X600X8.Z1) */
|
||||
{ { 56250, 800, 832, 896, 1048, 600, 601, 604, 631, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(800X600X8.Z1) */
|
||||
{ { 65000, 1024, 1048, 1184, 1344, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1024X768X8.Z1) */
|
||||
{ { 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(1024X768X8.Z1) */
|
||||
{ { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1024X768X8.Z1) */
|
||||
{ { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1024X768X8.Z1) */
|
||||
{ { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */
|
||||
{ { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1152X864X8.Z1) */
|
||||
{ { 121500, 1152, 1216, 1344, 1568, 864, 865, 868, 911, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1152X864X8.Z1) */
|
||||
{ { 108000, 1280, 1328, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X1024X8.Z1) */
|
||||
{ { 135000, 1280, 1296, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1280X1024X8.Z1) */
|
||||
{ { 157500, 1280, 1344, 1504, 1728, 1024, 1025, 1028, 1072, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1280X1024X8.Z1) */
|
||||
{ { 162000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1600X1200X8.Z1) */
|
||||
{ { 175500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@65Hz_(1600X1200X8.Z1) */
|
||||
{ { 189000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1600X1200X8.Z1) */
|
||||
{ { 202500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1600X1200X8.Z1) */
|
||||
{ { 216000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@80Hz_(1600X1200X8.Z1) */
|
||||
{ { 229500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@85Hz_(1600X1200X8.Z1) */
|
||||
};
|
||||
static const uint32 kNumBaseModes = sizeof(kBaseModeList) / sizeof(display_mode);
|
||||
static const uint32 kMaxNumModes = kNumBaseModes * 4;
|
||||
|
||||
|
||||
/** Creates the initial mode list of the primary accelerant.
|
||||
* It's called from vesa_init_accelerant().
|
||||
*/
|
||||
|
||||
status_t
|
||||
create_mode_list(void)
|
||||
{
|
||||
// ToDo: basically, the boot loader should pass a list of all supported
|
||||
// VESA modes to us.
|
||||
color_space spaces[4] = {B_RGB32_LITTLE, B_RGB16_LITTLE, B_RGB15_LITTLE, B_CMAP8};
|
||||
size_t size = ROUND_TO_PAGE_SIZE(kMaxNumModes * sizeof(display_mode));
|
||||
display_mode *list;
|
||||
|
||||
gInfo->mode_list_area = create_area("vesa modes", (void **)&list, B_ANY_ADDRESS,
|
||||
size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (gInfo->mode_list_area < B_OK)
|
||||
return gInfo->mode_list_area;
|
||||
|
||||
// for now, just copy all of the modes with different color spaces
|
||||
|
||||
const display_mode *source = kBaseModeList;
|
||||
uint32 count = 0;
|
||||
|
||||
for (uint32 i = 0; i < kNumBaseModes; i++) {
|
||||
for (uint32 j = 0; j < (sizeof(spaces) / sizeof(color_space)); j++) {
|
||||
list[count] = *source;
|
||||
list[count].space = spaces[j];
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
source++;
|
||||
}
|
||||
|
||||
gInfo->mode_list = list;
|
||||
gInfo->shared_info->mode_list_area = gInfo->mode_list_area;
|
||||
gInfo->shared_info->mode_count = count;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
uint32
|
||||
vesa_accelerant_mode_count(void)
|
||||
{
|
||||
TRACE(("vesa_accelerant_mode_count()\n"));
|
||||
return gInfo->shared_info->mode_count;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_get_mode_list(display_mode *modeList)
|
||||
{
|
||||
TRACE(("vesa_get_mode_info()\n"));
|
||||
memcpy(modeList, gInfo->mode_list, gInfo->shared_info->mode_count * sizeof(display_mode));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_propose_display_mode(display_mode *target, const display_mode *low,
|
||||
const display_mode *high)
|
||||
{
|
||||
TRACE(("vesa_propose_display_mode()\n"));
|
||||
|
||||
// just search for the specified mode in the list
|
||||
|
||||
for (uint32 i = 0; i < gInfo->shared_info->mode_count; i++) {
|
||||
display_mode *current = &gInfo->mode_list[i];
|
||||
|
||||
if (target->virtual_width != current->virtual_width
|
||||
|| target->virtual_height != current->virtual_height
|
||||
|| target->space != current->space)
|
||||
continue;
|
||||
|
||||
*target = *current;
|
||||
return B_OK;
|
||||
}
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_set_display_mode(display_mode *_mode)
|
||||
{
|
||||
TRACE(("vesa_set_display_mode()\n"));
|
||||
|
||||
display_mode mode = *_mode;
|
||||
if (vesa_propose_display_mode(&mode, &mode, &mode) != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
gInfo->shared_info->current_mode = mode;
|
||||
|
||||
switch (mode.space) {
|
||||
case B_RGB32_LITTLE:
|
||||
gInfo->shared_info->bytes_per_row = mode.virtual_width * 4;
|
||||
break;
|
||||
case B_RGB16_LITTLE:
|
||||
case B_RGB15_LITTLE:
|
||||
gInfo->shared_info->bytes_per_row = mode.virtual_width * 2;
|
||||
break;
|
||||
case B_CMAP8:
|
||||
gInfo->shared_info->bytes_per_row = mode.virtual_width;
|
||||
break;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_get_display_mode(display_mode *_currentMode)
|
||||
{
|
||||
TRACE(("vesa_get_display_mode()\n"));
|
||||
*_currentMode = gInfo->shared_info->current_mode;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_get_frame_buffer_config(frame_buffer_config *config)
|
||||
{
|
||||
TRACE(("vesa_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
|
||||
vesa_get_pixel_clock_limits(display_mode *mode, uint32 *low, uint32 *high)
|
||||
{
|
||||
TRACE(("vesa_get_pixel_clock_limits()\n"));
|
||||
|
||||
// ToDo: do some real stuff here (taken from radeon driver)
|
||||
uint32 total_pix = (uint32)mode->timing.h_total * (uint32)mode->timing.v_total;
|
||||
uint32 clock_limit = 2000000;
|
||||
|
||||
/* lower limit of about 48Hz vertical refresh */
|
||||
*low = (total_pix * 48L) / 1000L;
|
||||
if (*low > clock_limit)
|
||||
return B_ERROR;
|
||||
|
||||
*high = clock_limit;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_move_display(uint16 h_display_start, uint16 v_display_start)
|
||||
{
|
||||
TRACE(("vesa_move_display()\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vesa_get_timing_constraints(display_timing_constraints *dtc)
|
||||
{
|
||||
TRACE(("vesa_get_timing_constraints()\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vesa_set_indexed_colors(uint count, uint8 first, uint8 *color_data, uint32 flags)
|
||||
{
|
||||
TRACE(("vesa_set_indexed_colors()\n"));
|
||||
}
|
||||
|
@ -8,5 +8,6 @@ SubInclude OBOS_TOP src add-ons kernel drivers graphics nvidia ;
|
||||
SubInclude OBOS_TOP src add-ons kernel drivers graphics radeon ;
|
||||
SubInclude OBOS_TOP src add-ons kernel drivers graphics tdfx ;
|
||||
SubInclude OBOS_TOP src add-ons kernel drivers graphics skeleton ;
|
||||
SubInclude OBOS_TOP src add-ons kernel drivers graphics vesa ;
|
||||
|
||||
SubIncludeGPL OBOS_TOP src add-ons kernel drivers graphics atimach64 ;
|
||||
|
18
src/add-ons/kernel/drivers/graphics/vesa/Jamfile
Normal file
18
src/add-ons/kernel/drivers/graphics/vesa/Jamfile
Normal file
@ -0,0 +1,18 @@
|
||||
SubDir OBOS_TOP src add-ons kernel drivers graphics vesa ;
|
||||
|
||||
UsePrivateHeaders graphics ;
|
||||
UsePrivateHeaders [ FDirName graphics vesa ] ;
|
||||
|
||||
KernelAddon vesa : kernel drivers bin :
|
||||
device.cpp
|
||||
driver.cpp
|
||||
vesa.cpp
|
||||
;
|
||||
|
||||
# Link to kernel/drivers/dev/graphics
|
||||
{
|
||||
local dir = [ FDirName $(OBOS_ADDON_DIR) kernel drivers dev graphics ] ;
|
||||
local instDriver = <kernel!drivers!dev!graphics>vesa ;
|
||||
MakeLocate $(instDriver) : $(dir) ;
|
||||
RelSymLink $(instDriver) : vesa ;
|
||||
}
|
174
src/add-ons/kernel/drivers/graphics/vesa/device.cpp
Normal file
174
src/add-ons/kernel/drivers/graphics/vesa/device.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <KernelExport.h>
|
||||
#include <Drivers.h>
|
||||
#include <PCI.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <graphic_driver.h>
|
||||
#include <image.h>
|
||||
#include <boot_item.h>
|
||||
#include <frame_buffer_console.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "device.h"
|
||||
#include "vesa_info.h"
|
||||
#include "utility.h"
|
||||
|
||||
|
||||
//#define TRACE_DEVICE
|
||||
#ifdef TRACE_DEVICE
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
/* device hooks prototypes */
|
||||
|
||||
static status_t device_open(const char *, uint32, void **);
|
||||
static status_t device_close(void *);
|
||||
static status_t device_free(void *);
|
||||
static status_t device_ioctl(void *, uint32, void *, size_t);
|
||||
static status_t device_read(void *, off_t, void *, size_t *);
|
||||
static status_t device_write(void *, off_t, const void *, size_t *);
|
||||
|
||||
|
||||
device_hooks gDeviceHooks = {
|
||||
device_open,
|
||||
device_close,
|
||||
device_free,
|
||||
device_ioctl,
|
||||
device_read,
|
||||
device_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// the device will be accessed through the following functions (a.k.a. device hooks)
|
||||
|
||||
|
||||
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)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
vesa_info *info = gDeviceInfo[id];
|
||||
*_cookie = info;
|
||||
|
||||
acquire_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
|
||||
|
||||
frame_buffer_boot_info *bufferInfo = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO);
|
||||
if (bufferInfo != NULL) {
|
||||
info->frame_buffer = (uint8 *)bufferInfo->frame_buffer;
|
||||
info->frame_buffer_area = bufferInfo->area;
|
||||
}
|
||||
|
||||
info->id = id;
|
||||
|
||||
status = vesa_init(*info);
|
||||
}
|
||||
|
||||
release_lock(&gLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_close(void *cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_free(void *cookie)
|
||||
{
|
||||
struct vesa_info *info = (vesa_info *)cookie;
|
||||
|
||||
acquire_lock(&gLock);
|
||||
|
||||
if (info->open_count-- == 1) {
|
||||
// release info structure
|
||||
vesa_uninit(*info);
|
||||
}
|
||||
|
||||
release_lock(&gLock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
device_ioctl(void *cookie, uint32 msg, void *buffer, size_t bufferLength)
|
||||
{
|
||||
struct vesa_info *info = (vesa_info *)cookie;
|
||||
|
||||
switch (msg) {
|
||||
case B_GET_ACCELERANT_SIGNATURE:
|
||||
user_strlcpy((char *)buffer, VESA_ACCELERANT_NAME, B_FILE_NAME_LENGTH);
|
||||
dprintf(DEVICE_NAME ": acc: %s\n", VESA_ACCELERANT_NAME);
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
13
src/add-ons/kernel/drivers/graphics/vesa/device.h
Normal file
13
src/add-ons/kernel/drivers/graphics/vesa/device.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. 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 */
|
127
src/add-ons/kernel/drivers/graphics/vesa/driver.cpp
Normal file
127
src/add-ons/kernel/drivers/graphics/vesa/driver.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* 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 <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];
|
||||
vesa_info *gDeviceInfo[MAX_CARDS];
|
||||
lock gLock;
|
||||
|
||||
|
||||
extern "C" {
|
||||
status_t init_hardware(void);
|
||||
status_t init_driver(void);
|
||||
void uninit_driver(void);
|
||||
const char **publish_devices(void);
|
||||
device_hooks *find_device(const char *name);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static status_t
|
||||
get_next_graphics_card(int32 *_cookie, pci_info &info)
|
||||
{
|
||||
int32 index = *_cookie;
|
||||
|
||||
// find devices
|
||||
for (; gPCI->get_nth_pci_info(index, &info) == B_OK; index++) {
|
||||
if (info.class_base == PCI_display) {
|
||||
*_cookie = index + 1;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char **
|
||||
publish_devices(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": publish_devices()\n"));
|
||||
return (const char **)gDeviceNames;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": init_hardware()\n"));
|
||||
|
||||
return get_boot_item(FRAME_BUFFER_BOOT_INFO) != NULL ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_driver(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": init_driver()\n"));
|
||||
|
||||
if ((gDeviceInfo[0] = (vesa_info *)malloc(sizeof(vesa_info))) != NULL)
|
||||
memset(gDeviceInfo[0], 0, sizeof(vesa_info));
|
||||
else
|
||||
return B_NO_MEMORY;
|
||||
|
||||
gDeviceNames[0] = strdup("graphics/vesa");
|
||||
gDeviceNames[1] = NULL;
|
||||
|
||||
return init_lock(&gLock, "vesa lock");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uninit_driver(void)
|
||||
{
|
||||
TRACE((DEVICE_NAME ": uninit_driver()\n"));
|
||||
|
||||
uninit_lock(&gLock);
|
||||
|
||||
// free device related structures
|
||||
char *name;
|
||||
for (int32 index = 0; (name = gDeviceNames[index]) != NULL; index++) {
|
||||
free(gDeviceInfo[index]);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
20
src/add-ons/kernel/drivers/graphics/vesa/driver.h
Normal file
20
src/add-ons/kernel/drivers/graphics/vesa/driver.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef DRIVER_H
|
||||
#define DRIVER_H
|
||||
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <PCI.h>
|
||||
|
||||
#include "vesa_info.h"
|
||||
#include "lock.h"
|
||||
|
||||
|
||||
extern char *gDeviceNames[];
|
||||
extern vesa_info *gDeviceInfo[];
|
||||
extern lock gLock;
|
||||
|
||||
#endif /* DRIVER_H */
|
54
src/add-ons/kernel/drivers/graphics/vesa/lock.h
Normal file
54
src/add-ons/kernel/drivers/graphics/vesa/lock.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef LOCK_H
|
||||
#define LOCK_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
typedef struct lock {
|
||||
sem_id sem;
|
||||
vint32 count;
|
||||
} lock;
|
||||
|
||||
|
||||
static inline status_t
|
||||
init_lock(struct lock *lock, const char *name)
|
||||
{
|
||||
lock->sem = create_sem(0, name);
|
||||
lock->count = 0;
|
||||
|
||||
return lock->sem < B_OK ? lock->sem : B_OK;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
uninit_lock(struct lock *lock)
|
||||
{
|
||||
delete_sem(lock->sem);
|
||||
}
|
||||
|
||||
|
||||
static inline status_t
|
||||
acquire_lock(struct lock *lock)
|
||||
{
|
||||
if (atomic_add(&lock->count, 1) > 0)
|
||||
return acquire_sem(lock->sem);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static inline status_t
|
||||
release_lock(struct lock *lock)
|
||||
{
|
||||
if (atomic_add(&lock->count, -1) > 1)
|
||||
return release_sem(lock->sem);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
#endif /* LOCK_H */
|
96
src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp
Normal file
96
src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "vesa_info.h"
|
||||
#include "driver.h"
|
||||
#include "utility.h"
|
||||
|
||||
#include "util/kernel_cpp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
class PhysicalMemoryMapper {
|
||||
public:
|
||||
PhysicalMemoryMapper();
|
||||
~PhysicalMemoryMapper();
|
||||
|
||||
area_id Map(const char *name, void *physicalAddress, size_t numBytes,
|
||||
uint32 spec, uint32 protection, void **virtualAddress);
|
||||
status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; }
|
||||
void Keep();
|
||||
|
||||
private:
|
||||
area_id fArea;
|
||||
};
|
||||
|
||||
|
||||
PhysicalMemoryMapper::PhysicalMemoryMapper()
|
||||
:
|
||||
fArea(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PhysicalMemoryMapper::~PhysicalMemoryMapper()
|
||||
{
|
||||
if (fArea >= B_OK)
|
||||
delete_area(fArea);
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
PhysicalMemoryMapper::Map(const char *name, void *physicalAddress, size_t numBytes,
|
||||
uint32 spec, uint32 protection, void **virtualAddress)
|
||||
{
|
||||
fArea = map_physical_memory(name, physicalAddress, numBytes, spec, protection, virtualAddress);
|
||||
return fArea;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PhysicalMemoryMapper::Keep()
|
||||
{
|
||||
fArea = -1;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
vesa_init(vesa_info &info)
|
||||
{
|
||||
info.shared_area = create_area("vesa shared info", (void **)&info.shared_info,
|
||||
B_ANY_KERNEL_ADDRESS,
|
||||
ROUND_TO_PAGE_SIZE(sizeof(vesa_shared_info)),
|
||||
B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
|
||||
if (info.shared_area < B_OK)
|
||||
return info.shared_area;
|
||||
|
||||
memset((void *)info.shared_info, 0, sizeof(vesa_shared_info));
|
||||
|
||||
info.shared_info->frame_buffer_area = info.frame_buffer_area;
|
||||
info.shared_info->frame_buffer = info.frame_buffer;
|
||||
|
||||
physical_entry mapping;
|
||||
get_memory_map((void *)info.frame_buffer, B_PAGE_SIZE, &mapping, 1);
|
||||
info.shared_info->physical_frame_buffer = (uint8 *)mapping.address;
|
||||
|
||||
dprintf(DEVICE_NAME "vesa_init() completed successfully!\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vesa_uninit(vesa_info &info)
|
||||
{
|
||||
dprintf(DEVICE_NAME": vesa_uninit()\n");
|
||||
|
||||
delete_area(info.frame_buffer_area);
|
||||
delete_area(info.shared_area);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user