mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Add Bochs VBE VGA support
git-svn-id: svn://coreboot.org/openbios/openbios-devel@258 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -131,24 +131,26 @@ typedef struct osi_fb_info {
|
||||
} osi_fb_info_t;
|
||||
|
||||
|
||||
#define openbios_GetFBInfo(x) Qemu_GetFBInfo(x)
|
||||
|
||||
#include "../../../modules/font_8x16.c"
|
||||
#include "../../../modules/video.c"
|
||||
#include "../../../modules/console.c"
|
||||
|
||||
static uint32_t vga_phys_mem;
|
||||
static int vga_width, vga_height, vga_depth;
|
||||
|
||||
int Qemu_GetFBInfo( osi_fb_info_t *fb )
|
||||
{
|
||||
|
||||
fb->w=1024;
|
||||
fb->h=768;
|
||||
fb->depth=15;
|
||||
fb->rb=2048;
|
||||
fb->mphys=0x84000000;
|
||||
fb->mphys = vga_phys_mem;
|
||||
fb->w = vga_width;
|
||||
fb->h = vga_height;
|
||||
fb->depth = vga_depth;
|
||||
fb->rb = fb->w * ((fb->depth + 7) / 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define openbios_GetFBInfo(x) Qemu_GetFBInfo(x)
|
||||
|
||||
#include "../../../modules/video.c"
|
||||
|
||||
#include "../../../modules/console.c"
|
||||
|
||||
/* ******************************************************************
|
||||
* common functions, implementing simple concurrent console
|
||||
* ****************************************************************** */
|
||||
|
||||
@@ -118,7 +118,6 @@ arch_of_init( void )
|
||||
#endif
|
||||
|
||||
node_methods_init();
|
||||
init_video();
|
||||
|
||||
#if USE_RTAS
|
||||
if( !(ph=find_dev("/rtas")) )
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<option name="CONFIG_DEBUG_INTERPRETER" type="boolean" value="false"/>
|
||||
<option name="CONFIG_DEBUG_CONSOLE" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DEBUG_CONSOLE_SERIAL" type="boolean" value="true"/>
|
||||
<option name="CONFIG_SERIAL_PORT" type="boolean" value="true"/>
|
||||
<option name="CONFIG_SERIAL_PORT" type="integer" value="1"/>
|
||||
<option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/>
|
||||
<option name="CONFIG_DEBUG_CONSOLE_VGA" type="boolean" value="true"/>
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
<option name="CONFIG_IDE_NUM_CHANNELS" type="integer" value="4"/>
|
||||
<option name="CONFIG_DEBUG_IDE" type="boolean" value="false"/>
|
||||
<option name="CONFIG_DRIVER_ADB" type="boolean" value="true"/>
|
||||
<option name="CONFIG_DRIVER_VGA" type="boolean" value="true"/>
|
||||
|
||||
</config>
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<object source="obio.c" condition="DRIVER_OBIO"/>
|
||||
<object source="vga_load_regs.c" condition="DRIVER_VGA"/>
|
||||
<object source="vga_set_mode.c" condition="DRIVER_VGA"/>
|
||||
<object source="vga_vbe.c" condition="DRIVER_VGA"/>
|
||||
</library>
|
||||
|
||||
<dictionary name="openbios" target="forth">
|
||||
|
||||
@@ -301,11 +301,9 @@ static pci_dev_t vga_devices[] = {
|
||||
|
||||
static int vga_config_cb (pci_config_t *config)
|
||||
{
|
||||
#if 0
|
||||
if (config->regions[0] != 0x00000000)
|
||||
vga_vbe_init(config->path, config->regions[0], config->sizes[0],
|
||||
config->regions[1], config->sizes[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,8 @@ void vga_hardware_fixup(void);
|
||||
#define SEQ_I 0x3C4 /* Sequencer Index */
|
||||
#define PEL_IW 0x3C8 /* PEL Write Index */
|
||||
#define PEL_IR 0x3C7 /* PEL Read Index */
|
||||
#define DAC_REG 0x3C8 /* DAC register */
|
||||
#define DAC_VAL 0x3C9 /* DAC value */
|
||||
|
||||
/* standard VGA indexes max counts */
|
||||
#define CRTC_C 25 /* 25 CRT Controller Registers sequentially set*/
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
static int depth;
|
||||
|
||||
// prototypes
|
||||
static int vga_decode_var(const struct screeninfo *var, struct vga_par *par);
|
||||
static int vga_set_regs(const struct vga_par *par);
|
||||
@@ -124,11 +126,7 @@ static const struct screeninfo vga_settings = {
|
||||
0, // activate now
|
||||
-1,-1, // height and width in mm
|
||||
0, // accel flags
|
||||
39721, // pixclock: 79442 -> 12.587 Mhz (NOT USED)
|
||||
// 70616 -> 14.161
|
||||
// 39721 -> 25.175
|
||||
// 35308 -> 28.322
|
||||
|
||||
39721, // pixclock
|
||||
48, 16, 39, 8, // margins left,right,upper,lower
|
||||
96, // hsync length
|
||||
2, // vsync length
|
||||
|
||||
131
drivers/vga_vbe.c
Normal file
131
drivers/vga_vbe.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License V2
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "openbios/config.h"
|
||||
#include "openbios/kernel.h"
|
||||
#include "openbios/bindings.h"
|
||||
#include "openbios/pci.h"
|
||||
#include "asm/io.h"
|
||||
|
||||
/* VGA init. We use the Bochs VESA VBE extensions */
|
||||
#define VBE_DISPI_INDEX_ID 0x0
|
||||
#define VBE_DISPI_INDEX_XRES 0x1
|
||||
#define VBE_DISPI_INDEX_YRES 0x2
|
||||
#define VBE_DISPI_INDEX_BPP 0x3
|
||||
#define VBE_DISPI_INDEX_ENABLE 0x4
|
||||
#define VBE_DISPI_INDEX_BANK 0x5
|
||||
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
|
||||
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
|
||||
#define VBE_DISPI_INDEX_X_OFFSET 0x8
|
||||
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
|
||||
#define VBE_DISPI_INDEX_NB 0xa
|
||||
|
||||
#define VBE_DISPI_ID0 0xB0C0
|
||||
#define VBE_DISPI_ID1 0xB0C1
|
||||
#define VBE_DISPI_ID2 0xB0C2
|
||||
|
||||
#define VBE_DISPI_DISABLED 0x00
|
||||
#define VBE_DISPI_ENABLED 0x01
|
||||
#define VBE_DISPI_LFB_ENABLED 0x40
|
||||
#define VBE_DISPI_NOCLEARMEM 0x80
|
||||
|
||||
static void vbe_outw(int index, int val)
|
||||
{
|
||||
outw(index, 0x1ce);
|
||||
outw(val, 0x1d0);
|
||||
}
|
||||
|
||||
/* for depth = 8 mode, set a hardware palette entry */
|
||||
void vga_set_color(int i, unsigned int r, unsigned int g, unsigned int b)
|
||||
{
|
||||
r &= 0xff;
|
||||
g &= 0xff;
|
||||
b &= 0xff;
|
||||
outb(i, 0x3c8);
|
||||
outb(r >> 2, 0x3c9);
|
||||
outb(g >> 2, 0x3c9);
|
||||
outb(b >> 2, 0x3c9);
|
||||
}
|
||||
|
||||
/* build standard RGB palette */
|
||||
static void vga_build_rgb_palette(void)
|
||||
{
|
||||
static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
|
||||
int i, r, g, b;
|
||||
|
||||
i = 0;
|
||||
for(r = 0; r < 6; r++) {
|
||||
for(g = 0; g < 6; g++) {
|
||||
for(b = 0; b < 6; b++) {
|
||||
vga_set_color(i, pal_value[r], pal_value[g], pal_value[b]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* depth = 8, 15, 16 or 32 */
|
||||
void vga_vbe_set_mode(int width, int height, int depth)
|
||||
{
|
||||
outb(0x00, 0x3c0); /* enable blanking */
|
||||
vbe_outw(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
|
||||
vbe_outw(VBE_DISPI_INDEX_X_OFFSET, 0);
|
||||
vbe_outw(VBE_DISPI_INDEX_Y_OFFSET, 0);
|
||||
vbe_outw(VBE_DISPI_INDEX_XRES, width);
|
||||
vbe_outw(VBE_DISPI_INDEX_YRES, height);
|
||||
vbe_outw(VBE_DISPI_INDEX_BPP, depth);
|
||||
vbe_outw(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
|
||||
outb(0x00, 0x3c0);
|
||||
outb(0x20, 0x3c0); /* disable blanking */
|
||||
|
||||
if (depth == 8)
|
||||
vga_build_rgb_palette();
|
||||
}
|
||||
|
||||
void vga_vbe_init(char *path, uint32_t fb, uint32_t fb_size,
|
||||
uint32_t rom, uint32_t rom_size)
|
||||
{
|
||||
phandle_t ph, chosen, aliases;
|
||||
|
||||
vga_vbe_set_mode(800, 600, 8);
|
||||
|
||||
ph = find_dev(path);
|
||||
|
||||
set_int_property(ph, "width", 800);
|
||||
set_int_property(ph, "height", 600);
|
||||
set_int_property(ph, "depth", 8);
|
||||
set_int_property(ph, "linebytes", 800);
|
||||
set_int_property(ph, "address", fb & ~0x0000000F);
|
||||
|
||||
chosen = find_dev("/chosen");
|
||||
set_int_property(chosen, "display", ph);
|
||||
|
||||
aliases = find_dev("/aliases");
|
||||
set_property(aliases, "screen", path, strlen(path) + 1);
|
||||
if (rom_size >= 8) {
|
||||
const uint8_t *p;
|
||||
int size;
|
||||
p = rom;
|
||||
if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') {
|
||||
size = *(uint32_t*)(p + 4);
|
||||
set_property(ph, "driver,AAPL,MacOS,PowerPC",
|
||||
p + 8, size);
|
||||
}
|
||||
}
|
||||
|
||||
init_video(fb, 800, 600, 8, 800);
|
||||
}
|
||||
@@ -153,21 +153,8 @@ scroll1( void )
|
||||
osi_fb_info_t fb;
|
||||
int i, x, offs, size, *dest, *src;
|
||||
|
||||
openbios_GetFBInfo( &fb );
|
||||
video_scroll( FONT_ADJ_HEIGHT );
|
||||
|
||||
offs = fb.rb * FONT_ADJ_HEIGHT;
|
||||
size = (fb.h * fb.rb - offs)/16;
|
||||
dest = (int*)fb.mphys;
|
||||
src = (int*)(fb.mphys + offs);
|
||||
|
||||
for( i=0; i<size; i++ ) {
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
for( x=0; x<cons.w; x++ )
|
||||
cons.buf[(cons.h-1)*cons.w + x] = 0;
|
||||
draw_line(cons.h-1);
|
||||
|
||||
@@ -146,7 +146,7 @@ fill_rect( int col_ind, int x, int y, int w, int h )
|
||||
while( ww-- )
|
||||
*p++ = col;
|
||||
} else {
|
||||
char *p = (char*)pp + x;
|
||||
char *p = (ushort*)pp + x;
|
||||
while( ww-- )
|
||||
*p++ = col;
|
||||
}
|
||||
@@ -179,9 +179,32 @@ set_color( int ind, ulong color )
|
||||
dac[1] = ((color >> 8) & 0xff) << 24; // Green
|
||||
dac[1] = (color & 0xff) << 24; // Blue
|
||||
}
|
||||
#else
|
||||
vga_set_color(ind, ((color >> 16) & 0xff),
|
||||
((color >> 8) & 0xff),
|
||||
(color & 0xff));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
video_scroll( int height )
|
||||
{
|
||||
int i, x, offs, size, *dest, *src;
|
||||
|
||||
offs = video.fb.rb * height;
|
||||
size = (video.fb.h * video.fb.rb - offs)/16;
|
||||
dest = (int*)video.fb.mphys;
|
||||
src = (int*)(video.fb.mphys + offs);
|
||||
|
||||
for( i=0; i<size; i++ ) {
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* OF methods */
|
||||
@@ -257,14 +280,18 @@ video_write(void)
|
||||
PUSH(len);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
video_open(void)
|
||||
{
|
||||
RET(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
NODE_METHODS( video ) = {
|
||||
#if 0
|
||||
{"open", video_open },
|
||||
#endif
|
||||
{"dimensions", video_dimensions },
|
||||
{"set-colors", video_set_colors },
|
||||
{"fill-rectangle", video_fill_rect },
|
||||
@@ -278,22 +305,15 @@ NODE_METHODS( video ) = {
|
||||
/************************************************************************/
|
||||
|
||||
void
|
||||
init_video( void )
|
||||
init_video( uint32_t fb, int width, int height, int depth, int rb )
|
||||
{
|
||||
int i, s, size;
|
||||
phandle_t ph=0;
|
||||
|
||||
if( openbios_GetFBInfo(&video.fb) ) {
|
||||
printk("init_video: No video display\n");
|
||||
return;
|
||||
}
|
||||
while( (ph=dt_iterate_type(ph, "display")) ) {
|
||||
set_property( ph, "width", (char*)&video.fb.w, 4 );
|
||||
set_property( ph, "height", (char*)&video.fb.h, 4 );
|
||||
set_property( ph, "depth", (char*)&video.fb.depth, 4 );
|
||||
set_property( ph, "linebytes", (char*)&video.fb.rb, 4 );
|
||||
set_property( ph, "address", (char*)&video.fb.mphys, 4 );
|
||||
}
|
||||
video.fb.mphys = fb;
|
||||
video.fb.w = width;
|
||||
video.fb.h = height;
|
||||
video.fb.depth = depth;
|
||||
video.fb.rb = rb;
|
||||
video.has_video = 1;
|
||||
video.pal = malloc( 256 * sizeof(int) );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user