152 строки
3.5 KiB
C
152 строки
3.5 KiB
C
|
/*
|
||
|
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stddef.h>
|
||
|
#include <string.h>
|
||
|
#include <malloc.h>
|
||
|
#include <sys/mman.h>
|
||
|
|
||
|
#include "vesabios.h"
|
||
|
|
||
|
static int
|
||
|
vesa_init(disp_adapter_t *adapter, char *optstring)
|
||
|
{
|
||
|
vb_context_t *vb_ctx = NULL;
|
||
|
vbios_regs_t regs;
|
||
|
VESAInfoBlockStruct *VIPtr;
|
||
|
char *rombase;
|
||
|
int rc = -1;
|
||
|
|
||
|
if (vbios_register(adapter, 0) == -1)
|
||
|
goto done;
|
||
|
|
||
|
if (adapter->shmem == NULL) {
|
||
|
if ((vb_ctx = calloc(1, sizeof (*vb_ctx))) == NULL)
|
||
|
goto fail;
|
||
|
vb_ctx->free_context = 1;
|
||
|
} else {
|
||
|
vb_ctx = adapter->shmem;
|
||
|
memset(vb_ctx, 0, sizeof (*vb_ctx));
|
||
|
}
|
||
|
|
||
|
adapter->ms_ctx = vb_ctx;
|
||
|
vb_ctx->adapter = adapter;
|
||
|
|
||
|
/* Register with the display utility lib */
|
||
|
if (disp_register_adapter(adapter) == -1)
|
||
|
goto fail;
|
||
|
|
||
|
/*
|
||
|
* Grab ownership of legacy VGA registers before activating
|
||
|
* the device.
|
||
|
*/
|
||
|
if (disp_acquire_vga_resources(adapter) == -1) {
|
||
|
disp_unregister_adapter(adapter);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
disp_pci_init(adapter, DISP_PCI_INIT_BASES);
|
||
|
|
||
|
if ((rombase = disp_get_rom_image(adapter, 0, NULL, 0, 0)) == NULL)
|
||
|
goto done;
|
||
|
|
||
|
disp_warm_boot(adapter, rombase);
|
||
|
free(rombase);
|
||
|
|
||
|
disp_device_active(adapter, 1, 1);
|
||
|
|
||
|
VIPtr = (void *)adapter->vbios->xfer_area_ptr;
|
||
|
|
||
|
/* Make sure the BIOS is present and correct */
|
||
|
regs.eax = 0x4f00;
|
||
|
regs.es = adapter->vbios->xfer_area_seg;
|
||
|
regs.edi = adapter->vbios->xfer_area_off;
|
||
|
VIPtr = (VESAInfoBlockStruct *)adapter->vbios->xfer_area_ptr;
|
||
|
VIPtr->VESASignature = 0x32454256; /* VBE2 */
|
||
|
|
||
|
vbios_int(adapter->vbios, 0x10, ®s, 512);
|
||
|
|
||
|
disp_device_active(adapter, 0, 1);
|
||
|
|
||
|
#ifndef __ARM__
|
||
|
adapter->caps |= DISP_CAP_NO_IO_PRIVITY;
|
||
|
#endif
|
||
|
|
||
|
if ((regs.eax & 0xffff) == 0x004f) {
|
||
|
/* Max one display controller supported */
|
||
|
rc = 1;
|
||
|
adapter->caps |= DISP_CAP_MULTI_MONITOR_SAFE;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
disp_release_vga_resources(adapter);
|
||
|
|
||
|
if (rc == -1) {
|
||
|
disp_unregister_adapter(adapter);
|
||
|
fail:
|
||
|
if (vb_ctx && vb_ctx->free_context)
|
||
|
free(vb_ctx);
|
||
|
|
||
|
if (adapter->vbios)
|
||
|
vbios_unregister(adapter->vbios);
|
||
|
}
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
vesa_fini(disp_adapter_t *adapter)
|
||
|
{
|
||
|
vb_context_t *vb = adapter->ms_ctx;
|
||
|
|
||
|
if (adapter->ms_ctx == NULL)
|
||
|
/* Tsk tsk */
|
||
|
return;
|
||
|
|
||
|
if (vb->vidptr)
|
||
|
disp_munmap_device_memory(vb->vidptr, vb->vidsize);
|
||
|
|
||
|
vesa_restore_vga(adapter);
|
||
|
|
||
|
if (vb->free_context)
|
||
|
free(vb);
|
||
|
|
||
|
disp_pci_shutdown(adapter);
|
||
|
|
||
|
disp_unregister_adapter(adapter);
|
||
|
|
||
|
vbios_unregister(adapter->vbios);
|
||
|
|
||
|
}
|
||
|
|
||
|
int
|
||
|
devg_get_modefuncs(disp_adapter_t *adp, disp_modefuncs_t *funcs, int tabsize)
|
||
|
{
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
init, vesa_init, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
fini, vesa_fini, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
module_info, vesa_module_info, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
get_modeinfo, vesa_get_modeinfo, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
get_modelist, vesa_get_modelist, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
set_mode, vesa_set_mode, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
set_dpms_mode, vesa_set_dpms_mode, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
set_display_offset, vesa_set_display_offset, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
set_palette, vesa_set_palette, tabsize);
|
||
|
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
|
||
|
set_scroll_position, vesa_set_scroll_pos, tabsize);
|
||
|
|
||
|
return 0;
|
||
|
}
|